Jump to content

Own shell programming,linux,POSIX

- - - - -

  • Please log in to reply
No replies to this topic

#1
Exia

Exia

    Newbie

  • Members
  • Pip
  • 2 posts
Hello everyone!

My girlfriend gave me a home-made,half-ready shell.
It's 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.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users