APUE Learning Example Source Code
guowenxue
2023-11-06 d81310d55b9b7d07904c19f879f50e52fd7be489
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <libgen.h>
#include <stdlib.h>
 
#define FIFO_FILE1      ".fifo_chat1"
#define FIFO_FILE2      ".fifo_chat2"
 
int g_stop = 0;
 
void sig_pipe(int signum)
{
    if(SIGPIPE == signum)
    {
        printf("get pipe broken signal and let programe exit\n");
        g_stop = 1;
    }
}
 
int main(int argc, char **argv)
{
    int            fdr_fifo;
    int            fdw_fifo;
    int            rv;
    fd_set         rdset;
    char           buf[1024];
    int            mode = 0;
 
    if( argc != 2 )
    {
        printf("Usage: %s [0/1]\n", basename(argv[0]));
        printf("This chat program need run twice, 1st time run with [0] and 2nd time with [1]\n");
        return -1;
    }
 
    mode = atoi(argv[1]);
 
    if( access(FIFO_FILE1 , F_OK) )
    {
        printf("FIFO file \"%s\" not exist and create it now\n", FIFO_FILE1);
        mkfifo(FIFO_FILE1, 0666);
    }
 
    if( access(FIFO_FILE2 , F_OK) )
    {
        printf("FIFO file \"%s\" not exist and create it now\n", FIFO_FILE2);
        mkfifo(FIFO_FILE2, 0666);
    }
 
    signal(SIGPIPE, sig_pipe);
 
    if( 0 == mode )
    {
        printf("start open '%s' for read and it will blocked untill write endpoint opened...\n", FIFO_FILE1);
        if( (fdr_fifo=open(FIFO_FILE1, O_RDONLY)) < 0 )
        {
            printf("Open fifo[%s] for chat read endpoint failure: %s\n", FIFO_FILE1, strerror(errno));
            return -1;
        } 
        
        printf("start open '%s' for write...\n", FIFO_FILE2);
        if( (fdw_fifo=open(FIFO_FILE2, O_WRONLY)) < 0 )
        {
            printf("Open fifo[%s] for chat write endpoint failure: %s\n", FIFO_FILE2, strerror(errno));
            return -1;
        }
    }
    else
    {
        printf("start open '%s' for write and it will blocked untill read endpoint opened...\n", FIFO_FILE1);
        if( (fdw_fifo=open(FIFO_FILE1, O_WRONLY)) < 0 )
        {
            printf("Open fifo[%s] for chat write endpoint failure: %s\n", FIFO_FILE1, strerror(errno));
            return -1;
        }
 
        printf("start open '%s' for read...\n", FIFO_FILE2);
        if( (fdr_fifo=open(FIFO_FILE2, O_RDONLY)) < 0 )
        {
            printf("Open fifo[%s] for chat read endpoint failure: %s\n", FIFO_FILE2, strerror(errno));
            return -1;
        } 
    }
 
    printf("start chating with another program now, please input message now: \n");
    while( !g_stop )
    {
        FD_ZERO(&rdset);
        FD_SET(STDIN_FILENO, &rdset);
        FD_SET(fdr_fifo, &rdset);
 
        rv = select(fdr_fifo+1, &rdset, NULL, NULL, NULL); 
        if(  rv <= 0 )
        {
            printf("Select get timeout or error: %s\n", strerror(errno));
            continue;
        }
 
        /* get data arrive from FIFO */
        if( FD_ISSET(fdr_fifo, &rdset) )
        {
            memset(buf, 0, sizeof(buf));
            rv=read(fdr_fifo, buf, sizeof(buf));
            if( rv < 0)
            {
                printf("read data from FIFO get errorr: %s\n", strerror(errno));
                break;
            }
            else if( 0==rv )
            {
                printf("Another side of FIFO get closed and program will exit now\n");
                break;
            }
 
            printf("<-- %s", buf);
        }
 
        if( FD_ISSET(STDIN_FILENO, &rdset) )
        {
            memset(buf, 0, sizeof(buf));
            fgets(buf, sizeof(buf), stdin);
            write(fdw_fifo, buf, strlen(buf));
        }
    }
}