hi
iv been writing this lightweight shell. just finished writing a
function to implement piping.
the problem is that everytime i call a piped command, the command
executes ok, but afterwards stdin and stout get thrown for a toss.
for example, the prompt doesnt show up. then, if i do enter a command,
both the prompt and command output show up as complete output. i figure
there's a problem with my file descriptor handling in the piping
function.
flushing stdin and stdout dont seem to solve the problem.
code below.
swagat
p.s. the shell aint complete yet the redirections havent been
implemented, and there are probably fallacies in the main fn.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define CMMLINESIZ 300 /* Size of command input line/buffer */
#define CMMTKMAX 20 /* Maximum no. of tokens in command input line
*/
#define CMMINDIVMAX 20 /* Maximum no. of individulal commands in input
line */
int status;
void prompt() {
fprintf(stdout, "%s:%s$ ", getlogin(), get_current_dir_name());
fflush(stdout);
}
void tokenize(char *commandLine, char **commandTokens, char
*separators) {
int index; /* Index for parsing */
commandTokens[0] = strtok(commandLine, separators);
for (index = 1; index < CMMTKMAX; index++) {
commandTokens[index] = strtok(NULL, separators);
if (commandTokens[index] == NULL)
break;
}
}
int individualCommandsFn(char *commandLine, char **individualCommands)
{
char *separators = ";";
int Commands;
individualCommands[0] = strtok(commandLine, separators);
for (Commands = 1; Commands < CMMINDIVMAX ;
Commands++) {
individualCommands[Commands] = strtok(NULL, separators);
if (individualCommands[Commands] == NULL)
break;
}
return Commands;
}
void execute(char *commandLine) {
char *commandTokens[CMMTKMAX]; /* Command input line tokens */
char *separators = " \t\n"; /* Command input token separators */
int pid, wpid; /* Process ids */
tokenize(commandLine, commandTokens, separators);
switch (pid = fork()) {
case -1:
break;
case 0:
execvp(commandTokens[0], commandTokens);
default:
wpid = wait(0);
if (wpid < 0)
fprintf(stdout, "%s: Invalid command\n", commandTokens[0]);
break;
};
}
void executePipedCommand(char *commandLine) {
char *prePipeCommandTokens[CMMTKMAX],
*postPipeCommandTokens[CMMTKMAX], *pipeIndex;
char *separators = " \t\n";
int pid, pid2, wpid;
int pfd[2];
pipe(pfd);
pipeIndex = strchr(commandLine, '|');
*pipeIndex = '\0';
pipeIndex++;
tokenize(commandLine, prePipeCommandTokens, separators);
tokenize(pipeIndex, postPipeCommandTokens, separators);
pid = fork();
if (pid == 0) {
close(pfd[1]);
dup2(pfd[0], 0);
close(pfd[0]);
execvp(postPipeCommandTokens[0], postPipeCommandTokens);
} else {
pid2 = fork();
if (pid2 == 0) {
close(pfd[0]);
dup2(pfd[1], 1);
close(pfd[1]);
execvp(prePipeCommandTokens[0], prePipeCommandTokens);
} else {// I THINK THE PRBLEM IS SMEWHERE HERE!!!!
close(pfd[0]);
close(pfd[1]);
wpid = wait(0);
}
}
}
void executeIPRedirCommand(char *commandLine) {
}
void PRedirCommand(char *commandLine) {
}
int isPipingFn(char *commandLine, int *isPiping) {
char *pipingF, *pipingL;
if (pipingF = strchr(commandLine, '|')) {
pipingL = strrchr(commandLine, '|');
if (pipingF != pipingL) {
fprintf(stdout, "Multilevel piping not supported\n");
*isPiping = -1;
} else *isPiping = 1;
}
return *isPiping;
}
int PRedirectionFn(char *commandLine, int *PRedirection) {
char *opRedirF, *opRedirL;
if (opRedirF = strchr(commandLine, '>')) {
opRedirL = strrchr(commandLine, '>');
if (opRedirF != opRedirL) {
fprintf(stdout, "Multilevel output redirection not supported\n");
*PRedirection = -1;
} else *PRedirection = 1;
}
return *PRedirection;
}
int isIPRedirectionFn(char *commandLine, int *isIPRedirection) {
char *ipRedirF, *ipRedirL;
if (ipRedirF = strchr(commandLine, '<')) {
ipRedirL = strrchr(commandLine, '<');
if (ipRedirF != ipRedirL) {
fprintf(stdout, "Multilevel input redirection not supported\n");
*isIPRedirection = -1;
} else *isIPRedirection = 1;
}
return *isIPRedirection;
}
int main() {
char commandLine[CMMLINESIZ]; /* Command input line/buffer */
char *individualCommands[CMMINDIVMAX];
int isPiping, isIPRedirection, PRedirection, Commands, i;
while(1) {
prompt();
fgets(commandLine, CMMLINESIZ, stdin);
fflush(stdin);
if (commandLine[0] == '#' || commandLine[0] == '\n')
continue;
Commands = individualCommandsFn(commandLine,
individualCommands);
for (i = 0; i < Commands; i++) {
isPiping = isPipingFn(individualCommands[i], &isPiping);
isIPRedirection = isIPRedirectionFn(individualCommands[i],
&isIPRedirection);
PRedirection = PRedirectionFn(individualCommands[i],
&PRedirection);
if (isPiping == -1 || isIPRedirection == -1 || PRedirection ==
-1){
continue;
}
if (isPiping)
executePipedCommand(individualCommands[i]);
else if (isIPRedirection)
executeIPRedirCommand(individualCommands[i]);
else if (PRedirection)
PRedirCommand(individualCommands[i]);
else execute(individualCommands[i]);
isPiping = isIPRedirection = PRedirection = 0;
}
}
return 0;
}