Home > Net >  Chdir lagging Shell
Chdir lagging Shell

Time:10-17

I am writing a shell in C/C . When I try changing the directory with chdir(const char*), the shell starts to lag. The shell works very good until somthing like cd .. is typed. Then when I try typing ls, it says it cannot execute couldn't execute: l (not ls). to build: g main.cc -lreadline

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

#define clear printf("\033[H\033[J")

char** getInput(char* input)
{
  char** command = (char**) malloc(8 * sizeof(char*));
  char* separator = " ";
  char* parsed;
  int index = 0;

  parsed = strtok(input, separator);
  while (parsed != NULL)
    {
      command[index] = parsed;
      index  ;

      parsed = strtok(NULL, separator);
    }

  command[index] = NULL;
  return command;
}

int main()
{
  char** command;
  char* input;
  pid_t child_pid;
  int stat_loc;

  bool loop = true;
  do
    {
      input = readline("");
      command = getInput(input);
      child_pid = fork();
      if (child_pid < 0)
        {
          printf("Fork Failed\n");
          exit(0);
        }
      if (strncmp(command[0], "cd\n", 2) == 0)
        {
          if (chdir(std::string(command[1]).c_str()) < 0)
            printf("Couldn't execute: %s\n", command[1]);
          continue;
        }
      else if (child_pid == 0)
        {
          execvp(command[0], command);
          printf("couldn't execute: %s\n", input);
        }
      else waitpid(child_pid, &stat_loc, WUNTRACED);
      free(input);
      free(command);
    } while (loop);
}

CodePudding user response:

You are forking at the wrong position, resulting in spawning multiple children when using command cd. In addition to that, the continue for command cd prevents freeing input and command. Also, the child needs to break the loop to exit after running the command.

So this:

      child_pid = fork();
      if (child_pid < 0)
        {
          printf("Fork Failed\n");
          exit(0);
        }
      if (strncmp(command[0], "cd\n", 2) == 0)
        {
          if (chdir(std::string(command[1]).c_str()) < 0)
            printf("Couldn't execute: %s\n", command[1]);
          continue;
        }
      else if (child_pid == 0)
        {
          execvp(command[0], command);
          printf("couldn't execute: %s\n", input);
        }
      else waitpid(child_pid, &stat_loc, WUNTRACED);

should be:

      if (strncmp(command[0], "cd\n", 2) == 0)
        {
          if (chdir(std::string(command[1]).c_str()) < 0)
            printf("Couldn't execute: %s\n", command[1]);
          free(input);
          free(command);
          continue;
        }
      child_pid = fork();
      if (child_pid < 0)
        {
          printf("Fork Failed\n");
          exit(0);
        }
      else if (child_pid == 0)
        {
          execvp(command[0], command);
          printf("couldn't execute: %s\n", input);
          loop = false;
          // or:
          //free(input);
          //free(command);
          //exit(0);
        }
      else waitpid(child_pid, &stat_loc, WUNTRACED);
  • Related