简体   繁体   中英

File operations. A c program that will take a single command line argument using fork() execvp() , wait/waitpid()

I was writing a program that could pass in a command-line argument in c program. The linux command are stored in a file called "sample-input". It only contains cp file1 dest1 or mv file2 dest2. My problem is when I tokenize the string in the file. It seems like it only reading the first line of the file. Here is my code. Can someone help me, please?

error message i got (after edit):

    temp1/f4.txt
 temp1/f5.txt
 temp1/f6.txt
-temp1/f7.c
+temp1/f8.c
+temp2/f1.txt
 temp2/f2.c
+temp2/f3.txt
 temp2/f4.txt
+temp2/f5.txt
 temp2/f6.txt
 temp2/f9.c
Test Result: [Failed]


    my sample-input
    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

My current code.

   /* Your code goes here */

#define _GNU_SOURCE
#include <string.h>
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


int main(int argc, char* argv[])
{
    FILE* fp;
    fp = fopen("sample-input", "r");

    if (fp == NULL) {
        fprintf(stderr, "An error has occured1\n");
        exit(1);
    }
    if (argc != 2) {
        fprintf(stderr, "argc=%d\n", argc);
        fprintf(stderr, "An error has occured2 \n");
        exit(1);
    }
    else if (argc == 2) {
        char ag[1024];

        while (fgets(ag, 1024, fp) != NULL)
        {
            fgets(ag, 1024, fp);

            char* array[4];
            int i = 0;
            char* token = strtok(ag, " \t\n");

            while (token != NULL) {

                array[i] = token;
                i++;
                token = strtok(NULL, " \t\n");
            }
            array[i] = NULL;
            int r = fork();

            if (r == 0) {
                execvp(array[0], array);
            }
            else if (r < 0) {

                fprintf(stderr, "An error an occoured\n");
                exit(1);

            }
            else {

                wait(NULL);

            }


        }




    }
    return 0;
}

This

execvp(array[i], array);

has to be

execvp(array[0], array);

because the first argument shall be the filename of the executable. And you should handle the case, that execvp() fails, properly by issuing a message and exiting (!).

perror("execvp");
exit(EXIT_FAILURE);

Furthermore, you have to NULL-terminate your argument vector by setting

array[i] = NULL;

after your while-loop. And better add a check, that breaks out of the loop after parsing three arguments, otherwise array can overflow (write out of bounds leading to undefined behaviour).

Another problem is your read-loop

while (fgets(ag, 1024, fp) != NULL) {
        fgets(ag, 1024, fp);
}

This will somewhat read your file wildly and leave you with the last or previous-last line. You have to put the line handling inside the loop:

while (fgets(ag, 1024, fp) != NULL) {
    // Parse arguments and fork/exec here inside
}

According to your input file, it looks like tabulators might also be an argument separator, so use

strtok(ag, " \t\n");

and

strtok(NULL, " \t\n");

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