Own shell programming,linux,POSIX

Discussion in 'C' started by Exia, Apr 12, 2008.

  1. Exia

    Exia New Member

    Joined:
    Apr 12, 2008
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Hello everyone

    My girlfriend gave me a home-made,half-ready shell.
    It's code:

    Code:
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <wait.h>
    #include <ctype.h>
    
    #define LINE_LENGTH 100
    
    typedef void (*my_fork_t)(char **);
    
    int builtin_pid (char **);
    int builtin_result (char **);
    
    typedef struct builtins_t 
    {
      char *command;
      int (*function)(char **argv);
    } builtins_t;
    
    builtins_t builtins[] = {
      { "pid", builtin_pid },
      { "result", builtin_result },
      { NULL, NULL }
    };
    
    int last_result = 0;
    
    int
    builtin_pid (char **argv)
    {
      printf ("%d\n", getpid());
      return 0;
    }
    
    int
    builtin_result (char **argv)
    {
      printf ("%d\n", last_result);
      return 0;
    }
    
    
    int
    my_fork (my_fork_t fn, char **argv)
    {
      pid_t child;
      child = fork();
      if (child > 0)
        {
          int status;
          while (1)
            {
              if (waitpid (child, &status, 0) == -1)
                {
                  perror ("waitpid");
                  return -1;
                }
              if (WIFEXITED (status))
                {
                  return WEXITSTATUS (status);
                }
              else if (WIFSIGNALED (status))
                {
                  fprintf (stderr, "%s", strsignal (WTERMSIG (status)));
                  return -1;
                }
            }
        }
      else if (child == 0)
        {
          fn (argv);
          exit (0);
        }
      else
        {
          perror ("fork");
          exit (1);
        }
    }
    
    void
    run_argv (char **argv)
    {
      execvp (argv[0], argv);
      perror (argv[0]);
      exit (1);
    }
    
    #define ARGV_LIMIT 50
    
    char **
    cmdline_to_argv (char *cmdline)
    {
      int i = 0;
      char **cmd_argv = malloc (ARGV_LIMIT * sizeof (char *));
      char *p = cmdline;
      int in_word = 0;
      
      while (*p)
        {
          if (in_word)
            {
              if (isspace (*p))
                {
                  *p = 0;
                  in_word = 0;
                }
            }
          else
            {
              if (!isspace (*p))
                {
                  cmd_argv[i++] = p;
                  in_word = 1;
                }
            }
          p++;
        }
      cmd_argv[i] = NULL;
      return cmd_argv;
    }
    
    void
    free_cmd_argv (char **cmd_argv)
    {
      free (cmd_argv);
    }
    
    int
    run_command (char **argv)
    {
      int i = 0;
      while (builtins[i].command)
        {
          if (strcmp(builtins[i].command, argv[0]) == 0)
            {
              return builtins[i].function (argv);
            }
          i++;
        }
      return my_fork (run_argv, argv);
    }
    
    
    int
    main (int argc, char **argv)
    {
      char cmdline[LINE_LENGTH];
    
      while (printf ("$ "), fgets (cmdline, LINE_LENGTH, stdin))
        {
          char **cmd_argv = cmdline_to_argv (cmdline);
          if (cmd_argv[0])
            last_result = run_command (cmd_argv);
          free_cmd_argv (cmd_argv);
        }
      return 0;
    }
    
    She wants to make the "set" builtin command ,what can set an environment variable to a value,for example:' set APPLE "RINGO" ' sets the APPLE environment variable to the RINGO value.
    Unfortunately I'm not too good at POSIX prohramming,so I can't help her.
    So please if you don't mind help us.
    +She will be very happy if somebody show,how can she made a "get" bulletin, what gives back the value of an environment variable.

    Thank you for your help.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice