简体   繁体   中英

Process fork isn't executing desired code

So I'm trying to execute this code given to me by my professor. It's dead simple. It forks, checks to see if the forking works properly, then executes another bit of code in a separate file.

For some reason, on my OS X 10.9.5 machine, it's failing to execute the second bit of code. Here are both of the programs:

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;
}

And 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);
}

I compile both with the commands:

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

and

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

Unfortunately, the only thing I get back from the child process is a return code of 0

./exercise
child 903 exited normally and returned 0

I'm baffled. Can anyone help?

EDIT: Okay, so I included perror("execve") as requested, and it returns execve: Bad address . So how can I fix that?

EDIT2: All right. I fixed it. I've changed the bit of the above code to include this:

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

Null termination fixes the argv issues.

You need to terminate argv with a NULL element. From the execve man page:

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

Also it is not clear that NULL is valid for the envp argument. The Linux man page says

On Linux, argv can be specified as NULL, which has the same effect as specifying this argument as a pointer to a list containing a single NULL pointer. Do not take advantage of this misfeature! It is nonstandard and nonportable: on most other UNIX systems doing this will result in an error (EFAULT).

Possibly specifying envp as NULL is similarly nonstandard. Use execv not execve if you don't need to specify an environment.

You should check the return value of execve. And use errno to determine the cause. Eg., use perror("execve") It may be complaining.

您没有检查execve调用的结果,所以我怀疑它失败了,并且子进程在main的末尾达到了return 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM