17

I want to use system() function of stdlib.h in my c code. I am actually working on kernel programming.

Whenever i want to use system() in it, it gives error to stdlib.h saying no such file found.

enb081
  • 3,831
  • 11
  • 43
  • 66
user2122972
  • 191
  • 1
  • 1
  • 3
  • 6
    It's generally a bad bad bad idea to call user space commands from kernel :) – favoretti Mar 28 '13 at 07:58
  • 4
    Using `system()` in kernel is a bad idea. But it's not a good reason to down-vote the question. You can explain why he should avoid this, and what is the alternatives. _It's just my opinion_ – masoud Mar 28 '13 at 08:17
  • `I want to use system() function of stdlib.h in my c code. I am actually working on kernel programming.` , Its a really really bad idea !! , even if surprisingly you get it to work , and still your system has not crashed ..Are you trying to echo any debugging messages ?? If that is the case use [printk()](http://www.makelinux.net/books/lkd2/ch18lev1sec3) and dmesg !! – Barath Ravikumar Mar 28 '13 at 08:19
  • It is generally not too helpful to describe something as bad, but not explain why. It is much more flexible for the kernel to send an event to user-space. For example [netlink](http://en.wikipedia.org/wiki/Netlink) can be used to send a message to a user space task, which starts the user space task you want. This puts a lot more flexibility in how the event is handled, etc as it moves some *policy* about what happens on an event from the kernel to user space. Then an admin can decided what to do. This is not as important in embedded places, but should still be considered. – artless noise Mar 28 '13 at 16:41
  • Newer kernels offer [`inotify`](http://en.wikipedia.org/wiki/Inotify) on *sysfs* and/or *procfs* entries. This can also be used as a *user space* notification mechanism. Your user space task can then run the `system()` that you are familiar with. – artless noise Mar 28 '13 at 16:47

4 Answers4

21

It's simple!

#include <linux/kmod.h>

char * envp[] = { "HOME=/", NULL };
char * argv[] = { "/bin/ls", NULL };

call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
Ilya Matveychikov
  • 3,936
  • 2
  • 27
  • 42
6

What you probably want is executing a userspace function. That SE answer includes a link to an IBM article with an example userspace process invoked from the kernel. The search terms you should use are "usermodehelper" and "usermode helper".

In the kernel, see:

yba@tavas:~/linux-2.6/linux-2.6$ find . -type f | xargs grep "usermode.helper"
./kernel/cgroup.c:      /* Drop the lock while we invoke the usermode helper,
./kernel/kmod.c:    /* CLONE_VFORK: wait until the usermode helper has execve'd
./kernel/kmod.c: * call_usermodehelper_setup - prepare to call a usermode helper
./drivers/block/drbd/drbd_int.h:extern char usermode_helper[];
./drivers/block/drbd/drbd_nl.c: char *argv[] = {usermode_helper, cmd, mb, NULL };
./drivers/block/drbd/drbd_nl.c: dev_info(DEV, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
./drivers/block/drbd/drbd_nl.c: ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
./drivers/block/drbd/drbd_nl.c:             usermode_helper, cmd, mb,
./drivers/block/drbd/drbd_nl.c:             usermode_helper, cmd, mb,
./drivers/block/drbd/drbd_nl.c: char *argv[] = {usermode_helper, cmd, tconn->name, NULL };
./drivers/block/drbd/drbd_nl.c: conn_info(tconn, "helper command: %s %s %s\n", usermode_helper, cmd, tconn->name);
./drivers/block/drbd/drbd_nl.c: ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
./drivers/block/drbd/drbd_nl.c:           usermode_helper, cmd, tconn->name,
./drivers/block/drbd/drbd_nl.c:           usermode_helper, cmd, tconn->name,
./drivers/block/drbd/drbd_main.c:char usermode_helper[80] = "/sbin/drbdadm";
./drivers/block/drbd/drbd_main.c:module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644);
./drivers/block/drbd/drbd_main.c:        * currently blocked waiting for that usermode helper to
./security/keys/request_key.c: * Initialise a usermode helper that is going to have a specific session
./security/keys/request_key.c: * Clean up a usermode helper with session keyring.
./security/keys/request_key.c: * Call a usermode helper with a specific session keyring.
Community
  • 1
  • 1
Jonathan Ben-Avraham
  • 4,615
  • 2
  • 34
  • 37
0

No easy way, because system() is a user-level C library function, which involve many system calls, including:

 sys_fork()
 sys_execve()

You could acchive system() effect using the following ways ( I guess):

 create a kernel thread.

 let the kernel thread execute sys_execve( your command name)

Not sure this could work, but you can try.

xzhao28
  • 11
  • 1
-5

You can't use system() from the kernel. End of story. There is no application level code to execute from the kernel space.

Randy Howard
  • 2,165
  • 16
  • 26