fork

int fork(); 

创建一个新进程。fork在子进程中返回0,在父进程中返回子进程pid。 fork后的子进程拥有父进程fd表的拷贝,但是他们共享offset。

exit

int exit(int status);

结束当前进程,无返回值。status的值可在wait中接收。按惯例,0表示成功,1表示错误。

wait

int wait(int* status);

等待一个子进程结束。返回值为子进程pid,status接收子进程状态。如果当前进程没有子进程,wait立即返回-1。如果不关心返回状态,可传0作为参数。

exec

将当前进程的内存替换为指定文件的布局。无返回。

char *argv[3];
argv[0] = "echo";
argv[1] = "hello";
argv[2] = 0;
exec("/bin/echo", argv);
printf("exec error\n");

将fork和exec拆分为两个系统调用有什么好处?

fork后的子进程拥有父进程fd表的拷贝,exec将保留这些打开的文件。这使得我们可以在两个系统调用之间打开和关闭文件,以进行重定向。

char *argv[2];
argv[0] = "cat";
argv[1] = 0;
if(fork() == 0) {
  close(0);
  open("input.txt", O_RDONLY);
  exec("cat", argv);
}

read

从fd中读取最多n字节到buf中,返回读取的字节数。

int read(int fd, char *buf, int n)

write

向fd中写入buf中的n字节。返回写入的字节数。如果返回值不等于n,意味着写入出错。

dup

复制一个fd,返回新的fd,两个fd共享offset。

int dup(int fd);

dup允许shell实现以下命令:

ls existing-file non-existing-file > tmp1 2>&1

pipe

创建一个管道,fds[0]fds[1]分别用于读和写。

int pipe(int* fds)