| 
									
										
										
										
											2017-02-26 23:42:03 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 9p utilities | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright IBM, Corp. 2017 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Authors: | 
					
						
							|  |  |  |  *  Greg Kurz <groug@kaod.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This work is licensed under the terms of the GNU GPL, version 2 or later. | 
					
						
							|  |  |  |  * See the COPYING file in the top-level directory. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef QEMU_9P_UTIL_H
 | 
					
						
							|  |  |  | #define QEMU_9P_UTIL_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 14:21:04 +02:00
										 |  |  | #ifdef O_PATH
 | 
					
						
							|  |  |  | #define O_PATH_9P_UTIL O_PATH
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define O_PATH_9P_UTIL 0
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-26 23:42:03 +01:00
										 |  |  | static inline void close_preserve_errno(int fd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int serrno = errno; | 
					
						
							|  |  |  |     close(fd); | 
					
						
							|  |  |  |     errno = serrno; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int openat_dir(int dirfd, const char *name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-06 17:34:01 +01:00
										 |  |  |     return openat(dirfd, name, | 
					
						
							| 
									
										
										
										
											2017-08-10 14:21:04 +02:00
										 |  |  |                   O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_PATH_9P_UTIL); | 
					
						
							| 
									
										
										
										
											2017-02-26 23:42:03 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int openat_file(int dirfd, const char *name, int flags, | 
					
						
							|  |  |  |                               mode_t mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int fd, serrno, ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fd = openat(dirfd, name, flags | O_NOFOLLOW | O_NOCTTY | O_NONBLOCK, | 
					
						
							|  |  |  |                 mode); | 
					
						
							|  |  |  |     if (fd == -1) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     serrno = errno; | 
					
						
							| 
									
										
										
										
											2017-08-10 14:21:04 +02:00
										 |  |  |     /* O_NONBLOCK was only needed to open the file. Let's drop it. We don't
 | 
					
						
							|  |  |  |      * do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat() | 
					
						
							|  |  |  |      * ignored it anyway. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if (!(flags & O_PATH_9P_UTIL)) { | 
					
						
							|  |  |  |         ret = fcntl(fd, F_SETFL, flags); | 
					
						
							|  |  |  |         assert(!ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-26 23:42:03 +01:00
										 |  |  |     errno = serrno; | 
					
						
							|  |  |  |     return fd; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-26 23:42:26 +01:00
										 |  |  | ssize_t fgetxattrat_nofollow(int dirfd, const char *path, const char *name, | 
					
						
							|  |  |  |                              void *value, size_t size); | 
					
						
							| 
									
										
										
										
											2017-02-26 23:42:43 +01:00
										 |  |  | int fsetxattrat_nofollow(int dirfd, const char *path, const char *name, | 
					
						
							|  |  |  |                          void *value, size_t size, int flags); | 
					
						
							| 
									
										
										
										
											2018-06-07 12:17:22 +02:00
										 |  |  | ssize_t flistxattrat_nofollow(int dirfd, const char *filename, | 
					
						
							|  |  |  |                               char *list, size_t size); | 
					
						
							|  |  |  | ssize_t fremovexattrat_nofollow(int dirfd, const char *filename, | 
					
						
							|  |  |  |                                 const char *name); | 
					
						
							| 
									
										
										
										
											2017-02-26 23:42:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 |