父进程fork一个子进程后退出,子进程stdin怎么无效了?

han012 2009-04-14 04:35:40
父进程用fork()创建一个子进程后,没有使用wait()等待子进程结束,
而是父进程自己先退出。

结果,子进程的stdin变的无效了,也就是不能通过终端向子进程输入任何数据,
ctrl-c也不能结束子进程。

请问如何在父进程退出后,使子进程的stdin继续可以获得输入?

谢谢
...全文
894 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 han012 的回复:]
To hairetz:

那有没有办法在父进程退出后,不让子进程转到后台运行,可以继续从termial,也就是stdin读取数据?
谢谢!
[/Quote]
从需求上来说,我不能理解你这么做的原因是什么,有什么事情是一个孤儿进程可以完成,而父进程不能完成的呢?
既然你要退出父进程,还不如不fork,直接在父进程里继续操作。
liliangbao 2009-04-15
  • 打赏
  • 举报
回复
来学习!
morris88 2009-04-15
  • 打赏
  • 举报
回复
建议看看LZ, agetty -> login -> bash,它貌似就像楼主需要的:

/*
* We must fork before setuid() because we need to call
* pam_close_session() as root.
*/

child_pid = fork();
if (child_pid < 0) {
int errsv = errno;
/* error in fork() */
fprintf(stderr, _("login: failure forking: %s"), strerror(errsv));
PAM_END;
exit(0);
}

if (child_pid) {
/* parent - wait for child to finish, then cleanup session */
close(0);
close(1);
close(2);
sa.sa_handler = SIG_IGN;
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGINT, &sa, NULL);

/* wait as long as any child is there */
while(wait(NULL) == -1 && errno == EINTR)
;
openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
PAM_END;
exit(0);
}

/* child */

/* restore to old state */
sigaction(SIGHUP, &oldsa_hup, NULL);
sigaction(SIGTERM, &oldsa_term, NULL);
if(got_sig)
exit(1);

/*
* Problem: if the user's shell is a shell like ash that doesnt do
* setsid() or setpgrp(), then a ctrl-\, sending SIGQUIT to every
* process in the pgrp, will kill us.
*/

/* start new session */
setsid();

/* make sure we have a controlling tty */
opentty(ttyn);
openlog("login", LOG_ODELAY, LOG_AUTHPRIV); /* reopen */

/*
* TIOCSCTTY: steal tty from other process group.
*/
if (ioctl(0, TIOCSCTTY, 1))
syslog(LOG_ERR, _("TIOCSCTTY failed: %m"));
#endif
signal(SIGINT, SIG_DFL);

/* discard permissions last so can't get killed and drop core */
if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid) {
syslog(LOG_ALERT, _("setuid() failed"));
exit(1);
}

/* wait until here to change directory! */
if (chdir(pwd->pw_dir) < 0) {
printf(_("No directory %s!\n"), pwd->pw_dir);
if (chdir("/"))
exit(0);
pwd->pw_dir = "/";
printf(_("Logging in with home = \"/\".\n"));
}

/* if the shell field has a space: treat it like a shell script */
if (strchr(pwd->pw_shell, ' ')) {
buff = malloc(strlen(pwd->pw_shell) + 6);

if (!buff) {
fprintf(stderr, _("login: no memory for shell script.\n"));
exit(0);
}

strcpy(buff, "exec ");
strcat(buff, pwd->pw_shell);
childArgv[childArgc++] = "/bin/sh";
childArgv[childArgc++] = "-sh";
childArgv[childArgc++] = "-c";
childArgv[childArgc++] = buff;
} else {
tbuf[0] = '-';
xstrncpy(tbuf + 1, ((p = rindex(pwd->pw_shell, '/')) ?
p + 1 : pwd->pw_shell),
sizeof(tbuf)-1);

childArgv[childArgc++] = pwd->pw_shell;
childArgv[childArgc++] = tbuf;
}

childArgv[childArgc++] = NULL;

execvp(childArgv[0], childArgv + 1);

errsv = errno;

if (!strcmp(childArgv[0], "/bin/sh"))
fprintf(stderr, _("login: couldn't exec shell script: %s.\n"),
strerror(errsv));
else
fprintf(stderr, _("login: no shell: %s.\n"), strerror(errsv));

exit(0);
}
doudouduan 2009-04-15
  • 打赏
  • 举报
回复
关注中...
han012 2009-04-15
  • 打赏
  • 举报
回复
背景是这样的:
父进程完成自己的任务后,fork一个子进程,并为子进程准备运行环境,
然后在子进程中执行execv()启动另外一个可执行程序,
之后父子进程间进行一些通讯,最后父进程退出,子进程单独运行
han012 2009-04-14
  • 打赏
  • 举报
回复
To hairetz:

那有没有办法在父进程退出后,不让子进程转到后台运行,可以继续从termial,也就是stdin读取数据?
谢谢!
  • 打赏
  • 举报
回复
晕.,喝完酒果然就傻了.
楼主你把父进程退出了,这是守护进程的第一步.现在子进程已经算是后台运行了,自然就不能接收了.
  • 打赏
  • 举报
回复
if(scanf("%d",&value)==EOF)
{
int err = errno;
printf("errno is %d,%s\n",err,strerror(err));
}

你是说这里执行不了??什么症状?描述一下
han012 2009-04-14
  • 打赏
  • 举报
回复
以下代码可以表现我的问题

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

int main(int argc,char **argv)
{
pid_t cld_pid;
int status;
int i;

if( (cld_pid=fork())==0 )
{
// this is child process

// wait to parent process terminate...
//sleep(1);

printf("This is child process\n");
printf("My PID(child) is %d\n",getpid()); // print THIS process id
printf("My parent PID is %d\n",getppid()); // print parent process id

for(i=0;i<3;i++)
{
int value=0;
printf("Input %d integet value(child):\n",i);

if(scanf("%d",&value)==EOF)
{
int err = errno;
printf("errno is %d,%s\n",err,strerror(err));
}
else
printf("Input value(child) is %d\n",value);
}
exit(0);
}
else
{
printf("This is parent process\n");
printf("My PID(parent) is %d\n",getpid()); // print THIS process id
printf("My child PID is %d\n",cld_pid); // print parent process id

//printf("Input a integet value(parent):\n");
//int value=0;
//scanf("%d",&value);
//printf("Input value(parent) is %d\n",value);

//wait(&status);
}

return 111;
}
morris88 2009-04-14
  • 打赏
  • 举报
回复
貌似很奇特,有没有示例代码呀...
han012 2009-04-14
  • 打赏
  • 举报
回复
父进程可以使用stdin,

并且父进程退出之前,子进程和父进程都可以从stdin读入数据,就是父进程结束后,
子进程不能从stdin读入数据了,scanf()直接返回!
morris88 2009-04-14
  • 打赏
  • 举报
回复
那子进程继承的父进程可以使用 stdin 吗?
han012 2009-04-14
  • 打赏
  • 举报
回复
不要做成守护进程。

父进程创建完子进程后就没用了,希望及时退出释放所有资源。

在嵌入系统中开发软件,由于系统资源所限,希望同时运行的进程越少越好
morris88 2009-04-14
  • 打赏
  • 举报
回复
貌似守护进程就是这么做的啊...
你是不是做成了守护进程啊...

23,217

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧