It's a homework question. I have 3 programs A, B and C, they are not father/child processes, but separate programs. B must write a message ("Hello") to the stdin of A and read another message ("Hello") from stdout of C. Which concept i should use to implement it? I looked around for some time but i couldn't find anything proper. I thought i should use FIFO, but i couldn't redirect pipes. Can i use dup2 with FIFO? if yes, how? It's not the homework's itself, it just the way it should work. Then I will implement other things on it. (I can post my fifo base code, if it's the case, just don't do it now because i'm not sure)
Let me know if I missunderstood the question.
Let's say you create programs A
, B
and C
. Programmatically, you could use man 1 mkfifo
or man 3 mkfifo
, to create named pipes.
Then each one of your processes would open(2)
them and use dup2(2)
according to their needs.
For instance, program A
could redirect its stdout
like this:
int fifo = open("fifo_1", O_WRONLY);
dup2(fifo, 1);
or program B
could redirect both its stdin
and stdout
like this:
int fifo_in = open("fifo_1", O_RDONLY);
int fifo_out = open("fifo_2", O_WRONLY);
dup2(fifo_in, 0);
dup2(fifo_out, 1);
or whatever else you need.
I modified this code as @chrk explained. It's a FIFO example from the book "Advanced Unix Programming". A simple server-client example. Client sends three lowerletter strings to the server, server make them upperletter and send back to the client via FIFO("fifo#clientpid" is the name of client's fifo). Client prints them to its stdout. So i modified it in a way that after receiving the message from client, server writes upperletter strings to the STDINT of the client. And client reads them from STDINT and print to its stdout. It works as i expected. Thanks for all help. First i implemented in a wrong way. With the help of chrk's code i wrote it again. Here is the code:
client's output
client 2941 started
client 2941: applesauce --> APPLESAUCE
client 2941: tiger --> TIGER
client 2941: mountain --> MOUNTAIN
Client 2941 done
server:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#define ec_neg1(s,m) if((s) == -1) {perror(m); exit(errno);}
#define SERVER_FIFO_NAME "fifo_server"
#define PERM_FILE 0664
struct simple_message {
pid_t sm_clientpid;
char sm_data[200];
};
int main()
{
int fd_server, fd_client, i;
ssize_t nread;
struct simple_message msg;
char fifo_name[100];
printf("server started\n");
if (mkfifo(SERVER_FIFO_NAME, PERM_FILE) == -1 && errno != EEXIST)
{perror("can't make fifo"); exit(errno); }
ec_neg1( fd_server = open(SERVER_FIFO_NAME, O_RDWR), "cant open fd_server" )
while (1)
{
ec_neg1( nread = read(fd_server, &msg, sizeof(msg)), "can't read from fd_server")
if (nread == 0) {
errno = ENETDOWN;
perror("nread == 0"); exit(errno);
}
for (i = 0; msg.sm_data[i] != '\0'; i++)
msg.sm_data[i] = toupper(msg.sm_data[i]);
make_fifo_name(msg.sm_clientpid, fifo_name, sizeof(fifo_name));
ec_neg1( fd_client = open(fifo_name, O_WRONLY), "can't open fifo_name" )
ec_neg1( write(fd_client, &msg, sizeof(msg)), "can't write to fd_client" )
ec_neg1( close(fd_client), "can't close fd_client" )
}
/* never actually get here */
ec_neg1( close(fd_server), "can't close fd_server" )
exit(EXIT_SUCCESS);
return 0;
}
int make_fifo_name(pid_t pid, char *name, size_t name_max)
{
snprintf(name, name_max, "fifo%ld", (long)pid);
return 0;
}
client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define ec_neg1(s,m) if((s) == -1) {perror(m); exit(errno);}
#define SERVER_FIFO_NAME "fifo_server"
#define PERM_FILE 0664
struct simple_message {
pid_t sm_clientpid;
char sm_data[200];
};
int make_fifo_name(pid_t pid, char *name, size_t name_max)
{
snprintf(name, name_max, "fifo%ld", (long)pid);
return 0;
}
int main()
{
int fd_server, fd_client = -1, i;
ssize_t nread;
struct simple_message msg;
char fifo_name[100];
char *work[] = {
"applesauce",
"tiger",
"mountain",
NULL
};
printf("client %ld started\n", (long)getpid());
msg.sm_clientpid = getpid();
make_fifo_name(msg.sm_clientpid, fifo_name,
sizeof(fifo_name));
if (mkfifo(fifo_name, PERM_FILE) == -1 && errno != EEXIST)
{perror("can't make fifo"); exit(errno); }
ec_neg1( fd_server = open(SERVER_FIFO_NAME, O_WRONLY), "can't open fd_server" )
for (i = 0; work[i] != NULL; i++)
{
strcpy(msg.sm_data, work[i]);
ec_neg1( write(fd_server, &msg, sizeof(msg)),"can't write to fd_server" )
if (fd_client == -1){
ec_neg1( fd_client = open(fifo_name, O_RDWR), "can't open fifo_name" )
ec_neg1(dup2(fd_client, 0), "can't duplicate stdin")
}
ec_neg1( nread = read(0, &msg, sizeof(msg)), "can't read from fd_client" )
if (nread == 0) {
errno = ENETDOWN;
perror("nread == 0"); exit(errno);
}
printf("client %ld: %s --> %s\n", (long)getpid(),
work[i], msg.sm_data);
}
ec_neg1( close(fd_server), "can't close fd_server" )
ec_neg1( close(fd_client), "can't close fd_client" )
ec_neg1( unlink(fifo_name), "can't unlink fifo_name" )
printf("Client %ld done\n", (long)getpid());
exit(EXIT_SUCCESS);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With