Довольно давно Игорь Порецкий написал маленькую программу vcs_duty,
чтобы озвучить переключение виртуальных консолей. Для каждой консоли
нужно было запустить отдельный экземпляр программы; при переключении на
другую консоль соответствующий процесс просыпался и проговаривал номер.
В ядре 2.6.32 появился новый ioctl, с помощью которого эту задачу можно
решить попроще. Ниже привожу текст программы, которая при переключении
консолей выводит в stdout номер новой и старой консоли. Для компиляции
нужны заголовки ядра версии не ниже 2.6.32. В Debian это пакет
linux-libc-dev.

/* vtsneak.c */

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/vt.h>

int main(int argc, char *argv[])
{
  const char *dev = "/dev/console";
  int console = open(dev, O_RDONLY, 0);
  struct vt_event ev;

  if (console == -1) {
    perror(dev);
    exit(1);
  }

  ev.event = VT_EVENT_SWITCH;
  while (ioctl(console, VT_WAITEVENT, &ev) != -1) {
    printf("%u %u\n", ev.newev, ev.oldev);
    fflush(stdout);
    ev.event = VT_EVENT_SWITCH;
  }
  perror("ioctl");
  return 2;
}
Её можно использовать в скрипте, например, так:

#!/bin/dash

mkfifo /tmp/vtsneak.$$ || exit 1
trap "rm -f /tmp/vtsneak.$$" INT QUIT TERM EXIT
exec < /tmp/vtsneak.$$
vtsneak > /tmp/vtsneak.$$ &

while read new old; do
    killall say
    say "$new from $old" &
done

Запускается, естественно, от рута. say - команда, которая произносит
свои аргументы.

-- 
Дмитрий Падучих
-- 
Blinux-rus mailing list
[email protected]
http://www.a11ywiki.org/cgi-bin/mailman/listinfo/blinux-rus

Ответить