LINUX.ORG.RU

Help! Почему вызов ioctl FIONREAD для файла /dev/random завершается неудачей?!


0

0

Вот собсна код: 

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

int main() {
  struct stat buf;
  mode_t mode;
  int n, fd, ret;

  fd = open("/dev/random", O_RDONLY, 0666);

  if(fd < 0) {
    perror("open");
    return 1;
  }

  if((ret = fstat(fd, &buf)) < 0) {
    perror("fstat64");
    return 1;
  }

  mode = buf.st_mode;

  if(S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
    if(ioctl(fd, FIONREAD, &n) < 0) {
      perror("ioctl");
      return 1;
    }
    printf("ok, available %d bytes", n);
    return 0;
  }
  printf("regular file");
  return 0;
}

Оно говорит:

ioctl: Invalid argument

Что я неправильно делаю, где у меня ошибка?!!!

anonymous
Ответ на: комментарий от Murr

Re:

Забавно.... Вот такой код есть в сырцах Linux Sun JDK 1.4.1:

int
sysAvailable(int fd, jlong *pbytes) {
    jlong cur, end;
    int mode;

    if (sysFfileMode(fd, &mode) >= 0) {
        if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
            int n;
            if (ioctl(fd, FIONREAD, &n) >= 0) {
                *pbytes = n;
                return 1;
            }
        }
    }
    if ((cur = lseek64_w(fd, 0L, SEEK_CUR)) == -1) {
        return 0;
    } else if ((end = lseek64_w(fd, 0L, SEEK_END)) == -1) {
        return 0;
    } else if (lseek64_w(fd, cur, SEEK_SET) == -1) {
        return 0;
    }
    *pbytes = end - cur;
    return 1;
}

Обратим внимание, что обсуждаемый вызов ioctl делается для файлов в
режиме S_ISCHR.... :-/

Debugger
()
Ответ на: Re: от Debugger

FIONREAD - это не generic IOCTL, а random_ioctl его не обрабатывает. У character device по определению не может быть длины (но именно в Linux он иногда есть!). Так что конструкция выше не совсем чтобы корректна.

Murr ★★
()
Ответ на: комментарий от grustnoe

Какой буфер? Символьные устройства не буферизируются в Linux ...

Murr ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.