一、从内核调用用户空间应用程序
用户空间应用程序大多数时候是由其他应用程序从用户空间中调用的,不深入细节,让我们看一个例子:
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/workqueue.h> /* for work queue */ 4 #include <linux/kmod.h> 5 6 static struct delayed_work initiate_shutdown_work; 7 8 static void delayed_shutdown(struct work_struct *work) 9 { 10 char *cmd = "/sbin/shutdown"; // 要执行的命令 11 char *argv[] = { 12 cmd, //argv[0],代表/sbin/shutdown命令本身 13 "-h", // argv[1],命令行参数1 14 "now", // argv[2],命令行参数2 15 NULL, 16 }; 17 char *envp[] = { //环境变量 18 "HOME=/", 19 "PATH=/sbin:/bin:/usr/sbin:/usr/bin", 20 NULL, 21 }; 22 23 call_usermodehelper(cmd, argv, envp, 0); //设置环境变量envp,执行命令cmd,并传入参数argv[] 24 } 25 26 static int __init my_shutdown_init( void ) 27 { 28 INIT_DELAYED_WORK(&initiate_shutdown_work, delayed_shutdown); 29 schedule_delayed_work(&initiate_shutdown_work, msecs_to_jiffies(200)); 30 return 0; 31 } 32 33 static void __exit my_shutdown_exit( void ) 34 { 35 return; 36 } 37 38 module_init( my_shutdown_init ); 39 module_exit( my_shutdown_exit ); 40 MODULE_LICENSE("GPL"); 41 MODULE_AUTHOR("Allen Wang <1723762735@qq.com>"); 42 MODULE_DESCRIPTION("Simple module that trigger a delayed shut down");
在前面的例子中,使用的 API ( call_usermodehelper )是 Usermode-helper API 的一部分,所有函数都在 kernel/kmod.c 中定义。它的用途很简单,在 kmod.c 里面查一下就知道了。您可能想知道这个API定义的目的是什么。例如,它被内核用于模块 (un)loading 和 cgroups 管理。
二、从内核调用 shell 脚本
1static int call_shell_script(void) 2{ 3 int result = 0; 4 char cmdPath[] = "/bin/bash"; 5 6 char *cmdArgv[] = { 7 cmdPath, 8 "-c", 9 "/bin/ls >> /tmp/list", //可以是 ./xxx.sh 或者 bash xxx.sh 10 NULL, 11 }; 12 13 char *cmdEnvp[] = { 14 "HOME=/", 15 "PATH=/sbin:/bin:/usr/sbin:/usr/bin", 16 NULL, 17 } 18 result = call_usermodehelper(cmdPath, cmdArgv, cmdEnvp, UMH_WAIT_PROC); 19 20 printk(KERN_DEBUG "testDriver1 _init exec! The result of call_usermodehelper is %d ", result); 21 printk(KERN_DEBUG "testDriver1 _init exec! The process is "%s",pid is %d ", current->comm, current->pid); 22}
将上述函数 call_shell_script 添加进内核即可。