1 /* 2 * 9p utilities 3 * 4 * Copyright IBM, Corp. 2017 5 * 6 * Authors: 7 * Greg Kurz <groug@kaod.org> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #ifndef QEMU_9P_UTIL_H 14 #define QEMU_9P_UTIL_H 15 16 static inline void close_preserve_errno(int fd) 17 { 18 int serrno = errno; 19 close(fd); 20 errno = serrno; 21 } 22 23 static inline int openat_dir(int dirfd, const char *name) 24 { 25 #ifdef O_PATH 26 #define OPENAT_DIR_O_PATH O_PATH 27 #else 28 #define OPENAT_DIR_O_PATH 0 29 #endif 30 return openat(dirfd, name, 31 O_DIRECTORY | O_RDONLY | O_NOFOLLOW | OPENAT_DIR_O_PATH); 32 } 33 34 static inline int openat_file(int dirfd, const char *name, int flags, 35 mode_t mode) 36 { 37 int fd, serrno, ret; 38 39 fd = openat(dirfd, name, flags | O_NOFOLLOW | O_NOCTTY | O_NONBLOCK, 40 mode); 41 if (fd == -1) { 42 return -1; 43 } 44 45 serrno = errno; 46 /* O_NONBLOCK was only needed to open the file. Let's drop it. */ 47 ret = fcntl(fd, F_SETFL, flags); 48 assert(!ret); 49 errno = serrno; 50 return fd; 51 } 52 53 int relative_openat_nofollow(int dirfd, const char *path, int flags, 54 mode_t mode); 55 ssize_t fgetxattrat_nofollow(int dirfd, const char *path, const char *name, 56 void *value, size_t size); 57 int fsetxattrat_nofollow(int dirfd, const char *path, const char *name, 58 void *value, size_t size, int flags); 59 60 #endif 61