系统调用中与被调用的命令交互方式
2007-11-29 17:09
351 查看
系统调用中,如果要和系统命令进行多次交互,那么system函数和popen都不能胜任,popen是单向管道.
要么从中获取标准出,要么向其写入标准输入.所以用fork子进程和父进程利用pipe来进行双向通讯才
能解决.
以修改用户密码为例,当然直接执行echo mypwd|passwd myname --stdin是可以的,但为了说明
向被调用的子进程传递输入,我让子进程执行 passwd my name --stdin,然后从标准输入中获取密码.
父进程通过管道向其输入密码.然后等待子进程执行完成后,获取子进程的标准输出.来判断是否更新成功.
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
char passwd[] = "abcd1234/n";
main()
{
int mypipe[2];
char buf[256];
pid_t pid;
int stat_loc,i;
pipe(mypipe);
if ((pid = fork()) != 0) {
close(0); //父进程不需要使用标准输入.这里没有必要关闭,但为了说明
//因为要printf所以不能close(1);来重定向输出
write(mypipe[1],passwd,strlen(passwd));
//向管道写入密码后等待子进程的执行,如果是多次交互,应该使用
//状态标记来控制父子进程之间每一步的执行步骤.
waitpid(pid,&stat_loc,0);
//子进程执行完成后读取子进程的标准输出判断是否成功.
for(i=0;i<100;i++){
read(mypipe[0],buf,sizeof(buf));
//这里可以通过在上面重定向管道输入来从标准输入中读取
if(strstr(buf,"all authentication tokens updated successfully")){
printf("OK/n");
break;
}
}
exit(0);
}
else{
close(0); //关闭原来的标准输入
dup(mypipe[0]); //将管理输入重定向到标准输入
close(1); //关闭原来的标准输出
dup(mypipe[1]); //将管理输出重定向到标准输出
close(mypipe[0]);
close(mypipe[1]);
execlp("passwd","passwd", "axman","--stdin",0);
//以下代码不会执行,execlp将当前进程的执行码直接跳转到passwd开始处执行.但进程的所有状态不
//变,即从此处开始用passwd的执行码替换进程原来的执行码.
}
}
要么从中获取标准出,要么向其写入标准输入.所以用fork子进程和父进程利用pipe来进行双向通讯才
能解决.
以修改用户密码为例,当然直接执行echo mypwd|passwd myname --stdin是可以的,但为了说明
向被调用的子进程传递输入,我让子进程执行 passwd my name --stdin,然后从标准输入中获取密码.
父进程通过管道向其输入密码.然后等待子进程执行完成后,获取子进程的标准输出.来判断是否更新成功.
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
char passwd[] = "abcd1234/n";
main()
{
int mypipe[2];
char buf[256];
pid_t pid;
int stat_loc,i;
pipe(mypipe);
if ((pid = fork()) != 0) {
close(0); //父进程不需要使用标准输入.这里没有必要关闭,但为了说明
//因为要printf所以不能close(1);来重定向输出
write(mypipe[1],passwd,strlen(passwd));
//向管道写入密码后等待子进程的执行,如果是多次交互,应该使用
//状态标记来控制父子进程之间每一步的执行步骤.
waitpid(pid,&stat_loc,0);
//子进程执行完成后读取子进程的标准输出判断是否成功.
for(i=0;i<100;i++){
read(mypipe[0],buf,sizeof(buf));
//这里可以通过在上面重定向管道输入来从标准输入中读取
if(strstr(buf,"all authentication tokens updated successfully")){
printf("OK/n");
break;
}
}
exit(0);
}
else{
close(0); //关闭原来的标准输入
dup(mypipe[0]); //将管理输入重定向到标准输入
close(1); //关闭原来的标准输出
dup(mypipe[1]); //将管理输出重定向到标准输出
close(mypipe[0]);
close(mypipe[1]);
execlp("passwd","passwd", "axman","--stdin",0);
//以下代码不会执行,execlp将当前进程的执行码直接跳转到passwd开始处执行.但进程的所有状态不
//变,即从此处开始用passwd的执行码替换进程原来的执行码.
}
}
相关文章推荐
- Python调用系统命令的两种方式
- [收藏]通过命令的方式调用系统的小工具
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用----20135334赵阳林
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用(Linux)
- 实现自己的系统调用(两种方式) 【转】
- 实验四——使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- Linux内核分析-两种方式使用同一个系统调用
- ios开发之 调用系统电话方式(两种)
- 多种方式实现JS调用后台方法进行数据交互
- linux下php调用系统命令(root权限)
- 内存分配的原理__进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)
- 库函数系统调用文件方式,王明学learn
- 通过 open falcon 的 agent 的http 接口实现远程系统命令调用
- python可以调用外部系统命令
- Java调用Linux命令两种方式的例子
- 系统调用、POSIX、C库、系统命令和内核函数
- Python用subprocess的Popen来调用系统命令
- 2-8 系统调用方式的文件编程
- 用命令方式查看进程在你的系统中开了什么端口?
- Nodejs中调用系统命令、Shell脚本和Python脚本的方法和实例