Beispiel #1
0
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();
}
Beispiel #2
0
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;
}