简体   繁体   中英

How to exit a shell program

I'm making simple shell program and trying to exit it if the user enters "exit" and I've tried a few different keywords such as exit(), return 0, break;

This is my code:

void read_command(char path[], char *args[], char input[]) {
  char *array[MAX], *ptr;

  char *inputptr;
  if ((inputptr = strchr(input, '\n')) != NULL) {
      *inputptr = '\0';
  }

  int i = 0;
  char *p = strtok(input, " ");
  while (p != NULL) {
      array[i++] = p;
      p = strtok(NULL, " ");
  }

  for (int j = 0; j < i; j++) {
      args[j] = array[j];
  }
}

int main() {
  char path[MAX];
  char *args[MAX] = {NULL};
  int status;
  char input[MAX];

  while (TRUE) {
      printf(">> ");
      fgets(input, sizeof(input), stdin);

      if (fork() != 0) {
          if (waitpid(-1, &status, 0) < 0) {
              perror("waitpid error ");
          }

      } else {
          read_command(path, args, input);

          if (strcmp(input, "exit") == 0) {
              exit(0);
          }

          strcpy(path, "/bin/");
          strcat(path, args[0]);

          if (execve(path, args, 0) < 0) {
              perror("exec error ");
              return EXIT_FAILURE;
          }
      }
  }
  return EXIT_SUCCESS;
}

When I return the strcomp() value it does give me 0 so I'm not sure why it's not working the program seems to completely ignore that exit statement and just carries on with the code, can someone explain how I could to this? Thank you.

You're calling exit in the child process that you just forked off. Instead, read the command in the parent process and then either exit or fork. By the way, you should really be checking that fork does not return -1 :

  read_command(path, args, input);

  if (strcmp(input, "exit") == 0)
      /* Don't pass zero here, that's not portable. */
      exit(EXIT_SUCCESS);

  pid_t child;
  switch ((child = fork())) {
      case -1:
         perror("fork failed");
         exit(EXIT_FAILURE);
      case 0:
         // call exec
      default:
          /* Don't pass -1 here if you know which child to wait for.
             Also, you can just pass NULL if to status */
          if (waitpid(child, NULL, 0) < 0)
              perror("waitpid error ");
  }

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