So this code terminates after a pipe command: for example cat text.txt | wc
. It can open the text file and count the words but, instead of returning to the menu, it terminates. Any ideas?
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <dirent.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#define LOGOUT 20
#define MAXNUM 40
#define MAXLEN 160
#define MAXSIZE 100
#define BUFSIZE 20
#define TRUE 1
#define FALSE 0
typedef struct command_history
{
char *command;
struct command_history *next;
} history;
/* Main */
int main(void)
{
char *currentpath, *cmd, line[MAXLEN], *args[MAXNUM], *args2[MAXNUM], *args3[MAXNUM];
int background, i, j, t, wildcard, opts;
int redir_in, redir_out;
int fd;
long size;
char *buf;
pid_t pid, pid2;
char *history[MAXSIZE], command[MAXSIZE], command_number[MAXSIZE], *temp;
int history_count = 0, length, number, offs;
int pipefd[2], pipefd2[2];
int numberofpipes, pipesuccess;
char buffer[BUFSIZE];
FILE *fp;
buf = (char*)malloc((size_t)size);
/* set the signal handler for alarm */
/*get default working directory as current path*/
currentpath = getenv("PWD");
while (1)
{
/* initialize */
background = FALSE;
opts = FALSE;
redir_in = FALSE; redir_out = FALSE;
pipesuccess = FALSE;
numberofpipes = 0, t = 0, offs = 0;
/* print the prompt */
fprintf(stdout, "%s > ", currentpath);
/* set the timeout for autologout, function alarm() */
/* read the users command */
if (fgets(line,MAXLEN,stdin) == NULL) {
fprintf(stdout, "\nlogout\n");
exit(0);
}
line[strlen(line) - 1] = '\0';
if (strlen(line) == 0)
continue;
/* start to background? (check if the last character is '&') */
if(line[strlen(line)-1] == '&')
{
line[strlen(line)-1] = '\0'; //remove '&'
background = TRUE;
}
/* saving the user command into history list */
if(line[0] != '!'){
if (history_count < MAXSIZE){
history[history_count] = strdup(line);
history_count++;
}
}
/* split the command line to args[]*/
i = 0; //number of arguments
cmd = line;
while((args[i] = strtok(cmd, " ")) != NULL)
{
i++; //argument count
cmd = NULL;
}
/* history usage */
if(line[0] == '!')
{
// find right command index from history
j = 0;
while (isdigit(line[j+1])){
command_number[j] = line[j+1];
j++;
}
number = atoi(command_number);
if (number <= history_count)
{
// parsing the history commands back into args
t = 0;
temp = history[number-1];
while((args[t] = strtok(temp, " ")) != NULL)
{
t++;
temp = NULL;
}
}
else
{
printf("Out of range of array.\n");
}
}
/* find and open redirected files*/
for(j = 0; j < i; j++)
{
if(strcmp(args[j], ">") == 0){
args[j] = NULL;
fd = open(args[j+1], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
redir_out = TRUE;
if (fd < 0) {
perror("open");
exit(0);
}
}
else if(strcmp(args[j], "<") == 0){
args[j] = NULL;
fd = open(args[j+1], O_RDONLY, S_IRUSR | S_IWUSR);
redir_in = TRUE;
if (fd < 0) {
perror("open");
exit(0);
}
}
}
/* exit? */
if (strcmp(args[0], "exit") == 0) {
exit(0);
}
/* cd */
if (strcmp(args[0], "cd") == 0)
{
if(i > 1)
{
if(chdir(args[1]) != 0) //change to inputted directory
{
perror("chdir");
}
currentpath = getcwd(buf, (size_t)size); //set currentpath to cwd
}
else
{
currentpath = getenv("HOME"); // change to homedir
}
continue;
}
/* history */
if(strcmp(args[0], "history") == 0)
{
printf("Command history: \n");
for (j = 0; j < history_count; j++) {
printf("[%d] %s \n", j+1, history[j]);
}
continue;
}
/* find pipe marks for single and double pipe*/
int k=0, z=0, y=0;
if(!redir_out && !redir_in){
for (j = 0; j < i; j++) //i == argument count
{
if(strncmp(args[j], "|", 1) == 0){
args[j] = NULL; // make it null, so exec will stop there
numberofpipes++;
continue;
}
if(numberofpipes == 1){
args2[z] = args[j]; //copy other part of args to args2
args2[z+1] = NULL; //make sure last args2 is (null)
z++;
/* continue; */
}
/* if(numberofpipes == 2){
args3[y] = args[j]; //copy other part of args to args3
args3[y+1] = NULL; //make sure last args3 is (null)
y++;
} */
}
}
/* single pipe */
if(numberofpipes == 1){
pipe(pipefd);
if((pid = fork()) == -1){
perror("fork");
exit(1);
}
if(pid == 0) { /* child, args2 */
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
execvp(args[0], args);
}
else { /* parent, args */
close(pipefd[1]);
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
execvp(args2[0], args2);
perror("execv");
}
}
/* double pipe */
else if(numberofpipes == 2){
pipe(pipefd);
pipe(pipefd2);
if((pid = fork()) == -1){
perror("fork");
exit(1);
}
if(pid == 0) {
if((pid2 = fork()) == -1){
perror("fork 2");
exit(1);
}
if(pid2 == 0){ /* grandchild, args3 */
close(pipefd[0]);
close(pipefd[1]);
close(pipefd2[1]);
dup2(pipefd2[0], STDIN_FILENO);
close(pipefd2[0]);
execvp(args3[0], args3);
perror("execv");
}
else { /* child, args2 */
close(pipefd[1]);
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
close(pipefd2[0]);
dup2(pipefd2[1], STDOUT_FILENO);
close(pipefd2[0]);
execvp(args2[0], args2);
perror("execv");
}
}
else{ /* parent, args */
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
execvp(args[0], args);
}
}
/* fork to run the command */
switch (pid = fork()) {
case -1:
/* error */
perror("fork");
continue;
case 0:/* child process, exec() */
if(redir_out){ //redirection to output file
dup2(fd, STDOUT_FILENO);
close(fd);
}
else if(redir_in){ //redirection to input file
dup2(fd, STDIN_FILENO);
close(fd);
}
execvp(args[0], args);
perror("execv");
exit(1);
default:
/* parent (shell), wait() if not background process */
if(!background){
alarm(0);
while(wait(NULL) != pid)
{
printf("please.");
}
}
break;
}
}
//globfree(&globbuf);
free(buf);
return 0;
}