Sergiu
Sergiu

Reputation: 31

Processes, fork, pipes program...Where am I going wrong?

I'm working in Unix and I'm trying to write a .c file that will do the following:

For each command line argument the main process will launch a subprocess (type A).

The A process will try to execute, in a new subprocess (type B), using one of the exec functions, the received argument.

In case of failure, the process of type A, will send to his parent, using a pipe channel, the error code (errno value) generated by the exec call.

On success, the process A, will wait for process of type B and once finished it will transmit to his parent the zero code, using the same pipe channel.

The main process will print for each argument if the execution was successful or not. Only for failed executions the error received code will be printed too.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char const *argv[]) {
        int c2p[2], g2c[2];
        int i;
        char n[100];
        int *stat;
        for (i = 0; i < argc; i++ ) {
                pipe(c2p);
                pipe(g2c);
                if (fork() == 0) {
                        //child code
                        if (fork() == 0) {
                                //grandchild code
                                if (execlp("argv[i]", "argv[i]", NULL) == -1) {
                                        write(g2c[1], errno, sizeof(int));
                                } else {
                                        write(g2c[1], 0, sizeof(int));
                                }
                        }
                        wait(0);
                        read(g2c[0], n, 10);
                        write(c2p[1], n, 10);
                        exit(0);
                }
                read(c2p[0], &stat, sizeof(int));
                if (*stat !=0) {
                        printf("Not succsesful: %s  %d\n", argv[i], *stat);
                } else {
                        printf("Succes! %s\n", argv[i]);
                }
        }

        return 0;
}

Upvotes: 2

Views: 169

Answers (2)

Parham Alvani
Parham Alvani

Reputation: 2440

Changed your code as follow and this would worked for you:

int main(int argc, char const *argv[])
{
    int c2p[2];
    int i;
    int stat;

    for (i = 1; i < argc; i++ ) {
            pipe(c2p);
            if (fork() == 0) {
                    //child code
                    if (fork() == 0) {
                            //grandchild code
                            if (execlp(argv[i], argv[i], NULL) == -1)
                                 exit(errno);
                    }
                    wait(&stat);
                    write(c2p[1], &stat, sizeof(stat));
                    exit(0);
             }
             read(c2p[0], &stat, sizeof(int));
             if (stat != 0)
                   printf("Not succsesful: %s %d\n", argv[i], stat);
             else
                   printf("Succes! %s\n", argv[i]);
    }
}

as you see in my code:

  • stat must be integer not pointer
  • you pass argv[i] as argument not "argv[i]" into execlp
  • you exit status code for passing status of grandchild (you can also you this technique in child)
  • start your execution loop from 1 because argv[0] is your program name.
  • always remember after using exec family function your source code in that process replace with program you call so you cannot doing after it successful run.

Upvotes: 4

loreb
loreb

Reputation: 1357

Two problems:

  • you can't write an integer that way, write expects a pointer, so int n; ...; write(fd, &n, sizeof n);
  • execlp replaces the process that calls it, meaning if it works you'll never write zero to the pipe, because the grandchild has been replaced by the program it's execlp()ing

Upvotes: 0

Related Questions