#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
void prep_exe(char *sttp, char **path, char ***argv)
{
char *p;
char *endp;
static int max, i;
for (p = sttp; *p != '\0'; p++)
;
endp = p;
i = 0;
for (p = sttp; p < endp; p++) {
if (*p == ' ') {
*p = '\0';
p++;
i++;
for (;*p == ' '; p++)
;
}
}
max = i + 2;
*argv = malloc(sizeof(char *) * max);
*path = sttp;
(*argv)[0] = sttp;
i = 1;
for (p = sttp; p < endp; p++) {
if (*p == '\0') {
p++;
for (;*p == ' '; p++)
;
(*argv)[i++] = p;
}
}
(*argv)[i] = NULL;
return;
}
char *cut(char *comline, char *last)
{
char *p;
for (p = last; *p != '|' && p > comline; p--)
;
if (p > comline) {
*p = '\0';
return p + 1;
} else {
return p;
}
}
void task(char *comline)
{
char *endpos, *p, *path, **argv;
int pid, status;
int fd[2];
for (p = comline; *p != '\0'; p++)
;
p = cut(comline, p);
endpos = p;
if (fork() == 0) {
for (;;) {
if (p < endpos) {
dup2(fd[1], 1);
close(fd[1]);
close(fd[0]);
}
if (p > comline) {
pipe(fd);
if ((pid = fork()) == 0) {
p = cut(comline, p);
continue;
} else {
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
prep_exe(p, &path, &argv);
execv(path, argv);
/* not reached if no error */
fprintf(stderr, "cannot found %s\n", path);
free(*argv);
exit(-1);
}
} else {
prep_exe(p, &path, &argv);
execv(path, argv);
/* not reached if no error */
fprintf(stderr, "cannot found %s\n", path);
free(*argv);
exit(-1);
}
} /* for (;;) */
} else {
wait(&status);
putchar('\n');
}
}
#define BUFFSIZE 1024 /* >= 2 */
char *mygetline(FILE *fp)
{
static char inbuff[BUFFSIZE];
char *outbuff_malloc, *tmpbuff;
char *p, *q;
int fEOL;
if ((outbuff_malloc = malloc(1)) == NULL) {
return NULL;
}
*outbuff_malloc = '\0';
fEOL = 0;
do {
if ((q = fgets(inbuff, BUFFSIZE, fp)) == NULL)
break;
for (p = inbuff; *p != '\0'; p++)
;
if (*(p - 1) == '\n') {
*(p - 1) = '\0';
fEOL = 1;
}
if ((tmpbuff = realloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1)) ==NULL) {
free(outbuff_malloc);
return NULL;
}
strcat(tmpbuff, inbuff);
outbuff_malloc = tmpbuff;
} while (!fEOL);
if (q == NULL) {
free(outbuff_malloc);
return NULL;
}
return outbuff_malloc;
}
int main()
{
char *inputLine_malloc;
for (;;) {
printf("> ");
if ((inputLine_malloc = mygetline(stdin)) == NULL) {
break;
}
if (strstr(inputLine_malloc, "exit") != NULL) {
free(inputLine_malloc);
break;
} else {
task(inputLine_malloc);
free(inputLine_malloc); /* NULL ok */
}
}
return 0;
}
/* end */