Correct memory leak in listener test programme
[ric-app/mc.git] / sidecars / listener / src / pipe_reader.c
1 // vim: ts=4 sw=4 noet:
2 /*
3 --------------------------------------------------------------------------------
4         Copyright (c) 2018-2019 AT&T Intellectual Property.
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10            http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 --------------------------------------------------------------------------------
18 */
19
20 /*
21         Mnemonic:       pipe_reader.c
22         Abstract:       Read a single pipe which was associated with a message type.  This
23                                 programme is primarily for verification or example of how to use the
24                                 read1() function in the mc-listener library.
25
26         Date:           22 August 2019
27         Author:         E. Scott Daniels
28 */
29
30 #include <unistd.h>
31 #include <errno.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <time.h>
35 #include <string.h>
36 #include <signal.h>
37
38
39 #include "mcl.h"
40
41 //---- support -----------------------------------------------------------------------------
42
43 static void bad_arg( char* what ) {
44         fprintf( stderr, "[ERR] option is unrecognised or isn't followed by meaningful data: %s\n", what );
45 }
46
47 static void usage( char* argv0 ) {
48         fprintf( stderr, "usage: %s [-d fifo-dir] [-e] [-m msg-type] [-s]\n", argv0 );
49         fprintf( stderr, "   -d  dir (default is /tmp/mcl/fifos)\n" );
50         fprintf( stderr, "   -e  disable extended headers expectation in FIFO data\n" );
51         fprintf( stderr, "   -m  msg-type (default is 0)\n" );
52         fprintf( stderr, "   -M  max msg to read (default is all)\n" );
53         fprintf( stderr, "   -s  stats only mode\n" );
54 }
55
56 /*
57         We exit on any trapped signal so that we can kill  -15 the proecss
58         and still get gcoverage information to keep sonar happy.
59 */
60 static void sigh( int sig ) {
61         fprintf( stderr, "\n[INFO] exiting on signal %d\n", sig );
62         exit( 0 );
63 }
64
65 //------------------------------------------------------------------------------------------
66 int main( int argc,  char** argv ) {
67         void*   ctx;                                                    // the mc listener library context
68         char*   dname = NULL;                                   // directory where we open fifos
69         int             pidx = 1;                                               // parameter index
70         int             error = 0;
71         int             len;
72         int             mtype = 0;
73         char    buf[4096];
74         int             flush_often = 0;
75         int             long_hdrs = 1;                                  // -e is on command line turns this off, by default we expect long headers
76         int             stats_only = 0;
77         char    timestamp[MCL_TSTAMP_SIZE];             // we'll get the timestamp from this
78         long    count = 0;
79         int             blabber = 0;
80         int             max = 0;                                                // we'll force one reader down early to simulate MC going away
81
82         dname = strdup( "/tmp/mcl/fifos" );             // default to this so we can blindly free in 'd' to keep sonar happy
83         signal( SIGINT, sigh );
84         signal( SIGTERM, sigh );
85
86         while( pidx < argc && argv[pidx][0] == '-' ) {                  // simple argument parsing (-x  or -x value)
87                 switch( argv[pidx][1] ) {
88                         case 'd':
89                                 if( pidx+1 < argc ) {
90                                         if( dname != NULL ) {
91                                                 free( dname );                                          // keep sonar happy even though this is a test programme where a leak is meaningless
92                                         }
93                                         dname = strdup( argv[pidx+1] );
94                                         pidx++;
95                                 } else {
96                                         bad_arg( argv[pidx] );
97                                         error = 1;
98                                 }
99                                 break;
100
101                         case 'e':
102                                 long_hdrs = 0;
103                                 break;
104
105                         case 'f':
106                                 flush_often = 1;
107                                 break;
108
109                         case 'm':
110                                 if( pidx+1 < argc ) {
111                                         mtype = atoi( argv[pidx+1] );
112                                         pidx++;
113                                 } else {
114                                         bad_arg( argv[pidx] );
115                                         error = 1;
116                                 }
117                                 break;
118
119                         case 'M':
120                                 if( pidx+1 < argc ) {
121                                         max = atoi( argv[pidx+1] );
122                                         pidx++;
123                                 } else {
124                                         bad_arg( argv[pidx] );
125                                         error = 1;
126                                 }
127                                 break;
128
129                         case 's':
130                                 stats_only = 1;
131                                 break;
132
133                         case 'h':
134                         case '?':
135                                 usage( argv[0] );
136                                 exit( 0 );
137
138                         default:
139                                 bad_arg( argv[pidx] );
140                                 error = 1;
141                                 break;
142                 }
143
144                 pidx++;
145         }
146
147         if( error ) {
148                 usage( argv[0] );
149                 exit( 1 );
150         }
151
152         ctx = mcl_mk_context( dname );                  // initialise the library context
153         if( ctx == NULL ) {
154                 fprintf( stderr, "[FAIL] couldn't initialise the mc listener library" );
155                 exit( 1 );
156         }
157
158         fprintf( stderr, "[INFO] max = %d\n", max );
159         while( max == 0 || count < max ) {
160                 len = mcl_fifo_tsread1( ctx, mtype, buf, sizeof( buf ) -1, long_hdrs, timestamp );
161                 if( len > 0 ) {
162                         if( stats_only ) {
163                                 if( time( NULL ) > blabber ) {
164                                         fprintf( stdout, "[%d] %ld messages received\n", mtype, count );
165                                         blabber = time( NULL ) + 2;
166                                 }
167                         } else {
168                                 buf[len] = 0;
169                                 fprintf( stdout, "[%d] ts=%s count=%ld len=%d  msg=%s\n",  mtype, timestamp,  count, len, buf );
170                                 if( flush_often ) {
171                                         fflush( stdout );
172                                 }
173                         }
174
175                         count++;
176                 } else {
177                         sleep( 1 );
178                 }
179         }
180
181         fprintf( stderr, "[INFO] max reached: %d\n", max );
182 }
183