#include #include #include /* Check if a file descriptor is valid or not. Return 0 if the file descriptor is invalid, return non-zero otherwise. */ static int is_valid_fd(int fd) { #ifdef USE_FSTAT /* bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with EBADF. Prefer fstat() over dup() to detect such error. */ struct stat st; return (fstat(fd, &st) == 0); #else int fd2; if (fd < 0) return 0; /* Prefer dup() over fstat(). fstat() can require input/output whereas dup() doesn't, there is a low risk of EMFILE/ENFILE at Python startup. */ fd2 = dup(fd); if (fd2 >= 0) close(fd2); return fd2 >= 0; #endif } int main(void) { printf("0: %d\n", is_valid_fd(0)); printf("1: %d\n", is_valid_fd(1)); printf("2: %d\n", is_valid_fd(2)); return 0; }