Π€ΡΠ½ΠΊΡΠΈΡ setutent() ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ°Π΅Ρ Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ Π² Π½Π°ΡΠ°Π»ΠΎ.
Π€ΡΠ½ΠΊΡΠΈΡ endutent() Π·Π°ΠΊΡΡΠ²Π°Π΅Ρ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ . ΠΡΠΎ Π·Π°ΠΊΡΡΠ²Π°Π΅Ρ ΡΠ°ΠΉΠ»ΠΎΠ²ΡΠΉ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ Π°ΡΡΠΎΡΠΈΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅. ΠΡΠ·ΡΠ²Π°ΠΉΡΠ΅ endutent() ΠΊΠ°ΠΊ ΠΏΠ΅ΡΠ΅Π΄ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ utmpname() Π΄Π»Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ Π΄ΡΡΠ³ΠΎΠΌΡ ΡΠ°ΠΉΠ»Ρ utmp, ΡΠ°ΠΊ ΠΈ ΠΏΠΎΡΠ»Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ Π΄Π°Π½Π½ΡΠΌ utmp.
ΠΠ°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π½Π°Π΄Π΅ΠΆΠ½ΡΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ wtmp ΡΠ²Π»ΡΡΡΡΡ Π΄Π²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠ΅ BSD ΠΈ Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ ΠΊΠ°ΠΊ ΡΠ°ΡΡΡ glibc.
Π€ΡΠ½ΠΊΡΠΈΡ updwtmp() ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠ°ΠΉΠ»ΠΎΠ²ΠΎΠ΅ ΠΈΠΌΡ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ wtmp (ΠΎΠ±ΡΡΠ½ΠΎ _PATH_WTMP) ΠΈ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½ΡΡ ΡΡΡΡΠΊΡΡΡΡ struct utmp, ΠΏΡΡΠ°ΡΡΡ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΠΊ ΡΠ°ΠΉΠ»Ρ wtmp. ΠΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π½Π΅ ΡΠΎΠΎΠ±ΡΠ°Π΅Ρ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ .
Π€ΡΠ½ΠΊΡΠΈΡ logwtmp() ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΄ΠΎΠ±Π½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ, Π·Π°ΠΏΠΎΠ»Π½ΡΡΡΠ΅ΠΉ struct utmp ΠΈ Π²ΡΠ·ΡΠ²Π°ΡΡΠ΅ΠΉ updwtmp() Π΄Π»Ρ Π½Π΅Π΅. ΠΡΠ³ΡΠΌΠ΅Π½Ρ line ΠΊΠΎΠΏΠΈΡΡΠ΅ΡΡΡ Π² ut_line, name β Π² ut_user, host β Π² ut_host, ut_tv Π·Π°ΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΠ΅ΠΊΡΡΠΈΠΌ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, a ut_pid β ΡΠ΅ΠΊΡΡΠΈΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠ°. ΠΠ°ΠΊ ΠΈ updwtmp(), ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π½Π΅ ΡΠΎΠΎΠ±ΡΠ°Π΅Ρ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ .
Π ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ utmp Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΡΡΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ ΡΡΠ΅Π½ΠΈΡ Π±Π°Π· Π΄Π°Π½Π½ΡΡ utmp ΠΈ wtmp.
1: /* utmp.Ρ */
2:
3: #include <stdio.h>
4: #include <unistd.h>
5: #include <string.h>
6: #include <time.h>
7: #include <sys/time.h>
8: #include <sys/types.h>
9: #include <sys/socket.h>
10: #include <netinet/in.h>
11: #include <arpa/inet.h>
12: #include <utmp.h>
13: #include <popt.h>
14:
15: void print_utmp_entry(struct utmp * u) {
16: struct tm *tp;
17: char * type;
18: char addrtext[INET6_ADDRSTRLEN];
19:
20: switch (u->ut_type) {
21: case EMPTY: type = "EMPTY"; break;
22: case RUN_LVL: type = "RUN_LVL"; break;
23: case BOOT_TIME: type = "BOOT_TIME"; break;
24: case NEW_TIME: type = "NEW_TIME"; break;
25: case OLD_TIME: type = "OLD_TIME"; break;
26: case INIT_PROCESS: type = "INIT_PROCESS"; break;
27: case LOGIN_PROCESS: type = "LOGIN_PROCESS"; break;
28: case USER_PROCESS: type = "USER_PROCESS"; break;
29: case DEAD_PROCESS: type = "DEAD_PROCESS"; break;
30: case ACCOUNTING: type = "ACCOUNTING "; break;
31: }
32: printf("%-13s:", type);
33: switch (u->ut_type) {
34: case LOGIN_PROCESS:
35: case USER_PROCESS:
36: case DEAD_PROCESS:
37: printf(" line: %s", u->ut_line);
38: /* fall through */
39: case INIT_PROCESS:
40: printf("\n pid: %6d id: %4.4s", u->ut_pid, u->ut_id);
41: }
42: printf ("\n");
43: tp = gmtime(&u->ut_tv.tv_sec);
44: printf("time: %24.24s.%lu\n", asctime(tp), u->ut_tv.tv_usec);
45: switch (u->ut_type) {
46: case USER_PROCESS:
47: case LOGIN_PROCESS:
48: case RUN_LVL:
49: case BOOT_TIME:
50: printf("ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ: %s\n", u->ut_user);
51: }
52: if (u->ut_type == USER_PROCESS) {
53: if (u->ut_session)
54: printf(" ΡΠ΅Π°Π½Ρ: %lu\n", u->ut_session);
55: if (u->ut_host)
56: printf (" Ρ ΠΎΡΡ: %s\n", u->ut_host);
57: if (u->ut_addr_v6[0]) {
58: if (!(u->ut_addr_v6[1] |
59: u->ut_addr_v6[2] |
60: u->ut_addr_v6[3])) {
61: /* Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠ΅ΡΠ²ΠΎΠΉ Π³ΡΡΠΏΠΏΡ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ Π°Π΄ΡΠ΅Ρ IPV4 */
62: inet_ntop(AF_INET, u->ut_addr_v6,
63: addrtext, sizeof(addrtext));
64: printf(" IPV4: %s\n", addrtext);
65: } else {
66: inet_ntop(AF_INET_6, u->ut_addr_v6,
67: addrtext, sizeof(addrtext));
68: printf (" IPV6: %s\n", addrtext);
69: }
70: }
71: }
72: if (u->ut_type == DEAD_PROCESS) {
73: printf(" Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ : %u: %u\n",
74: u->ut_exit.e_termination,
75: u->ut_exit.e_exit);
76: }
77: printf("\n");
78: }
79:
80: struct utmp * get_next_line (char * id, char * line) {
81: struct utmp request;
82:
83: if (!id && !line)
84: return getutent();
85:
86: memset(&request, 0, sizeof(request));
87:
88: if (line) {
89: strncpy(&request.ut_line[0], line, UT_LINESIZE);
90: return getutline(&request);
91: }
92:
93: request.ut_type = INIT_PROCESS;
94: strncpy(&request.ut_id[0], id, 4);
95: return getutid(&request);
96: }
97:
98: void print_file(char * name, char * id, char * line) {
99: struct utmp * u;
100:
101: if (utmpname(name)) {
102: fprintf (stderr, "ΡΠ±ΠΎΠΉ ΠΏΡΠΈ ΠΎΡΠΊΡΡΡΠΈΠΈ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ utmp %s\n", name);
103: return;
104: }
105: setutent();
106: printf("%s:\n====================\n", 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\n",
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: "Π²ΡΠ±ΠΎΡ ΠΏΠΎ ΡΡΡΠΎΠΊΠ΅\n");
151:
152: if (show_utmp)
153: print_file(_PATH_UTMP, id, line);
154: if (show_utmp && show_wtmp)
155: printf("\n\n\n");
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 ΠΏΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΠΎΡΠ²ΠΈΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠΈΡΠ°ΡΡ ΠΈΠ»ΠΈ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡ Π² Π½Π΅Π³ΠΎ.