Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение




Скачать 221.51 Kb.
НазваниеПояснительная записка к курсовой работе по дисциплине системное программное обеспечение
Дата публикации27.10.2013
Размер221.51 Kb.
ТипПояснительная записка
uchebilka.ru > Информатика > Пояснительная записка


Пензенский государственный университет

Кафедра “Вычислительная техника”

Пояснительная записка
к курсовой работе по дисциплине


СИСТЕМНОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ

Тема: Разработка программы на языке C для ОС Linux с использованием системного API

Выполнил: ст. гр. 97ВВ3 Левин С.С.

Принял: Коннова Л.Г.

Содержание

Введение 4

1 Описание метода решения задачи 5

2 Руководство пользователя 8

3 Описание логического представления входных и выходных данных 9

4 Схема программы 11

5 Схема взаимодействия программ 12

6 Спецификации на программные модули 13

6.1 Модуль lchat.h 13

6.2 Модуль lchat.c 13

6.3 Модуль message.c 13

6.4 Модуль screen.c 15

7 План отладки программы 17

Заключение 18

Приложение А (исходный текст программы) 19

^ 1. Файл lchat.h 19

2. Файл lchat.c 20

3. Файл message.c 20

4. Файл screen.c 22

Приложение Б (результаты работы программы) 26

1. Вид программы после запуска 26

2. Вид программы во время работы 26

Приложение В (список использованных источников) 27



Введение


Непрерывное снижение цен, рост производительности и ожидаемое появление новых микро- и супер-микрокомпьютеров делают мощь операционных систем семейства Unix доступной для все большего круга пользователей. Операционные системы типа Unix работают на самых различных аппаратных платформах: от уровня IBM PC XT до AT и выше. Доступность больших объемов оперативной памяти и мощных микропроцессоров привела к возрастанию интереса к многозадачности, системам мультипроцессирования - сфере, в которой операционные системы семейства Unix имеет солидную репутацию.

В сентябре 1991 г. L. B. Torvalds распространил по электронной почте первый вариант операционной системы Linux. С этого момента многие программисты стали поддерживать Linux, добавляя драйверы устройств, разрабатывая разные продвинутые приложения и учитывая соглашения POSIX. В настоящее время Linux - очень мощная система, но самое замечательное то, что она является совершенно бесплатной. Другим преимуществами Linux являются: довольно простое ядро с хорошо структурированным интерфейсом; отсутствие в ядре раздробленных участков в связи с тем, что контроль за написанием ядра вел один человек – L. B. Torvalds; свободное распространение исходных текстов ядра, позволяющее всем желающим изучать их.

Операционные системы семейства Unix тесно связаны с языком C, который был изобретен в 1972 г. D. M. Ritchie, как раз при написании первого варианта Unix. Язык C наиболее эффективен при решении задач системного программирования, хотя он, безусловно, удобен и при написании прикладных программ. Среди преимуществ языка C можно отметить переносимость программ, лаконичность, логическую стойкость и удобочитаемость программ, возможность получить очень эффективный код программ. Удобство языка C основано на том, что он является одновременно и языком высокого уровня, поддерживающим модульность, блочную структуру программ, возможность раздельной компиляции модулей. В то же самое время язык C имеет набор низкоуровневых средств, позволяющих иметь удобный доступ к большей части аппаратных средств компьютера.

Сказанное выше объясняет огромную популярность языка C как языка системного программирования в операционных системах семейства Unix.
^

1Описание метода решения задачи


Целью курсовой работы является разработка программы, обеспечивающей ведение диалога между пользователями одного компьютера. Одновременно должны работать несколько экземпляров программы. Каждая из программ обладает свойствами приемника и передатчика. Пользователь вводит с терминала текст, который отображается на экранах других терминалов. Во время ввода данных одним из пользователей режим ввода данных для других пользователей должен быть заблокирован. Для передачи данных необходимо использовать разделяемую область памяти, для блокировки данных – семафоры.

При разработке программы мне пришлось решить следующие задачи:

  • Обеспечение параллельного функционирования приемника и передатчика;

  • Обеспечение синхронизации приемников и передатчиков, а также обеспечение одновременного ввода данных только одним пользователем;

  • Разработка текстового оконного интерфейса.

Для обеспечения параллельного функционирования приемника и передатчика каждый экземпляр программы использует два процесса. Родительский процесс является приемником. Он содержит цикл, в котором производится прием сообщений и вывод их на экран. Если родительский процесс получает сообщение, сигнализирующее о завершении работы дочернего процесса, то цикл приема сообщений прерывается, ожидается завершение работы дочернего процесса, и работа программы завершается. Дочерний процесс является передатчиком. Он содержит цикл, в котором производится опрос клавиатуры терминала. При получении команды отправки сообщения дочерний процесс отправляет сообщение, при получении команды завершения работы дочерний процесс отправляет сообщение, сигнализирующее о завершении работы, цикл передачи завершается, и работа процесса завершается. Для реализации рассмотренного взаимодействия двух процессов были использованы системные вызовы fork( ), _exit( ), getpid( ), getppid( ) и wait( ).

Согласно заданию на курсовую работу, различные экземпляры программы должны взаимодействовать по одноранговой схеме. Для обеспечения корректного взаимодействия программ был использован набор, состоящий из двух семафоров. В различных режимах работы программы семафоры имеют следующие значения. При инициализации, если запускается первый экземпляр программы, создаваемым семафорам присваиваются значения 0, 1 (разрешена передача данных), если запускается не первый экземпляр программы, то с помощью соответствующего системного вызова осуществляется ожидание нулевого значения первого семафора (т.о., производится ожидание завершения чтения всеми приемниками последнего отправленного сообщения). При передаче данных сначала с помощью соответствующего системного вызова осуществляется ожидание нулевого значения первого семафора и производится уменьшение на единицу значения второго семафора (после завершения данной операции семафоры получают значения 0, 0, т.о., все процессы, кроме текущего, блокируются), производится запрос текста передаваемого сообщения, сообщение записывается в разделяемую область памяти, затем с помощью соответствующего системного вызова осуществляется увеличение значения первого семафора на количество процессов, которые ожидают уменьшения его значения, т.е. на количество приемников (т.о., снимается блокировка со всех приемников). При приеме данных сначала с помощью соответствующего системного вызова осуществляется уменьшение значения первого семафора на единицу, сообщение считывается из разделяемой области памяти, затем с помощью соответствующего системного вызова осуществляется ожидание нулевого значения первого семафора (т.о., текущий приемник блокируется), а если текущий приемник считывал данные из разделяемой области памяти последним, то значение второго семафора увеличивается на единицу (т.о., снимается блокировка со всех передатчиков). Для реализации рассмотренного взаимодействия нескольких экземпляров программы были применены разделяемая область памяти и семафорный набор в стиле Unix System V. Для управления семафорным набором были использованы системные вызовы semget( ), semop( ) и semctl( ); для управления разделяемой областью памяти – shmget( ), shmat( ), shmdt( ) и shmctl( ).

Для построения текстового оконного интерфейса я использовал библиотеку функций терминального ввода/вывода ncurses. Программа манипулирует тремя окнами: Received messages – окно для принимаемых сообщений; Send message – окно для отправляемого сообщения; Welcome - окно, посредством которого запрашивается имя текущего пользователя программы. Все окна построены таким образом, что их координаты могут динамически изменяться в зависимости от соответствующих установок терминала. Для вывода сообщений об ошибках программа использует стандартный поток ошибок. Программа имеет простой, но достаточно удобный интерфейс. Цветовые схемы выбраны подобными цветовым схемам популярных файловых менеджеров. Минимальное разрешение экрана терминала, с которого запускается программа, не должно быть меньше 64х символов по горизонтали и 10и символов по вертикали. Если указанное условие не соблюдается, то программа не запустится. Для реализации оконного интерфейса программы были использованы следующие функции и макросы библиотеки ncurses: attrset( ), beep( ), cbreak( ), clear( ), delwin( ), echo( ), delwin( ), getch( ), getmaxyx( ), getyx( ), has_color( ), init_pair( ), initscr( ), mvaddstr( ), mvwaddch( ), mvwaddstr( ), newwin( ), noecho( ), refresh( ), scrollok( ), start_color( ), touchwin( ), waddch( ), waddstr( ), wattrset( ), wborder( ), wgetnstr( ), wmove( ), wrefresh( ).

Также при написании программы были использованы следующие функции и макросы стандартной библиотеки языка C: atexit( ), exit( ), fputs( ), memcpy( ), sprintf( ), strcat( ), strcmp( ), strcpy( ), strerror( ), strlen( ), va_start( ), va_end( ), vsprintf( ).

Исходный текст программы состоит из четырех модулей и строго придерживается принципов структурного программирования.

При присвоении имен локальным переменным функций программы я старался сделать эти имена достаточно информативными для понимания назначения конкретных переменных и использовал соответствующие комментарии. Я считаю, что при чтении исходного текста программы не должно возникнуть никаких вопросов о типах и назначении конкретных локальных переменных.
^

2Руководство пользователя


Программа Local Chat предназначена для ведения диалога между пользователями одного компьютера, работающего под управлением операционной системы Linux. Программа может быть запущена как с одного из локальных терминалов, так и с удаленного терминала, реализованного посредством какого-либо клиента telnet, причем этот клиент может функционировать под управлением операционной системы, отличной от Linux.

Для корректной работы программы необходимы следующие аппаратные и программные средства:

  • Компьютер с установленной операционной системой Linux;

  • 11 Кбайт свободного дискового пространства при динамической компоновке программы и 296 Кбайт – при статической (для использования динамически скомпонованной программы необходимо наличие корректно установленной библиотеки ncurses);

  • Терминал с разрешением экрана не хуже 64x10 символов (желательно 80x25 символов и с поддержкой цвета).

Программа может быть запущена любым доступным способом: из командной строки, из скрипта Shell или из любой оболочки, например, Midnight Commander.

Программа имеет оконный интерфейс, функционирующий в текстовом режиме. Главное окно программы содержит строку заголовка, окна Received messages и Send message, информационную строку. Строка заголовка отображает название программы и информацию об авторе. Информационная строка содержит информацию о “горячих” клавишах программы и имя текущего пользователя. Назначение окон понятно из их названия. Ввод команд и текстов отправляемых сообщений производится с клавиатуры терминала. Имя пользователя запрашивается в начале сеанса работы с помощью диалогового окна.

При проектировании программы я старался создать приложение, максимально понятное и удобное для рядовых пользователей. Дополнительными аргументами в пользу программы могут стать ее небольшой размер и относительно высокое быстродействие.
^

3Описание логического представления входных и выходных данных


С точки зрения пользователя программы входные данные представляют собой вводимые с клавиатуры терминала команды, имя пользователя, текст отправляемых сообщений; выходные данные представляют собой имеющие предопределенный формат сообщения, выводимые на экран терминала.

Логически сообщения передаются в виде блоков данных, формат которых задан структурой MESSAGE, определенной в файле lchat.h следующим образом:

typedef struct _MSG {

pid_t pid;

char name[MAX_USER];

char text[MAX_TEXT];

} MESSAGE;

Поля данной структуры имеют следующие значения: pid – PID родительского процесса процесса-передатчика, т.е. PID процесса-приемника (данное поле необходимо для идентификации передатчика, который послал сообщение, сигнализирующее о завершении работы); name[ ] – имя пользователя программы, который отправил данное сообщение; text[ ] – текст сообщения.

Для завершения работы процессов программы передатчик посылает сообщение предопределенного формата, которое сигнализирует приемнику о завершении работы. Текст такого сообщения определяется константой BYE_MSG. Все приемники, получившие указанное сообщение, анализируют значение поля pid полученного сообщения, и тот приемник, PID которого совпал со значением pid полученного сообщения, также завершает работу. Т.о., обеспечиваются синхронное завершение работы процессов программы и извещение других пользователей о том, что данный пользователь завершил работу. Применение PID процесса, а не имени пользователя в качестве идентификатора конкретного экземпляра программы обусловлено тем, что несколько пользователей могут использовать одно и тоже имя (например, заданное по-умолчанию), а PID любого процесса всегда уникален во время одного сеанса работы.

Максимальные длины имени пользователя и текста сообщения равны 10и и 128и символам и определяются в файле lchat.h константами MAX_USER и MAX_TEXT соответственно. Указанные константы учитывают завершающий соответствующие строки NULL-символ.

Обмен данными между несколькими экземплярами программы происходит по приведенной ниже схеме:


^

4Схема программы



5Схема взаимодействия программ




  • Модуль lchat.h – является заголовком (на схеме он не показан, т.к. не содержит исполняемый код);

  • Модуль lchat.c – содержит функцию main( );

  • Модуль message.c – содержит функции приема/передачи сообщений с использованием разделяемой области памяти и набора семафоров;

  • Модуль screen.c – содержит функции терминального ввода/вывода, базирующиеся на функциях библиотеки ncurses.

  • T – временная передача управления.
^

6Спецификации на программные модули

6.1Модуль lchat.h


Данный модуль является заголовком. Он содержит: директивы, ускоряющие компиляцию программы; включения библиотечных и системных заголовков для используемых в программе библиотечных и системных функций; определения символических имен констант: MAX_USER (максимальная длина имени пользователя в байтах), MAX_TEXT (максимальная длина текста сообщения в байтах), IPC_KEY (ключ разделяемой области памяти и семафорного набора) и BYE_MSG (сообщение, сигнализирующее о завершения работы); определение типа данных MESSAGE; переименование системных типов данных union semunSEMUN), struct sembufSEMBUF) и struct shmid_dsSHMIDDS) для сокращения исходного текста программы; декларации внешних функций программы.
^

6.2Модуль lchat.c


Данный модуль является главным и содержит единственную функцию – int main(void), которая выполняет следующие действия: инициализирует систему терминального ввода вывода; инициализирует разделяемую область памяти и семафорный набор; запрашивает имя текущего пользователя программы; порождает дочерний процесс. Родительский процесс выполняет прием сообщений; дочерний процесс опрашивает клавиатуру и выполняет передачу сообщений.
^

6.3Модуль message.c


Данный модуль обеспечивает прием/передачу сообщений с использованием семафорного набора и разделяемой области памяти. Он содержит следующие глобальные переменные:

  • int semid – идентификатор двухсемафорного набора;

  • int shmid – идентификатор разделяемой области памяти;

  • char* shmaddr – виртуальный адрес разделяемой области памяти.

Модуль содержит следующие функции:

  • void initipc(key_t key) – инициализирует разделяемую область памяти и двухсемафорный набор. Аргумент функции задает ключ открываемых (создаваемых) IPC-объектов. Функция осуществляет попытку открытия существующих разделяемой области памяти и семафорного набора, дожидается соответствующего значения первого семафора; если разделяемая область памяти не существует, то создает разделяемую область памяти и двухсемафорный набор с правами чтения и записи для всех пользователей (0666), устанавливает соответствующие значения семафоров; подсоединяет разделяемую область памяти к виртуальному адресному пространству процесса; регистрирует функцию, обеспечивающую завершение работы с разделяемой областью памяти и семафорным набором для ее выполнения при завершении работы программы. При возникновении какой-либо ошибки выводит соответствующее сообщение и завершает работу программы с кодом завершения 1.

  • void closeipc(void) – завершает работу с разделяемой областью памяти и семафорным набором. Функция отсоединяет разделяемую область памяти от виртуального адресного пространства процесса; и, если завершается работа последнего экземпляра программы, удаляет разделяемую область памяти и семафорный набор.

  • void sendmessage(MESSAGE* msg) – записывает сообщение в разделяемую область памяти. Аргумент функции указывает на передаваемое сообщение (поля pid и name передаваемого сообщения должны быть заполнены перед вызовом данной функции). Функция блокирует все приемники и передатчики; запрашивает текст сообщения, если текст сообщения не является строкой BYE_MSG; записывает сообщение в разделяемую область памяти; снимает блокировку со всех приемников.

  • void receivemessage(MESSAGE* msg) – считывает сообщение из разделяемой области памяти. Аргумент функции указывает на считываемое сообщение. Функция ожидает, когда какой-либо передатчик отправит сообщение; считывает сообщение из разделяемой области памяти; ожидает, когда все приемники завершат чтение сообщения; и, если текущий процесс считывает сообщение последним, снимает блокировку со всех передатчиков.

  • void ipcerror(const char* func) – выводит сообщение об ошибке IPC-функции и завершает работу программы с кодом завершения 1. Аргумент функции указывает на буфер, содержащий имя функции, при выполнении которой произошла ошибка.
^

6.4Модуль screen.c


Данный модуль обеспечивает терминальный ввод/вывод с использованием функций библиотеки ncurses. Он содержит следующие глобальные переменные:

  • int width – ширина экрана терминала;

  • int height – высота экрана терминала;

  • WINDOW* recvwin – указатель на окно Received messages;

  • WINDOW* sendwin – указатель на окно Send message.

Модуль содержит следующие функции:

  • void initscreen(void) – инициализирует систему терминального ввода/вывода. Функция инициализирует библиотеку ncurses; выводит на экран строку заголовка и информационную строку; создает окна Received messages и Send message; устанавливает параметры терминального ввода/вывода; регистрирует функцию, обеспечивающую завершение работы с библиотекой ncurses, для ее выполнения при завершении работы программы.

  • void restorescreen(void) – удаляет окна Received messages и Send message, очищает экран и завершает работу с библиотекой ncurses.

  • void putmessage(MESSAGE  msg) – форматирует и выводит текст сообщения в окно Received messages. Аргумент функции указывает на выводимое сообщение.

  • void getmessagetext(char* text) – выводит приглашение в окно Send message и запрашивает текст отправляемого сообщения. Аргумент функции указывает на буфер для текста отправляемого сообщения.

  • void logindlg(char* username) – запрашивает имя пользователя. Аргумент функции указывает на буфер для имени пользователя. Функция создает и выводит на экран диалоговое окно Welcome; выводит в это окно приглашение и запрашивает имя пользователя; если пользователь сразу нажимает клавишу Enter, то в указанный буфер записывается значение, принятое по-умолчанию (“Anonymous”); выводит имя пользователя в информационную строку программы; удаляет созданное диалоговое окно; восстанавливает внешний вид экрана программы.

  • WINDOW* createwin(int nlines, int ncols, int begin_y, int begin_x, int attrs, const char* title) – создает окно с рамкой и заголовком, выровненным по центру. Аргументы функции имеют следующее назначение: nlines – высота окна, ncols – ширина окна, begin_x и begin_y – координаты левого верхнего угла окна, attrs – атрибуты окна и title – указатель на буфер, содержащий заголовок окна. Функция возвращает указатель на созданное окно.

  • void clearwin(WINDOW* win) – очищает рабочую область окна и перемещает курсор в левый верхний угол окна. Аргумент функции указывает на очищаемое окно.

  • void initcolors(void) – инициализирует цветовые пары, имеющие символические имена COLOR_LOGO, COLOR_WINDOW, COLOR_DIALOG и COLOR_SHADE в зависимости от возможности экрана терминала поддерживать цветной вывод.

  • void errormsg(char* format, …) – выводит сообщение об ошибке в стандартный поток ошибок и ожидает нажатия пользователем любой клавиши. Функция имеет переменное число аргументов. Аргументы данной функции аналогичны соответствующим аргументам таких библиотечных функций, как, например, printf( ).
^

7План отладки программы


Программа проектировалась методом восходящего программирования, т.е. сначала был спроектирован модуль, обеспечивающий терминальный ввод/вывод (модуль screen.c), затем был спроектирован модуль, обеспечивающий прием/передачу сообщений с использованием механизма IPC (модуль message.c), и, наконец, главный модуль программы (модуль lchat.c). Затем все общие фрагменты исходного текста программы (такие как включения, определения типов данных, макроопределения и директивы препроцессора) были вынесены в заголовок (модуль lchat.h). Функции, код которых еще не был разработан, заменялись программными заглушками. Для отладки программы использовался отладчик GNU Debugger.

При комплексной отладке программы каждый модуль подключался к программе по следующей упрощенной схеме:


Заключение


В результате выполнения курсовой работы была спроектирована программа ведения диалога между пользователями компьютера, работающего под управлением операционной системы Linux. Для написания программы, согласно заданию на курсовую работу, был использован язык C. Во время проектирования программы была изучена библиотека функций терминального ввода/вывода ncurses, были закреплены знания в областях синхронизации параллельного выполнения процессов и реализации межпроцессного взаимодействия с использованием таких элементов механизма InterProcess Communication, как семафоры и разделяемые области памяти. Был получен большой практический опыт работы с текстовым редактором Joe’s Own Editor версии 2.2, компилятором GNU C Compiler версии 2.7, отладчиком GNU Debugger версии 4.15.1, а также файловым менеджером MidNignt Commander версии 3.2.1.

При оформлении пояснительной записки были закреплены навыки оформления программной документации в соответствии с Единой Системой Программной Документации, а также получен большой практический опыт работы в Microsoft Word 97.
^

Приложение А (исходный текст программы)

  1. Файл lchat.h


/*

* Local Chat for Linux - Common definitions and includes

* Copyright (C) 2001 Sergey S. Levin (E-mail: sl@sura.ru)

*/

#ifndef LCHAT_H

#define LCHAT_H
#include

#include

#include

#include

#include

#include

#include

#include

#include
/*

* Constants

*/

#define MAX_USER 11

#define MAX_TEXT 129

#define IPC_KEY 32767

#define BYE_MSG "Bye-bye..."
/*

* Message structure

*/

typedef struct _MSG {

pid_t pid; /* receiver pid */

char name[MAX_USER]; /* user name */

char text[MAX_TEXT]; /* message text */

} MESSAGE;
/*

* Rename system data types

*/

typedef union semun SEMUN;

typedef struct sembuf SEMBUF;

typedef struct shmid_ds SHMIDDS;
/*

* Extern functions

*/

/* message.c */

extern void initipc(key_t);

extern void sendmessage(MESSAGE*);

extern void receivemessage(MESSAGE*);

/* screen.c */

extern void initscreen(void);

extern void putmessage(const MESSAGE*);

extern void getmessagetext(char*);

extern void logindlg(char*);

extern void errormsg(char*, ...);

#endif
  1. ^

    Файл lchat.c


/*

* Local Chat for Linux - main function

* Copyright (C) 2001 Sergey S. Levin (E-mail: sl@sura.ru)

*/
#include "lchat.h"
main(void)

{

int key; /* code of last pressed key */

MESSAGE msg; /* sended (received) message */

initscreen();

initipc(IPC_KEY);

logindlg(msg.name);

switch (fork()) {
case -1: errormsg("Error of creating child process: %s",

strerror(errno));

exit(1);
case 0: /* Send messages (child process) */

msg.pid = getppid();

do {

key = tolower(getch());

if (key != 'q' && key != 's')

continue;

if (key == 'q')

strcpy(msg.text, BYE_MSG);

sendmessage(&msg);

} while (strcmp(msg.text, BYE_MSG));

_exit(0);
default: /* Receive messages (parent process) */

while (1) {

receivemessage(&msg);

putmessage(&msg);

if (!strcmp(msg.text, BYE_MSG))

if (msg.pid = getpid())

break;

}

wait(NULL);

}

return 0;

}
  1. ^

    Файл message.c


/*

* Local Chat for Linux - IPC control functions

* Copyright (C) 2001 Sergey S. Levin (E-mail: sl@sura.ru)

*/
#include "lchat.h"
void closeipc(void);

void ipcerror(const char*);
int semid; /* id of 2 - semaphore set */

int shmid; /* id of shared memory segment */

char* shmaddr; /* addres of shared memory segment */
/*

* Open ( create ) shared memory segment and semaphore set, attach

* shared memory segment to data segment, initialize semaphore and

* register function for deinitialize IPC objects.

*/

void initipc(key_t key)

{

SEMUN su; /* semaphore value */

SEMBUF sb = { 0, 0, 0 }; /* semaphore operation */

if ((shmid = shmget(key, sizeof(MESSAGE), 0)) == -1) {

if (errno == ENOENT) {

if ((shmid = shmget(key, sizeof(MESSAGE), 0666|IPC_CREAT))

== -1)

ipcerror("shmget");

else if ((semid = semget(key, 2, 0666|IPC_CREAT)) == -1)

ipcerror("semget");

else {

su.val = 0;

semctl(semid, 0, SETVAL, su);

su.val = 1;

semctl(semid, 1, SETVAL, su);

}

}

else

ipcerror("shmget");

}

else if ((semid = semget(key, 0, 0)) == -1)

ipcerror("semget");

else

semop(semid, &sb, 1);

shmaddr = (char*)shmat(shmid, 0, 0);

if (shmaddr == (char*)-1)

ipcerror("shmat");

atexit(closeipc);

}
/*

* Detach shared memory segment from data segment, and if only one

* instance of program found, remove IPC objects.

*/

void closeipc(void)

{

SHMIDDS shmds;

shmctl(shmid, IPC_STAT, &shmds);

shmdt(shmaddr);

if (shmds.shm_nattch == 1) {

shmctl(shmid, IPC_RMID, 0);

semctl(semid, 0, IPC_RMID, 0);

}

}
/*

* Lock all other transmitters and all receivers, get message text

* (if message text is not equal byemsg), write message to shared

* memory segment and unlock all receivers (fields pid and name in

* msg stucture may be fill before calling this function!).

*/

void sendmessage(MESSAGE* msg)

{

/* semaphore set operation */

SEMBUF sb[] = { { 0, 0, 0 }, { 1, -1, 0 } };

semop(semid, sb, 2);

if (strcmp(msg->text, BYE_MSG))

getmessagetext(msg->text);

memcpy(shmaddr, msg, sizeof(MESSAGE));

sb[0].sem_op = semctl(semid, 0, GETNCNT, 0);

semop(semid, sb, 1);

}
/*

* Receive message from other instance of program.

*/

void receivemessage(MESSAGE* msg)

{

/* semaphore operation */

SEMBUF sb[] = { { 0, -1, 0 }, { 1, 1, 0 } };

semop(semid, sb, 1);

memcpy(msg, shmaddr, sizeof(MESSAGE));

sb[0].sem_op = 0;

if (!semctl(semid, 0, GETNCNT, 0))

semop(semid, sb, 2);

else

semop(semid, sb, 1);

}
/*

* Output IPC error message and terminate process with exit code 1.

*/

void ipcerror(const char* func)

{

char message[256]; /* formatted error message */

errormsg("Error of IPC function [%s]: %s", func, strerror(errno));

exit(1);

}
  1. ^

    Файл screen.c


/*

* Local Chat for Linux - Terminal I/O functions

* Copyright (C) 2001 Sergey S. Levin (E-mail: sl@sura.ru)

*/
#include "lchat.h"
/*

* Color pairs

*/

#define COLOR_LOGO 1

#define COLOR_WINDOW 2

#define COLOR_DIALOG 3

#define COLOR_SHADE 4
void restorescreen(void);

WINDOW* createwin(int, int, int, int, int, const char*);

void clearwin(WINDOW*);

void initcolors(void);
int width; /* screen width */

int height; /* screen height */

WINDOW* recvwin; /* pointer to received messages window */

WINDOW* sendwin; /* pointer to send message window */
/*

* Initialize screen: initialize ncurses library, output about info,

* create windows, change terminal i/o options, register function

* for deinitialize ncurses library.

*/

void initscreen(void)

{

char string[81]; /* formatted messages */

stdscr = initscr();

cbreak();

getmaxyx(stdscr, height, width);

if (width < 64 || height < 10) {

endwin();

errormsg("%s: %dx%d. %s!", "Detected screen resolution", width,

height, "Local Chat need 64x10 or more resolution");

exit(1);

}

initcolors();

attrset(COLOR_PAIR(COLOR_LOGO));

clearwin(stdscr);

mvaddstr(0, 3, "Local Chat for Linux");

strcpy(string, "Copyright (C) 2001 Sergey Levin");

mvaddstr(0, width-strlen(string)-3, string);

mvaddstr(height-1, 3, "(S)end message (Q)uit to Shell");

strcpy(string, "User name: ");

mvaddstr(height-1, width-strlen(string)-13, string);

refresh();

recvwin = createwin(height-6, width, 1, 0,

COLOR_PAIR(COLOR_WINDOW), "Received messages");

sendwin = createwin(4, width, height-5, 0, COLOR_PAIR(COLOR_WINDOW),

"Send message");

scrollok(recvwin, TRUE);

atexit(restorescreen);

}
/*

* Remove windows, clear screen and shutdown ncurses library.

*/

void restorescreen(void)

{

delwin(recvwin);

delwin(sendwin);

attrset(A_NORMAL);

clear();

refresh();

endwin();

}
/*

* Output message text to received messages window.

*/

void putmessage(const MESSAGE* msg)

{

int x, y; /* cursor position */

char text[MAX_USER+MAX_TEXT+2]; /* formatted message text */

sprintf(text, "%s : %s", msg->name, msg->text);

waddstr(recvwin, text);

getyx(recvwin, y, x);

for (; x <= recvwin->_maxx; x++)

waddch(recvwin, 0x20);

wrefresh(recvwin);

wrefresh(sendwin);

}
/*

* Output prompt and get message text from send message window.

*/

void getmessagetext(char* text)

{

echo();

waddstr(sendwin, "Enter message text: ");

wrefresh(sendwin);

wgetnstr(sendwin, text, MAX_TEXT-1);

clearwin(sendwin);

wrefresh(sendwin);

noecho();

beep();

}
/*

* Create and show login dialog box.

*/

void logindlg(char* username)

{

WINDOW* loginwin; /* pointer to login window */

WINDOW* shadewin; /* pointer to login window shade */

echo();

touchwin(recvwin);

shadewin = newwin(5, 60, (height-5)/2+1, (width-60)/2+1);

wattrset(shadewin, COLOR_PAIR(COLOR_SHADE));

clearwin(shadewin);

loginwin = createwin(5, 60, (height-5)/2, (width-60)/2,

COLOR_PAIR(COLOR_DIALOG), "Welcome");

mvwaddstr(loginwin, 1, 1,

"Enter your login name (Anonymous by default): ");

wrefresh(loginwin);

wgetnstr(loginwin, username, MAX_USER-1);

if (!strlen(username))

strcpy(username, "Anonymous");

mvaddstr(height-1, width-13, username);

delwin(loginwin);

delwin(shadewin);

wrefresh(recvwin);

refresh();

noecho();

}
/*

* Create and show window with border and centered title.

*/

WINDOW* createwin(int nlines, int ncols, int begin_y, int begin_x,

int attrs, const char* title)

{

WINDOW* win; /* pointer to created window */

char string[81]; /* formatted title buffer */

win = newwin(nlines, ncols, begin_y, begin_x);

wattrset(win, attrs);

wborder(win, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,

^ ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER);

sprintf(string, "[ %s ]", title);

mvwaddstr(win, 0, (ncols-strlen(string))/2, string);

wrefresh(win);

delwin(win);

win = newwin(nlines-2, ncols-2, begin_y+1, begin_x+1);

wattrset(win, attrs);

clearwin(win);

return win;

}
/*

* Clear window client area and set cursor to ul corner.

*/

void clearwin(WINDOW* win)

{

int x, y; /* cursor position */

for (x=0; x <= win->_maxx; x++)

for (y=0; y <= win->_maxy; y++)

mvwaddch(win, y, x, 0x20);

wmove(win, 0, 0);

wrefresh(win);

}
/*

* Initialize color pairs.

*/

void initcolors(void)

{

start_color();

if (has_colors()) {

init_pair(COLOR_LOGO, COLOR_BLACK, COLOR_CYAN);

init_pair(COLOR_WINDOW, COLOR_WHITE, COLOR_BLUE);

init_pair(COLOR_DIALOG, COLOR_BLACK, COLOR_WHITE);

init_pair(COLOR_SHADE, COLOR_BLACK, COLOR_BLACK);

}

else {

init_pair(COLOR_LOGO, COLOR_WHITE, COLOR_BLACK);

init_pair(COLOR_WINDOW, COLOR_WHITE, COLOR_BLACK);

init_pair(COLOR_DIALOG, COLOR_WHITE, COLOR_BLACK);

init_pair(COLOR_SHADE, COLOR_WHITE, COLOR_WHITE);

}

}
/*

* Output error message to stderr stream.

*/

void errormsg(char* format, ...)

{

va_list args; /* arguments buffer */

char message[256]; /* formatted message buffer */

va_start(args, format);

vsprintf(message, format, args);

va_end(args);

strcat(message, "\nPress any key to shutdown...");

fputs(message, stderr);

getch();

}
^

Приложение Б (результаты работы программы)

  1. Вид программы после запуска



  1. Вид программы во время работы



Приложение В (список использованных источников)


  1. Б. Керниган, Д. Ритчи. Язык программирования C. 2е изд., М.: Финансы и статистика, 1992.

  2. Т. Чан. Системное программирование на C++ для Unix. К.: Издательская группа BHV, 1997.

  3. Man-страницы операционной системы Linux, посвященные программированию.

  4. Конспект лекций по курсу “Системное программное обеспечение”.

Пенза 2001

Добавить документ в свой блог или на сайт

Похожие:

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная записка по курсовой работе по дисциплине «Системное программное обеспечение»
В этом курсе мы не ставим задачу познакомить слушателей с ос multics. Это могло бы быть темой отдельного большого курса. Однако отметим...

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconМетодические указания к курсовой работе по дисциплине «Системное...
Методические указания к курсовой работе по дисциплине «Системное программирование и операционные системы» для студентов специальности...

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная записка к курсовой работе по дисциплине «информатика»

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная записка к курсовой работе по дисциплине «Информатика»

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная записка к курсовой работе по дисциплине «Вычислительный практикум»

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная записка к курсовой работе по дисциплине «Системы сокрытия информации»

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная записка к курсовой работе по дисциплине: «Алгоритмические...

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная Записка к Курсовой Работе по Дисциплине «Информатика. Основы Программирования»

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconКлассификация программного обеспечения
В отличие от аппаратного обеспечения, программы, которые выполняются на нем, неосязаемы и классифицируются как программное обеспечение....

Пояснительная записка к курсовой работе по дисциплине системное программное обеспечение iconПояснительная записка к курсовой работе по дисциплине "Информатика"...

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
uchebilka.ru
Главная страница


<