fork ,system,popen

popen函数定义:

FILE* popen(const char* command,const char* type);
int pclose(FILE* stream);

函数说明:

popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。这个进程必须由 pclose() 函数关闭,而不是 fclose() 函数。pclose() 函数关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态。如果 shell 不能被执行,则 pclose() 返回的终止状态与 shell 已执行 exit 一样。
type 参数只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 "r" 则文件指针连接到 command 的标准输出;如果 type 是 "w" 则文件指针连接到 command 的标准输入。
command 参数是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用-c 标志,shell 将执行这个命令。

popen 的返回值是个标准 I/O 流,必须由 pclose 来终止。前面提到这个流是单向的。所以向这个流写内容相当于写入该命令的标准输入;命令的标准输出和调用 popen 的进程相同。与之相反的,从流中读数据相当于读取命令的标准输出;命令的标准输入和调用 popen 的进程相同。

返回值:

如果调用 fork() 或 pipe() 失败,或者不能分配内存将返回NULL,否则返回标准 I/O 流。

有关popen函数代码:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<wait.h>
#include<stdlib.h>
void printf_popen(FILE* ret)
{
 char buf[100];
 memset(buf,0,sizeof(buf));
 if(ret==NULL)
 {
	 return ;
 }
 else
 {
	 fgets(buf,sizeof(buf)-1,ret);
	 printf("%s\n",buf);
 }
}
int main()
{
 FILE* ret=NULL;
 ret=popen("ls -1","r");
 if(ret==NULL)
 {
	 perror("popen");
	 exit(EXIT_FAILURE);
 }
 printf_popen(ret);
 pclose(ret);
 sleep(1);
}

sysytem函数定义:

int system( const char* string);

函数说明:

system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。

返回值:

如果fork()失败 返回-1:出现错误
如果exec()失败,表示不能执行Shell,返回值相当于Shell执行了exit(127)
如果执行成功则返回子Shell的终止状态
如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),仅当命令处理程序可用时,返回非零值,可以通过这一特征判断在一个给定的操作系统上是否支持system函数(当system函数返回值为0时,表明system函数无效,在UNIX系统中,system函数总是可用的);。如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。

有关system函数的代码::
#include<stdio.h>
#include<unistd.h>
#include<string.h>

int main()
{
    int ret;
   ret= system("ls");
   printf("ret=%d\n",ret);
	return 0;
}

程序运行结果:


fork函数定义:

pid_t fork(void);

函数说明:

一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。

子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。

UNIX将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。在不同的UNIX (Like)系统下,我们无法确定fork之后是子进程先运行还是父进程先运行,这依赖于系统的实现。所以在移植代码的时候我们不应该对此作出任何的假设。

返回值:

当返回0时,表示程序进入子进程;当返回-1,表示fork失败;否则程序进入父进程。

有关fork函数的代码:

#include<stdio.h>
#include<unistd.h>
#include<wait.h>
#include<string.h>
#include<stdlib.h>
int main()
{
	pid_t ret;
	ret=fork();
	switch(ret)
	{
		case -1:
			perror("fork");
			exit(EXIT_FAILURE);
			break;
		case 0:
			printf("子进程\n");
			break;
		default:
			{
				int status;
				pid_t num;
				printf("父进程");
				num=wait(&status);
				break;
			}

	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值