⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pipe_imp.c

📁 《Beginning Linux Programming》书的配置实例源代码。
💻 C
字号:
// First the #includes.#include "cd_data.h"#include "cliserv.h"// We also define some values that we need in different functions within the file.static int server_fd = -1;static pid_t mypid = 0;static char client_pipe_name[PATH_MAX + 1] = {'\0'};static int client_fd = -1;static int client_write_fd = -1;// The server_starting routine creates the named pipe from which the server will read commands.// It then opens it for reading. This open will block until a client opens the pipe for writing.// We use a blocking mode, so that the server can perform blocking reads on the pipe while// waiting for commands to be sent to it.int server_starting(void){    #if DEBUG_TRACE            printf("%d :- server_starting()\n",  getpid());    #endif    	unlink(SERVER_PIPE);    if (mkfifo(SERVER_PIPE, 0777) == -1) {        fprintf(stderr, "Server startup error, no FIFO created\n");        return(0);    }    if ((server_fd = open(SERVER_PIPE, O_RDONLY)) == -1) {        fprintf(stderr, "Server startup error, no FIFO opened\n");        return(0);    }    return(1);}// When the server ends, it removes the named pipe, so clients can detect that no server// is running.void server_ending(void){    #if DEBUG_TRACE            printf("%d :- server_ending()\n",  getpid());    #endif    (void)close(server_fd);    (void)unlink(SERVER_PIPE);}// The read_request_from_client function, shown below, will block reading the server pipe// until a client writes a message into it.int read_request_from_client(message_db_t *rec_ptr){    int return_code = 0;    int read_bytes;    #if DEBUG_TRACE            printf("%d :- read_request_from_client()\n",  getpid());    #endif    if (server_fd != -1) {        read_bytes = read(server_fd, rec_ptr, sizeof(*rec_ptr)); // In the special case when no clients have the pipe open for writing, the read will return 0,// i.e. it detects an EOF.// Then the server closes the pipe and opens it again, so that it blocks until a client also// opens the pipe.// This is just the same as when the server first starts; we have re-initialized the server.// Insert this code in the function above.        if (read_bytes == 0) {            (void)close(server_fd);            if ((server_fd = open(SERVER_PIPE, O_RDONLY)) == -1) {               fprintf(stderr, "Server error, FIFO open failed\n");               return(0);            }            read_bytes = read(server_fd, rec_ptr, sizeof(*rec_ptr));        }        if (read_bytes == sizeof(*rec_ptr)) return_code = 1;    }    return(return_code);}// First, we open the client pipe.int start_resp_to_client(const message_db_t mess_to_send){    #if DEBUG_TRACE        printf("%d :- start_resp_to_client()\n", getpid());    #endif    (void)sprintf(client_pipe_name, CLIENT_PIPE, mess_to_send.client_pid);    if ((client_fd = open(client_pipe_name, O_WRONLY)) == -1) return(0);    return(1);}// The messages are all sent using calls to this function.// We'll look at the corresponding client-side functions that field the message soon.int send_resp_to_client(const message_db_t mess_to_send){    int write_bytes;    #if DEBUG_TRACE        printf("%d :- send_resp_to_client()\n", getpid());    #endif    if (client_fd == -1) return(0);    write_bytes = write(client_fd, &mess_to_send, sizeof(mess_to_send));    if (write_bytes != sizeof(mess_to_send)) return(0);    return(1);}// Finally, we close the client pipe.void end_resp_to_client(void){    #if DEBUG_TRACE        printf("%d :- end_resp_to_client()\n",  getpid());    #endif    if (client_fd != -1) {        (void)close(client_fd);        client_fd = -1;    }}// After checking that a server is accessible, the client_starting function initializes// the client-side pipe.int client_starting(void){    #if DEBUG_TRACE        printf("%d :- client_starting\n",  getpid());    #endif    mypid = getpid();    if ((server_fd = open(SERVER_PIPE, O_WRONLY)) == -1) {        fprintf(stderr, "Server not running\n");        return(0);    }    (void)sprintf(client_pipe_name, CLIENT_PIPE, mypid);    (void)unlink(client_pipe_name);    if (mkfifo(client_pipe_name, 0777) == -1) {        fprintf(stderr, "Unable to create client pipe %s\n",                    client_pipe_name);        return(0);    }    return(1);}// The client_ending function closes file descriptors and deletes the now redundant named pipe.void client_ending(void){    #if DEBUG_TRACE            printf("%d :- client_ending()\n",  getpid());     #endif    if (client_write_fd != -1) (void)close(client_write_fd);    if (client_fd != -1) (void)close(client_fd);    if (server_fd != -1) (void)close(server_fd);    (void)unlink(client_pipe_name);}// The send_mess_to_server function passes the request through the server pipe.int send_mess_to_server(message_db_t mess_to_send){    int write_bytes;    #if DEBUG_TRACE            printf("%d :- send_mess_to_server()\n",  getpid());    #endif    if (server_fd == -1) return(0);    mess_to_send.client_pid = mypid;    write_bytes = write(server_fd, &mess_to_send, sizeof(mess_to_send));    if (write_bytes != sizeof(mess_to_send)) return(0);    return(1);}// This client function starts to listen for the server response.// It opens a client pipe as read-only and then reopens this pipe's file as write-only.// We'll see why in a moment.int start_resp_from_server(void){    #if DEBUG_TRACE            printf("%d :- start_resp_from_server()\n",  getpid());        #endif    if (client_pipe_name[0] == '\0') return(0);    if (client_fd != -1) return(1);    client_fd = open(client_pipe_name, O_RDONLY);    if (client_fd != -1) {        client_write_fd = open(client_pipe_name, O_WRONLY);        if (client_write_fd != -1) return(1);        (void)close(client_fd);        client_fd = -1;    }    return(0);}// Here's the main read from the server which gets the matching database entries.int read_resp_from_server(message_db_t *rec_ptr){    int read_bytes;    int return_code = 0;    #if DEBUG_TRACE            printf("%d :- read_resp_from_server()\n",  getpid());        #endif    if (!rec_ptr) return(0);    if (client_fd == -1) return(0);    read_bytes = read(client_fd, rec_ptr, sizeof(*rec_ptr));    if (read_bytes == sizeof(*rec_ptr)) return_code = 1;    return(return_code);}// And finally, the client function that marks the end of the server response.void end_resp_from_server(void){    #if DEBUG_TRACE            printf("%d :- end_resp_from_server()\n",  getpid());            #endif    /* This function is empty in the pipe implementation */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -