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