-2

I am writing a C program. All code is in while loop but I did not add it yet. It takes input from user like start ls -l and run ls -l. And wait new command. If user write "wait" and there is a process that is not end, It waits until the child process is completed and print child process id that is just completed and take new command. My wait command does not working, and I need your help.

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


int main (int argc, char **argv) 
{   

    char command[1024];
    char *cmd;
    char *ptr1;
    char *ptr2 = (char*)malloc(10 * sizeof(char));
    char *ptr3;
    char *pos;
    char *args[3];
    char tmp[1024];
    int count = 0;
    int cstatus;
    pid_t  child;
    pid_t c;


    printf("newShell> ");
    fgets( command, 1024, stdin );


    if ((pos=strchr(command, '\n')) != NULL)
            *pos = '\0';

    if (strlen(command) > 1024)
    {
        printf("Command is too long\n");
        exit(1);    
    }

    strcpy(tmp,command);

    ptr1 = strtok(tmp," ");
    cmd = ptr1;


    while(ptr1 != NULL) 
    {   
        ptr1 = strtok(NULL, " ");


        if (ptr1 == NULL) break;

        if (count == 0)
        {
            ptr3 = ptr1;

            count = 1;
        }

        else
            strcat(strcat(ptr2,ptr1)," ");
        }

    ptr2[strlen(ptr2) - 1] = '\0';

    args[0] = ptr3;
    args[1] = ptr2;
    args[2] = NULL;

    if (strcmp(cmd,"start") == 0)
    {
        if ((child = fork()) == 0) 
        { 
            printf("\nProcess %ld is started\n", (long) getpid());
            execvp(args[0], args); 

            fprintf(stderr, "execvp() couldn't do the process\n");
            exit(1);
        }

        if (child == (pid_t)(-1)) 
        {
            fprintf(stderr, "Fork error.\n"); exit(1);
        }
    }

    else if (strcmp(cmd,"wait") == 0)
    {   

        if (child > 0)
        {
            c = wait(&cstatus); 
            printf("Process %ld completed with code: %d \n",
            (long) c, cstatus);
        }
        else
            printf("There is no process\n");
    }   


}

Edit:

Should i change that part with:

child = fork();

    if (child == (pid_t)(-1)) 
    {
            fprintf(stderr, "Fork failed.\n"); 
            exit(1);
    }

    if (strcmp(cmd,"start") == 0)
    {
        if (child == 0) 
        { 
            printf("\nProcess %ld is started\n", (long) getpid());
            execvp(args[0], args); 

            fprintf(stderr, "execvp() couldn't do the process\n");
            exit(1);

            continue;
        }

    else if (strcmp(cmd,"wait") == 0)

        c = wait(&cstatus); 
        printf("Parent: Child  %ld exited with status = %d\n",
        (long) c, cstatus);
        continue;


    }
Emin Çiftçi
  • 139
  • 2
  • 16

1 Answers1

2

A process can only wait for its own children. You need to add the while loop to your program, so that it can wait for the child that it forked. You can't re-run the program and wait for a process that was started by the previous invocation, because that process is not its child.

So you need to add the while loop to your program.

while (1) {
    printf("newShell> ");
    fgets( command, 1024, stdin );

    ... // all the rest of your code
}

Note that you may not be able to find the newShell> prompt. Since your program doesn't wait for the child before going back to the beginning of the loop, it will often print the prompt before the child process runs and prints its output.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I know this but i am testing the code part by part and i will add it, and i understand a child proccess and wait() must be in the same scope, but if a process is started and user write "wait" that must wait() for running process, how can i make it ? – Emin Çiftçi Jun 08 '16 at 21:26
  • You can't do that. It's not possible to wait for a process that's not your child. – Barmar Jun 08 '16 at 21:27
  • Your edit is worse. You shouldn't call `fork()` before checking whether they typed `start` or `wait`, because you only need to fork a child for `start`. – Barmar Jun 08 '16 at 22:13
  • No matter what you do, you need a loop, so that the user can type `wait` **after** you start the child process. – Barmar Jun 08 '16 at 22:14