#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
static const int CMD_LEN = 512;
char cmd[CMD_LEN] = "";
#define SAFE_CLOSE(fd) do { if (-1 != fd) { close(fd); fd = -1; } } while (0)
void fork_and_exec(const char *cmd, int pin, int pout) {
pid_t pid = fork();
if (0 == pid) {
if (-1 != pin) {
dup2(pin, 0);
SAFE_CLOSE(pin);
}
if (-1 != pout) {
dup2(pout, 1);
SAFE_CLOSE(pout);
}
system(cmd);
exit(0);
}
SAFE_CLOSE(pin);
SAFE_CLOSE(pout);
}
int execute_cmd(char *cmd, int in) {
int status = 0;
char *p = cmd;
int pipefd[2] = {0};
while (*p) {
switch (*p) {
case '|':
*p++ = 0;
pipe(pipefd);
fork_and_exec(cmd, in, pipefd[1]);
execute_cmd(p, pipefd[0]);
return 0;
break;
default:
p++;
break;
}
}
fork_and_exec(cmd, in, -1);
while (waitpid(-1, &status, WNOHANG) != -1);
return 0;
}
char* const gets_s(char* const array, int maxlen) {
int i;
char c;
for (i = 0;i < maxlen;i++) {
c = getchar();
if (c !='\n') {
array[i] = c;
}
else {
break;
}
}
array[i]='\0';
return array;
}
int main() {
while (true) {
printf ("tiny sh>>");
gets_s(cmd, CMD_LEN - 1);
if (0 == strcmp(cmd, "q")) {
exit(0);
}
execute_cmd(cmd, -1);
}

return 0;
}