New FIFO using fifo_reply and fixing previous shortcomings in
authorJiri Kuthan <jiri@iptel.org>
Tue, 3 Sep 2002 08:38:00 +0000 (08:38 +0000)
committerJiri Kuthan <jiri@iptel.org>
Tue, 3 Sep 2002 08:38:00 +0000 (08:38 +0000)
blocking thru unsucessful randez-vous mit FIFO client

config.h
fifo_server.c
fifo_server.h
modules/tm/t_stats.c
modules/tm/uac.c

index 2cf062c..d35ee16 100644 (file)
--- a/config.h
+++ b/config.h
 */
 #define CLEANUP_EOL "      \n"
 
+/* how patient is ser with FIFO clients not awaiting a reply? 
+       4 x 80ms = 0.32 sec
+*/
+#define FIFO_REPLY_RETRIES     4
+#define FIFO_REPLY_WAIT                80000
+
 #endif
index 4b712ea..5099290 100644 (file)
@@ -39,6 +39,7 @@
 #include <signal.h>
 #include <string.h>
 #include <time.h>
+#include <stdarg.h>
 #include "dprint.h"
 #include "ut.h"
 #include "error.h"
@@ -256,9 +257,11 @@ static char *trim_filename( char * file )
 }
 
 /* tell FIFO client what happened via reply pipe */
-void fifo_reply( char *reply_fifo, char *reply_txt)
+void fifo_reply( char *reply_fifo, char *reply_fmt, ... )
 {
        FILE *file_handle;
+       int r;
+       va_list ap;
 
        file_handle=open_reply_pipe(reply_fifo);
        if (file_handle==0) {
@@ -266,22 +269,59 @@ void fifo_reply( char *reply_fifo, char *reply_txt)
                        fifo);
                return;
        }
-       if (fprintf(file_handle, "%s", reply_txt)<=0) {
+retry:
+       va_start(ap, reply_fmt);
+       r=vfprintf(file_handle, reply_fmt, ap);
+       va_end(ap);
+       if (r<=0) {
                LOG(L_ERR, "ERROR: fifo_error: write error (%s): %s\n",
                        fifo, strerror(errno));
+               if ((errno==EINTR)||(errno==EAGAIN)||(errno==EWOULDBLOCK)) {
+                       goto retry;
+               }
        }
        fclose(file_handle);
 }
 
 FILE *open_reply_pipe( char *pipe_name )
 {
+
+       int fifofd;
        FILE *file_handle;
 
-       if (!pipe_name) {
+       int retries=FIFO_REPLY_RETRIES;
+
+       if (!pipe_name || *pipe_name==0) {
                DBG("DEBUG: open_reply_pipe: no file to write to about missing cmd\n");
                return 0;
        }
-       file_handle=fopen( pipe_name, "w");
+
+tryagain:
+       fifofd=open( pipe_name, O_WRONLY | O_NONBLOCK );
+       if (fifofd==-1) {
+               /* retry several times if client is not yet ready for getting
+                  feedback via a reply pipe
+               */
+               if (errno==ENXIO) {
+                       /* give up on the client - we can't afford server blocking */
+                       if (retries==0) {
+                               LOG(L_ERR, "ERROR: open_reply_pipe: no client at %s\n",
+                                       pipe_name );
+                               return 0;
+                       }
+                       /* don't be noisy on the very first try */
+                       if (retries!=FIFO_REPLY_RETRIES)
+                               DBG("DEBUG: open_reply_pipe: retry countdown: %d\n", retries );
+                       sleep_us( FIFO_REPLY_WAIT );
+                       retries--;
+                       goto tryagain;
+               }
+               /* some other opening error */
+               LOG(L_ERR, "ERROR: open_reply_pipe: open error (%s): %s\n",
+                       pipe_name, strerror(errno));
+               return 0;
+       }
+       file_handle=fdopen( fifofd, "w");
        if (file_handle==NULL) {
                LOG(L_ERR, "ERROR: open_reply_pipe: open error (%s): %s\n",
                        pipe_name, strerror(errno));
@@ -296,7 +336,6 @@ static void fifo_server(FILE *fifo_stream)
        int line_len;
        char *file_sep, *command, *file;
        struct fifo_command *f;
-       FILE *file_handle;
 
        file_sep=command=file=0;
 
@@ -349,33 +388,12 @@ static void fifo_server(FILE *fifo_stream)
                if (f==0) {
                        LOG(L_ERR, "ERROR: fifo_server: command %s is not available\n",
                                command);
-                       file_handle=open_reply_pipe(file);
-                       if (file_handle==0) {
-                               LOG(L_ERR, "ERROR: fifo_server: no reply pipe\n");
-                               goto consume;
-                       }
-                       if (fprintf(file_handle, "[%s not available]\n", command)<=0) {
-                               LOG(L_ERR, "ERROR: fifo_server: write error: %s\n",
-                                       strerror(errno));
-                       }
-                       fclose(file_handle);
+                       fifo_reply(file, "[%s not available]\n", command);
                        goto consume;
                }
                if (f->f(fifo_stream, file)<0) {
                        LOG(L_ERR, "ERROR: fifo_server: command (%s) "
                                "processing failed\n", command );
-#ifdef _OBSOLETED
-                       file_handle=open_reply_pipe(file);
-                       if (file_handle==0) {
-                               LOG(L_ERR, "ERROR: fifo_server: no reply pipe\n");
-                               goto consume;
-                       }
-                       if (fprintf(file_handle, "[%s failed]\n", command)<=0) {
-                               LOG(L_ERR, "ERROR: fifo_server: write error: %s\n",
-                               strerror(errno));
-                       }
-                       fclose(file_handle);
-#endif
                        goto consume;
                }
 
@@ -433,6 +451,8 @@ int open_fifo_server()
                                strerror(errno));
                        return -1;
                }
+               /* a real server doesn't die if writing to reply fifo fails */
+               signal(SIGPIPE, SIG_IGN);
                LOG(L_INFO, "SER: open_uac_fifo: fifo server up at %s...\n",
                        fifo);
                fifo_server( fifo_stream ); /* never retruns */
@@ -453,21 +473,6 @@ static int print_version_cmd( FILE *stream, char *response_file )
 {
        if (response_file) {
                fifo_reply(response_file, SERVER_HDR CRLF );
-#ifdef _OBSOLETED
-               file=open( response_file, O_WRONLY );
-               if (file<0) {
-                       LOG(L_ERR, "ERROR: print_version_cmd: open error (%s): %s\n",
-                               response_file, strerror(errno));
-                       return -1;
-               }
-               if (write(file, SERVER_HDR CRLF, SERVER_HDR_LEN+CRLF_LEN)<0) {
-                       LOG(L_ERR, "ERROR: print_version_cmd: write error: %s\n",
-                               strerror(errno));
-                       close(file);
-                       return -1;
-               }
-               close(file);
-#endif
        } else {
                LOG(L_ERR, "ERROR: no file for print_version_cmd\n");
        }
@@ -487,9 +492,6 @@ static int print_fifo_cmd( FILE *stream, char *response_file )
                return -1;
        }
        if (!read_line(text, MAX_PRINT_TEXT, stream, &text_len)) {
-#ifdef _OBSOLETED
-               LOG(L_ERR, "ERROR: print_fifo_cmd: too big text\n");
-#endif
                fifo_reply(response_file, 
                        "ERROR: print_fifo_cmd: too big text");
                return -1;
@@ -497,21 +499,6 @@ static int print_fifo_cmd( FILE *stream, char *response_file )
        /* now the work begins */
        if (response_file) {
                fifo_reply(response_file, text );
-#ifdef _OBSOLETED
-               file=open( response_file , O_WRONLY);
-               if (file<0) {
-                       LOG(L_ERR, "ERROR: print_fifo_cmd: open error (%s): %s\n",
-                               response_file, strerror(errno));
-                       return -1;
-               }
-               if (write(file, text,text_len)<0) {
-                       LOG(L_ERR, "ERROR: print_fifo_cmd: write error: %s\n",
-                                strerror(errno));
-                       close(file);
-                       return 1;
-               }
-               close(file);
-#endif
        } else {
                LOG(L_INFO, "INFO: print_fifo_cmd: %.*s\n", 
                        text_len, text );
@@ -521,14 +508,20 @@ static int print_fifo_cmd( FILE *stream, char *response_file )
 
 static int uptime_fifo_cmd( FILE *stream, char *response_file )
 {
-       FILE *file;
        time_t now;
 
        if (response_file==0 || *response_file==0 ) { 
                LOG(L_ERR, "ERROR: uptime_fifo_cmd: null file\n");
                return -1;
        }
-       file=fopen(response_file, "w" );
+
+       time(&now);
+       fifo_reply( response_file, "Now: %sUp Since: %sUp time: %.0f [sec]\n",
+               ctime(&now), ctime(&up_since), difftime(now, up_since) );
+
+#ifdef _OBSOLETED
+
+       file=open_reply_pipe(response_file);
        if (file==NULL) {
                LOG(L_ERR, "ERROR: uptime_fifo_cmd: file %s bad: %s\n",
                        response_file, strerror(errno) );
@@ -536,11 +529,31 @@ static int uptime_fifo_cmd( FILE *stream, char *response_file )
        }
 
        time(&now);
-       fprintf(file, "Now: %s", ctime(&now) );
-       fprintf(file, "Up since: %s", ctime(&up_since) );
-       fprintf(file, "Up time: %.0f [sec]\n", difftime(now, up_since));
+
+       r=fprintf(file, "Now: %s", ctime(&now) );
+       r=1;
+       if (r<=0) {
+               printf("XXX: r: %d : %s\n", r, strerror(errno));
+               goto done;
+       }
+
+       r=fprintf(file, "Up since: %s", ctime(&up_since) );
+       r=1;
+       if (r<=0) {
+               printf("XXX: r: %d : %s\n", r, strerror(errno));
+               goto done;
+       }
+       r=fprintf(file, "Up time: %.0f [sec]\n", difftime(now, up_since));
+       r=1;
+       if (r<=0) {
+               printf("XXX: r: %d : %s\n", r, strerror(errno));
+               goto done;
+       }
+
+done:
 
        fclose(file);
+#endif
        return 1;
 }
 
index 43b5a49..7ae457e 100644 (file)
@@ -43,7 +43,7 @@ int register_core_fifo();
 FILE *open_reply_pipe( char *pipe_name );
 
 /* tell FIFO client an error occured via reply pipe */
-void fifo_reply( char *reply_fifo, char *reply_txt);
+void fifo_reply( char *reply_fifo, char *reply_fmt, ... );
 
 
 #endif
index e52872a..4f36933 100644 (file)
@@ -61,7 +61,7 @@ int static fifo_stats( FILE *pipe, char *response_file )
                return -1;
        }
 
-       file=fopen(response_file, "w" );
+       file=open_reply_pipe(response_file );
        if (file==NULL) {
                LOG(L_ERR, "ERROR: fifo_stats: file %s bad: %s\n",
                        response_file, strerror(errno) );
index 93b7e9f..feb1f7e 100644 (file)
@@ -211,35 +211,24 @@ static void fifo_callback( struct cell *t, struct sip_msg *msg,
 {
 
        char *filename;
-       int file;
-       int r;
        str text;
 
        DBG("DEBUG: fifo UAC completed with status %d\n", code);
-       if (t->cbp) {
-               filename=(char *)(t->cbp);
-               file=open(filename, O_WRONLY);
-               if (file<0) {
-                       LOG(L_ERR, "ERROR: fifo_callback: can't open file %s: %s\n",
-                               filename, strerror(errno));
-                       return;
-               }
-               get_reply_status(&text,msg,code);
-               if (text.s==0) {
-                       LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");
-                       return;
-               }
-               r=write(file, text.s , text.len );
-               close(file);
-               pkg_free(text.s);
-               if (r<0) {
-                       LOG(L_ERR, "ERROR: fifo_callback: write error: %s\n",
-                               strerror(errno));
-                       return; 
-               }
-       } else {
+       if (!t->cbp) {
                LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", code);
+               return;
+       }
+
+       filename=(char *)(t->cbp);
+       get_reply_status(&text,msg,code);
+       if (text.s==0) {
+               LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");
+               fifo_reply(filename, "ERROR: fifo_callback: get_reply_status failed\n");
+               return;
        }
+       fifo_reply(filename, "%.*s", text.len, text.s );
+       pkg_free(text.s);
+       DBG("DEBUG: fifo_callback sucesssfuly completed\n");
 }      
 
 /* to be obsoleted in favor of fifo_uac_from */