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 COMMLINESIZ 300 /* Size of command input line/buffer */
#define COMMTOKMAX 20 /* Maximum no. of tokens in command input line
*/
#define COMMINDIVMAX 20 /* Maximum no. of individulal commands in input
line */
int status;
void prompt() {
fprintf(stdout, "%s:%s$ ", getlogin(), get_current_dir_name());
fflush(stdout);
*separators) {
int index; /* Index for parsing */
commandTokens[0] = strtok(commandLine, separators);
for (index = 1; index < COMMTOKMAX; index++) {
commandTokens[index] = strtok(NULL, separators);
if (commandTokens[index] == NULL)
break;
}
{
char *separators = ";";
int numOfCommands;
individualCommands[0] = strtok(commandLine, separators);
for (numOfCommands = 1; numOfCommands < COMMINDIVMAX ;
numOfCommands++) {
individualCommands[numOfCommands] = strtok(NULL, separators);
if (individualCommands[numOfCommands] == NULL)
break;
}
return numOfCommands;
char *commandTokens[COMMTOKMAX]; /* 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;
};
char *prePipeCommandTokens[COMMTOKMAX],
*postPipeCommandTokens[COMMTOKMAX], *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 PROBLEM IS SOMEWHERE HERE!!!!
close(pfd[0]);
close(pfd[1]);
wpid = wait(0);
}
}
char *pipingFirstOcc, *pipingLastOcc;
if (pipingFirstOcc = strchr(commandLine, '|')) {
pipingLastOcc = strrchr(commandLine, '|');
if (pipingFirstOcc != pipingLastOcc) {
fprintf(stdout, "Multilevel piping not supported\n");
*isPiping = -1;
} else *isPiping = 1;
}
return *isPiping;
char *opRedirFirstOcc, *opRedirLastOcc;
if (opRedirFirstOcc = strchr(commandLine, '>')) {
opRedirLastOcc = strrchr(commandLine, '>');
if (opRedirFirstOcc != opRedirLastOcc) {
fprintf(stdout, "Multilevel output redirection not supported\n");
*isOPRedirection = -1;
} else *isOPRedirection = 1;
}
return *isOPRedirection;
char *ipRedirFirstOcc, *ipRedirLastOcc;
if (ipRedirFirstOcc = strchr(commandLine, '<')) {
ipRedirLastOcc = strrchr(commandLine, '<');
if (ipRedirFirstOcc != ipRedirLastOcc) {
fprintf(stdout, "Multilevel input redirection not supported\n");
*isIPRedirection = -1;
} else *isIPRedirection = 1;
}
return *isIPRedirection;
char commandLine[COMMLINESIZ]; /* Command input line/buffer */
char *individualCommands[COMMINDIVMAX];
int isPiping, isIPRedirection, isOPRedirection, numOfCommands, i;
while(1) {
prompt();
fgets(commandLine, COMMLINESIZ, stdin);
fflush(stdin);
if (commandLine[0] == '#' || commandLine[0] == '\n')
continue;
numOfCommands = individualCommandsFn(commandLine,
individualCommands);
for (i = 0; i < numOfCommands; i++) {
isPiping = isPipingFn(individualCommands[i], &isPiping);
isIPRedirection = isIPRedirectionFn(individualCommands[i],
&isIPRedirection);
isOPRedirection = isOPRedirectionFn(individualCommands[i],
&isOPRedirection);
if (isPiping == -1 || isIPRedirection == -1 || isOPRedirection ==
-1){
continue;
}
if (isPiping)
executePipedCommand(individualCommands[i]);
else if (isIPRedirection)
executeIPRedirCommand(individualCommands[i]);
else if (isOPRedirection)
executeOPRedirCommand(individualCommands[i]);
else execute(individualCommands[i]);
isPiping = isIPRedirection = isOPRedirection = 0;
}
}
return 0;