Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

writing a shell

Name: Anonymous 2009-09-19 22:39

I was hoping for some advice from someone more knowledgeable than myself. I'm messing around and trying to learn how to write a shell. So far, I've successfully used flex to parse input and properly put it into a char**. Then I fork() and run execvp() in the child process and wait() in the parent process. Works fine, except that when I run one command it works, but when I run another, it doesn't. What gives?

>echo itworks
itworks
>ls
>echo itworks
>wtf
>^C


Any advice would be appreciated. I don't understand why this would happen. ps doesn't list and child processes, either.

Name: Anonymous 2009-09-19 23:05

Here's the body of the loop. One may assume that all variables and functions used are defined, of course.


  while(1)
    {
      printf(">");
      argv = getline();

      if(strcmp(argv[0],"exit") == 0) exit(0);
      if(argv[argc] == NULL) continue;

      argc=0;
      while(argv[argc] != NULL)
        {
          if(strcmp(argv[argc],"|") == 0)
            {
              split = argc;
              split_type = PIPE;
            }
          else if(strcmp(argv[argc],">") == 0)
            {
              split = argc;
              split_type = REDIRECT;
            }
          argc++;
       }

      if(split == -1)
        {
          pid = fork();
          if(pid == 0)
            {
              if(execvp(argv[0],argv) == -1)
                handle_error_execvp(errno);
            }
          else if(pid > 0)
            {
              if(wait(&status) == -1)
                handle_error_wait(errno);
            }
          else
            {
              handle_error_fork(errno);
            }
        }
      else
        {
          cmda = copy_indices(argv,0,split-1);
         cmdb = copy_indices(argv,split+1,argc-1);
          if(split_type == PIPE)
            {
              pida = fork();
              if(pida == 0)
                {
                  pipe(fd);
                  pidb = fork();
                  if(pidb == 0)
                    {
                      close(fd[0]);
                      dup2(fd[1], 1);
                      close(fd[1]);
                      if(execvp(cmda[0],cmda) == -1)
                        handle_error_execvp(errno);
                    }
                  else if(pidb > 0)
                    {
                      close(fd[1]);
                      dup2(fd[0],0);
                      close(fd[0]);
                      if(execvp(cmdb[0],cmdb) == -1)
                        handle_error_execvp(errno);
                    }
                  else
                    {
                      handle_error_fork(errno);
                    }
                }
              else if(pida > 0)
                {
                  if(wait(&status) == -1)
                    handle_error_wait(errno);
                }
              else
                {
                  handle_error_fork(errno);
                }
            }
          else if(split_type == REDIRECT)
            {
              pid = fork();
              if(pid == 0)
                {
                  if(freopen(cmdb[0],"w",stdout) == NULL)
                    handle_error_freopen(errno);
                  if(execvp(cmda[0],cmda) == -1)
                    handle_error_execvp(errno);
                }
              else if(pid > 0)
                {
                  if(wait(&status) == -1)
                    handle_error_wait(errno);
                }
              else
                {
                  handle_error_fork(errno);
                }
            }
          else
            {
              printf("This section of the code should never execute. Something strange happened.\n");
              exit(-1);
            }
          free(cmda);
          free(cmdb);
        }
    }

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List