Not completly redirect output to file - c

Hello and thank you for attention. I am writing my own shell and I have small problem with redirect output to file. For example user wrote: ls -l >> output. If I find ">>", I should redirect first part of command, I mean call effect ls -l to file "output". I try to do it in case 1 but to file is redirected just one lane and the program is stopped, there is not appear "Shell -> " and nothing is going on. Can you give some advice to solve that problem? Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
int *parse(char *linia, char **argv)
{
int counter = -1;
while (*linia != '\0')
{
while (*linia == ' ' || *linia == '\t' || *linia == '\n')
*linia++ = '\0';
*argv++ = linia;
counter++;
while (*linia != '\0' && *linia != ' ' && *linia != '\t' && *linia != '\n')
linia++;
}
*argv = '\0';
return counter;
}
void execute(char **argv)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
else if (pid == 0)
{
if (execvp(*argv, argv) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
}
else
{
while (wait(&status) != pid);
}
}
int specialChar(char *argv)
{
int i=0;
while(argv[i]!='\0')
{
if(argv[i]=='>' && argv[i+1]=='>')
return 1;
else if(argv[i]=='&')
return 2;
else if(argv[i]=='|')
return 3;
i++;
}
}
void main()
{
char command[20];
char *argv[64];
char **history = (char**)malloc(20*sizeof(char*));
int counter1=-1;
int counter2=0;
for(counter2 = 0; counter2<20; counter2++)
{
history[counter2]=(char*)malloc(100*sizeof(char));
}
int start = 0;
FILE *file;
file=fopen("his", "w");
if(!file)
printf("ERROR");
int i=0;
while (1)
{
printf("Shell -> ");
gets(command);
counter1++;
strcpy(history[counter1],command);
fopen("his", "w");
if(counter1<20)
for(i=0; i<=counter1; i++)
{
fprintf(file,"%s\n",history[i]);
}
else
for(i=counter1-20; i<counter1; i++)
{
fprintf(file,"%s\n",history[i]);
}
fflush(file);
printf("\n");
switch(specialChar(command))
{
case 1:
i = parse(command, argv);
int file1 = open(argv[i], O_APPEND | O_WRONLY);
dup2(file1,1) ;
if (strcmp(argv[0], "exit") == 0)
exit(0);
execute(argv);
close(file1);
break;
case 2:
break;
case 3:
break;
default:
parse(command, argv);
if (strcmp(argv[0], "exit") == 0)
exit(0);
execute(argv);
break;
}
fclose(file);
}
}

Related

Implementing an exit function on my C shell

I have been trying to implement an exit command on my C shell. I have tried the fork-exec method since it's a system call.
When I run the program, it prompts for the stdin input and when I type in "exit" it returns a "segmentation fault (core dumped)" error.
What am I doing wrong?
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#define ARGVMAX 100
#define LINESIZE 1024
#define EXITCMD "exit"
//makeargv - builds an argv vector from words in a string
int makeargv(char *s, char *argv[ARGVMAX]) {
int ntokens = 0;
if (s == NULL || argv == NULL || ARGVMAX == 0)
return -1;
argv[ntokens] = strtok(s, " \t\n");
while ((argv[ntokens] != NULL) && (ntokens < ARGVMAX)) {
ntokens++;
argv[ntokens] = strtok(NULL, " \t\n");
}
argv[ntokens] = NULL; // it must terminate with NULL
return ntokens;
}
void prompt() {
printf("sish> ");
fflush(stdout); //writes the prompt
}
/****** MAIN ******/
int main() {
char line[LINESIZE];
int wstatus;
while (1) {
prompt();
if (fgets(line, LINESIZE, stdin) == NULL)
break;
// TODO:
if(fgets(line, LINESIZE, strcmp(stdin, EXITCMD )) == 0)
return 0;
signal(SIGINT, SIG_DFL);
if (fork() == 0) exit(execvp(line[0], line));
{
signal(SIGINT, SIG_IGN);
}
wait(&wstatus);
if(WIFEXITED(wstatus))
printf("<%d>", WEXITSTATUS(wstatus));
}
return 0;
}
After reviewing and cleaning the code, I was finally able to implement the exit command.
Here goes the code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#define ARGVMAX 100
#define LINESIZE 1024
#define EXITCMD "exit"
//makeargv - build an argv vector from words in a string
int makeargv(char *s, char *argv[ARGVMAX]) {
int ntokens = 0;
if (s == NULL || argv == NULL || ARGVMAX == 0)
return -1;
argv[ntokens] = strtok(s, " \t\n");
while ((argv[ntokens] != NULL) && (ntokens < ARGVMAX)) {
ntokens++;
argv[ntokens] = strtok(NULL, " \t\n");
}
argv[ntokens] = NULL; // it must terminate with NULL
return ntokens;
}
void prompt() {
printf("C Shell >> ");
fflush(stdout); //writes the prompt
}
/****** MAIN ******/
int main() {
char line[LINESIZE];
while (1) {
prompt();
if (fgets(line, LINESIZE, stdin) == NULL)
break;
// TODO:
char *p = strchr(line, '\n');
if (p)
*p = 0;
if(strcmp(line, "exit") == 0)
break;
char *args[] = {line, (char*) 0};
int pid = fork();
if (pid == 0){
execvp(line, args);
perror("Command Error!");
exit(1);
} else {
wait(NULL);
}
return 0;
}
return 0;
}

C - ls optional flag

I've got a basic shell program that can change directories using cd and list the files with ls. I want to extend this further by adding optional flags to the ls command. In particular, I want to implement the ls -l (lowercase 'ell') command whereby it shows a total sum of all file sizes on the line before the long listing. I'm not sure how I can implement this. My code I have so far is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#define MAX_LENGTH 1024
#define DELIMS " \t\r\n"
int main(int argc, char *argv[]) {
char *cmd;
char line[MAX_LENGTH];
while(1){
printf("> ");
if (!fgets(line, MAX_LENGTH, stdin)) break;
if ((cmd = strtok(line, DELIMS))) {
char *arg = strtok(0, DELIMS);
if (strcmp(cmd, "cd") == 0) {
if (!arg) fprintf(stderr, "cd missing argument.\n");
else {
chdir(arg);
}
}
else if (strcmp(cmd, "ls") == 0) {
struct dirent **namelist;
int n;
n = scandir(".",&namelist,NULL,alphasort);
if(n < 0)
{
perror("scandir");
exit(EXIT_FAILURE);
}
else
{
while (n--)
{
printf("%s\n",namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
}
}
else if (strcmp(cmd, "exit") == 0) {
break;
}
}
}
return 0;
}

shared memory producer consumer in C

I have to implement a producer-consumer problem via shared memory and semaphores. It should takes input from input.txt file and save it to output.txt file. Process of saving information should be showed in terminal. I have a problem with, I guess, synchronization. When I call fork() and then execl() producer.c file inside, the program seems to be not responding. producer(at least) was working before, but during modifying some lines of code it stopped working and I can't solve it. Here's the piece of code:
#include <stdio.h> // main.c
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include "semaphore.h"
#include "memory.h"
#define SIZE 10
typedef struct cyclicalBuf
{
int size;
char bufor[SIZE];
} cyclicalBuf;
int main(int argc, char *argv[])
{
if(argc != 1)
{
perror("Need no arguments!");
exit(1);
}
int semid;
int memoryID;
int key;
key = semGetKey('A');
semid = semCreate(key, 2); // 2 sem made
setVal(semid, 0, SIZE);
setVal(semid, 1, 0);
memoryID = memoryCreate('A', sizeof(cyclicalBuf));
pid_t pid;
pid = fork();
switch(pid)
{
case -1:
perror("fork() error in producer section");
exit(2);
break;
case 0:
execl("./producer", "./producer", NULL);
perror("execl() error in producer section");
exit(3);
break;
default:
break;
}
sleep(1);
switch(pid)
{
case -1:
perror("fork() error in consumer section");
exit(4);
break;
case 0:
execl("./consumer", "./consumer", NULL);
perror("execl() error in consumer section");
exit(5);
break;
default:
break;
}
int i;
for(i = 0; i < 2; i++)
{
if(wait(0) < 0 )
{
perror("wait() error [main.c]");
}
}
semDelete(semid, 2);
memoryDelete(memoryID);
return 0;
}
#include <stdio.h> // producer.c
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "memory.h"
#include "semaphore.h"
#define SIZE 10
typedef struct cyclicalBuf
{
int size;
char bufor[SIZE];
} cyclicalBuf;
void producer()
{
FILE *fp;
int i;
int semid;
int memoryID;
cyclicalBuf * buf;
char c;
if((fp = fopen("./input.txt", "r")) == NULL)
{
perror("fopen() error [producer]");
exit(1);
}
int key;
key = semGetKey('A');
semid = semCreate(key, 2); y
memoryID = memoryAccess('A');
buf = (cyclicalBuf *)memoryLink(memoryID);
printf("Producer: ");
for(i = 0; (c = fgetc(fp)) != EOF; i++)
{
semRelease(semid, 0);
usleep(rand()%5555);
buf->bufor[i%SIZE] = c;
buf->size++;
semAcquire(semid, 1);
printf(" %c", c);
}
if(fclose(fp) == EOF)
{
perror("fclose() error [producer]");
exit(2);
}
memoryUnlink(buf);
}
int main(int argc, char *argv[])
{
if(argc != 1)
{
perror("Need no arguments!");
exit(3);
}
srand(time(NULL));
producer();
return 0;
}
#include <stdio.h> // consumer.c
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/sem.h>
#include "memory.h"
#include "semaphore.h"
#define SIZE 10
typedef struct cyclicalBuf
{
int size;
char bufor[SIZE];
} cyclicalBuf;
void consumer()
{
FILE *fp;
int c_cnt = 0;
int i = 0;
int semid;
int memoryID;
cyclicalBuf * buf;
char c;
if((fp = fopen("./output.txt", "w")) == NULL)
{
perror("fopen() error [consumer]");
exit(1);
}
int key;
key = semGetKey('A');
semid = semCreate(key, 2);
memoryID = memoryAccess('A');
buf = (cyclicalBuf *)memoryLink(memoryID);
printf("Consumer: ");
while(!((semctl(semid, 0, GETVAL) == SIZE) && (c_cnt == buf->size)))
{
semRelease(semid, 1);
usleep(rand()%5555);
c = buf->bufor[i%SIZE];
semAcquire(semid, 0);
fputc(c, fp);
printf(" %c", c);
i++;
c_cnt++;
}
if(fclose(fp) == EOF) //
{
perror("fclose() error [consumer]");
exit(2);
}
memoryUnlink(buf); //
}
int main(int argc, char *argv[])
{
if(argc != 1)
{
perror("Need no arguments!");
exit(3);
}
srand(time(NULL));
consumer();
return 0;
}
I can provide semaphore and shared memory functions if needed.
OUTPUT:
./main
| --> this is just blinking cursor, nothing happens

Implement own shell

Hello and thank you for attention. I am trying to implement my own shell. I have a few questions about my code and about tasks ro resolv. Below I present my previous code and questions:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
void parse(char *line, char **argv, char **argv2)
{
while (*line != '\0')
{
while (*line == ' ' || *line == '\t' || *line == '\n')
{
*line++ = '\0';
}
if(*line == '>' && *(line+1) == '>')
{
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n')
{
line++;
}
while (*line == ' ' || *line == '\t' || *line == '\n')
{
*line++ = '\0';
}
*argv2 = line;
break;
}
if(*line == '&')
{
break;
}
*argv++ = line;
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n')
{
line++;
}
}
*argv = '\0';
}
void execute(char **argv, int option)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
else if (pid == 0)
{
if (execvp(*argv, argv) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
}
else if(option == 1)
{
while (wait(&status) != pid);
}
}
void execute2(char *command, char **argv, char **argv2)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
else if (pid == 0)
{
//close(1);
parse(command, argv, argv2);
int output = open(*argv2, O_APPEND | O_WRONLY);
dup2(output,1);
if (strcmp(argv[0], "exit") == 0)
exit(0);
if (execvp(*argv, argv) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
close(output);
}
else
{
while (wait(&status) != pid);
}
}
int specialChar(char *argv)
{
int i=0;
while(argv[i]!='\0')
{
if(argv[i]=='>' && argv[i+1]=='>')
return 1;
else if(argv[i]=='&')
return 2;
else if(argv[i]=='|')
return 3;
i++;
}
}
void main()
{
char command[20];
char *argv[64];
char *argv2[1];
char **history = (char**)malloc(20*sizeof(char*));
int counterHistory1=-1;
int counterHistory2=0;
int i;
for(counterHistory2 = 0; counterHistory2<20; counterHistory2++)
{
history[counterHistory2]=(char*)malloc(100*sizeof(char));
}
FILE *file;
file=fopen("history", "w");
if(!file)
printf("ERROR");
while (1)
{
printf("Shell -> ");
gets(command);
counterHistory1++;
strcpy(history[counterHistory1],command);
fopen("history", "w");
if(counterHistory1<20)
for(i=0; i<=counterHistory1; i++)
{
fprintf(file,"%s\n",history[i]);
}
else
for(i=counterHistory1-20; i<counterHistory1; i++)
{
fprintf(file,"%s\n",history[i]);
}
fflush(file);
printf("\n");
switch(specialChar(command))
{
case 1:
//close(1);
execute2(command,argv,argv2);
break;
case 2: //running program in background
parse(command, argv, argv2);
if (strcmp(argv[0], "exit") == 0)
exit(0);
execute(argv,0);
break;
case 3:
break;
default:
parse(command, argv, argv2);
if (strcmp(argv[0], "exit") == 0)
exit(0);
execute(argv,1);
break;
}
fclose(file);
}
}
1) When last sign gettin from user is '&' I need to run my program in background. I have read that I can do this if I don 't call wait. Did I do this good or I should change something?
2) If I find ">>" I should redirect output to file. For example I get ls >> output, all catalogs and files should be written to file "output". Unfortunetly, it works only once. After this my program is stopped. I think that proces has never finished and then I can 't write next command. I tried to kill that proces but it didn 't works or I did something wrong.
3) In my shell I should create pipes of any length with the | sign. I have no idea how to resolv that problem...
Thank you for answers and help.
Answer 1
In a shell, a process that is created is child of shell and needs control of terminal, by getting access to stdout, stdin and stderr
signal(SIGTTOU, SIG_IGN);
setpgid(getpid(),getpid());
if(background==false) //shell for foreground process
{
tcsetpgrp(0,getpgid(getpid())); //access to stdin
tcsetpgrp(1,getpgid(getpid())); //access to stdout
tcsetpgrp(2,getpgid(getpid())); //access to stderr
}
execvp(command,args);

Shell program with pipes in C

I have a problem with pipes. My program is a Shell program in C. I want to execute for example ls | wc, but what I get after running is:
ls: cannot access |: no such file or directory ls: cannot access wc: no such file or directory.
What am I doing wrong?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#define MAX_CMD_LENGTH 100
#define MAX_NUM_PARAMS 10
int parsecmd(char* cmd, char** params) { //split cmd into array of params
int i,n=-1;
for(i=0; i<MAX_NUM_PARAMS; i++) {
params[i] = strsep(&cmd, " ");
n++;
if(params[i] == NULL) break;
}
return(n);
};
int executecmd(char** params) {
pid_t pid = fork(); //fork process
if (pid == -1) { //error
char *error = strerror(errno);
printf("error fork!!\n");
return 1;
} else if (pid == 0) { // child process
execvp(params[0], params); //exec cmd
char *error = strerror(errno);
printf("unknown command\n");
return 0;
} else { // parent process
int childstatus;
waitpid(pid, &childstatus, 0);
return 1;
}
};
int execpipe (char ** argv1, char ** argv2) {
int fds[2];
pipe(fds);
int i;
pid_t pid = fork();
for (i=0; i<2; i++) {
if (pid == -1) { //error
char *error = strerror(errno);
printf("error fork!!\n");
return 1;
} else
if (pid == 0) {
if(i ==0){
close(fds[1]);
dup2(fds[0], 0);
close(fds[0]);
execvp(argv1[0], argv1);
char *error = strerror(errno);
printf("unknown command\n");
return 0;
} else if(i == 1) {
close(fds[0]);
dup2(fds[1], 1);
close(fds[1]);
execvp(argv2[0], argv2);
char *error = strerror(errno);
printf("unknown command\n");
return 0;
}
} else { // parent process
int childstatus;
waitpid(pid, &childstatus, 0);
return 1;
}
} // end for
};
int main() {
char cmd[MAX_CMD_LENGTH+1];
char * params[MAX_NUM_PARAMS+1];
char * argv1[MAX_NUM_PARAMS+1];
char * argv2[MAX_NUM_PARAMS+1];
int k, y, x;
int f = 1;
while(1) {
printf("$"); //prompt
if(fgets(cmd, sizeof(cmd), stdin) == NULL) break; //read command, ctrl+D exit
if(cmd[strlen(cmd)-1] == '\n') { //remove newline char
cmd[strlen(cmd)-1] = '\0';
}
int j=parsecmd(cmd, params); //split cmd into array of params
if (strcmp(params[0], "exit") == 0) break; //exit
for (k=0; k <j; k++) { //elegxos gia uparksi pipes
if (strcmp(params[k], "|") == 0) {
f = 0; y = k;
printf("pipe found\n");
}
}
if (f==0) {
for (x=0; x<k; x++) {
argv1[x]=params[x];
}
int z = 0;
for (x=k+1; x< j; x++) {
argv2[z]=params[x];
z++;
}
if (execpipe(argv1, argv2) == 0) break;
} else if (f==1) {
if (executecmd(params) == 0) break;
}
} // end while
return 0;
}
Updated your code with following corrections.
Removed for() loop that iterated two times after fork() call.
Removed incorrect close of pipe FDs after dup2 calls for both parent and child processes.
Aligned the command that needed to be run as per the file descriptors that were duplicated in dup2() calls for parent and child. Basically I needed to swap execvp(argv2[0], argv2) and execvp(argv1[0], argv1) calls.
Added a break; statement in the for loop that searched for pipe character.
The updated code is as below.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX_CMD_LENGTH 100
#define MAX_NUM_PARAMS 10
int parsecmd(char* cmd, char** params) { //split cmd into array of params
int i,n=-1;
for(i=0; i<MAX_NUM_PARAMS; i++) {
params[i] = strsep(&cmd, " ");
n++;
if(params[i] == NULL) break;
}
return(n);
};
int executecmd(char** params) {
pid_t pid = fork(); //fork process
if (pid == -1) { //error
char *error = strerror(errno);
printf("error fork!!\n");
return 1;
} else if (pid == 0) { // child process
execvp(params[0], params); //exec cmd
char *error = strerror(errno);
printf("unknown command\n");
return 0;
} else { // parent process
int childstatus;
waitpid(pid, &childstatus, 0);
return 1;
}
};
int execpipe (char ** argv1, char ** argv2) {
int fds[2];
pipe(fds);
int i;
pid_t pid = fork();
if (pid == -1) { //error
char *error = strerror(errno);
printf("error fork!!\n");
return 1;
}
if (pid == 0) { // child process
close(fds[1]);
dup2(fds[0], 0);
//close(fds[0]);
execvp(argv2[0], argv2); // run command AFTER pipe character in userinput
char *error = strerror(errno);
printf("unknown command\n");
return 0;
} else { // parent process
close(fds[0]);
dup2(fds[1], 1);
//close(fds[1]);
execvp(argv1[0], argv1); // run command BEFORE pipe character in userinput
char *error = strerror(errno);
printf("unknown command\n");
return 0;
}
};
int main() {
char cmd[MAX_CMD_LENGTH+1];
char * params[MAX_NUM_PARAMS+1];
char * argv1[MAX_NUM_PARAMS+1] = {0};
char * argv2[MAX_NUM_PARAMS+1] = {0};
int k, y, x;
int f = 1;
while(1) {
printf("$"); //prompt
if(fgets(cmd, sizeof(cmd), stdin) == NULL) break; //read command, ctrl+D exit
if(cmd[strlen(cmd)-1] == '\n') { //remove newline char
cmd[strlen(cmd)-1] = '\0';
}
int j=parsecmd(cmd, params); //split cmd into array of params
if (strcmp(params[0], "exit") == 0) break; //exit
for (k=0; k <j; k++) { //elegxos gia uparksi pipes
if (strcmp(params[k], "|") == 0) {
f = 0; y = k;
printf("pipe found\n");
break;
}
}
if (f==0) {
for (x=0; x<k; x++) {
argv1[x]=params[x];
}
int z = 0;
for (x=k+1; x< j; x++) {
argv2[z]=params[x];
z++;
}
if (execpipe(argv1, argv2) == 0) break;
} else if (f==1) {
if (executecmd(params) == 0) break;
}
} // end while
return 0;
}
If you are interested only in changes I made, here is the diff between your code and the above updated code:
--- original.c
+++ updated.c
## -4,6 +4,7 ##
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/wait.h>
#define MAX_CMD_LENGTH 100
## -43,44 +44,36 ##
pipe(fds);
int i;
pid_t pid = fork();
- for (i=0; i<2; i++) {
if (pid == -1) { //error
char *error = strerror(errno);
printf("error fork!!\n");
return 1;
- } else
- if (pid == 0) {
- if(i ==0){
+ }
+ if (pid == 0) { // child process
close(fds[1]);
dup2(fds[0], 0);
- close(fds[0]);
- execvp(argv1[0], argv1);
+ //close(fds[0]);
+ execvp(argv2[0], argv2); // run command AFTER pipe character in userinput
char *error = strerror(errno);
printf("unknown command\n");
return 0;
- } else if(i == 1) {
+ } else { // parent process
close(fds[0]);
dup2(fds[1], 1);
- close(fds[1]);
- execvp(argv2[0], argv2);
+ //close(fds[1]);
+ execvp(argv1[0], argv1); // run command BEFORE pipe character in userinput
char *error = strerror(errno);
printf("unknown command\n");
return 0;
}
- } else { // parent process
- int childstatus;
- waitpid(pid, &childstatus, 0);
- return 1;
- }
- } // end for
};
int main() {
char cmd[MAX_CMD_LENGTH+1];
char * params[MAX_NUM_PARAMS+1];
- char * argv1[MAX_NUM_PARAMS+1];
- char * argv2[MAX_NUM_PARAMS+1];
+ char * argv1[MAX_NUM_PARAMS+1] = {0};
+ char * argv2[MAX_NUM_PARAMS+1] = {0};
int k, y, x;
int f = 1;
while(1) {
## -95,6 +88,7 ##
if (strcmp(params[k], "|") == 0) {
f = 0; y = k;
printf("pipe found\n");
+ break;
}
}
if (f==0) {
execv* procedure doesn't interpret shell script string. It merely starts an executable file and passes an array of arguments to it. Thus, it cannot organize a pipeline.
If you need "normal" shell command execution, you may want to use system(char*) procedure instead of execvp.
Otherwise, if you need to do the pipes yourself, you may want to parse the string with '|' special characters and use pipe(), fork() and I/O redirection. Like here How to run a command using pipe?

Resources