I am to implement a nameless pipe, and I must execute the command in the parent process, not in any of his child. every "-" equals a call for a pipeline ("|"), also part of the assignment I have this code. can someone explain to me why it doesn't work?
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h> // for open flags
#include <time.h> // for time measurement
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
void my_exec(char* cmd, char** argv)
{
int pipefd[2], f;
if (pipe(pipefd) < 0)
perror("pipe creation failed");
f = fork();
assert(f >= 0);
if (f == 0) {
// inside son process - connecting STDOUT to pipe write
if (dup2(pipefd[1], STDOUT_FILENO) < 0)
perror("dup2 failed");
close(pipefd[0]);
close((int)stdout);
} else {
// inside parent process - connecting STDIN to pipe read and execute command with args
if (dup2(pipefd[0], STDIN_FILENO) < 0)
perror("dup2 failed");
close(pipefd[1]);
close((int)stdin);
if (execvp(cmd, argv) < 0)
perror("execvp failed");
}
}
int main(int argc, char** argv)
{
assert(strcmp(argv[argc-1], "-"));
int i;
for (i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "-")) {
argv[i] = NULL;
my_exec(argv[1], &argv[1]);
argv = &argv[i];
argc -= i;
i = 0;
}
}
char* args[argc];
args[argc-1] = NULL;
for (i = 1; i < argc; ++i) {
args[i-1] = argv[i];
}
if (execvp(args[0], args) == -1)
perror("execvp failed");
return;
}
the command :
./mypipe.o ls -l - grep "pipe"
returns
total 24
-rw-rw-r-- 1 omer omer 1463 May 23 19:38 mypipe.c
-rwxrwxr-x 1 omer omer 7563 May 23 19:37 mypipe.o
-rw-rw-rw- 1 omer omer 873 May 23 20:01 nice.c
-rwxrwxr-x 1 omer omer 7417 May 23 19:44 nice.o
-rw-rw-r-- 1 omer omer 0 May 23 17:10 try
which obviouslly means the pipe didnt work... any ideas?
I need to make sure that Each call to np_exec starts a single child process that continues parsing the rest of the arguments, while the original parent process executes the given program and arguments (using execvp),
EDIT: i think i found the mistake: i switch the "read- write " ends of the pipe.
the correct function:
void np_exec(char* cmd, char** argv)
{
int pipefd[2];
int file;
if (pipe(pipefd) < 0)
perror("failed to create pipe");
file = fork();
assert(file >= 0);
if (file != 0) {
// inside parent process - connecting STDOUT to pipe write and execute command with args
if (dup2(pipefd[WRITE], STDOUT_FILENO) < 0)
perror("the function dup2 failed");
close(pipefd[READ]);
close((int)stdout);
if (execvp(cmd, argv) < 0)
perror("the function execvp failed");
} else {
// inside son process - connecting STDIN to pipe read
if (dup2(pipefd[READ], STDIN_FILENO) < 0)
perror("the function dup2 failed");
close(pipefd[WRITE]);
close((int)stdin);
}
}