C 无法读取fork之后子项中的stdin?
一个常规的C程序,是一些shell程序的实现,它使用标准输入获取命令并执行它们,其中main()声明为:int main(int argc,char*argv[]),正常工作。 这是一个小的shell程序,它打印一个提示并在循环中等待用户输入,然后执行输入的命令。但是,我希望在调用时使命令行参数不可见,如下所示:C 无法读取fork之后子项中的stdin?,c,shell,fork,C,Shell,Fork,一个常规的C程序,是一些shell程序的实现,它使用标准输入获取命令并执行它们,其中main()声明为:int main(int argc,char*argv[]),正常工作。 这是一个小的shell程序,它打印一个提示并在循环中等待用户输入,然后执行输入的命令。但是,我希望在调用时使命令行参数不可见,如下所示: 将main()函数重命名为old_main() 创建一个新的main()函数: 将argv[]字符串数组复制到新数组,然后 删除原始argv[]结构 分叉自身,并在子进程中使用保存
- 将main()函数重命名为old_main()
- 创建一个新的main()函数:
- 将argv[]字符串数组复制到新数组,然后
- 删除原始argv[]结构李>
- 分叉自身,并在子进程中使用保存的命令行参数调用old_main,然后退出父进程
$ echo quit | ./newprog
命令'quit'被执行(导致程序退出),因此当stdin被重定向时程序仍然工作,但在交互模式下不工作
下面是分叉的新程序,在子程序中使用保存的命令行参数调用旧的main
/* newprog.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_NARGS 40
extern int old_main(int nargc, char *nargv[]);
int main(int argc, char *argv[])
{
int i; pid_t pid;
int nargc=argc;
char *nargv[];
nargv[0]=argv[0];
for (i = 1; i < argc; i++)
{
nargv[i]=strdup(argv[i]);
memset(argv[i],0,strlen(argv[i]));
}
nargv[i]=NULL;
pid=fork();
if (pid == 0) return old_main(nargc, nargv); /* child calls old_main() */
else if (pid == -1) printf("error: fork()\n");
exit(0); /* exit parent */
}
/*newprog.c*/
#包括
#包括
#包括
#包括
#定义最大值40
旧城区外部(内部nargc,字符*nargv[]);
int main(int argc,char*argv[])
{
int i;pid_t pid;
int nargc=argc;
char*nargv[];
nargv[0]=argv[0];
对于(i=1;i
我无意中发现,对于我原来的问题(不在进程列表中显示命令行参数),我不必执行fork,这里介绍的方法是将旧的命令行参数复制到新变量,然后删除旧的命令行参数,这在原始的主函数中起作用。但这个问题只解决了一个问题,即在子程序中fork()之后,标准输入似乎不再像原始程序中那样起作用。仍然有兴趣知道这是什么原因。父进程是shell的子进程。在执行命令之前,shell很可能会设置到父stdin的重定向。退出父级时,重定向将终止。孩子的stdin不再监听任何东西。这是关于这个问题的相关阅读,可能是值得复制的@StoryTeller:我假设(fork()的文档化特性-参见man 2 fork)孩子继承openfiles的父文件描述符,通常包括stdin、stdout和stderr,所以即使父文件退出,孩子也应该能够像往常一样读取stdin和写入stdout。在我的例子中,我发现子对象在父对象退出后调用的fgets()中的输入不会等待用户输入,但是,如果我使用shell重定向,则该输入会通过子对象的fgets,并正常工作。为什么会有这种行为差异?man 2 fork:“子对象继承父对象的一组打开文件描述符的副本。子对象中的每个文件描述符都引用相同的打开文件描述(参见打开(2))作为父级中相应的文件描述符。这意味着这两个描述符共享打开的文件状态标志、当前文件偏移量和信号驱动的I/O属性(请参阅fcntl(2)中的F_SETOWN和F_SETSIG说明)。“问题不在于复制文件描述符。问题在于有人在流中写入父级和子级侦听。使用管道命令时,子管道描述符足以保持管道打开。但这与shell从终端转发输入不同。只要父节点还活着,它就会转发,因为这是它等待的唯一PID。