简体   繁体   中英

How can I get my C Shell to recognize that this is a command?

I am very new at C but am currently working on creating a C program to serve as a shell interface. It is supposed to accept commands and then execute each command in a separate process. I am currently stuck trying to get C to recognize that it is a command. I am unsure how to do this, and can't seem to find any useful examples.

Here is my code, it is saying that everything is not a valid command ("no cmd"). Does anyone have any idea why this would be occurring? Is C not able to recognize it is a command in the execvp() function or do I need to implement something for that specific purpose?

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

#define MAX_LINE 80
/* 80 chars per line per command */

int main(void) {
  //char *args[MAX_LINE/2 + 1];
    char *args = calloc(MAX_LINE, (MAX_LINE/2 +1));
    const size_t sz = MAX_LINE;
    pid_t pid;
  /* command line (of 80) has max of 40 arguments*/
  int should_run = 1;

  while (should_run) {
    printf("osh>"); //beginning of command line
        fgets(args, sz, stdin); //gets the stdin

        char *token = strtok(args, " \n"); //supposed to break str if it has a space or line and recognize there are 2 commands
        printf("%s\n", token);
        
        token = strtok(NULL," \n");
        printf("%s\n", token);
            pid_t parent = getpid();
      pid = fork(); //forking child
            if(pid == 0){ //if forking occurred
                int status = execvp(&args[0], &args); //status of input, is it a command?
                printf("%d", status);
                printf("forked!");
                if(status == -1) { //if cmd err, print
                    printf("no cmd");
                    return 1;
                } else {
                    printf("line will be printed");
                }
                return 0;
            }
        fflush(stdout); //flush
        /*

   
    * After reading user input, the steps are :
    * 1: fork a child process
    * 2: the child process will invoke execvp()
    * 3: parent process waits for the child to exit before       
    continuing
    */
  }

  exit(0);
  /**
  return to the operating system:
    -exit this process
    -flush all
  */

  
}

If you look at the documentation for the exec family of functions, you'll note that the functions only return if the exec failed. That's because exec , when successful, completely replaces the calling process with the invoked program.

What you need to do is, from the parent process (ie, the one that got a positive value returned from fork ), wait on the child process via waitpid .

pid_t pid;

pid = fork();
if ( pid < 0 ) {
    // Handle the error.
}
else if ( pid == 0 ) {
    execvp(&args[0], &args);
    // The fact that we've reached this line means that execvp failed.
    exit(1);
}
else {
    int status;

    while ( waitpid(pid, &status, 0) != pid ) {} // We need this loop in case waitpid gets interrupted by a signal.

    // status doesn't equal the return value of the child process.  We need to extract that with macros.
    if ( WIFEXITED(status) ) {
        printf("Child process exited with code %i\n", WEXITSTATUS(status));
    }
    else {
        printf("Child process was terminated by signal number %i\n", WTERMSIG(status));
    }
}

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