linux 命名管道FIFO

#define FIFO_FILE_NUM 5 /*3*/
char *fifo_name[FIFO_FILE_NUM] = {"/tmp/testfifo1", "/tmp/testfifo2", "/tmp/testfifo3", "/tmp/testfifo4", "/tmp/testfifo5"};

typedef struct FifoFileHandle{
    struct FifoFileHandle *this;
    char fifo_name[255];
    int r_fd;
    int w_fd;
    int (*init)(struct FifoFileHandle *this);//init fifo
    int (*open)(struct FifoFileHandle *this, int mode, int is_nonblock);//open fifo file
    int (*read)(struct FifoFileHandle *this, void *buffer, int buffer_size, long timeout_ms);//read data from the fifo file
    int (*write)(struct FifoFileHandle *this, void *buffer, int buffer_size, long timeout_ms);//write data to the fifo file
    int (*close)(struct FifoFileHandle *this, int mode);//close fifo file
    int (*destroy)(struct FifoFileHandle *this);
}fifo_file_handle;

fifo_file_handle *fifo_handle[FIFO_FILE_NUM];

typedef enum {
    READ_MODE = 0,
    WRITE_MODE = 1,
}OPEN_FILE_MODE;

int init_fifo_file(fifo_file_handle *this) {
    if (NULL == this) {
        ERROR("arguments error.\n");
        return -1;
    }

    int re_value = mkfifo(this->fifo_name, 0777);
    if (0 != re_value && 17 != errno) {
        ERROR("called mkfifo failed, errno:%d, %s.\n", errno, strerror(errno));
    }
    return 0;
}

int destroy_fifo_file(fifo_file_handle *this) {
    if (NULL != this) {
        free(this);
        this = NULL;
    }
    return 0;
}

/*open fifo file*/
int open_fifo_file(fifo_file_handle *this, int mode, int is_nonblock) {
    if (NULL == this || (READ_MODE != mode && WRITE_MODE != mode)) {
        ERROR("arguments error.\n");
        return -1;
    }

    int *fd = NULL;
    int flag = 0;
    if (READ_MODE == mode) {
        fd = &this->r_fd;
        flag |= O_RDWR;
    }
    else if (WRITE_MODE == mode) {
        fd = &this->w_fd;
        flag |= O_RDWR;
    }

    if ((*fd = open(this->fifo_name, flag, 0777)) < 0) {
        ERROR("called open fifo file failed, errno:%d, %s.\n", errno, strerror(errno));
        return -2;
    }

    if (is_nonblock) {
        int flags = fcntl(*fd, F_GETFL, 0);
        if (fcntl(*fd, F_SETFL, flags|O_NONBLOCK) < 0) {
            ERROR("called fcntl failed, errno:%d, %s\n", errno, strerror(errno));
            return -2;
        }
    }
    return 0;
}

int close_fifo_file(fifo_file_handle *this, int mode) {    //close fifo file
    if (NULL == this || (READ_MODE != mode && WRITE_MODE != mode)) {
        ERROR("arguments error.\n");
        return -1;
    }

    int *fd = NULL;
    if (READ_MODE == mode) {
        fd = &this->r_fd;
    }
    else if (WRITE_MODE == mode) {
        fd = &this->w_fd;
    }

    if (*fd > 0) {
        close(*fd);
        *fd = -1;
    }
    return 0;
}

int read_data_from_fifo_file(fifo_file_handle *this, void *buffer, int buffer_size, long waittime_ms)
{
    if (NULL == this || NULL == buffer || 0 == buffer_size) {
        ERROR("Param error.\n");
        return -1;
    }

    int read_num = 0;
    int maxfd = this->r_fd + 1;

    struct timeval timeout = {0, 0};

    if (0 < waittime_ms) {
        timeout.tv_sec = waittime_ms / 1000;
        timeout.tv_usec = (waittime_ms % 1000) * 1000;
    }

    fd_set fdset;
    FD_ZERO(&fdset);
    FD_SET(this->r_fd, &fdset);
    select(maxfd, &fdset, NULL, NULL, (0 != waittime_ms)?(&timeout):(NULL));
    if(FD_ISSET(this->r_fd, &fdset)) {
        if ((read_num = read(this->r_fd, buffer, buffer_size)) < 0) {
            ERROR("Called read failed, errno:%d, %s.\n", errno, strerror(errno));
            return -2;
        }
    }

    FD_CLR(this->r_fd, &fdset);

    return 0;
}

int write_data_to_fifo_file(fifo_file_handle *this, void *buffer, int buffer_size, long waittime_ms)
{
    if (NULL == this || NULL == buffer || 0 == buffer_size) {
        ERROR("Param error.\n");
        return -1;
    }

    int write_num = 0;
    int32_t maxfd = this->r_fd + 1;
    fd_set fdset;
    int fifo_status = -1;

    struct timeval timeout = {0, 0};
    if (0 < waittime_ms) {
        timeout.tv_sec = waittime_ms / 1000;
        timeout.tv_usec = (waittime_ms % 1000) * 1000;
    }
    FD_ZERO(&fdset);
    FD_SET(this->r_fd, &fdset);

    fifo_status = select(maxfd, NULL, &fdset, NULL, (0 != waittime_ms)?(&timeout):(NULL));
    if (0 == fifo_status) {
        FD_CLR(this->r_fd, &fdset);
        return -2;
    }
    if(FD_ISSET(this->r_fd, &fdset)) {
        if ((write_num = write(this->r_fd, buffer, buffer_size)) < 0) {
            ERROR("called write failed, error:%d, %s.\n", errno, strerror(errno));
            return -3;
        }
    }
    FD_CLR(this->r_fd, &fdset);

    return 0;
}


int init_fifo_handle() {
    int i = 0;
    for (i=0; i<FIFO_FILE_NUM; i++) {
        fifo_handle[i] = NULL;
        fifo_handle[i] = (fifo_file_handle *)calloc(sizeof(fifo_file_handle), 1);
        if (NULL == fifo_handle[i]) {
            ERROR("called calloc failed, errno:%d, %s.\n", errno, strerror(errno));
            return -1;
        }

        strcpy(fifo_handle[i]->fifo_name, fifo_name[i]);
        fifo_handle[i]->this = fifo_handle[i];
        fifo_handle[i]->r_fd = -1;
        fifo_handle[i]->w_fd = -1;
        fifo_handle[i]->init = init_fifo_file;
        fifo_handle[i]->open = open_fifo_file;
        fifo_handle[i]->read = read_data_from_fifo_file;
        fifo_handle[i]->write = write_data_to_fifo_file;
        fifo_handle[i]->close = close_fifo_file;
        fifo_handle[i]->destroy = destroy_fifo_file;
    }
    return 0;
}

int destroy_fifo_handle() {
    int i = 0;

    for (i=0; i<FIFO_FILE_NUM; i++) {
        if (fifo_handle[i]) {
            free(fifo_handle[i]);
            fifo_handle[i] = NULL;
        }
    }

    return 0;
}

static int open_fifo_file_handle() {
    fifo_handle[0]->init(fifo_handle[0]);
    fifo_handle[1]->init(fifo_handle[1]);
    fifo_handle[2]->init(fifo_handle[2]);

    fifo_handle[3]->init(fifo_handle[3]);
    fifo_handle[4]->init(fifo_handle[4]);

    fifo_handle[0]->open(fifo_handle[0], READ_MODE, 0);
    fifo_handle[0]->open(fifo_handle[0], WRITE_MODE, 0);
    fifo_handle[1]->open(fifo_handle[1], READ_MODE, 0);
    fifo_handle[1]->open(fifo_handle[1], WRITE_MODE, 0);
    fifo_handle[2]->open(fifo_handle[2], READ_MODE, 0);
    fifo_handle[2]->open(fifo_handle[2], WRITE_MODE, 0);

    fifo_handle[3]->open(fifo_handle[3], READ_MODE, 1);
    fifo_handle[3]->open(fifo_handle[3], WRITE_MODE, 1);

    fifo_handle[4]->open(fifo_handle[4], READ_MODE, 0);
    fifo_handle[4]->open(fifo_handle[4], WRITE_MODE, 0);

    return 0;
}

int main(int argc, char **argv) {
     ....................
     /*int fifo handle*/
    init_fifo_handle();
    open_fifo_file_handle();
     ..........
     ..........
}

发布了95 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ding283595861/article/details/105285278