Reputation:
I'm trying writing to the pipe and read the content of it when exec to another file but, For some reason I can't make it work.
Here is the main.c file
int main(int argc, char * argv[]) {
int pipe_descs[2];
int matrix[SIZE][SIZE];
int fdr, fdw; // file descriptors
int i;
pid_t status=0;
if (pipe(pipe_descs) == -1) {
fprintf(stderr, "cannot open");
exit(1);
}
fdr = open(argv[1], O_RDONLY); // open files
fdw = open("gg.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fdr < 0 || fdw < 0) { //validation for error
perror("failed to open input or output files");
exit(EXIT_FAILURE);
}
removeSpaces(matrix, fdr, fdw);
status=fork();
if (status < 0) {
fputs("error in fork", stderr);
exit(EXIT_FAILURE);
}
close(pipe_descs[0]);
close(STDOUT_FILENO);
dup(pipe_descs[1]);
write(pipe_descs[1],matrix,sizeof(matrix));
if(status == 0) {
execl("rowsValidation", "rowsValidation", NULL);
/*dup2(pipe_descs[IN],0);
dup2(pipe_descs[OUT],4);
close(STDOUT_FILENO);*/
}
…
This is the other file which trying to read the data from the buffer but nothing happened.
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char * argv[]){
int pipe_descs[2];
int mat[9][9];
int fdr, fdw; // file descriptors
char ans='9';
int i, j;
printf("%s","got here");
close(pipe_descs[1]);
close(STDIN_FILENO);
dup(pipe_descs[0]);
read(pipe_descs[0],mat,sizeof(mat));
for (i = 0; i < 9; i++) { /* Iterate of each row */
for (j = 0; j < 9; j++) { /* In each row, go over each col element */
printf("%d ", mat[i][j]); /* Print each row element */
}
printf("\n"); /* Finish a row, start a new line */
}
exit(0);
}
After reading the comments and reading more in the net i have changed it to this i tried to check it with a char but i still cant manage it to work. the father writes the char to the pipe and the son do the exec to the new process and then it reads from the pipe but it still doesnt work. please help me fix it
int main(int argc, char * argv[]) {
int pipe_descs[2];
int matrix[SIZE][SIZE];
int fdr, fdw; // file descriptors
int i;
char a='10';
pid_t status=0;
if (pipe(pipe_descs) == -1) {
fprintf(stderr, "cannot open");
exit(1);
}
fdr = open(argv[1], O_RDONLY); // open files
fdw = open("gg.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fdr < 0 || fdw < 0) { //validation for error
perror("failed to open input or output files");
exit(EXIT_FAILURE);
}
removeSpaces(matrix, fdr, fdw);
status=fork();
if (status < 0) {
fputs("error in fork", stderr);
exit(EXIT_FAILURE);
}
if(status == 0) {
dup2(pipe_descs[0], 0); // read the matrix from pipe1 to 0
close(pipe_descs[0]);
dup2(pipe_descs[1], 4);
printf("Execl1 start\n");
// write to 4 instead of pipe1[1]
execl("rowsValidation", "rowsValidation", NULL);
}
else{
write(pipe_descs[1],&a,sizeof(char));
close(pipe_descs[1]);
/*char buffer[10];
close(pipe_descs[1]);
close(STDIN_FILENO);
dup(pipe_descs[0]);
read(pipe_descs[0],buffer,sizeof(buffer));
printf("%s",buffer);
close(pipe_descs[0]);*/
}
close(fdr); // close the files
close(fdw);
exit(EXIT_SUCCESS);
}
int main(int argc, char * argv[]){
int pipe_descs[2];
int mat[9][9];
int fdr, fdw; // file descriptors
char ans;
int i, j;
read(0,&ans,sizeof(char));
printf("%c ", ans);
for (i = 0; i < 9; i++) { /* Iterate of each row */
for (j = 0; j < 9; j++) { /* In each row, go over each col element */
printf("%d ", mat[i][j]); /* Print each row element */
}
printf("\n"); /* Finish a row, start a new line */
}
/* if (pipe(pipe_descs) == -1) {
fprintf(stderr, "cannot open");
exit(1);
}*/
//write(4,1,sizeof(char));
exit(0);
}
Upvotes: 1
Views: 71
Reputation: 1207
I think you have a slight understanding of what you want and how to do it, but you're not 100% there. If you want to create a pipe, write information there and have another program read it: you start by creating the pipe, create a new process via a fork(), for example, (some people advise against the use of fork: https://www.microsoft.com/en-us/research/publication/a-fork-in-the-road/) and change the file descriptors around via dup2() (and dup()) calls. The process of creating a pipe, forking and doing an exec can be easly done via a popen() call, and I advise that you look into it.
Here's an example that might help you:
char* generate_hash(char* password, char* salt)
{
char password_plus_salt[MAX_PASSWORD_LEN + SALT_LEN];
strcpy(password_plus_salt, password);
strcat(password_plus_salt, salt);
int fd[2];
pipe(fd);
int stdout_save = dup(STDOUT_FILENO);
dup2(fd[WRITE], STDOUT_FILENO);
FILE* input = popen("sha256sum", "w");
fprintf(input, password_plus_salt, "%s");
FILE* output = fdopen(fd[READ], "r");
pclose(input);
char* hash = (char*)malloc(sizeof(char) * (HASH_LEN + 1));
memset(hash, '\0', (HASH_LEN + 1) * sizeof(char));
for (int i = 0; i < HASH_LEN; i++) {
hash[i] = (char)fgetc(output);
}
dup2(stdout_save, STDOUT_FILENO);
return hash;
}
I also advise you to switch your error checking around and change stuff like:
if (fdr < 0 || fdw < 0) { //validation for error
perror("failed to open input or output files");
exit(EXIT_FAILURE);
}
for:
if (fdr < 0)
{
perror("fdr");
exit(EXIT_FAILURE);
}
if (fdw < 0)
{
perror("fdw");
exit(EXIT_FAILURE);
}
So you can be certain of the origin of the error.
Upvotes: 2