Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C (http://www.go4expert.com/forums/c/)
-   -   Own shell programming,linux,POSIX (http://www.go4expert.com/forums/own-shell-programminglinuxposix-t9973/)

Exia 12Apr2008 22:12

Own shell programming,linux,POSIX
 
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.


All times are GMT +5.5. The time now is 23:31.