LINUX.ORG.RU

История изменений

Исправление theNamelessOne, (текущая версия) :

Читай ман CONSOLE_IOCTL(4): KDSETLED/KDGETLED включает/получает состояние светодиодов, а KDSKBLED/KDGKBLED включает/получает состояние соответствующих клавиатурных флагов. Т.е если тебе нужно лишь мигать светодиодами, а не писать капсом, то ты используешь связку KDSETLED/KDGETLED, в противном случае — связку KDSKBLED/KDGKBLED. Смешивать эти вызовы не стоит.

Вот такой код у меня работает:

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char get_led() {
  char arg;
  int fd = open("/dev/console", O_RDONLY);

  if (fd == -1) {
    perror("open");
    exit(1);
  }

  if (ioctl(fd, KDGETLED, &arg) == -1) {
    perror("ioctl");
    exit(1);
  }

  if (close(fd) == -1) {
    perror("close");
    exit(1);
  }

  return arg;
}

void set_led(char arg) {
  int fd = open("/dev/console", O_WRONLY);

  if (fd == -1) {
    perror("open");
    exit(1);
  }

  if (ioctl(fd, KDSETLED, arg) == -1) {
    perror("ioctl");
    exit(1);
  }

  if (close(fd) == -1) {
    perror("close");
    exit(1);
  }
}

void print_led(char arg) {
  printf("  CAPS is %s\n", arg & LED_CAP ? "on" : "off");
  printf("  NUM is %s\n", arg & LED_NUM ? "on" : "off");
  printf("  SCROLL is %s\n", arg & LED_SCR ? "on" : "off");
}

int main(void) {
  char led;

  puts("Before setting LEDs");
  led = get_led();
  printf("Current state (%#x):\n", led);
  print_led(led);

  char old_led = led;

  /* Turn on all LEDs */
  set_led(0x7);

  puts("\nAfter setting LEDs");
  led = get_led();
  printf("Current state (%#x):\n", led);
  print_led(led);

  /* Restore LED state */
  set_led(old_led);

  return 0;
}

Результат:

λ nameless@desktop /tmp → sudo ./led
Before setting LEDs
Current state (0x2):
  CAPS is off
  NUM is on
  SCROLL is off

After setting LEDs
Current state (0x7):
  CAPS is on
  NUM is on
  SCROLL is on
λ nameless@desktop /tmp →

Исправление theNamelessOne, :

Читай ман: KDSETLED/KDGETLED включает/получает состояние светодиодов, а KDSKBLED/KDGKBLED включает/получает состояние соответствующих клавиатурных флагов. Т.е если тебе нужно лишь мигать светодиодами, а не писать капсом, то ты используешь связку KDSETLED/KDGETLED, в противном случае — связку KDSKBLED/KDGKBLED. Смешивать эти вызовы не стоит.

Вот такой код у меня работает:

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char get_led() {
  char arg;
  int fd = open("/dev/console", O_RDONLY);

  if (fd == -1) {
    perror("open");
    exit(1);
  }

  if (ioctl(fd, KDGETLED, &arg) == -1) {
    perror("ioctl");
    exit(1);
  }

  if (close(fd) == -1) {
    perror("close");
    exit(1);
  }

  return arg;
}

void set_led(char arg) {
  int fd = open("/dev/console", O_WRONLY);

  if (fd == -1) {
    perror("open");
    exit(1);
  }

  if (ioctl(fd, KDSETLED, arg) == -1) {
    perror("ioctl");
    exit(1);
  }

  if (close(fd) == -1) {
    perror("close");
    exit(1);
  }
}

void print_led(char arg) {
  printf("  CAPS is %s\n", arg & LED_CAP ? "on" : "off");
  printf("  NUM is %s\n", arg & LED_NUM ? "on" : "off");
  printf("  SCROLL is %s\n", arg & LED_SCR ? "on" : "off");
}

int main(void) {
  char led;

  puts("Before setting LEDs");
  led = get_led();
  printf("Current state (%#x):\n", led);
  print_led(led);

  char old_led = led;

  /* Turn on all LEDs */
  set_led(0x7);

  puts("\nAfter setting LEDs");
  led = get_led();
  printf("Current state (%#x):\n", led);
  print_led(led);

  /* Restore LED state */
  set_led(old_led);

  return 0;
}

Результат:

λ nameless@desktop /tmp → sudo ./led
Before setting LEDs
Current state (0x2):
  CAPS is off
  NUM is on
  SCROLL is off

After setting LEDs
Current state (0x7):
  CAPS is on
  NUM is on
  SCROLL is on
λ nameless@desktop /tmp →

Исходная версия theNamelessOne, :

Читай ман: KDSETLED/KDGETLED включает/получает состояние светодиодов, а KDSKBLED/KDGKBLED включает/получает состояние соответствующих клавиатурных флагов. Т.е если тебе нужно лишь мигать светодиодами, а не писать капсом, то ты используешь связку KDSETLED/KDGETLED, в противном случае — связку KDSKBLED/KDGKBLED. Смешивать эти вызовы не стоит.

Вот такой код у меня работает:

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char get_led() {
  char arg;
  int fd = open("/dev/console", O_RDONLY);

  if (fd == -1) {
    perror("open");
    exit(1);
  }

  if (ioctl(fd, KDGETLED, &arg) == -1) {
    perror("ioctl");
    exit(1);
  }

  if (close(fd) == -1) {
    perror("close");
    exit(1);
  }

  return arg;
}

void set_led(char arg) {
  int fd = open("/dev/console", O_WRONLY);

  if (fd == -1) {
    perror("open");
    exit(1);
  }

  if (ioctl(fd, KDSETLED, arg) == -1) {
    perror("ioctl");
    exit(1);
  }

  if (close(fd) == -1) {
    perror("close");
    exit(1);
  }
}

void print_led(char arg) {
  printf("  CAPS is %s\n", arg & LED_CAP ? "on" : "off");
  printf("  NUM is %s\n", arg & LED_NUM ? "on" : "off");
  printf("  SCROLL is %s\n", arg & LED_SCR ? "on" : "off");
}

int main(void) {
  char led;

  puts("Before setting LEDs");
  led = get_led();
  printf("Current state (%#x):\n", led);
  print_led(led);

  char old_led = led;

  /* Turn on all LEDs */
  set_led(0x7);

  puts("\nAfter setting LEDs");
  led = get_led();
  printf("Current state (%#x):\n", led);
  print_led(led);

  /* Restore LED state */
  set_led(old_led);

  return 0;
}