Code:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>
#include<errno.h>
#include<string.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<sys/stat.h>
#define MAX_BUF 100
#define MAXMESGDATA (MAX_BUF - 2* sizeof(long))
#define MESGHDRSIZE (sizeof(struct mymesg)-MAXMESGDATA)
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
struct mymesg{
long mesg_len; //byte in mesg_data
long mesg_type; //message type
char mesg_data[MAXMESGDATA];
};
ssize_t mesg_send (int fd, struct mymesg *mptr){
return (write (fd,mptr,MESGHDRSIZE + mptr->mesg_len));
}
ssize_t mesg_recv(int fd,struct mymesg *mptr){
size_t len;
ssize_t n;
if ((n=read(fd,mptr,MESGHDRSIZE))==0) {//read hear first, get len of data
return0; //end of file
} elseif (n!=MESGHDRSIZE){
printf("message header: expected %d, got %d\n", MESGHDRSIZE,n);
exit(1);
}
if ((len=mptr->mesg_len)>0)
{
if ((n=read(fd,mptr->mesg_data,len))!=len)
{
printf("message data: expected %d, got %d\n", len,n);
exit(1);
}
}
return len;
}
void client(int readfd,int writefd){
size_t len;
ssize_t n;
struct mymesg mesg;
for (;;)
{
printf("\nClient:");
fgets(mesg.mesg_data,MAXMESGDATA,stdin);//read mesg
len=strlen(mesg.mesg_data);
if (mesg.mesg_data[len-1]=='\n') //ignore newline
len--;
mesg.mesg_len=len;
mesg.mesg_type=1;
mesg_send(writefd,&mesg);//write to IPC channel
//read from IPC,write to std output
if((n=mesg_recv(readfd,&mesg))>0)
write(STDOUT_FILENO,mesg.mesg_data,n);
}
}
void server(int readfd,int writefd){
ssize_t n;
struct mymesg mesg;
for(;;)
{
mesg.mesg_type=1;
//read from IPC channel
if ((n=mesg_recv(readfd,&mesg))==0){
printf("Message missing");
exit(1);
}
mesg.mesg_data[n]='\0';
mesg.mesg_len=strlen(mesg.mesg_data);
char* str=NULL;
if (strcasecmp ("Knock Knock", mesg.mesg_data)==0){
str="Server:Who's there?";
strcpy(mesg.mesg_data,str);
mesg.mesg_len=strlen(str)-1;
}
elseif(strcasecmp ("Eric", mesg.mesg_data)==0){
str="Server:Eric,Welcome!";
strcpy(mesg.mesg_data,str);
mesg.mesg_len=strlen(str)-1;
}
elseif(strcasecmp ("Exit", mesg.mesg_data)==0){
kill(getpid(),SIGTERM); // getpid() gets your OWN pid!
kill(getppid(),SIGTERM); // After you're dead, you can't kill anything else.
exit(0);
}
mesg_send(writefd,&mesg);
}
}
int main(int argc, char ** argv){
/*MAXMESGDATA== 92 bytes; sizeof(struct mymesg)== 100 bytes
2* sizeof(long)== 8 bytes; MESGHDRSIZE ==8 bytes*/
int readfd,writefd;
pid_t childpid;
//create 2 FIFOs
if ((mkfifo(FIFO1,FILE_MODE)<0) && (errno!=EEXIST)){
printf("can't create %s",FIFO1);
exit(1);
}
if ((mkfifo(FIFO2,FILE_MODE)<0) && (errno!=EEXIST)){
printf("can't create %s",FIFO1);
unlink(FIFO1);
exit(1);
}
if ((childpid=fork()==0)){//child
readfd=open(FIFO1,O_RDONLY,0);
writefd=open(FIFO2,O_WRONLY,0);
server(readfd,writefd);
exit(0);
}
//parent
writefd=open(FIFO1,O_WRONLY,0);
readfd=open(FIFO2,O_RDONLY,0);
client(readfd,writefd);
waitpid(childpid,NULL,0);
close(readfd);
close(writefd);
unlink(FIFO1);
unlink(FIFO2);
return EXIT_SUCCESS;
}