views:

123

answers:

2

Hi,

I have this c code:

if(fork()==0){
  execl("/usr/bin/fsck", "fsck", "/dev/c0d0p1s0", NULL);
}

it calls execl to run fsck for checking the filesystem /dev/c0d0p1s0.

My question is: how can I get the return value of fsck?

I need the return value of fsck to check whether the file system is consistence or not.

Thank you.

+8  A: 

Have the parent process wait for the child to exit:

pid_t pid = fork();
if (pid == -1) {
  // error, no child created
}
else if (pid == 0) {
  // child
}
else {
  // parent
  int status;
  if (waitpid(pid, &status, 0) == -1) {
    // handle error
  }
  else {
    // child exit code in status
    // use WIFEXITED, WEXITSTATUS, etc. on status
  }
}
Roger Pate
Yup, guess I misread it! I was trying to point out; return code would be set in "errno". Well off course to read that return code parent has to wait for the child :) ... Anyways deleted the answer.
Kedar
@Roger thank you. I will try it out and let you know what was the result.
mnish
It must be noted that in the particular case of calling `execl()` in the child, you should also call `_exit()` right after that to prevent the child from continuing execution in case `execl()` fails. You should also have a new case in the parent that handles an eventual `execl()` failure.
Blagovest Buyukliev
@Blagovest: Didn't you already mention that in your answer?
Roger Pate
@Roger Pate and @Blagovest: Thank you guys for your help, really appriciate it
mnish
+3  A: 

You must call wait() or waitpid() in the parent process and it will give you the exit status of the program executed by execl(). Not calling one of these will make the child process remain a zombie when it terminates, i.e. a process that is dead but stays in the process table because its parent wasn't interested in its return code.

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

...

pid_t pid;
int status;

if ((pid = fork()) == 0) {
  /* the child process */
  execl(..., NULL);
  /* if execl() was successful, this won't be reached */
  _exit(127);
}

if (pid > 0) {
  /* the parent process calls waitpid() on the child */
  if (waitpid(pid, &status, 0) > 0) {
    if (WIFEXITED(status) && !WEXITSTATUS(status)) {
      /* the program terminated normally and executed successfully */
    } else if (WIFEXITED(status) && WEXITSTATUS(status)) {
      if (WEXITSTATUS(status) == 127) {
        /* execl() failed */
      } else {
        /* the program terminated normally, but returned a non-zero status */
        switch (WEXITSTATUS(status)) {
          /* handle each particular return code that the program can return */
        }
      }
    } else {
      /* the program didn't terminate normally */
    }
  } else {
    /* waitpid() failed */
  }
} else {
  /* failed to fork() */
}

The _exit() call in the child is to prevent it from continuing execution in case execl() fails. Its return status (127) is also necessary to distinguish the case of an eventual execl() failure in the parent.

Blagovest Buyukliev