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

📄 clientif.c

📁 《linux程序设计(第三版)》例程代码
💻 C
字号:
/* The file starts with #include files and constants. */#define _POSIX_SOURCE#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <fcntl.h>#include <limits.h>#include <sys/types.h>#include <sys/stat.h>#include "cd_data.h"#include "cliserv.h"/* The static variable mypid reduces the number of calls to getpid that would otherwise be required. We use a local function, read_one_response, to eliminate duplicated code.*/static pid_t mypid;static int read_one_response(message_db_t *rec_ptr);/*The database_initialize and close routines are still called, but are now used, respectively,for initializing the client-side of the pipes interface and for removing redundant namedpipes when the client exits.*/int database_initialize(const int new_database){    if (!client_starting()) return(0);    mypid = getpid();    return(1);    } /* database_initialize */void database_close(void) {    client_ending();}/*The get_cdc_entry routine is called to get a catalog entry from the database,given a CD catalog title.Here we encode the request in a message_db_t structure and pass it to the server.We then read the response back into a different message_db_t structure.If an entry is found, it's included inside the message_db_t structure as a cdc_entrystructure, so we pass back the appropriate part of the structure.*/cdc_entry get_cdc_entry(const char *cd_catalog_ptr){    cdc_entry ret_val;    message_db_t mess_send;    message_db_t mess_ret;    ret_val.catalog[0] = '\0';    mess_send.client_pid = mypid;    mess_send.request = s_get_cdc_entry;    strcpy(mess_send.cdc_entry_data.catalog, cd_catalog_ptr);    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                ret_val = mess_ret.cdc_entry_data;            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(ret_val);}/* The function read_one_response is used to avoid duplicating code. */static int read_one_response(message_db_t *rec_ptr) {    int return_code = 0;    if (!rec_ptr) return(0);        if (start_resp_from_server()) {        if (read_resp_from_server(rec_ptr)) {            return_code = 1;        }        end_resp_from_server();    }    return(return_code);} /* The other get_xxx, del_xxx and add_xxx routines are implemented in a similar way to the get_cdc_entry function. */  /* First, the function for retrieving CD tracks. */cdt_entry get_cdt_entry(const char *cd_catalog_ptr, const int track_no){    cdt_entry ret_val;    message_db_t mess_send;    message_db_t mess_ret;    ret_val.catalog[0] = '\0';    mess_send.client_pid = mypid;    mess_send.request = s_get_cdt_entry;    strcpy(mess_send.cdt_entry_data.catalog, cd_catalog_ptr);    mess_send.cdt_entry_data.track_no = track_no;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                ret_val = mess_ret.cdt_entry_data;            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(ret_val);}/* Next, two functions for adding data, first to the catalog and then to the tracks database. */int add_cdc_entry(const cdc_entry entry_to_add){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_add_cdc_entry;    mess_send.cdc_entry_data = entry_to_add;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}int add_cdt_entry(const cdt_entry entry_to_add){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_add_cdt_entry;    mess_send.cdt_entry_data = entry_to_add;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}/* And lastly, two functions for data deletion. */int del_cdc_entry(const char *cd_catalog_ptr){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_del_cdc_entry;    strcpy(mess_send.cdc_entry_data.catalog, cd_catalog_ptr);    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}int del_cdt_entry(const char *cd_catalog_ptr, const int track_no){    message_db_t mess_send;    message_db_t mess_ret;    mess_send.client_pid = mypid;    mess_send.request = s_del_cdt_entry;    strcpy(mess_send.cdt_entry_data.catalog, cd_catalog_ptr);    mess_send.cdt_entry_data.track_no = track_no;    if (send_mess_to_server(mess_send)) {        if (read_one_response(&mess_ret)) {            if (mess_ret.response == r_success) {                return(1);            } else {                fprintf(stderr, "%s", mess_ret.error_text);            }        } else {            fprintf(stderr, "Server failed to respond\n");        }    } else {        fprintf(stderr, "Server not accepting requests\n");    }    return(0);}/* This function looks more complicated than it is because it calls three pipe functions, send_mess_to_server, start_resp_from_server and read_resp_from_server. */cdc_entry search_cdc_entry(const char *cd_catalog_ptr, int *first_call_ptr){    message_db_t mess_send;    message_db_t mess_ret;        static FILE *work_file = (FILE *)0;    static int entries_matching = 0;    cdc_entry ret_val;    ret_val.catalog[0] = '\0';    if (!work_file && (*first_call_ptr == 0)) return(ret_val);/*Here's the first call to search, i.e. with *first_call_ptr set to true.It's set to false immediately, lest we forget. A work_file is created and the client message structure initialized.*/    if (*first_call_ptr) {        *first_call_ptr = 0;        if (work_file) fclose(work_file);        work_file = tmpfile();        if (!work_file) return(ret_val);        mess_send.client_pid = mypid;        mess_send.request = s_find_cdc_entry;        strcpy(mess_send.cdc_entry_data.catalog, cd_catalog_ptr);/*Now set of condition tests, which makes calls to functions in pipe_imp.c.If the message is successfully sent to the server, the client waits for the server's response.While reads from the server are successful, the search matches are returned to the client's work_file and the entries_matching counter is incremented.*/        if (send_mess_to_server(mess_send)) {            if (start_resp_from_server()) {                while (read_resp_from_server(&mess_ret)) {                    if (mess_ret.response == r_success) {               fwrite(&mess_ret.cdc_entry_data, sizeof(cdc_entry), 1, work_file);                        entries_matching++;                    } else {                        break;                    }                } /* while */            } else {                fprintf(stderr, "Server not responding\n");            }        } else {            fprintf(stderr, "Server not accepting requests\n");        }/*The next test checks whether the search had any luck.Then the fseek call sets the work_file to the next place for data to be written.*/        if (entries_matching == 0) {            fclose(work_file);            work_file = (FILE *)0;            return(ret_val);        }              (void)fseek(work_file, 0L, SEEK_SET);/*If this is not the first call to the search function with this particular search term,the code checks whether there are any matches left. Finally, the next matching entry isread to the ret_val structure. The previous checks guarantee that a matching entry exists.*/    } else {            /* not *first_call_ptr */        if (entries_matching == 0) {            fclose(work_file);            work_file = (FILE *)0;                        return(ret_val);        }    }    fread(&ret_val, sizeof(cdc_entry), 1, work_file);        entries_matching--;        return(ret_val);}

⌨️ 快捷键说明

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