static inline FILE* get_fifo_stream(FILE *old_stream) { int fd, n; struct stat fst; if (mi_reload_fifo == 0) { fd = fileno(old_stream); if (!mi_fifo_check(fd, mi_fifo_name)) return old_stream; LM_INFO("invalid FIFO file: creating a new one (%s)\n", mi_fifo_name); } else { LM_INFO("Forcefully replacing FIFO file (%s)\n", mi_fifo_name); } /* here we are either forced to reload or the check did not pass */ n = stat(mi_fifo_name, &fst); if (n == 0) { if (unlink(mi_fifo_name) < 0) { LM_ERR("cannot delete fifo file %s\n", mi_fifo_name); return NULL; } LM_INFO("deleted FIFO file (%s)\n", mi_fifo_name); } else if (n < 0 && errno != ENOENT) { LM_ERR("stat failed: %s\n", strerror(errno)); return NULL; } mi_reload_fifo = 0; return mi_create_fifo(); }
int mi_open_reply_pipe( char *pipe_name ) { int fifofd; int retries=FIFO_REPLY_RETRIES; if (!pipe_name || *pipe_name==0) { LM_DBG("no file to write to about missing cmd\n"); return -1; } tryagain: /* open non-blocking to make sure that a broken client will not * block the FIFO server forever */ 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) { LM_ERR("no client at %s\n",pipe_name ); return -1; } /* don't be noisy on the very first try */ if (retries!=FIFO_REPLY_RETRIES) LM_DBG("retry countdown: %d\n", retries ); sleep_us( FIFO_REPLY_WAIT ); retries--; goto tryagain; } /* some other opening error */ LM_ERR("open error (%s): %s\n", pipe_name, strerror(errno)); return -1; } /* security checks: is this really a fifo?, is * it hardlinked? is it a soft link? */ if (mi_fifo_check(fifofd, pipe_name)<0) goto error; return fifofd; error: close(fifofd); return -1; }
static FILE *mi_open_reply_pipe( char *pipe_name ) { int fifofd; FILE *file_handle; int flags; int retries=FIFO_REPLY_RETRIES; if (!pipe_name || *pipe_name==0) { LM_DBG("no file to write to about missing cmd\n"); return 0; } tryagain: /* open non-blocking to make sure that a broken client will not * block the FIFO server forever */ 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) { LM_ERR("no client at %s\n",pipe_name ); return 0; } /* don't be noisy on the very first try */ if (retries!=FIFO_REPLY_RETRIES) LM_DBG("retry countdown: %d\n", retries ); sleep_us( FIFO_REPLY_WAIT ); retries--; goto tryagain; } /* some other opening error */ LM_ERR("open error (%s): %s\n", pipe_name, strerror(errno)); return 0; } /* security checks: is this really a fifo?, is * it hardlinked? is it a soft link? */ if (mi_fifo_check(fifofd, pipe_name)<0) goto error; /* we want server blocking for big writes */ if ( (flags=fcntl(fifofd, F_GETFL, 0))<0) { LM_ERR("pipe (%s): getfl failed: %s\n", pipe_name, strerror(errno)); goto error; } flags&=~O_NONBLOCK; if (fcntl(fifofd, F_SETFL, flags)<0) { LM_ERR("pipe (%s): setfl cntl failed: %s\n", pipe_name, strerror(errno)); goto error; } /* create an I/O stream */ file_handle=fdopen( fifofd, "w"); if (file_handle==NULL) { LM_ERR("open error (%s): %s\n", pipe_name, strerror(errno)); goto error; } return file_handle; error: close(fifofd); return 0; }