0

I am making a command shell where I am trying to implement piping and redirection using "|" and ">" for commands that will be executed using execv. I am stuck on trying to implement ">" and am getting seg faults. The code that I am using to read input from the command line after reading the command and interpreting it is:

//this is the while loop I am using to seperate the command line input
//stored in the variable line( retrieved using getline) 
//delim here is a whitespace
while((temp=strsep(&line,delim)+'\0')!=NULL) 
//these are the kinds of statements I am using to store them in the 
//**char global array: input
i++;
input=realloc(input,i*sizeof(char*));
input[i-1]=temp;
//I used realloc here because the input function reads input until it //encounters "\n",";" or">" and eventually "|"
//these lines are where I think my problem begins
else if(strncmp(temp,">",1)==0)
{
    redirect=1;
    continue;
}
//redirect is a global integer with initial value 0
//I change it to 1, so that the function can use that information to direct 
//output to another file
 if(redirect==1)
     {
         if(temp[strlen(temp)-1]=='\n')
              {
                   temp[strlen(temp)-1]=0;
               }
                     filename=temp;
                     break;
      }
//this is the code in the input reading function that also reads the //filename to redirect output to in the global char* 'filename'
//this happens in the child process
if(pid==0)
    {
            if(redirect==1)
            {
                    int file=open(filename, O_WRONLY | O_CREAT, 0777);
                    if(file==-1)
                    {
                             char error_message[30] = "An error has occurred\n";
              write(STDERR_FILENO, error_message, strlen(error_message));
              breakptr=1;//this tells the main loop that an error has occured
              return;
                    }
                   int file2= dup2(file, STDOUT_FILENO);
                   close(file);
                   redirect=0;
            }
        if(execv(found,input)==-1)
.
.
.
}

 

when this code executes, I get segfaults, and if not that, then bin/ls will work once and then not at all. I need help figuring out where I am going wrong, and if there's a better way to accomplish this.

I tried changing the command loop, and initially I was checking the entire input string in the function where I forked the processes for '>' or'|' characters. I faced similar issues in that implementation. I also tried checking the internet, and stack overflow for similar implementations to get ideas from but most of them used this method, and it worked just fine for them. I am also suspecting that the filename variable could be causing problems because it is a character array on the stack that is dynamically allocated, only in certain cases?

  • 2
    With `temp=strsep(&line,delim)+'\0'`, what is the addition to `'\0'` supposed to do? – Some programmer dude Feb 21 '23 at 06:55
  • 1
    And have you tried to use a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to step through the code line by line while monitoring variables and their values, to see what really happens? – Some programmer dude Feb 21 '23 at 06:56
  • please post a [repro] – pynexj Feb 21 '23 at 08:05
  • the '\0' was added when I was confused about the strsep method, and I thought it returned nonnull terminating character arrays. If I removed it, it would not cause any problems. – user21255437 Feb 21 '23 at 15:41

1 Answers1

1

I cant see what "found" and "input" is. Execv according to linux pages "int execv(const char *path, char *const argv[]);". so this could be execv("usr/bin/cat", {"cat", "NULL"}). Second argument (the 2D string, in your case "input") needs to be null terminate.

Also maybe you can put printf different places in the code to let us know where it segfaults

  • I tried using printf statements and gdb to debug. It works sometimes, and sometimes it crashes vaguely. What surprised me is that there is no way to predict when it crashes or when it works. My guess is that the fork() command is affecting this, however when I use dup2 in the parent process, it starts printing the "smash>" prompt in the file as well and then crashes. – user21255437 Feb 21 '23 at 20:54