system("~/myprogram/test.sh")}执行结果如下:xiakeyou@ubuntu:~/myprogram$ gcc systemtest.c -o
systemtestxiakeyou@ubuntu:~/myprogram$ ./systemtest/home/d/e/xiakeyouxiakeyou@ubuntu:~/myprogram$2)popen(char *command,char *type)执行过程:popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh
-c来执行参数command的指令。参数
type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件
指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。此外,所有使用文件指针(FILE*) *** 作的函数也都可以使
用,除了fclose()以外。返回值:若成功则返回文件指针,否则返回NULL,错误原因存于errno中。
注意:在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。例:C程序popentest.c内容如下:#include<stdio.h>main(){FILE * fpcharbuffer[80]fp=popen(“~/myprogram/test.sh”,”r”)fgets(buffer,sizeof(buffer),fp)printf(“%s”,buffer)pclose(fp)}执行结果如下:xiakeyou@ubuntu:~/myprogram$ vim popentest.cxiakeyou@ubuntu:~/myprogram$ gcc popentest.c -o popentestxiakeyou@ubuntu:~/myprogram$ ./popentest/home/d/e/xiakeyouxiakeyou@ubuntu:~/myprogram$
只是偶能力可能有点有限,没有太看懂。直接用system()倒是脚本可是执行,只是返回值却是一塌糊涂,试了多次也没有找到什么规律。不免又看了一下上面的那篇博文,得到一些启发,可以这样来实现:先将脚本的返回值利用 echo >XXXXX 输出到一个本地文件中当需要这个返回值是,可是通过C语言的文件 *** 作函数来直接从文件中读取后来一想,这应该就是上文中POPEN的实现方法!C程序调用shell脚本共有三种法子 :system()、popen()、exec系列函数 system()
不用你自己去产生进程,它已经封装了,直接加入自己的命令exec 需要你自己 fork 进程,然后exec 自己的命令popen() 也可以实现执行你的命令,比system 开销小1)system(shell命令或shell脚本路径)system()会调用fork()产生 子历程,由子历程来调用/bin/sh-c string来履行
参数string字符串所代表的命令,此命令履行 完后随即返回原调用的历程。在调用system()期间SIGCHLD
信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被漠视 。
返回值:如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值。
如果 system()调用成功 则最后会返回履行
shell命令后的返回值,但是此返回值也有可能为system()调用/bin/sh失败所返回的127,因 此最好能再反省 errno
来确认履行 成功 。system命令以其简略 高效的作用得到很很广泛 的利用 ,下面是一个例子例:在~/test/目录下有shell脚本test.sh,内容为#!bin/bash#test.shecho hello在同层目录下新建一个c文件system_test.c,内容为:#include<stdlib.h>int main(){system("~/test/test.sh")}履行 效果 如下:[root@localhost test]$gcc system_test.c -o system_test[root@localhost test]$./system_testhello[root@localhost test]$2)popen(char *command,char *type)popen()会调用fork()产生 子历程,然后从子历程中调用/bin/sh -c来履行
参数command的指令。参数type可应用 “r”代表读取,“w”代表写入。遵循此type值,popen()会建立
管道连到子历程的标准 输出设备 或标准 输入设备 ,然后返回一个文件指针。随后历程便可利用 此文件指针来读取子历程的输出设备
或是写入到子历程的标准 输入设备 中。此外,所有应用 文 件指针(FILE*) *** 作的函数也都可以应用
,除了fclose()以外。返回值:若成功 则返回文件指针,否则返回NULL,差错
原因存于errno中。注意:在编写具SUID/SGID权限的程序时请尽量避免应用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。例:C程序popentest.c内容如下:#include<stdio.h>main{FILE * fpcharbuffer[80]fp=popen(“~/myprogram/test.sh”,”r”)fgets(buffer,sizeof(buffer),fp)printf(“%s”,buffer)pclose(fp)}履行 效果 如下:[root@localhost test]$ vim popentest.c[root@localhost test]$ gcc popentest.c -o popentest[root@localhost test]$ ./popentest/root/test[root@localhost test]$
Linux驱动程序的使用可以按照两种方式编译,一种是静态编译进内核,另一种是编译成模块以供动态加载。由于uClinux不支持模块动态加载,而且嵌入式LINUX不能够象桌面LINUX那样灵活的使用insmod/rmmod加载卸载设备驱动程序,因而这里只介绍将设备驱动程序静态编译进uClinux内核的方法。下面以UCLINUX为例,介绍在一个以模块方式出现的驱动程序test.c基础之上,将其编译进内核的一系列步骤:
(1)
改动test.c源带代码
第一步,将原来的:
#include
#include
char
kernel_version[]=UTS_RELEASE
改动为:
#ifdef
MODULE
#include
#include
char
kernel_version[]=UTS_RELEASE
#else
#define
MOD_INC_USE_COUNT
#define
MOD_DEC_USE_COUNT
#endif
第二步,新建函数int
init_test(void)
将设备注册写在此处:
result=register_chrdev(254,"test",&test_fops)
(2)将test.c复制到/uclinux/linux/drivers/char目录下,并且在/uclinux/linux/drivers/char目录下mem.c中,int
chr_dev_init(
)函数中增加如下代码:
#ifdef
CONFIG_TESTDRIVE
init_test()
#endif
(3)在/uclinux/linux/drivers/char目录下Makefile中增加如下代码:
ifeq($(CONFIG_TESTDRIVE),y)
L_OBJS+=test.o
Endif
(4)在/uclinux/linux/arch/m68knommu目录下config.in中字符设备段里增加如下代码:
bool
'support
for
testdrive'
CONFIG_TESTDRIVE
y
(5)
运行make
menuconfig(在menuconfig的字符设备选项里你可以看见我们刚刚添加的'support
for
testdrive'选项,并且已经被选中);make
dep;make
linux;make
linux.text;make
linux.data;cat
linux.text
linux.data
>
linux.bin。
(6)
在
/uclinux/romdisk/romdisk/dev/目录下创建设备:
mknod
test
c
254
0
并且在/uclinux/appsrc/下运行make,生成新的Romdisk.s19文件。
到这里,在UCLINUX中增加设备驱动程序的工作可以说是完成了,只要将新的linux.bin与Romdisk
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)