// Программа из конспекта "Системное программное обеспечение" // Очереди сообщений в Linux // стр. 108 // Название: server.c // Описание: функция сервера клиент-серверной системы // на основе очередей с мультиплексированием //svmsgmpx1q/server.c #include "mesg_send.c" #include "mesg_recv.c" void server(int readfd, int writefd) { FILE *fp; char *ptr; pid_t pid; ssize_t n; struct mymesg mesg; for ( ; ; ) { /* считывание полного имени из канала IPC */ mesg.mesg_type = 1; if ( (n = mesg_recv(readfd, &mesg)) ==0) { printf("pathname missing\n"); continue; } mesg.mesg_data[n] = '\0'; /* полное имя */ if ( (ptr = strchr(mesg.mesg_data, ' ')) == NULL) { printf("bogus request: n%s\n", mesg.mesg_data); continue; } *ptr++ =0; /* ptr - полное имя */ pid = atol(mesg.mesg_data); printf("Запрос от процесса %d\n",pid); mesg.mesg_type = pid; /* для обратных сообщений */ printf("Запрошен файл %s\n",ptr); if ( (fp = fopen(ptr, "r")) == NULL) { /* 4error: must tell client */ snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) - n,"\n: can't open. %s\n", strerror(errno)); mesg.mesg_len = strlen(ptr); memmove(mesg.mesg_data, ptr, mesg.mesg_len); mesg_send(writefd, &mesg); } else { /* файл открыт, копируем клиенту */ while (fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) { mesg.mesg_len = strlen(mesg.mesg_data); mesg_send(writefd, &mesg); } fclose(fp); } /* сообщение нулевой длины заканчивает связь */ mesg.mesg_len =0; mesg_send(writefd, &mesg); } }