]>
Commit | Line | Data |
---|---|---|
ec250c6e | 1 | /* |
5e0de328 | 2 | * Copyright (C) 2009-2012 the libgit2 contributors |
ec250c6e | 3 | * |
bb742ede VM |
4 | * This file is part of libgit2, distributed under the GNU GPL v2 with |
5 | * a Linking Exception. For full terms see the included COPYING file. | |
ec250c6e AE |
6 | */ |
7 | #ifndef INCLUDE_fileops_h__ | |
8 | #define INCLUDE_fileops_h__ | |
9 | ||
5690f02e | 10 | #include "common.h" |
79ca2edc | 11 | #include "map.h" |
f79026b4 VM |
12 | #include "posix.h" |
13 | #include "path.h" | |
14 | ||
15 | /** | |
16 | * Filebuffer methods | |
17 | * | |
18 | * Read whole files into an in-memory buffer for processing | |
19 | */ | |
13224ea4 | 20 | extern int git_futils_readbuffer(git_buf *obj, const char *path); |
744cc03e RB |
21 | extern int git_futils_readbuffer_updated( |
22 | git_buf *obj, const char *path, time_t *mtime, size_t *size, int *updated); | |
60b9d3fc | 23 | extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len); |
f79026b4 VM |
24 | |
25 | /** | |
26 | * File utils | |
27 | * | |
28 | * These are custom filesystem-related helper methods. They are | |
29 | * rather high level, and wrap the underlying POSIX methods | |
30 | * | |
0d0fa7c3 | 31 | * All these methods return 0 on success, |
f79026b4 VM |
32 | * or an error code on failure and an error message is set. |
33 | */ | |
34 | ||
f79026b4 VM |
35 | /** |
36 | * Create and open a file, while also | |
37 | * creating all the folders in its path | |
38 | */ | |
ce8cd006 | 39 | extern int git_futils_creat_withpath(const char *path, const mode_t dirmode, const mode_t mode); |
f79026b4 VM |
40 | |
41 | /** | |
42 | * Create an open a process-locked file | |
43 | */ | |
33127043 | 44 | extern int git_futils_creat_locked(const char *path, const mode_t mode); |
f79026b4 VM |
45 | |
46 | /** | |
47 | * Create an open a process-locked file, while | |
48 | * also creating all the folders in its path | |
49 | */ | |
ce8cd006 | 50 | extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, const mode_t mode); |
f79026b4 | 51 | |
662880ca | 52 | /** |
ca1b6e54 RB |
53 | * Create a path recursively |
54 | * | |
55 | * If a base parameter is being passed, it's expected to be valued with a | |
56 | * path pointing to an already existing directory. | |
662880ca | 57 | */ |
ca1b6e54 | 58 | extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode); |
662880ca | 59 | |
f79026b4 | 60 | /** |
ca1b6e54 | 61 | * Flags to pass to `git_futils_mkdir`. |
dc07184f | 62 | * |
ca1b6e54 RB |
63 | * * GIT_MKDIR_EXCL is "exclusive" - i.e. generate an error if dir exists. |
64 | * * GIT_MKDIR_PATH says to make all components in the path. | |
65 | * * GIT_MKDIR_CHMOD says to chmod the final directory entry after creation | |
66 | * * GIT_MKDIR_CHMOD_PATH says to chmod each directory component in the path | |
67 | * * GIT_MKDIR_SKIP_LAST says to leave off the last element of the path | |
331e7de9 | 68 | * * GIT_MKDIR_VERIFY_DIR says confirm final item is a dir, not just EEXIST |
ca1b6e54 RB |
69 | * |
70 | * Note that the chmod options will be executed even if the directory already | |
71 | * exists, unless GIT_MKDIR_EXCL is given. | |
f79026b4 | 72 | */ |
ca1b6e54 RB |
73 | typedef enum { |
74 | GIT_MKDIR_EXCL = 1, | |
75 | GIT_MKDIR_PATH = 2, | |
76 | GIT_MKDIR_CHMOD = 4, | |
77 | GIT_MKDIR_CHMOD_PATH = 8, | |
331e7de9 RB |
78 | GIT_MKDIR_SKIP_LAST = 16, |
79 | GIT_MKDIR_VERIFY_DIR = 32, | |
ca1b6e54 RB |
80 | } git_futils_mkdir_flags; |
81 | ||
82 | /** | |
83 | * Create a directory or entire path. | |
84 | * | |
85 | * This makes a directory (and the entire path leading up to it if requested), | |
86 | * and optionally chmods the directory immediately after (or each part of the | |
87 | * path if requested). | |
88 | * | |
89 | * @param path The path to create. | |
90 | * @param base Root for relative path. These directories will never be made. | |
91 | * @param mode The mode to use for created directories. | |
92 | * @param flags Combination of the mkdir flags above. | |
93 | * @return 0 on success, else error code | |
94 | */ | |
95 | extern int git_futils_mkdir(const char *path, const char *base, mode_t mode, uint32_t flags); | |
f79026b4 VM |
96 | |
97 | /** | |
98 | * Create all the folders required to contain | |
99 | * the full path of a file | |
100 | */ | |
ce8cd006 | 101 | extern int git_futils_mkpath2file(const char *path, const mode_t mode); |
f79026b4 | 102 | |
331e7de9 RB |
103 | /** |
104 | * Flags to pass to `git_futils_rmdir_r`. | |
105 | * | |
106 | * * GIT_RMDIR_EMPTY_HIERARCHY - the default; remove hierarchy of empty | |
107 | * dirs and generate error if any files are found. | |
108 | * * GIT_RMDIR_REMOVE_FILES - attempt to remove files in the hierarchy. | |
109 | * * GIT_RMDIR_SKIP_NONEMPTY - skip non-empty directories with no error. | |
110 | * * GIT_RMDIR_EMPTY_PARENTS - remove containing directories up to base | |
111 | * if removing this item leaves them empty | |
ad9a921b | 112 | * * GIT_RMDIR_REMOVE_BLOCKERS - remove blocking file that causes ENOTDIR |
331e7de9 RB |
113 | * |
114 | * The old values translate into the new as follows: | |
115 | * | |
116 | * * GIT_DIRREMOVAL_EMPTY_HIERARCHY == GIT_RMDIR_EMPTY_HIERARCHY | |
117 | * * GIT_DIRREMOVAL_FILES_AND_DIRS ~= GIT_RMDIR_REMOVE_FILES | |
118 | * * GIT_DIRREMOVAL_ONLY_EMPTY_DIRS == GIT_RMDIR_SKIP_NONEMPTY | |
119 | */ | |
555aa453 | 120 | typedef enum { |
331e7de9 RB |
121 | GIT_RMDIR_EMPTY_HIERARCHY = 0, |
122 | GIT_RMDIR_REMOVE_FILES = (1 << 0), | |
123 | GIT_RMDIR_SKIP_NONEMPTY = (1 << 1), | |
124 | GIT_RMDIR_EMPTY_PARENTS = (1 << 2), | |
ad9a921b | 125 | GIT_RMDIR_REMOVE_BLOCKERS = (1 << 3), |
331e7de9 | 126 | } git_futils_rmdir_flags; |
555aa453 | 127 | |
df743c7d | 128 | /** |
1744fafe | 129 | * Remove path and any files and directories beneath it. |
555aa453 | 130 | * |
131 | * @param path Path to to top level directory to process. | |
0d64bef9 | 132 | * @param base Root for relative path. |
331e7de9 | 133 | * @param flags Combination of git_futils_rmdir_flags values |
555aa453 | 134 | * @return 0 on success; -1 on error. |
df743c7d | 135 | */ |
331e7de9 | 136 | extern int git_futils_rmdir_r(const char *path, const char *base, uint32_t flags); |
df743c7d | 137 | |
f79026b4 | 138 | /** |
97769280 RB |
139 | * Create and open a temporary file with a `_git2_` suffix. |
140 | * Writes the filename into path_out. | |
141 | * @return On success, an open file descriptor, else an error code < 0. | |
f79026b4 | 142 | */ |
97769280 | 143 | extern int git_futils_mktmp(git_buf *path_out, const char *filename); |
f79026b4 | 144 | |
f79026b4 VM |
145 | /** |
146 | * Move a file on the filesystem, create the | |
147 | * destination path if it doesn't exist | |
148 | */ | |
ce8cd006 | 149 | extern int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode); |
f79026b4 | 150 | |
ca1b6e54 | 151 | /** |
85bd1746 | 152 | * Copy a file |
ca1b6e54 | 153 | * |
85bd1746 | 154 | * The filemode will be used for the newly created file. |
ca1b6e54 | 155 | */ |
85bd1746 | 156 | extern int git_futils_cp( |
ca1b6e54 RB |
157 | const char *from, |
158 | const char *to, | |
85bd1746 | 159 | mode_t filemode); |
ca1b6e54 RB |
160 | |
161 | /** | |
162 | * Flags that can be passed to `git_futils_cp_r`. | |
163 | */ | |
164 | typedef enum { | |
165 | GIT_CPDIR_CREATE_EMPTY_DIRS = 1, | |
166 | GIT_CPDIR_COPY_SYMLINKS = 2, | |
167 | GIT_CPDIR_COPY_DOTFILES = 4, | |
168 | GIT_CPDIR_OVERWRITE = 8, | |
169 | GIT_CPDIR_CHMOD = 16 | |
170 | } git_futils_cpdir_flags; | |
171 | ||
172 | /** | |
173 | * Copy a directory tree. | |
174 | * | |
175 | * This copies directories and files from one root to another. You can | |
176 | * pass a combinationof GIT_CPDIR flags as defined above. | |
177 | * | |
178 | * If you pass the CHMOD flag, then the dirmode will be applied to all | |
179 | * directories that are created during the copy, overiding the natural | |
180 | * permissions. If you do not pass the CHMOD flag, then the dirmode | |
181 | * will actually be copied from the source files and the `dirmode` arg | |
182 | * will be ignored. | |
183 | */ | |
184 | extern int git_futils_cp_r( | |
185 | const char *from, | |
186 | const char *to, | |
187 | uint32_t flags, | |
188 | mode_t dirmode); | |
189 | ||
ae9e29fd | 190 | /** |
deafee7b | 191 | * Open a file readonly and set error if needed. |
ae9e29fd | 192 | */ |
deafee7b | 193 | extern int git_futils_open_ro(const char *path); |
ae9e29fd | 194 | |
f79026b4 VM |
195 | /** |
196 | * Get the filesize in bytes of a file | |
197 | */ | |
198 | extern git_off_t git_futils_filesize(git_file fd); | |
502acd16 | 199 | |
74fa4bfa RB |
200 | #define GIT_MODE_PERMS_MASK 0777 |
201 | #define GIT_CANONICAL_PERMS(MODE) (((MODE) & 0100) ? 0755 : 0644) | |
202 | #define GIT_MODE_TYPE(MODE) ((MODE) & ~GIT_MODE_PERMS_MASK) | |
203 | ||
b6c93aef RB |
204 | /** |
205 | * Convert a mode_t from the OS to a legal git mode_t value. | |
206 | */ | |
207 | extern mode_t git_futils_canonical_mode(mode_t raw_mode); | |
208 | ||
209 | ||
20e7f426 SP |
210 | /** |
211 | * Read-only map all or part of a file into memory. | |
212 | * When possible this function should favor a virtual memory | |
213 | * style mapping over some form of malloc()+read(), as the | |
214 | * data access will be random and is not likely to touch the | |
215 | * majority of the region requested. | |
216 | * | |
217 | * @param out buffer to populate with the mapping information. | |
218 | * @param fd open descriptor to configure the mapping from. | |
219 | * @param begin first byte to map, this should be page aligned. | |
220 | * @param end number of bytes to map. | |
221 | * @return | |
0d0fa7c3 RB |
222 | * - 0 on success; |
223 | * - -1 on error. | |
20e7f426 | 224 | */ |
f79026b4 | 225 | extern int git_futils_mmap_ro( |
79ca2edc | 226 | git_map *out, |
20e7f426 | 227 | git_file fd, |
f0bde7fa | 228 | git_off_t begin, |
20e7f426 SP |
229 | size_t len); |
230 | ||
74fa4bfa RB |
231 | /** |
232 | * Read-only map an entire file. | |
233 | * | |
234 | * @param out buffer to populate with the mapping information. | |
235 | * @param path path to file to be opened. | |
236 | * @return | |
0d0fa7c3 RB |
237 | * - 0 on success; |
238 | * - GIT_ENOTFOUND if not found; | |
239 | * - -1 on an unspecified OS related error. | |
74fa4bfa RB |
240 | */ |
241 | extern int git_futils_mmap_ro_file( | |
242 | git_map *out, | |
243 | const char *path); | |
244 | ||
20e7f426 SP |
245 | /** |
246 | * Release the memory associated with a previous memory mapping. | |
247 | * @param map the mapping description previously configured. | |
248 | */ | |
f79026b4 | 249 | extern void git_futils_mmap_free(git_map *map); |
20e7f426 | 250 | |
73b51450 RB |
251 | /** |
252 | * Find a "global" file (i.e. one in a user's home directory). | |
253 | * | |
254 | * @param pathbuf buffer to write the full path into | |
255 | * @param filename name of file to find in the home directory | |
256 | * @return | |
0d0fa7c3 | 257 | * - 0 if found; |
73b51450 | 258 | * - GIT_ENOTFOUND if not found; |
0d0fa7c3 | 259 | * - -1 on an unspecified OS related error. |
73b51450 RB |
260 | */ |
261 | extern int git_futils_find_global_file(git_buf *path, const char *filename); | |
262 | ||
263 | /** | |
264 | * Find a "system" file (i.e. one shared for all users of the system). | |
265 | * | |
266 | * @param pathbuf buffer to write the full path into | |
267 | * @param filename name of file to find in the home directory | |
268 | * @return | |
0d0fa7c3 | 269 | * - 0 if found; |
73b51450 | 270 | * - GIT_ENOTFOUND if not found; |
0d0fa7c3 | 271 | * - -1 on an unspecified OS related error. |
73b51450 RB |
272 | */ |
273 | extern int git_futils_find_system_file(git_buf *path, const char *filename); | |
274 | ||
8651c10f BS |
275 | |
276 | /** | |
277 | * Create a "fake" symlink (text file containing the target path). | |
278 | * | |
279 | * @param new symlink file to be created | |
280 | * @param old original symlink target | |
281 | * @return 0 on success, -1 on error | |
282 | */ | |
283 | extern int git_futils_fake_symlink(const char *new, const char *old); | |
284 | ||
c8b511f3 RB |
285 | /** |
286 | * A file stamp represents a snapshot of information about a file that can | |
287 | * be used to test if the file changes. This portable implementation is | |
288 | * based on stat data about that file, but it is possible that OS specific | |
289 | * versions could be implemented in the future. | |
290 | */ | |
744cc03e | 291 | typedef struct { |
c8b511f3 | 292 | git_time_t mtime; |
744cc03e RB |
293 | git_off_t size; |
294 | unsigned int ino; | |
c1f61af6 | 295 | } git_futils_filestamp; |
744cc03e RB |
296 | |
297 | /** | |
298 | * Compare stat information for file with reference info. | |
299 | * | |
c8b511f3 RB |
300 | * This function updates the file stamp to current data for the given path |
301 | * and returns 0 if the file is up-to-date relative to the prior setting or | |
302 | * 1 if the file has been changed. (This also may return GIT_ENOTFOUND if | |
303 | * the file doesn't exist.) | |
744cc03e | 304 | * |
c8b511f3 RB |
305 | * @param stamp File stamp to be checked |
306 | * @param path Path to stat and check if changed | |
744cc03e RB |
307 | * @return 0 if up-to-date, 1 if out-of-date, <0 on error |
308 | */ | |
c1f61af6 VM |
309 | extern int git_futils_filestamp_check( |
310 | git_futils_filestamp *stamp, const char *path); | |
c8b511f3 RB |
311 | |
312 | /** | |
313 | * Set or reset file stamp data | |
314 | * | |
315 | * This writes the target file stamp. If the source is NULL, this will set | |
316 | * the target stamp to values that will definitely be out of date. If the | |
317 | * source is not NULL, this copies the source values to the target. | |
318 | * | |
319 | * @param tgt File stamp to write to | |
320 | * @param src File stamp to copy from or NULL to clear the target | |
321 | */ | |
c1f61af6 VM |
322 | extern void git_futils_filestamp_set( |
323 | git_futils_filestamp *tgt, const git_futils_filestamp *src); | |
744cc03e | 324 | |
ec250c6e | 325 | #endif /* INCLUDE_fileops_h__ */ |