问题
So, I'm trying to create a pipe that sends char arrays back and forth through pipes that connect through argv[]. Right now, I'm stuck at receiving the array (param which is sent to c_param from the parent to the child.) in interface.c to receiving the characters 3 and 5 at db.c. I know that 3 and 5 are the index for argv[] that my pipes are at, but I'm not sure how to take that and print out my message in db.c.
interface.c creates the pipes, forks into a parent process and a child process. The char array param is transfered to the child process to char array c_param. Using snprintf, I made my pipe into a char to send using execl with my char array c_param.
interface.c:
int main (int argc, char *argv[])
{
int to_Child[2];
int to_Parent[2];
int id, toChildPipe, toParentPipe, err;
char param[100] = "This is the parameter!";
char sendPipe[100];
char recPipe[100];
/*CREATING PIPE*/
toChildPipe = pipe(to_Child);
toParentPipe = pipe(to_Parent);
if(toChildPipe == -1 || toParentPipe == -1)
{
printf ("Error on pipe creation: %d", errno);
exit (1);
}
/*Creating Child Process*/
id = fork();
if(id == 0)
{
/**
*
* IN THE CHILD Process
*
*/
close(to_Child[1]); //reading
close(to_Parent[0]); //writing
char c_param[100];
toChildPipe = read(to_Child[0], c_param, 100);
if (toChildPipe == -1)
{
//If failed
printf("Error on read from pipe from parent: %d\n",errno);
//exit with error
exit(2);
}//Error pipe from parent
snprintf(sendPipe,sizeof(sendPipe), "%d",to_Parent[0]);
snprintf(recPipe,sizeof(recPipe), "%d",to_Child[0]);
err = execl("./db","db",sendPipe,recPipe,(char *)0);
if(err == -1)
{
printf("Error on execl: %d\n", errno);
}//Error execl
toChildPipe = read(to_Child[0], c_param, 100);
if (toChildPipe == -1)
{
//If failed
printf("Error on read from pipe from parent: %d\n",errno);
//exit with error
exit(2);
}//Error pipe from parent
}//CHILD PROCESS
else if (id > 0)
{
/**
*
*IN THE PARENT PROCESS
*
*/
close(to_Child[0]); //writing
close(to_Parent[1]); //reading
toChildPipe = write(to_Child[1],param,100);
if(toChildPipe == -1)
{
printf("Error on write to pipe: %d", errno);
exit(3);
}
/*Piping was successful!*/
exit(0);
}//PARENT PROCESS
else
{
exit(4);
}
}
db.c started up from interface.c execl and should receive the parameters over argv[], which then should print it out. db.c
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
FILE *finput;
int j = 0;
int fd;
int toChildPipe;
char c_param[100];
if(argc > 1)
{
for(j ; j < argc ; j++)
printf("argv = %s\n", argv[j]);
printf("argc = %d\n",argc);
}
fd = atoi(argv[1]);
printf("Statement: %s\n", argv[fd]);
strcpy(c_param, argv[3]);
printf("filename: %s\n", c_param);
}
This is the current output I'm getting, I'm aware that 5 and 3 are the indexes I need to send a message and receive the message that I'm currently trying to print in db.c
output(db.c):
argv = db
argv = 5
argv = 3
argc = 3
Statement: TERM=xterm
I hope I gave you enough information, I appreciate any help you are willing to give me. Thank you in advance!
回答1:
There were lots of little things wrong. Your biggest problems were your assumptions/assertions in db.c
about the parameters passed to it by interface.c
— there was a total mismatch between what was passed and what was expected. There was also a good deal of extraneous code in interface.c
. In particular, the child read from the pipe before executing db
, so there was nothing left on the pipe for db
to read.
Here's the 'fixed' code, with some debug code still in place.
interface.c
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int to_Child[2];
int to_Parent[2];
int id;
char param[100] = "This is the parameter!";
char sendPipe[100];
char recPipe[100];
if (pipe(to_Child) == -1 || pipe(to_Parent) == -1)
{
printf("Error on pipe creation: %d", errno);
exit(1);
}
printf("Pipes: C(%d,%d), P(%d,%d)\n", to_Child[0], to_Child[1], to_Parent[0], to_Parent[1]);
id = fork();
if (id == 0)
{
close(to_Child[1]); // Child does not write to itself
close(to_Parent[0]); // Child does not read what it writes
snprintf(sendPipe, sizeof(sendPipe), "%d", to_Parent[1]);
snprintf(recPipe, sizeof(recPipe), "%d", to_Child[0]);
execl("./db", "db", sendPipe, recPipe, (char *)0);
fprintf(stderr, "Error on execl: %d\n", errno);
exit(2);
}
else if (id > 0)
{
close(to_Child[0]); // Parent does not read childs input
close(to_Parent[1]); // Parent does not
int nbytes = write(to_Child[1], param, 100);
if (nbytes == -1)
{
fprintf(stderr, "Error on write to pipe: %d\n", errno);
exit(3);
}
close(to_Child[1]);
if ((nbytes = read(to_Parent[0], param, 100)) <= 0)
{
fprintf(stderr, "Error on read from pipe: %d\n", errno);
exit(5);
}
printf("Data from pipe: [%.*s]\n", nbytes, param);
exit(0);
}
else
{
perror("fork failed");
exit(4);
}
}
### db.c
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
printf("argc = %d\n", argc);
for (int j = 0; j < argc; j++)
printf("argv[%d] = %s\n", j, argv[j]);
if (argc != 3)
{
fprintf(stderr, "Usage: %s write-fd read-fd\n", argv[0]);
return 1;
}
int ofd = atoi(argv[1]);
int ifd = atoi(argv[2]);
printf("ifd = %d; ofd = %d\n", ifd, ofd);
char c_param[100];
int nbytes = read(ifd, c_param, sizeof(c_param));
if (nbytes <= 0)
{
fprintf(stderr, "Error: failed to read any data (%d)\n", errno);
return 1;
}
printf("Child: [%.*s]\n", nbytes, c_param);
assert(strlen(c_param) + sizeof(" - sent back to parent") <= sizeof(c_param));
strcat(c_param, " - sent back to parent");
if (write(ofd, c_param, nbytes) != nbytes)
{
fprintf(stderr, "Error: failed to write all the data (%d)\n", errno);
return 1;
}
return 0;
}
Sample run
Pipes: C(3,4), P(5,6)
argc = 3
argv[0] = db
argv[1] = 6
argv[2] = 3
ifd = 3; ofd = 6
Child: [This is the parameter!]
Data from pipe: [This is the parameter! - sent back to parent]
Note that the code reports errors to standard error (that's what it is for). It also delimits the printed data which can make it easier to spot unexpected problems. It doesn't assume that the data is null padded; it limits the length printed to the length read, though in fact the data has numerous nulls at the end.
来源:https://stackoverflow.com/questions/39714636/sending-and-receiving-character-array-using-piping-through-argv-in-c