Why is it read successfully from the / dev source of the errno data source?

A simple test program in C is called get1:

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(void) {
    errno = 0;
    int ch = fgetc(stdin);
    printf("ch = %d\n", ch);
    if (errno)
        printf("errno = %d: %s\n", errno, strerror(errno));
    return 0;
}

It simply prints the first byte, read in decimal, and then shows errnothe error message associated with it, if errnonot non-zero.

Some results ( foo- this is a text file, empty- this is a file with zero length):

% ./get1 < foo
ch = 104
% ./get1 < empty
ch = -1

Good, as expected. However:

% ./get1 < /dev/zero 
ch = 0
errno = 25: Inappropriate ioctl for device
% ./get1 < /dev/null 
ch = -1
errno = 25: Inappropriate ioctl for device
% ./get1 < /dev/random 
ch = 196
errno = 25: Inappropriate ioctl for device

Reading works fine, but when I read from any of these devices, it installs errno. Why?

It was on macOS (Darwin). I get the same thing on Linux (Debian) and NetBSD, except for another error only for /dev/random(the errors on other devices were the same as for macOS):

% ./get1 < /dev/random 
ch = 170
errno = 22: Invalid argument

, EOF, . EOF, errno, , . , . errno .

( printf , - .)

, errno AIX, SunOS OpenSUSE.

? , ? ? ? errno?

+4
2

, ( , , ), C, Posix.

C Posix errno 0, errno, . C errno " , , errno "( 7,5 3). C errno fgetc.

Posix : ,

errno , , errno .

errno fgetc, , errno , .

, Posix,

, , fgetc() EOF errno .

, EOF ( ) . errno . , errno , ferror(stdin) .

, , . fgetc ? , libc - .

+2

errno , FILE *stdin stdio .

Libc stat(), lseek() , , /dev/ . Libc, , .

, , errno .

Linux strace, , , , errno:

strace ./my program

.

+4

Source: https://habr.com/ru/post/1665576/


All Articles