I'm trying to do ioctl command through Mono framework, but I cant find what I'm looking for.
I'm trying to send command to a DVB card that has a kernel module. I hope someone can link or explain clearly how this can be done. Any example with Mono using kernel modules would be useful I guess.
Mono does not contain a wrapper for ioctl in Mono.Unix, because ioctl call parameters vary greatly and such a wrapper would be almost useless. You should declare a DllImport for each ioctl you need.
You probably don't need a helper library written in C, however, you may need it during development to extract actual values hidden behind different C preprocessor macros. For example, to expand C header:
#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
compile and execute this helper:
#include <linux/dvb/frontend.h>
#include <stdio.h>
int main()
{
printf("const int FE_GET_INFO = %d;\n", FE_GET_INFO);
return 0;
}
A short mono mailing list discussion on the topic.
ioctl isn't supported by Mono AFAIK. Too OS-specific and parameter list depends on actual request. You could try DLLImport
Interop with Native Libraries
You should write a wrapper library for your exact calls. Look at how Mono.Unix wraps syscalls (google codesearch for Mono.Unix Syscall.cs) to get the idea. Then create a wrapper for each specific ioctl command, which uses your own representation of the data.
As jitter said - you'll need to DLLImport the ioctl itself.
Check for my similar question, and later question on the subject. In this case I'm trying to wrap the Videl4Linux interface, that could be of interest for you.
I really suggest those readings.
Related
I know how to write some 100 lines C, but I do not know how to read/organize larger source like Rebol. Somewhere was a tutorial with hostkit and dll, but it seems R3 is now statically linked. So I do not know where to look.
How would I write a native which gets a value and returns another? Where to put it in the source? What to obey, like telling the GC I created something in C?
Also, how can I embed R3 in other programms, to call it from Python or Node? I ask for Python/Node part comes later. But my learning-main should access R3 in a similar way. Means dll. And are there some typical hooks for startup/shutdown etc in such ffi's?
[Edit: forgot to mention: it is for Rebol 3.]
That's two questions. :-)
Regarding the first (about adding a native)... it's probably best elaborated as developer documentation on a Wiki. Questions in the rebol tag should generally be more about the language from a user's point of view. The answers regarding source code itself typically will be long, and there's really only a few people who can answer it, or care about the answer (what StackOverflow calls "too localized"). And it will wind up being more of a c question at that point, if anything.
So telling the developers to get their act together and write that documentation and put it in a centrally organized place is probably the best idea! :-P But I actually did try this myself. I added a set-env native to set environment variables from the interpreter, and you can look at the diffs it took to do that in GitHub for a bit of an idea.
add SET-ENV, tweaks to host api for environment string handling
An important thing to remember is that when you touch certain files, you have to run make prep which does a lot of scanning and code generation automatically. Adding a native is one of those things where you're definitely going to have to do that, each time you change to an interface that fundamental.
As for your second question, which is more of a user-facing question about interpreter embedding, one of the first places to look is just in how the simple REPL is implemented. There are two versions in the main repository right now, one for Posix and one for Windows.
https://github.com/rebol/r3/blob/master/src/os/host-main.c
So a string goes in and a string comes out. But there are more complicated forms of interaction, and you can get to them from reb-host.h, which includes these files from src/include
#include "reb-config.h"
#include "reb-c.h"
#include "reb-ext.h" // includes reb-defs.h
#include "reb-args.h"
#include "reb-device.h"
#include "reb-file.h"
#include "reb-event.h"
#include "reb-evtypes.h"
#include "reb-net.h"
#include "reb-filereq.h"
#include "reb-gob.h"
#include "reb-lib.h"
So you can look through those files for the API as it existed at the moment of the December-12th open-sourcing. Things will be evolving, and hopefully much better documented. But for now that's what seems to be available. You could link the host kit as a shared/DLL or static library, it depends on your build settings and what compiler you use.
If I build a function with LLVM, like
int sum(int a, int b)
{
return a + b;
}
using something like http://www.llvmpy.org/llvmpy-doc/dev/doc/firstexample.html, is possible to use that function from inside iOS? as if was a function made with C/C++/Obj-c?
This is because I wonder if building a languaje on LLVM auto-magically provide the path to support iOS for free (ie: is as hard as embed python or something like that).
If yes, how can be done? (ie: call sum from obj-c)
Yes, it is possible. I have done exactly that on Android. And iOS is similar enough that it should be possible there. As long as you are using Interpreter for executing your LLVM code. Because using JIT is forbidden by Apple Developer agreement.
I'm trying to compile some software I've been writing in Linux that uses some fancy new C++0x features on my Mac. I used MacPorts to install the gcc45 package, which gave me /opt/local/bin/g++-mp-4.5, however this compiler doesn't want to compile anything in <thread>. Eg I try to compile:
//test.cpp
#include <thread>
int main()
{
std::thread x;
return 0;
}
and get:
bash-3.2$ /opt/local/bin/g++-mp-4.5 -std=c++0x test.cpp
test.cpp: In function 'int main()':
test.cpp:5:2: error: 'thread' is not a member of 'std'
test.cpp:5:14: error: expected ';' before 'x'
A quick look in /opt/local/include/gcc45/c++/thread shows that the std::thread class is defined, but is guarded by the following:
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
Again, this works perfectly on my Ubuntu machine, so what's the proper way to enable the c++0x <thread> library under the MacPorts version of g++ 4.5 (g++-mp-4.5)? Failing that, is there anything I need to know (configure flags, etc.) before I go about compiling gcc 4.5 myself?
Update:
It doesn't look like the SO community knows much about this, so maybe it's time to go a little closer to the developers. Does anyone know of an official mailing list I could forward this question to? Are there any etiquette tips to help me get an answer?
Update 2:
I asked SO for another temporary solution here, and so I'm now just substituting the boost::thread libraries for the std ones. Unfortunately, there is no boost::future so this isn't quite a full solution yet. Any help would still be greatly appreciated.
Actually <thread> library doesn't work under Mac OS X because pthreads here don't have some functions with timeouts (e.g. pthread_mutex_timedlock()). Availability of this functions have to be checked using _POSIX_TIMEOUTS macro but it's defined to -1 in Mac OS X 10.4, 10.5 and 10.6 (I don't know what's about 10.7) and this functions are really absent in pthread.h.
The _POSIX_TIMEOUTS macro is checked during the configuration of libstdc++. If the check ends successfully _GLIBCXX_HAS_GTHREADS macro becomes defined. And <thread> contents become available with -std=c++0x.
libstdc++ really needs _POSIX_TIMEOUTS e.g. in std::timed_mutex class implementation (see <mutex> header).
To summarize, I think that <thread> would become available on Mac OS X when GCC's gthreads or libstdc++ will implement pthread_mutex_timedlock() (and others) emulation or when this functions will be implemented in Mac OS X.
Or maybe there would be a way in the future C++ standard to query for language features (e.g. this timed functions and classes) and it will be possible to build libstdc++ with this features disabled. However I'm not very familiar with the future standard and have doubts about that feature.
Update - gcc4.7 now allows compilation of on OS X: See here
I would like to be able to do one or more of the following from the shell:
- call any function from the program not only the main
- pass parameters that are not only strings (not only argv)
- have a program return not only int (the return code from main)
- assign returned values to shell-level variables to be able to pass them to other programs
You get the idea.
For instance python toplevel allow this for python programs.
What about C++?
Or a ELF replacement on linux that would allow that?
If you looking for an operating system that does this - the vxWorks shell/C interpreter does this.
But, it's vxWorks - a realtime operating system (no GUI).
It's not too difficult to come up with an app that allows you to call certain functions by name from dynamic libraries such as DLLs under Windows, provided those functions take only a limited selection of parameter types such as ints, floats and fixed strings.
However, for most C++ programs this is not sufficient. For example, suppose your C++ function takes s std::map of dynamic string to socket as a parameter - how are you going to create the map, to say nothing of its contents in your shell?
But if you can forgo C++, there is one language cum operating system that does exactly what you suggest - Smalltalk. If you are interested in this paradigm, take a look at Squeak, which is free software.
Under Windows, there is RUNDLL32 to call DLL function, eg
RUNDLL32.EXE USER32.DLL,SwapMouseButton
Have you looked at c-repl?
The system would have to be completely interpreted, right? And how would you know the function signatures of the things you were calling?
I'm writing a Linux kernel module that needs to open and read files. What's the best way to accomplish that?
Can I ask why are you trying to open a file?
I like to follow Linux development (out of curiosity, I'm not a kernel developer, I do Java), and I've seen discussion of this question before. I was able to find a LKML message about this, basically mentioning it's usually a bad idea. I'm almost positive that LWN covered it in the last year, but I'm having trouble finding the article.
If this is a private module (like for some custom hardware and the module won't be distributed) then you can do this, but I'm under the impression that if you are going to submit your code to the mainline then it may not be accepted.
Evan Teran mentioned sysfs, which seems like a good idea to me. If you really need to do harder custom stuff you could always make new ioctrls.
EDIT:
OK, I found the article I was looking for, it's from Linux Journal. It explains why doing this kind of stuff is generally a bad idea, then goes on to tell you exactly how to do it anyway.
assuming you can get pointers to the relavent function pointers to the open/read/close system calls, you can do something like this:
mm_segment_t fs = get_fs();
set_fs(KERNEL_DS);
fd = (*syscall_open)(file, flags, mode);
if(fd != -1) {
(*syscall_read)(fd, buf, size);
(*syscall_close)(fd);
}
set_fs(fs);
you will need to create the "syscall_*" function pointers I have shown though. I am sure there is a better way, but I believe that this would work.
Generally speaking, if you need to read/write files from a kernel module, you're doing something wrong architecturally.
There exist mechanisms (netlink for example - or just register a character device) to allow a kernel module to talk to a userspace helper process. That userspace helper process can do whatever it wants.
You could also implement a system call (or such like) to take a file descriptor opened in userspace and read/write it from the kernel.
This would probably be neater than trying to open files in kernel space.
There are some other things which already open files from kernel space, you could look at them (the loop driver springs to mind?).
/proc filesystem is also good for private use, and it's easy.
http://www.linuxtopia.org/online_books/Linux_Kernel_Module_Programming_Guide/x773.html
All of the kernel developers say that file I/O from kernel space is bad (especially if you're referring to these files by their paths) but the mainstream kernel does this when you load firmware. If you just need to read from files, use the
kernel_read_file_from_path(const char *path, void **buf, loff_t *size, loff_t max_size, enum kernel_read_file_id id)
function, which is what the firmware loader code uses, declared in include/linux/fs.h. This function returns a negative value on error.
I'm not really sure of the point of the id variable at the end, if you look at the code it's not really used, so just put something like READING_FIRMWARE there (no quotes).
buf is not null terminated, instead refer to its size in size. If you need it to be null terminated, create a string size + 1 bytes long and copy it over or rewrite the kernel_read_file() function (used by kernel_read_file_from_path(), defined in fs/exec.c) and add one to i_size where memory is allocated. (If you want to do this, you can redefine the kernel_read_file() function in your module with a different function name to avoid modifying the whole kernel.)
If you need to write to files, there is a kernel_write() function (analogous to kernel_read(), which is used by kernel_read_file() and therefore also by kernel_read_file_from_path()), but there is no kernel_write_file() or kernel_write_file_from_path() function. You can look at the code in the fs/exec.c file in the Linux kernel source tree where kernel_read_file() and kernel_read_file_from_path() are defined to write your own kernel_write_file() and kernel_write_file_from_path() functions that you can include in your module.
And as always, you can store a file's contents in a char pointer instead of a void pointer with this function by casting it.
You can also find some informations about sys_call_open in this Linux Kernel Module Programing Guide.