7

Given a FILE*, is it possible to determine the underlying type? That is, is there a function that will tell me if the FILE* is a pipe or a socket or a regular on-disk file?

alamar
  • 18,729
  • 4
  • 64
  • 97
paleozogt
  • 6,393
  • 11
  • 51
  • 94

2 Answers2

8

There's a fstat(2) function.

NAME stat, fstat, lstat - get file status

SYNOPSIS

   #include <sys/types.h>
   #include <sys/stat.h>
   #include <unistd.h>

   int fstat(int fd, struct stat *buf);

You can get the fd by calling fileno(3).

Then you can call S_ISFIFO(buf) to figure it out.

alamar
  • 18,729
  • 4
  • 64
  • 97
  • 4
    might have been worth mentioning: `S_ISFIFO(buf.st_mode)` this macro doesn't crawl the structure for you. –  Apr 04 '12 at 21:29
3

Use the fstat() function. However, you'll need to use the fileno() macro to get the file descriptor from file FILE struct.

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

FILE *fp = fopen(path, "r");
int fd = fileno(fp);
struct stat statbuf;

fstat(fd, &statbuf);

/* a decoding case statement would be good here */
printf("%s is file type %08o\n", path, (statbuf.st_mode & 0777000);
Shannon Nelson
  • 2,090
  • 14
  • 14
  • 2
    This is a good example but to an inexperienced coder it doesn't make sense. Q&A should always be generalized to the base problem so that others who have similar problems can understand the answer in similar contexts. The question was distinguishing a pipe from a file in unix. Your answer just shows how to parse a stat mode. It is a great example you just did not answer the question properly. The answer to this question is `FILE *fp = fopen(path, "r"); int fd = fileno(fp); struct stat statbuf; fstat(fd, &statbuf); if (S_ISFIFO(statbuf.st_mode)) //its a pipe!` –  Apr 04 '12 at 22:04