-1

I am trying to use fork with execvp to run two shell commands concurrently. I have two problems which are when I input mkdir folder1&mkdir folder2, it creates a folder named folder1 and another folder named folder2? (the question mark is included in the folder name). The other problem is that the code exits after performing the two commands.

Here is the code:

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

#define MAXLINE 80 /* The maximum length command */

int main(void) {
    char *args [MAXLINE / 2 + 1]; /* command line arguments */
    char *line = (char *) malloc((MAXLINE + 1) * sizeof (char));
    char *firstCommand = (char *) malloc((MAXLINE + 1) * sizeof (char));
    char *secondCommand = (char *) malloc((MAXLINE + 1) * sizeof (char));
    int shouldrun = 1; /* flag to determine when to exit program */
    pid_t pid;
    while (shouldrun) {
        printf("osh>");
        fflush(stdout);
        fgets(line, MAXLINE, stdin);
        if (strncmp(line, "exit", 4) == 0) {
            shouldrun = 0;
        } else {
            firstCommand = strsep(&line, "&");
            secondCommand = strsep(&line, "&");
            pid = fork();
            if (pid == 0) {
                // child
                if (secondCommand != NULL) {
                    char *token;
                    int n = 0;
                    do {
                        token = strsep(&secondCommand, " ");
                        args[n] = token;
                        n++;
                    } while (token != NULL);
                    execvp(args[0], args);
                }
            } else {
                // parent
                char *token;
                int n = 0;
                do {
                    token = strsep(&firstCommand, " ");
                    args[n] = token;
                    n++;
                } while (token != NULL);
                execvp(args[0], args);
            }
        }
    }
    return 0;
}

UPDATE 1:

I tried to follow Kevin's answer. I am trying to execute multiple processes concurrently, e.g. ps&ls&who&date. I tried a recursive method which gave me the same behavior. Here is my code:

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

#define MAXLINE 80 /* The maximum length command */

void execute(char *command) {
    char *args [MAXLINE / 2 + 1]; /* command line arguments */
    char *parentCommand = strsep(&command, "&");
    pid_t pid = fork();;
    if (pid == 0) {
        // child
        if (command != NULL) {
            execute(command);
        }
    } else {
        // parent
        char *token;
        int n = 0;
        do {
            token = strsep(&parentCommand, " ");
            args[n] = token;
            n++;
        } while (token != NULL);
        execvp(args[0], args);
    }
}

int main(void) {
    char *line = (char *) malloc((MAXLINE + 1) * sizeof (char));
    int shouldrun = 1; /* flag to determine when to exit program */
    while (shouldrun) {
        printf("osh>");
        fflush(stdout);
        fgets(line, MAXLINE, stdin);
        if (strncmp(line, "exit", 4) == 0) {
            shouldrun = 0;
        } else {
            execute(line);
        }
    }
    return 0;
}
Community
  • 1
  • 1
Ambitions
  • 2,369
  • 3
  • 13
  • 24

2 Answers2

1

For your question about why it doesn't loop, you're calling fork once but calling execvp twice. If successful, execvp will not return. Nothing will get back to run the loop again. What you need to do is call fork once for each execvp. I suggest you move the fork and execvp calls to a separate function:

void run_command(const char* command) {
    /* I suggest you also check for errors here */
    pid_t pid = fork();
    if (pid == 0) {
        /* get args, call execvp */
    }
}

/* in your loop */
run_command(firstCommand);
run_command(secondCommand);
Kevin
  • 6,993
  • 1
  • 15
  • 24
  • In this case, the two commands will not run concurrently, I want to enter two shell commands with an ampersand between them and run them concurrently by using forking. – Ambitions Jul 14 '17 at 12:34
  • Why do you think they won't run concurrently? My code doesn't include any waiting. – Kevin Jul 14 '17 at 12:35
0

Regarding the first question, you need to truncate the \n from the line. Regarding the second question, you can use system function from stdlib.h header file which will not terminate your program.

Ambitions
  • 2,369
  • 3
  • 13
  • 24