title: Problems with shell implementation in c
body: <p>Been working on a simple shell implementation for a for days. But I have 2 issues:</p>
  <p>1.When you run the program and type a command like &quot;/bin/ls -l /usr/include&quot; and then press enter it will execute the command but if you then enter a few new lines the program will still go into execvp() and output &quot;Permission denied&quot;, because it goes into the error handling of execvp and that's not supposed to happen. (I tried a few different things to stop it from going into the if() in main but they didn't work.)</p>
  <p>2.If you type enter and then enter a command the command won't be executed. (I tried freeing the buff and allocating memory again but that caused more issues.)</p>
  <p><strong>So basically it goes in the &quot;if(buff[offset] == '\n')&quot; even if the line is empty when it shouldn't and it doesn't execute a command unless its the first input after starting the program.</strong></p>
  <p><strong>Code:</strong></p>
  <pre><code>int fd = 0;
  const size_t read_size = 1;
  size_t size = read_size;
  char *buff = malloc(size+1);
  size_t offset = 0;
  size_t res = 0;
  
  write(STDOUT_FILENO, &quot;$ &quot;, strlen(&quot;$ &quot;));
  while((res = read(fd, buff + offset, read_size)) &gt; 0) 
  {
      if(buff[offset] == '\n')
      {
          buff[offset] = '\0';
          char **result = parse_cmdline(buff); // turn string into array for execvp()
  
          int exec;
          int status;
          pid_t pid = fork();
          if(pid == -1) {/*error handling*/}
          else if(pid == 0)
          {
              if((exec = execvp(result[0], result)) == -1) {/*error handling*/}
          }
          else
          {
              waitpid(pid, &amp;status, 0);
          }
  
          offset = 0;
          free(result[0]);
          free(result);
          result = NULL;
          write(STDOUT_FILENO, &quot;$ &quot;, strlen(&quot;$ &quot;));
      }
      offset += res;
      if (offset + read_size &gt; size)
      {
          size *= 2;
          buff = realloc(buff, size+1);
      }
      buff[offset] = '\0';
  }
  free(buff);
  return 0;
  </code></pre>
  <p><strong>UPDATE:</strong> Works with commands inputted after the first line, but with an error in every case:</p>
  <p>&quot;a.out: malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) &amp;&amp; old_size == 0) || ((unsigned long) (old_size) &gt;= MINSIZE &amp;&amp; prev_inuse (old_top) &amp;&amp; ((unsigned long) old_end &amp; (pagesize - 1)) == 0)' failed.
  Aborted (core dumped)&quot;</p>
  <p><strong>Updated code:</strong></p>
  <pre><code>if(buff[offset] == '\n')
          {
              buff[offset] = '\0';
              char **result = parse_cmdline(buff);
              if(result[0] != NULL)
              {
              int exec;
              int status;
              pid_t pid = fork(); // create the child process
              if(pid == -1) // check for fork() errors (no memory, etc.)
              {
                  fork_error();
              }
              else if(pid == 0) // Handle child process
              {
                  if((exec = execvp(result[0], result)) == -1) // run the command itself and check if an error will occur (invalid command, etc.)
                  {
                      file_error(result[0]);
                  }
              }
              else // Handle parent process
              {
                  waitpid(pid, &amp;status, 0);
              }
  
              offset = 0;
              free(buff);
              size = read_size;
              free(result[0]);
              free(result);
              result = NULL;
              }
              write(STDOUT_FILENO, &quot;$ &quot;, strlen(&quot;$ &quot;));
              
          }
          else
          {
              offset += res;
              if (offset + read_size &gt; size)
              {
                  size *= 2;
                  buff = realloc(buff, size+1);
              }
              buff[offset] = '\0';
          }
  </code></pre>