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.