lundi 23 novembre 2020

Malloc(): memory corruption errors while executing execv() commands

I am currently taking an OS class and our current project is to create a fully functional shell. I have a function for executing various commands using execv() and it works, but occasionally when I use certain commands like wc or ls -a I will get a malloc(): memory corruption aborted(core dumped) error. I am assuming it has something to do with memory management.

I use the new operator here

const char **cmdAndArgs = new const char *[cmdAndArgsVect.size() + 1]

and I thought I could just delete() the array at the end of the function, but when I do that, every input for my other commands comes in as ' !'.

Here is the full function in question

  static int shellCommand(String_std lineCommand) {
    std::vector<String_std> cmdAndArgsVect = splitCmd(lineCommand);
    const char **cmdAndArgs = new const char *[cmdAndArgsVect.size() + 1];
    bool redirectOut = false;
    int redirectIndex;

    const char *command = cmdAndArgsVect[0].c_str();
    //changes the paths into const char *
    String_std usrPath = "/usr/bin/";
    usrPath += command;
    const char *charUsrPath = usrPath.c_str();

    String_std binPath = "/bin/";
    binPath += command;
    const char *charBinPath = binPath.c_str();

    String_std localPath = "/usr/local/bin/";
    localPath += command;
    const char *charLocalPath = localPath.c_str();

    //sets up argument array for execv
    if (cmdAndArgsVect.size() + 1 == 2) {
      //No arguments, but array still needs to be null terminating
      cmdAndArgs[1] = NULL;
    } else {
      for (int i = 1; i < cmdAndArgsVect.size(); ++i) {
        //in case of redirect operator
        if (cmdAndArgsVect[i].compare(">") == 0) {
          cmdAndArgs[i] = NULL;
          redirectOut = true;
          redirectIndex = i;
          break;
        }
        cmdAndArgs[i] = cmdAndArgsVect[i].c_str();
      }
      //end of arguments, array needs to be null terminating unless redirect operator exist
      if (!redirectOut) cmdAndArgs[cmdAndArgsVect.size() + 1] = NULL;
    }

    //section to check if redirect was done correctly
    if (redirectOut) {
      if (cmdAndArgsVect.size() != redirectIndex + 2) {
        std::cout << "that is not the correct format for a redirect command" << "\n";
        return 1;
      }
    }


    pid_t pid = fork();
    int status;

    if (pid == -1) {
      perror("did not fork properly");
      //2 means that the fork failed
      return 2;
    } else if (pid == 0) {

      if (redirectOut) {
        const char *file = cmdAndArgsVect[redirectIndex + 1].c_str();
        int fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

        dup2(fd, 1);   // make stdout go to file
        dup2(fd, 2);   // makes stderr go to the file

        close(fd);
      }

      cmdAndArgs[0] = charBinPath;
      if (execv(charBinPath, (char **) cmdAndArgs) != -1) exit(0);

      cmdAndArgs[0] = charUsrPath;
      if (execv(charUsrPath, (char **) cmdAndArgs) != -1) exit(0);

      cmdAndArgs[0] = charLocalPath;
      if (execv(charLocalPath, (char **) cmdAndArgs) != -1) exit(0);

      std::cout << command << ": is not a valid command" << "\n";
      exit(-1);
    }

    waitpid(pid, &status, 0);

    return 1;
  } 

Aucun commentaire:

Enregistrer un commentaire