Search code examples
cforkexecstrtok

Using execvp,fork and wait to execute codes in file


I have been using execvp to execute unix commands written in a text file. Below is the code i have written but it doesn't seem to work.
I am reading lines from a file and each line contains a unix command(mv,cp etc).

#include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    #include <unistd.h>
    int main ( int argc, char *argv[] )
    {   pid_t  pid;
        pid_t child_pid;
        int child_status;  
        char *token;    
        FILE *fp;
        fp = fopen(argv[1],"r");
        int i,j,ctr,rc_wait;
        if( fp == NULL){
            perror("An error has occurred\n");
            exit(1);
            }
        char buff[100];
        while(fgets(buff, sizeof(buff), fp)){    
            child_pid=fork();
            if(child_pid<0){
                printf("\nfork failed, error");
                exit(0);
            }
            else if(child_pid==0){
            //printf("\nString value = %s", buff);
            token = strtok(buff, " \t");
            execvp(token,buff);
            }
            else{
            rc_wait = wait(NULL);
            continue;
            }

            }   

            }
            return 0;
            }

input file has been provided as an argument to the program and the input contains below as example:

    cp temp1/f1.txt              temp2/
    mv temp1/f2.c                           temp2/
    cp temp1/f3.txt                temp2/
    cp temp1/f4.txt                temp2/
    cp temp1/f5.txt                temp2/
    cp temp1/f6.txt                 temp2/
    mv temp1/f7.c                   temp1/f8.c
    mv temp1/f9.c                   temp2/
    cp temp1/f1.txt              temp1/f1a.txt

Solution

  • You're misusing strtok and execvp. The former mutates the input string as you call it, so after it has run once, it's split up buff by a NUL (token and buff actually refer to the same address after the first call, though token would change after additional tokenization). You can only use strtok to fully parse the input if you make copies of each result as it's generated (e.g. via strdup if you can rely on modern POSIX standards), because only the most recently returned pointer is ever valid.

    Your execvp usage is also wrong; the second argument to execvp is an array of C-style strings, char*s (the array itself being terminated with a NULL pointer). You passed it a plain array of char (one string, not an array of them).

    Please read the man pages for both APIs; you're so far off the mark it's clear you're just guessing at how they work.