一个简单的关于 fork 的问题

anggogo 2005-01-31 11:14:54
以下这段代码是实现一个非常简单的类似 shell 功能的效果, 让用户输入一个完整的命令, 读取后让child process执行它.

for (;;) {
printf(">> ");
scanf("%s", input);
printf("\n");

pid = fork();
wait(NULL);

if (pid==0)
{
rc = execl(input,NULL);

if (rc!=0) {
printf("Error - unknown program.\n");
exit(0);
}
}

} /* end for */

这段代码在我自己的 cygwin 就很正常, 但是在 red hat linux 上, 就只能执行第一次输入的命令, 然后就不断的打印 >> 和 Error - unknown program.

最奇怪的就是在 solaris 上, 这段代码永远都是 segmentation fault

看来这段代码的确有问题, 请熟悉 system call 的指点, 我最近才接触这些, 谢谢!
...全文
139 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
anggogo 2005-02-01
  • 打赏
  • 举报
回复
对, 我后来都自己发现了

我没有 allocate 指针的大小, 所以总是出错

哈哈, 马上给分
anggogo 2005-01-31
  • 打赏
  • 举报
回复
wait 可以接受一个 status 的参数, 但我这里不需要, 所以就设成 NULL 了

win 不是也有提供 createProcess 之类的 api 吗,少用
defyer007 2005-01-31
  • 打赏
  • 举报
回复
应该是wait(pid)吧?
是不是应该加一个父进程的处理代码?
不同os上的进程调度机制不一样
顺便问一个问题,在win下模拟进程调度应该怎么作?
anggogo 2005-01-31
  • 打赏
  • 举报
回复
to piaozi2003()

结果还是一样的, 你确认 wait 是放在子进程代码后面? 因为我用其他文件试过, wait 是放在卡面比较正常

to sharkhuang

在 solaris 上我用 gdb debug 过, 居然在 pid=fork 这行就出错了, 我估计那台机器可能做了什么设置吧. 在 linux 上虽然也能用 gdb 看, 但是执行的跨度比较跳跃, 看得我比较糊涂
piaozi2003 2005-01-31
  • 打赏
  • 举报
回复
for (;;) {
printf(">> ");
scanf("%s", input);
printf("\n");

pid = fork();

if (pid==0)
{
rc = execl(input,NULL);

if (rc!=0) {
printf("Error - unknown program.\n");
exit(0);
}
}

wait(NULL);
} /* end for */
sharkhuang 2005-01-31
  • 打赏
  • 举报
回复
你把core文件打开看看不就知道了
sunvin 2005-01-31
  • 打赏
  • 举报
回复
pid==0??
不断的打印,主程序没关
Kert_t8 2005-01-31
  • 打赏
  • 举报
回复
在Solaris上运行的时候重新编译没有?
Kert_t8 2005-01-31
  • 打赏
  • 举报
回复
-------------------------------------------------------
ding@uj07:~/c379/lab1/tmp>gcc getenv.c -o get
ding@uj07:~/c379/lab1/tmp>gcc te.c
ding@uj07:~/c379/lab1/tmp>./a.out
>> ./get

HOME: /home/dsk03/ugrad/dingdirnanny.¾
>>
-------------------------------------------------------
这是我的部分运行记录



--------------------------------------------------------
UW PICO(tm) 4.6 File: te.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {

char *input;
pid_t pid;
int rc;
for (;;) {
printf(">> ");
input=malloc(100);
scanf("%s", input);
printf("\n");

pid = fork();
wait(NULL);

if (pid==0)
{
rc = execl(input,NULL);

if (rc!=0) {
printf("Error - unknown program.\n");
exit(0);
}
}
free(input);

} /* end for */
}
--------------------------------------------------------
这是我用的你的源代码,补充了必要的声明
Kert_t8 2005-01-31
  • 打赏
  • 举报
回复
知道了,路径问题

你看一下man
-----------------------------------------------------------------------------------
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg , ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
-----------------------------------------------------------------------------------

所以我就估计是路径问题,然后我试了一下,是用绝对路径的时候是正确的
piaozi2003 2005-01-31
  • 打赏
  • 举报
回复
for (;;) {
printf(">> ");
scanf("%s", input);
if((pid = fork())==0){
rc = execl(input,(char*)0);
if (rc!=0) {
printf("Error - unknown program.\n");
exit(0);
}
}
waitpid(pid,NULL,0);
} /* end for */
Kert_t8 2005-01-31
  • 打赏
  • 举报
回复
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAXLINE 1000

int
main()
{

char buf[MAXLINE];
pid_t pid;
int status;

printf("%% ");
while( fgets(buf, MAXLINE, stdin) != NULL ) {
buf[strlen(buf)-1] = 0; /* replace newline with NULL */

if( (pid = fork()) < 0 ) {
perror("fork() failed");
abort;
}
else if( pid == 0 ) {
execlp(buf, buf, (char *)0);
perror("execlp() failed");
fprintf(stderr, "couldn't execute: %s\n", buf);
exit(127);
}

/* parent */

if( (pid = waitpid(pid, &status, 0)) < 0 ) {
perror("waitpid() failed");
abort();
}

printf("%d %% ", WEXITSTATUS(status));
}

exit(0);
}

这段代码肯定可以用,你的代码嘛,。。。。。。再看一下,嘿嘿
ringerxyz 2005-01-31
  • 打赏
  • 举报
回复
这种情况下其实用waitpid比较好,另外我觉得wait应该在子进程之后执行才对,
像楼主的那段代码应该在子进程中也要执行wait(null)的(请高手指正),还有一个问题是你用wait(null),其实返回的不一定是你想要的那个子进程,任何一个子进程返回的话wait(null)就返回了,而此时你的exec说不定还没有执行完呢
我的代码没调试过,楼主要是有兴趣可以试试:
for (;;) {
printf(">> ");
scanf("%s", input);
printf("\n");

pid = fork();


if (pid==0)
{
rc = execl(input,NULL);

if (rc!=0) {
printf("Error - unknown program.\n");
exit(0);
}
}
else
{
waitpid(pid,NULL,0);
}

}

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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