1

Right now, I am working on a project in which I autocompile .c files from the command line. In order to do so, I use the following code:

bool auto_compile(process_t *p) {
    char* file_name = p->argv[0];
    char* compile_args[] = {"gcc", "-o", "devil", file_name, NULL};
    int status, pid;
    switch(pid = fork()) {
        case -1:
            logger("fork", 1);
            exit(EXIT_FAILURE);
        case 0:
            execvp("gcc", compile_args);    
        default:
            waitpid(pid, &status, WUNTRACED);
            if(WIFEXITED(status)) {
                if(status != EXIT_SUCCESS) {
                   logger("Error, could not compile", 4);
               return false;
                }
            }    
     }
     return true;
}

When I enter an invalid parameter for gcc (i.e. an invalid filename), it prints the gcc error message to the terminal. If I wanted to instead redirect this error to a file, how would I go about catching it?

  • How about redirecting the output/error of gcc to one/two file? The file redirect arguments can be setup in the `compile_args[]` – Arun Feb 18 '14 at 20:31
  • One minor suggestion. I believe `status != EXIT_SUCCESS` should be `WEXITSTATUS(status) != EXIT_SUCCESS`. – Joseph Quinsey Feb 21 '14 at 03:27

1 Answers1

0

Like most programs, gcc writes ordinary output (like if you use the -E switch) to file descriptor 1 and error messages to file descriptor 2. An exec-ed process usually inherits open file descriptors from its parent. If you don't want fd 1 and 2 to be your shell's terminal, you can replace them using dup2.

switch(pid = fork()) {
    /*...*/
    case 0: {
        int gccerr_fd = open("gcc_errors.txt", O_CREAT|O_WRONLY);
        if (gccerr_fd > 0) {
            dup2(gccerr_fd, 2);
            close(gccerr_fd);
        }
        execvp("gcc", compile_args);
    }

Or if you want to just read the results in the parent process or another child, you could consider using a pipe instead of open-ing a file.

aschepler
  • 70,891
  • 9
  • 107
  • 161