笔记1-3: 从标准输入读取命令并执行

来源:互联网 发布:大数据好学吗 编辑:程序博客网 时间:2024/04/30 15:15

从标准输入读取命令并执行:

 

#include <apue.h>

#include <unistd.h>

#include <sys/wait.h>

 

int main(int argc, char ** argv)

{

   char  buf[MAXLINE];

   pid_t pid;

   int   status;

   printf("%% ");

   while (fgets(buf, MAXLINE, stdin) != NULL)

   {

      if (buf[strlen(buf) - 1] == '\n')

          buf[strlen(buf) - 1] = 0;      // replace newline with NULL

      if ((pid = fork()) < 0) {

          err_sys("fork error\n");

      } else if (pid == 0) {            // child,子进程从这里执行

          execlp(buf, buf, (char*)0);

          err_ret("could not execute : %s\n", buf);

          exit(127);

      }

      // parent, 父进程从这里执行

      if ((pid = waitpid(pid, &status, 0)) < 0)

          err_sys("waitpid error.\n");

      printf("%% ");

   }

   return 0;

}

 

因为上面的gfets函数读入命令到buf时,缓冲区最后一个字符为’\n’,所以读入后,要把’\n’置换为NULL

Unix通过fork函数创建一个新的进程,函数原型为:

pid_t fork (void);

pid_t为一个整数类型。

fork()的调用,会创建一个新的Unix进程,新进程是原进程的一个复制品,我们称呼原来的进程为父进程,新创建的进程为子进程。fork()调用一次,会得到两次返回。对于父进程,fork()会返回新的子进程的进程ID(非负数);对于子进程,fork()会返回0(分别在父子进程返回)。

fork()函数调用,会将父进程的地址空间完整地复制给子进程,调用后,父子进程各自拥有自己独立的进程空间。后续程序可根据pid_t的返回值,来确定父子进程的程序不同走向。

fork()返回负数,表示创建进程失败。

 

exec系列函数用于执行一个新的可执行文件。通常是在fork()后的子进程中调用,其作用是,把新的可执行文件加载到内存,来覆盖本进程的原有的进程空间,并跳到新可执行文件的起始位置重新执行。execlp()函数是exec()系列函数组中的一个。

 

父进程希望等待子进程终止,可以调用waitpid()函数实现。原型为:

pid_t waitpid(pid_t pid,int * status,int options);

pid指出子进程的IDwaitpid可以返回子进程的终止状态(status)