20.6. Пример команды open

We use cookies. Read the Privacy and Cookie Policy

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: }