Search code examples
cstdinio-redirection

How to notice stdin redirected to directory


How can you notice in a program that stdin is redirected to a directory?

If for example I execute:

$ cat < .

I get a message from cat telling me: cat: -: Is a directory. How can I make my C program notice that stdin has been redirected to a directory?


Solution

  • You can get the file descriptor of stdin via fileno() and then do fstat on the file descriptor.

    Here's a simple demonstration:

    $ cat test.c
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    int main(void)
    {
        struct stat sb;
        if ( fstat(fileno(stdin), &sb) == -1) {
            perror("fstat");
            exit(1);
        }
    
        switch (sb.st_mode & S_IFMT) {
            case S_IFBLK:  printf("block device\n");            break;
            case S_IFCHR:  printf("character device\n");        break;
            case S_IFDIR:  printf("directory\n");               break;
            case S_IFIFO:  printf("FIFO/pipe\n");               break;
            case S_IFLNK:  printf("symlink\n");                 break;
            case S_IFREG:  printf("regular file\n");            break;
            case S_IFSOCK: printf("socket\n");                  break;
            default:       printf("unknown?\n");                break;
        }
    }
    $ gcc -Wall -Wextra test.c
    $ ./a.out < .
    directory