104: }
105: setutent();
106: printf('%s:
====================
', name);
107: while ((u = get_next_line(id, line))) {
108: print_utmp_entry(u);
109: /* POSIX требует очистки статических данных перед
110: * повторным вызовом getutline или getutid
111: */
112: memset(u, 0, sizeof(struct utmp));
113: }
114: endutent();
115: }
116:
117: int main(int argc, const char **argv) {
118: char * id = NULL, *line = NULL;
119: int show_utmp = 1, show_wtmp = 0;
120: int c;
121: poptContext optCon;
122: struct poptOption optionsTable[] = {
123: {'utmp', 'u', POPT_ARG_NONE|POPT_ARGFLAG_XOR,
124: &show_utmp, 0,
125: 'переключить просмотр содержимого файла utmp', NULL},
126: { 'wtmp', 'w', POPT_ARG_NONE | POPT_ARGFLAG_XOR,
127: &show_wtmp, 0,
128: 'переключить просмотр содержимого файла wtmp', NULL},
129: {'id', 'i', POPT_ARG_STRING, &id, 0,
130: 'показать записи процесса для заданного идентификатора inittab',
131: '<inittab id>' },
132: {'line', 'l', POPT_ARG_STRING, &line, 0,
133: 'показать записи процесса для заданной строки устройства',
134: '<line>' },
135: POPT_AUTOHELP
136: POPT_TABLEEND
137: };
138:
139: optCon = poptGetContext('utmp', argc, argv, optionsTable, 0);
140: if ((c = poptGetNextOpt(optCon)) < -1) {
141: fprintf(stderr, '%s:%s
',
142: poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
143: poptStrerror(c));
144: return 1;
145: }
146: poptFreeContext(optCon);
147:
148: if (id && line)
149: fprintf(stderr, 'Невозможно выбирать сразу по идентификатору и строке,'
150: 'выбор по строке
');
151:
152: if (show_utmp)
153: print_file(_PATH_UTMP, id, line);
154: if (show_utmp && show_wtmp)
155: printf('
');
156: if (show_wtmp)
157: print_file(_PATH_WTMP, id, line);
158:
159: return 0;
160: }
16.2. Обзор termios
Все манипуляции tty осуществляются с помощью одной структуры, struct termios, а также нескольких функций, определенных в заголовочном файле <termios.h>. Из этих функций широко применяются только шесть. Когда не нужно устанавливать скорость передачи данных по линии, используются только две наиболее важных функции — tcgetattr() и tcsetattr ().
#include <termios.h>
struct termios {
tcflag_t c_iflag; /* флаги режима ввода */
tcflag_t c_oflag; /* флаги режима вывода */
tcflag_t c_cflag; /* флаги управляющего режима */
tcflag_t c_lflag; /* флаги локального режима */
cc_t c_line; /* дисциплина линии связи */
cc_t c_cc[NCCS]; /* управляющие символы */
};
int tcgetattr(int fd, struct termios * tp);
int tcsetattr(int fd, int oact, struct termios * tp);
Почти в каждом случае программы должны использовать tcgetattr() для получения текущих установок устройства, модифицировать эти установки, а затем применять tcsetattr() для активизации модифицированных установок. Многие программы также сохраняют копии оригинальных установок и восстанавливают их перед завершением. В общем случае, следует модифицировать только интересующие вас установки; изменение других установок может усложнить работу пользователей с необычными системными конфигурациями (или сбоями в вашем коде).
Вызов tcsetattr() может не принять на обработку выбранные вами установки; разрешено игнорировать произвольные установки. Если оборудование просто не поддерживает установку, tcsetattr() игнорирует ее, а не возвращает ошибку. Если вам небезразлично воздействие, оказываемое установкой, следует использовать tcgetattr() после tcsetattr() и проверить, оказало ли воздействие внесенное вами изменение.
Для получения установок устройства tty необходимо открыть устройство и передать файловый дескриптор tcgetattr(). Это вызывает проблемы с некоторыми устройствами tty; некоторые обычно можно открыть лишь один раз с целью предотвращения конфликта устройств. К счастью, передача флага O_NONBLOCK в open() вызывает его немедленное открытие и предотвращает блокирование любых операций. Однако все равно можно предпочесть блокирование read(); в таком случае используйте fcntl() для отключения режима O_NONBLOCK перед тем, как появится возможность читать или записывать в него.
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
