进程fork没有执行所需的代码

时间:2014-09-21 14:40:51

标签: c exec fork

所以我正在尝试执行我教授给我的这段代码。这很简单。它分叉,检查分叉是否正常工作,然后在另一个文件中执行另一段代码。

出于某种原因,在我的OS X 10.9.5机器上,它无法执行第二位代码。以下是两个程序:

exercise.c

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


int main() {
  pid_t child = fork();
  if ((int)child < 0) {
    fprintf(stderr, "fork error!\n");
    exit(0);
  } else if ((int)child > 0) {
    int status;
    (void) waitpid(child, &status, 0);
    if (WIFEXITED(status)) {
      printf("child %d exited normally and returned %d\n",
         child, WEXITSTATUS(status));
    } else if (WIFSIGNALED(status)) {
      printf("\nchild %d was killed by signal number %d and %s leave a core dump\n",
         child, WTERMSIG(status), (WCOREDUMP(status) ? "did" : "didn't"));
    } else {
      printf("child %d is dead and I don't know why!\n", child);
    }
  } else {
    char *argv[] = { "./getcode" };
    execve(argv[0], argv, NULL);
  }

  return 0;
}

和getcode.c

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


int main() {
  int rc = 256;
  printf("I am child process %d\n", getpid());
  while ((rc > 255) || (rc < 0)) {
    printf("please type an integer from 0 to 255: ");
    scanf("%d", &rc);
  }
  exit(rc);
}

我使用命令编译两者:

gcc -Wall -pedantic-errors exercise.c -o exercise

gcc -Wall -pedantic-errors getcode.c -o getcode

不幸的是,我从子进程中回来的唯一一件事是返回代码为0

./exercise
child 903 exited normally and returned 0

我很困惑。有人可以帮忙吗?

编辑:好的,所以我按要求添加了perror("execve"),然后返回execve: Bad address。那么我该如何解决这个问题呢?

EDIT2:好的。我修好了它。我已经改变了上面代码的位,包括:

char *argv[] = { "./getcode",NULL };
execve(argv[0], argv, NULL);

空终止修复了argv问题。

2 个答案:

答案 0 :(得分:2)

您需要使用NULL元素终止argv。从execve手册页:

Both argv and envp must be terminated by a NULL pointer.

还不清楚NULL对envp参数是否有效。 Linux手册页说

  

在Linux上,argv可以指定为NULL,这与将此参数指定为指向包含单个NULL指针的列表的指针具有相同的效果。不要利用这种错误!它是非标准且不可移植的:在大多数其他UNIX系统上执行此操作将导致错误(EFAULT)。

可能将envp指定为NULL同样是非标准的。如果您不需要指定环境,请使用execv not execve。

你应该检查execve的返回值。并使用errno来确定原因。例如,使用perror("execve")可能会抱怨。

答案 1 :(得分:1)

您没有查看execve来电的结果,因此我怀疑它失败了,子进程在return 0结束时到达main