/src/util-linux/include/fileutils.h
Line | Count | Source |
1 | | /* |
2 | | * No copyright is claimed. This code is in the public domain; do with |
3 | | * it what you wish. |
4 | | **/ |
5 | | #ifndef UTIL_LINUX_FILEUTILS |
6 | | #define UTIL_LINUX_FILEUTILS |
7 | | |
8 | | #include <stdio.h> |
9 | | #include <fcntl.h> |
10 | | #include <unistd.h> |
11 | | #include <dirent.h> |
12 | | #include <sys/stat.h> |
13 | | |
14 | | #ifdef HAVE_LINUX_OPENAT2_H |
15 | | # include <linux/openat2.h> |
16 | | #endif |
17 | | |
18 | | #include "c.h" |
19 | | #include "pathnames.h" |
20 | | |
21 | | extern int mkstemp_cloexec(char *template); |
22 | | |
23 | | extern int xmkstemp(char **tmpname, const char *dir, const char *prefix); |
24 | | |
25 | | static inline FILE *xfmkstemp(char **tmpname, const char *dir, const char *prefix) |
26 | 0 | { |
27 | 0 | int fd; |
28 | 0 | FILE *ret; |
29 | 0 |
|
30 | 0 | fd = xmkstemp(tmpname, dir, prefix); |
31 | 0 | if (fd == -1) |
32 | 0 | return NULL; |
33 | 0 |
|
34 | 0 | if (!(ret = fdopen(fd, "w+" UL_CLOEXECSTR))) { |
35 | 0 | close(fd); |
36 | 0 | return NULL; |
37 | 0 | } |
38 | 0 | return ret; |
39 | 0 | } Unexecuted instantiation: probe.c:xfmkstemp Unexecuted instantiation: blkdev.c:xfmkstemp Unexecuted instantiation: fileutils.c:xfmkstemp Unexecuted instantiation: path.c:xfmkstemp Unexecuted instantiation: sysfs.c:xfmkstemp Unexecuted instantiation: devname.c:xfmkstemp Unexecuted instantiation: save.c:xfmkstemp Unexecuted instantiation: canonicalize.c:xfmkstemp Unexecuted instantiation: loopdev.c:xfmkstemp |
40 | | |
41 | | #ifdef HAVE_OPENAT |
42 | | static inline FILE *fopen_at(int dir, const char *filename, |
43 | | int flags, const char *mode) |
44 | 0 | { |
45 | 0 | int fd = openat(dir, filename, flags); |
46 | 0 | FILE *ret; |
47 | 0 |
|
48 | 0 | if (fd < 0) |
49 | 0 | return NULL; |
50 | 0 |
|
51 | 0 | ret = fdopen(fd, mode); |
52 | 0 | if (!ret) |
53 | 0 | close(fd); |
54 | 0 | return ret; |
55 | 0 | } Unexecuted instantiation: probe.c:fopen_at Unexecuted instantiation: blkdev.c:fopen_at Unexecuted instantiation: fileutils.c:fopen_at Unexecuted instantiation: path.c:fopen_at Unexecuted instantiation: sysfs.c:fopen_at Unexecuted instantiation: devname.c:fopen_at Unexecuted instantiation: save.c:fopen_at Unexecuted instantiation: canonicalize.c:fopen_at Unexecuted instantiation: loopdev.c:fopen_at |
56 | | |
57 | | extern FILE *fopen_at_no_link(int dir, const char *filename, |
58 | | int flags, mode_t perm, const char *mode); |
59 | | #endif /* HAVE_OPENAT */ |
60 | | |
61 | | static inline int is_same_inode(const int fd, const struct stat *st) |
62 | 0 | { |
63 | 0 | struct stat f; |
64 | |
|
65 | 0 | if (fstat(fd, &f) < 0) |
66 | 0 | return 0; |
67 | 0 | else if (f.st_dev != st->st_dev || f.st_ino != st->st_ino) |
68 | 0 | return 0; |
69 | 0 | return 1; |
70 | 0 | } Unexecuted instantiation: probe.c:is_same_inode Unexecuted instantiation: blkdev.c:is_same_inode Unexecuted instantiation: fileutils.c:is_same_inode Unexecuted instantiation: path.c:is_same_inode Unexecuted instantiation: sysfs.c:is_same_inode Unexecuted instantiation: devname.c:is_same_inode Unexecuted instantiation: save.c:is_same_inode Unexecuted instantiation: canonicalize.c:is_same_inode Unexecuted instantiation: loopdev.c:is_same_inode |
71 | | |
72 | | extern int ul_open_no_symlinks(const char *path, int flags, mode_t mode); |
73 | | extern int ul_openat_resolve(int dirfd, const char *path, int flags, |
74 | | mode_t mode, unsigned long long resolve); |
75 | | |
76 | | #ifndef RESOLVE_NO_SYMLINKS |
77 | 0 | # define RESOLVE_NO_SYMLINKS 0x04 |
78 | | #endif |
79 | | #ifndef RESOLVE_BENEATH |
80 | | # define RESOLVE_BENEATH 0x08 |
81 | | #endif |
82 | | |
83 | | extern int dup_fd_cloexec(int oldfd, int lowfd); |
84 | | extern unsigned int get_fd_tabsize(void); |
85 | | |
86 | | extern int ul_mkdir_p(const char *path, mode_t mode); |
87 | | extern char *stripoff_last_component(char *path); |
88 | | |
89 | | /* This is readdir()-like function, but skips "." and ".." directory entries */ |
90 | | static inline struct dirent *xreaddir(DIR *dp) |
91 | 0 | { |
92 | 0 | struct dirent *d; |
93 | |
|
94 | 0 | while ((d = readdir(dp))) { |
95 | 0 | if (!strcmp(d->d_name, ".") || |
96 | 0 | !strcmp(d->d_name, "..")) |
97 | 0 | continue; |
98 | 0 | break; |
99 | 0 | } |
100 | 0 | return d; |
101 | 0 | } Unexecuted instantiation: probe.c:xreaddir Unexecuted instantiation: blkdev.c:xreaddir Unexecuted instantiation: fileutils.c:xreaddir Unexecuted instantiation: path.c:xreaddir Unexecuted instantiation: sysfs.c:xreaddir Unexecuted instantiation: devname.c:xreaddir Unexecuted instantiation: save.c:xreaddir Unexecuted instantiation: canonicalize.c:xreaddir Unexecuted instantiation: loopdev.c:xreaddir |
102 | | |
103 | | |
104 | | #ifdef HAVE_SYS_SYSCALL_H |
105 | | # include <sys/syscall.h> |
106 | | |
107 | | # if !defined(HAVE_CLOSE_RANGE) && defined(SYS_close_range) |
108 | | # include <sys/types.h> |
109 | | static inline int close_range(unsigned int first, unsigned int last, int flags) |
110 | | { |
111 | | return syscall(SYS_close_range, first, last, flags); |
112 | | } |
113 | | # define HAVE_CLOSE_RANGE 1 |
114 | | # endif /* SYS_close_range */ |
115 | | |
116 | | # if !defined(HAVE_STATX) && defined(HAVE_STRUCT_STATX) && defined(SYS_statx) |
117 | | static inline int statx(int fd, const char *restrict path, int flags, |
118 | | unsigned int mask, struct statx *stx) |
119 | | { |
120 | | return syscall(SYS_statx, fd, path, flags, mask, stx); |
121 | | } |
122 | | # define HAVE_STATX 1 |
123 | | # endif /* SYS_statx */ |
124 | | |
125 | | # if !defined(HAVE_FCHMODAT2) && defined(SYS_fchmodat2) |
126 | | static inline int fchmodat2(int dirfd, const char *path, mode_t mode, |
127 | | unsigned int flags) |
128 | | { |
129 | | return syscall(SYS_fchmodat2, dirfd, path, mode, flags); |
130 | | } |
131 | | # define HAVE_FCHMODAT2 1 |
132 | | # endif /* SYS_fchmodat2 */ |
133 | | |
134 | | # if !defined(HAVE_COPY_FILE_RANGE) && defined(SYS_copy_file_range) |
135 | | static inline ssize_t copy_file_range(int fd_in, off_t *off_in, |
136 | | int fd_out, off_t *off_out, size_t size, unsigned int flags) |
137 | | { |
138 | | return syscall(SYS_copy_file_range, fd_in, off_in, fd_out, |
139 | | off_out, size, flags); |
140 | | } |
141 | | # define HAVE_COPY_FILE_RANGE 1 |
142 | | # endif /* SYS_copy_file_range */ |
143 | | |
144 | | #endif /* HAVE_SYS_SYSCALL_H */ |
145 | | |
146 | | |
147 | | extern void ul_close_all_fds(unsigned int first, unsigned int last); |
148 | | |
149 | 0 | #define UL_COPY_READ_ERROR (-1) |
150 | 0 | #define UL_COPY_WRITE_ERROR (-2) |
151 | | int ul_copy_file(int from, int to); |
152 | | |
153 | | /* Size of the buffer for ul_fd_mkpath() */ |
154 | | #define UL_FDPATH_BUFSIZ (sizeof(_PATH_PROC_FDDIR) + sizeof(stringify_value(INT_MAX))) |
155 | | |
156 | | extern int ul_reopen(int fd, int flags); |
157 | | extern char *ul_fd_mkpath(char *buf, size_t bufsz, int fd); |
158 | | extern char *ul_fd_get_path(int fd); |
159 | | extern char *ul_basename(char *path); |
160 | | |
161 | | extern char *ul_restricted_path_oper(const char *path, |
162 | | int (*oper)(const char *path, char **result, void *data), |
163 | | void *data); |
164 | | |
165 | | /* return 1 if @d is "." or ".." */ |
166 | | static inline bool is_dotdir_dirent(const struct dirent *d) |
167 | 0 | { |
168 | 0 | return (d && d->d_name[0] == '.' |
169 | 0 | && (d->d_name[1] == 0 |
170 | 0 | || (d->d_name[1] == '.' && d->d_name[2] == 0))); |
171 | 0 | } Unexecuted instantiation: probe.c:is_dotdir_dirent Unexecuted instantiation: blkdev.c:is_dotdir_dirent Unexecuted instantiation: fileutils.c:is_dotdir_dirent Unexecuted instantiation: path.c:is_dotdir_dirent Unexecuted instantiation: sysfs.c:is_dotdir_dirent Unexecuted instantiation: devname.c:is_dotdir_dirent Unexecuted instantiation: save.c:is_dotdir_dirent Unexecuted instantiation: canonicalize.c:is_dotdir_dirent Unexecuted instantiation: loopdev.c:is_dotdir_dirent |
172 | | |
173 | | #endif /* UTIL_LINUX_FILEUTILS */ |