/* Given a filename in FILE->PATH, with the empty string interpreted as <stdin>, open it. On success FILE contains an open file descriptor and stat information for the file. On failure the file descriptor is -1 and the appropriate errno is also stored in FILE. Returns TRUE iff successful. We used to open files in nonblocking mode, but that caused more problems than it solved. Do take care not to acquire a controlling terminal by mistake (this can't happen on sane systems, but paranoia is a virtue). Use the three-argument form of open even though we aren't specifying O_CREAT, to defend against broken system headers. O_BINARY tells some runtime libraries (notably DJGPP) not to do newline translation; we can handle DOS line breaks just fine ourselves. */ static bool open_file (_cpp_file *file) { if (file->path[0] == '\0') { file->fd = 0; set_stdin_to_binary_mode (); } else file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666); if (file->fd != -1) { if (fstat (file->fd, &file->st) == 0) { if (!S_ISDIR (file->st.st_mode)) { file->err_no = 0; return true; } /* Ignore a directory and continue the search. The file we're looking for may be elsewhere in the search path. */ errno = ENOENT; } close (file->fd); file->fd = -1; } #if defined(_WIN32) && !defined(__CYGWIN__) else if (errno == EACCES) { /* On most UNIX systems, open succeeds on a directory. Above, we check if we have opened a directory and if so, set errno to ENOENT. However, on Windows, opening a directory fails with EACCES. We want to return ENOENT in that case too. */ if (stat (file->path, &file->st) == 0 && S_ISDIR (file->st.st_mode)) errno = ENOENT; else /* The call to stat may have reset errno. */ errno = EACCES; } #endif else if (errno == ENOTDIR) errno = ENOENT; file->err_no = errno; return false; }
/* Given a filename in FILE->PATH, with the empty string interpreted as <stdin>, open it. On success FILE contains an open file descriptor and stat information for the file. On failure the file descriptor is -1 and the appropriate errno is also stored in FILE. Returns TRUE iff successful. We used to open files in nonblocking mode, but that caused more problems than it solved. Do take care not to acquire a controlling terminal by mistake (this can't happen on sane systems, but paranoia is a virtue). Use the three-argument form of open even though we aren't specifying O_CREAT, to defend against broken system headers. O_BINARY tells some runtime libraries (notably DJGPP) not to do newline translation; we can handle DOS line breaks just fine ourselves. */ static bool open_file (_cpp_file *file) { if (file->path[0] == '\0') { file->fd = 0; set_stdin_to_binary_mode (); } else file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666); if (file->fd != -1) { if (fstat (file->fd, &file->st) == 0) { if (!S_ISDIR (file->st.st_mode)) { file->err_no = 0; return true; } /* Ignore a directory and continue the search. The file we're looking for may be elsewhere in the search path. */ errno = ENOENT; } close (file->fd); file->fd = -1; } else if (errno == ENOTDIR) errno = ENOENT; file->err_no = errno; return false; }