#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include "proto.h"
/* Constants */
#define LINELEN 1024
#define EXPANDEDLEN 200000
/* Globals */
volatile sig_atomic_t sig_int = 0;
int last_exit_status = 0;
int m_argc;
int m_shifted_argc;
char **m_argv;
char **m_shifted_argv;
pid_t cpid = 1;
/* Prototypes */
void processline (char *line, int outFD, int waitFlag);
void print_args(char **args);
/* SIG HANDLERS */
void sigint_handler(int sig)
{
sig_int = 1;
if(!cpid) kill (0, SIGINT);
}
/* Shell main */
int main (int mainargc, char **mainargv)
{
/* PROTOTYPES IN MAIN */
void sigint_handler(int sig);
/* Defining Locals */
struct sigaction sa;
char *promptStr;
char buffer [LINELEN];
int len;
FILE *fp;
cpid = getpid();
sa.sa_handler = sigint_handler;
//sa.sa_flags = 0;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
if(sigaction(SIGINT, &sa, NULL) == -1)
{
perror("sigaction");
exit(1);
}
m_argc = mainargc;
m_shifted_argc = mainargc;
m_argv = mainargv;
m_shifted_argv = mainargv;
if(m_argc > 1) fp = fopen(m_argv[1], "r");
else fp = stdin;
if(fp == NULL)
{
fprintf(stderr, "./msh: Can not open file %s\n", m_argv[1]);
exit(127);
}
while(1)
{
if(fp == stdin)
{
if(!(promptStr = getenv("P1"))) fprintf(stderr, "%% ");
else fprintf(stderr, promptStr);
}
if(fgets(buffer, LINELEN, fp) != buffer) break;
len = strlen(buffer);
if (buffer[len-1] == '\n') buffer[len-1] = 0;
processline (buffer, 1, 1); //, mainargc, mainargv, shiftedMArgV);
}
if (!feof(fp)) perror ("read");
if(fclose(fp) != 0) perror("close");
return 0; /* Also known as exit (0); */
}
void processline (char *line, int outFD, int waitFlag) //, int mainargc, char **mainargv, char **shiftedMArgV)
{
int status;
/* All the parsed arguments, will be passed to exec */
/* int expanded_len = 2048;*/
char expanded_line[EXPANDEDLEN];
char **args;
int command_count;
if(expand(line, expanded_line, EXPANDEDLEN)) return; //, mainargc, mainargv, shiftedMArgV)) return;
command_count = arg_parse(expanded_line, &args);
/* print_args(args); */
if(!command_count) return;
if(!exec_if_built_in(args, outFD))
{
/* Start a new process to do the job. */
cpid = fork();
if (cpid < 0) {
perror ("fork");
free(args);
return;
}
/* Check for who we are! */
if (cpid == 0) {
/* We are the child! */
/* Turning stdout into pipe output if needed */
if((dup2(outFD, 1)) < 0)
{
perror("dup");
return;
}
execvp(args[0], args);
perror ("exec");
exit (127);
last_exit_status = 127;
}
/* Have the parent wait for child to complete */
if(waitFlag)
{
if (wait (&status) < 0) perror ("wait");
last_exit_status = ((WEXITSTATUS(status) || !WIFEXITED(status)) ? 127 : 0);
}
}
free(args);
}
/* Procedure for testing purposes,
prints the arguments of a command array */
void print_args(char **args)
{
int i = 0;
char** cmd = args;
printf("COMMANDS: ");
while(cmd[i] != 0)
{
printf("'%s'\n", cmd[i]);
i++;
}
}