Named Pipes
#include <sys/types.h& /********** Multi-Client Fifo Server! **********/
#include <sys/stat.h&
#include <stdio.h&
#include <signal.h&
#include <sys/fcntl.h&
#include <errno.h&
#include <stdlib.h&
#include <unistd.h&
#include <string.h&
main()
{
int readfifo, writefifo, dummyfd;
pid_t client_pid;
char buf[80], outbuf[80], filename[80], *fifoid, *message, client[80];
void handler(int signum);
signal(SIGPIPE, handler); /****** In case client disappears ******/
signal(SIGTTOU, handler); /****** To keep server alive on printf *****/
sprintf(filename, "%s/sysprog/demos/server", getenv("HOME"));
if ((mkfifo(filename, S_IRUSR | S_IWUSR) < 0) && (errno != EEXIST))
{
printf("Cannot make server fifo!");
exit(1);
}
if ((readfifo = open(filename, O_RDONLY)) < 0)
{
printf("Cannot open server fifo!");
exit(2);
}
if ((dummyfd = open(filename, O_WRONLY)) < 0)
{
printf("Cannot open server fifo dummy!");
exit(3);
}
while (read(readfifo, buf, 80) == 80)
{
fifoid = strtok(buf, "\040");
message = strtok(NULL, "\n");
printf("Got %s from client\n", buf);
if ((writefifo = open(fifoid, O_WRONLY)) < 0)
{
printf("Cannot open fifo to client!");
continue;
}
memset(outbuf, 0, 80);
sprintf(outbuf, "%s\n", message);
write(writefifo, outbuf, 80);
close(writefifo);
}
}
void handler(int signum)
{
printf("Fifo has been closed in reader!");
exit(0);
}
#include <sys/types.h& /********** Fifo Client ***********/
#include <sys/stat.h&
#include <stdio.h&
#include <signal.h&
#include <sys/fcntl.h&
#include <errno.h&
#include <stdlib.h&
#include <unistd.h&
#include <string.h&
int main()
{
int clientfifo, serverfifo, dummyfd;
char buf[80], filename[80], outbuf[256], inbuf[80], fifoname[80];
sprintf(filename, "%s/sysprog/demos/server", getenv("HOME"));
if ((serverfifo = open(filename, O_WRONLY)) < 0)
{
perror("Cannot open server's fifo!");
exit(3);
}
sprintf(fifoname, "fifo.%ld", getpid());
if ((mkfifo(fifoname, S_IRUSR | S_IWUSR) < 0) && (errno != EEXIST))
{
perror("mkfifo error!");
exit(1);
}
memset(buf, 0, 80);
printf("Enter string: ");
while(fgets(buf, 80, stdin) && strcmp(buf, "quit\n") != 0)
{
/************* Tell server who we are
*************/
memset(outbuf, 0, 256);
sprintf(outbuf, "fifo.%ld %s", getpid(), buf);
write(serverfifo, outbuf, 80);
/************* Open must be done here! It blocks if done above loop
************* because opens for read block until data arrives!!
*************/
memset(inbuf, 0, 80);
if ((clientfifo = open(fifoname, O_RDONLY, 0)) < 0)
{
perror("Could not open client fifo!");
exit(2);
}
read(clientfifo, inbuf, 80);
printf("From server: %s", inbuf);
memset(buf, 0, 80);
printf("Enter string: ");
close(clientfifo);
}
unlink(fifoname); /****** Get rid of filesystem entry. ******/
}
/************************ A Multi-Client Session **********************/
$ ms& /****** Server in background. ******/
[1] 25815
$ mc
Enter string: hello
Got fifo.25816 from client
From server: hello
Enter string: goodbyte
Got fifo.25816 from client
From server: goodbyte /******* Here, I CTRL-Z'ed this client! *******/
Enter string: [2] + Stopped mc
$ mc /******* New client!! *******/
Enter string: what's happening?
Got fifo.25817 from client
From server: what's happening? /***** Now I CTRL-Z this client, too! *****/
Enter string: [3] + Stopped mc
$ mc
Enter string: who's on first?
Got fifo.25818 from client
From server: who's on first?
Enter string: quit /****** A normal exit. ******/
$ fg /******** I revive one of the two suspended clients. ********/
mc
I am back!!
Got fifo.25817 from client
From server: I am back!!
Enter string: quit
$ fg /********* Here comes the other suspended client!! **********/
mc
I am also back
Got fifo.25816 from client
From server: I am also back
Enter string: quit
$ ls -l fifo.* /******** Any fifo.pid files left?? ********/
-rw------- 1 jwp2286 staff 1590 Nov 15 00:27 fifo.demo