20.6. Пример команды open
20.6. Пример команды open
Ниже показан пример кода, выполняющий следующие задачи: поиск неиспользуемой VC, запуск на ней оболочки, ожидание завершения оболочки, переключение обратно, а также освобождение памяти, выделенной под VC, по завершении программы. Программа open, входящая в состав дистрибутива Linux, выполняет те же самые действия, но при этом она содержит больше опций и лучший контроль ошибок, таким образом, является более надежной. Хотя приведенная ниже версия тоже будет работать, ее трудно назвать удобной, надежной или безопасной.
1: /* minopen.c */
2:
3: #include <stdio.h>
4: #include <unistd.h>
5: #include <stdlib.h>
6: #include <signal.h>
7: #include <fcntl.h>
8: #include <sys/ioctl.h>
9: #include <sys/vt.h>
10: #include <sys/stat.h>
11: #include <sys/types.h>
12: #include <sys/wait.h>
13:
14: int main (int argc, const char ** argv) {
15: int vtnum;
16: int vtfd;
17: struct vt_stat vtstat;
18: char device[32];
19: int child;
20:
21: vtfd = open("/dev/tty", O_RDWR, 0);
22: if (vtfd < 0) {
23: perror("minopen: не удается открыть /dev/tty");
24: exit(1);
25: }
26: if (ioctl(vtfd, VT_GETSTATE, &vtstat) < 0) {
27: perror("minopen: tty не является виртуальной консолью");
28: exit(1);
29: }
30: if (ioctl(vtfd, VT_OPENQRY, &vtnum) < 0) {
31: perror("minopen: нет свободных виртуальных консолей");
32: exit(1);
33: }
34: sprintf(device, "/dev/tty%d", vtnum);
35: if (access(device, (W_OK|R_OK)) < 0) {
36: perror("minopen: недостаточные полномочия на tty");
37: exit(1);
38: }
39: child = fork();
40: if (child == 0) {
41: ioctl(vtfd, VT_ACTIVATE, vtnum);
42: ioctl(vtfd, VT_WAITACTIVE, vtnum);
43: setsid();
44: close(0); close(1); close(2);
45: close(vtfd);
46: vtfd = open(device, O_RDWR, 0); dup(vtfd); dup(vtfd);
47: execlp("/bin/bash", "bash", NULL);
48: }
49: wait(&child);
50: ioctl(vtfd, VT_ACTIVATE, vtstat.v_active);
51: ioctl(vtfd, VT_WAITACTIVE, vtstat.v_active);
52: ioctl(vtfd, VT_DISALLOCATE, vtnum);
53: exit(0);
54: }