Qsmtp  0.30dev
diropen.h
Go to the documentation of this file.
1 
4 #ifndef DIROPEN_H
5 #define DIROPEN_H
6 
7 #define _GNU_SOURCE /* needed for O_PATH according to manpage */
8 #define __USE_GNU /* needed for O_PATH according to code */
9 #include <fcntl.h>
10 #undef __USE_GNU /* seems to cause chaos if visible at other places */
11 #include <unistd.h>
12 #include <sys/stat.h>
13 
14 #if O_DIRECTORY == 0
15 #include <errno.h>
16 #include <sys/stat.h>
17 #endif /* O_DIRECTORY == 0 */
18 
35 static inline int __attribute__ ((nonnull (2)))
36 get_dirfd(int base, const char *dirname)
37 {
38  int fd;
39 
40 #ifdef O_PATH /* recent Linux */
41  fd = openat(base, dirname, O_PATH | O_DIRECTORY | O_CLOEXEC);
42 #elif defined(O_SEARCH)
43  fd = openat(base, dirname, O_SEARCH | O_DIRECTORY | O_CLOEXEC);
44 #else /* O_SEARCH */
45  fd = openat(base, dirname, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
46 #endif /* O_PATH */
47 
48 #if O_DIRECTORY == 0
49  {
50  struct stat st;
51  /* in case O_DIRECTORY is not supported make sure that this really is
52  * a directory */
53  if (fstat(fd, &st) != 0) {
54  int e = errno;
55  close(fd);
56  errno = e;
57  return -1;
58  }
59 
60  if (!S_ISDIR(st.st_mode)) {
61  close(fd);
62  errno = ENOTDIR;
63  return -1;
64  }
65  }
66 #endif /* O_DIRECTORY */
67 
68  return fd;
69 }
70 
71 #endif /* DIROPEN_H */
static int get_dirfd(int base, const char *dirname)
get a file descriptor for the given directory
Definition: diropen.h:36