9fdee30b55edb5020a3eb2c05201fa24154f44ca
[wsti_so.git] / src / process1.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 /* open/read/write/close */
6 #include <fcntl.h>
7
8 /* Signals handling.. */
9 #include <signal.h>
10
11 /** If buffer is too small to hold entire string, it is incremented by this value */
12 #define BUFFER_STEP 16
13
14 /** Buffer used to store line of characters */
15 char * buffer = NULL;
16
17 /** Named pipe used to communnicate with process2 */
18 char * write_pipe = "/tmp/process1pipe";
19
20 /** File descriptor of pipe */
21 int file_descriptor;
22
23 /**
24  * Handler for signals.
25  */
26 void sig_handler(int signo)
27 {
28         fprintf(stderr, "[%s] Received %s!\n", "process1", strsignal(signo));
29         if (signo == SIGUSR1) {
30         }
31         else if (signo == SIGTERM) {
32                 fprintf(stderr, "[%s] > Releasing resources\n", "process1");
33                 close(write_pipe);
34                 unlink(write_pipe);
35
36                 if (buffer) {
37                         free(buffer);
38                         buffer = NULL;
39                 }
40                 exit(0);
41         }
42         else if (signo == SIGTSTP) {
43                 fprintf(stderr, "[%s] > Closing pipe\n", "process1");
44                 close(write_pipe);
45                 raise (SIGSTOP);
46         }
47         else if (signo == SIGCONT) {
48                 fprintf(stderr, "[%s] > Opening pipe\n", "process1");
49                 file_descriptor = open(write_pipe, O_WRONLY);
50         }
51 }
52
53 /**
54  * Program reads entire lines of text from the standard input and pass them
55  * to the process2 using created pipe.
56  */
57 int main(void) {
58         /** Currently fetched from stdin character */
59         int c;
60
61         /** Current buffer length*/
62         int buffer_length = 0;
63
64         /** Index of the current character */
65         int i = 0;
66
67         /**
68          * Temporary buffer used as a proxy between
69          * checking memory allocation and copying data to real buffer 
70          */
71         char * tmp = NULL;
72
73         fprintf(stderr, "[%s] Init!\n", "process1");
74
75         /**
76          * Register signals handled by process
77          */
78         if (signal(SIGUSR1, sig_handler) == SIG_ERR) {
79                 fprintf(stderr, "can't catch SIGUSR1\n");
80         }
81         if (signal(SIGTERM, sig_handler) == SIG_ERR) {
82                 fprintf(stderr, "can't catch SIGTERM\n");
83         }
84         if (signal(SIGTSTP, sig_handler) == SIG_ERR) {
85                 fprintf(stderr, "can't catch SIGTSTP\n");
86         }
87         if (signal(SIGCONT, sig_handler) == SIG_ERR) {
88                 fprintf(stderr, "can't catch SIGCONT\n");
89         }
90
91         mkfifo(write_pipe, 0666);
92
93         file_descriptor = open(write_pipe, O_WRONLY);
94
95         do {
96                 c = fgetc(stdin);
97
98                 /*
99                  * Check if current index is bigger than current buffer size.
100                  * If so increment buffer size. On error release memory, and set
101                  * appropriate flags.
102                  */
103                 if (i >= buffer_length) {
104                         tmp = NULL;
105                         buffer_length += BUFFER_STEP;
106                         tmp = (char*) realloc(buffer, buffer_length);
107                         if (tmp == NULL) {
108                                 fprintf(stderr, "[%s] Memory allocation problem on read!\n", "process1");
109                                 free(buffer);
110                                 buffer = NULL;
111                                 c = EOF;
112                         }
113                 }
114
115                 /*
116                  * If there were no errors or it was not just an empty newline:
117                  * parse data.
118                  */
119                 if (c != EOF || ((i == 0) && (c == 10))) {
120                         /* If newline has been found
121                          * return entire string and release the memory
122                          */
123                         if (c == 10 && (i != 0)) {
124                                 buffer[i] = '\n';
125                                 write(file_descriptor, buffer, strlen(buffer));
126                                 fprintf(stderr, "[%s] buffer: %s/%d\n", "process1", buffer, strlen(buffer));
127
128                                 buffer_length = 0;
129                                 i = 0;
130
131                                 free(buffer);
132                                 buffer = NULL;
133                                 tmp = NULL;
134                         }
135                         /*
136                          * Normal character, add it to the buffer
137                          */
138                         else {
139                                 buffer = tmp;
140                                 buffer[i] = c;
141
142                                 /* Used only for debugging..*/
143                                 /*
144                                 printf("c: %c/%d, i: %d, bl: %d\n", c, c, i, buffer_length);
145                                 */
146                                 i++;
147                         }
148                 }
149         } while(c != EOF);
150
151         /* Release resources in normal program flow exit. */
152         close(write_pipe);
153         unlink(write_pipe);
154
155         if (buffer) {
156                 free(buffer);
157                 buffer = NULL;
158         }
159
160         return 0;
161 }