]> git.proxmox.com Git - libgit2.git/blame - src/futils.h
New upstream version 1.4.3+dfsg.1
[libgit2.git] / src / futils.h
CommitLineData
ec250c6e 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
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 6 */
22a2d3d5
UG
7#ifndef INCLUDE_futils_h__
8#define INCLUDE_futils_h__
ec250c6e 9
5690f02e 10#include "common.h"
eae0bfdc 11
79ca2edc 12#include "map.h"
f79026b4 13#include "posix.h"
e579e0f7 14#include "fs_path.h"
500ec543
ET
15#include "pool.h"
16#include "strmap.h"
e579e0f7 17#include "hash.h"
f79026b4
VM
18
19/**
20 * Filebuffer methods
21 *
22 * Read whole files into an in-memory buffer for processing
23 */
e579e0f7 24extern int git_futils_readbuffer(git_str *obj, const char *path);
744cc03e 25extern int git_futils_readbuffer_updated(
e579e0f7
MB
26 git_str *obj,
27 const char *path,
28 unsigned char checksum[GIT_HASH_SHA1_SIZE],
29 int *updated);
30extern int git_futils_readbuffer_fd(git_str *obj, git_file fd, size_t len);
f79026b4 31
5312621b
ET
32/* Additional constants for `git_futils_writebuffer`'s `open_flags`. We
33 * support these internally and they will be removed before the `open` call.
34 */
35#ifndef O_FSYNC
36# define O_FSYNC (1 << 31)
37#endif
38
4742148d 39extern int git_futils_writebuffer(
e579e0f7 40 const git_str *buf, const char *path, int open_flags, mode_t mode);
4742148d 41
f79026b4
VM
42/**
43 * File utils
44 *
45 * These are custom filesystem-related helper methods. They are
46 * rather high level, and wrap the underlying POSIX methods
47 *
0d0fa7c3 48 * All these methods return 0 on success,
f79026b4
VM
49 * or an error code on failure and an error message is set.
50 */
51
f79026b4
VM
52/**
53 * Create and open a file, while also
54 * creating all the folders in its path
55 */
ce8cd006 56extern int git_futils_creat_withpath(const char *path, const mode_t dirmode, const mode_t mode);
f79026b4
VM
57
58/**
7b3f49f0 59 * Create and open a process-locked file
f79026b4 60 */
33127043 61extern int git_futils_creat_locked(const char *path, const mode_t mode);
f79026b4
VM
62
63/**
7b3f49f0 64 * Create and open a process-locked file, while
f79026b4
VM
65 * also creating all the folders in its path
66 */
ce8cd006 67extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, const mode_t mode);
f79026b4 68
662880ca 69/**
ac2fba0e 70 * Create a path recursively.
662880ca 71 */
ac2fba0e 72extern int git_futils_mkdir_r(const char *path, const mode_t mode);
662880ca 73
f79026b4 74/**
ca1b6e54 75 * Flags to pass to `git_futils_mkdir`.
dc07184f 76 *
ca1b6e54
RB
77 * * GIT_MKDIR_EXCL is "exclusive" - i.e. generate an error if dir exists.
78 * * GIT_MKDIR_PATH says to make all components in the path.
79 * * GIT_MKDIR_CHMOD says to chmod the final directory entry after creation
80 * * GIT_MKDIR_CHMOD_PATH says to chmod each directory component in the path
81 * * GIT_MKDIR_SKIP_LAST says to leave off the last element of the path
3c42e4ef 82 * * GIT_MKDIR_SKIP_LAST2 says to leave off the last 2 elements of the path
331e7de9 83 * * GIT_MKDIR_VERIFY_DIR says confirm final item is a dir, not just EEXIST
e74340b0
ET
84 * * GIT_MKDIR_REMOVE_FILES says to remove files and recreate dirs
85 * * GIT_MKDIR_REMOVE_SYMLINKS says to remove symlinks and recreate dirs
ca1b6e54
RB
86 *
87 * Note that the chmod options will be executed even if the directory already
88 * exists, unless GIT_MKDIR_EXCL is given.
f79026b4 89 */
ca1b6e54
RB
90typedef enum {
91 GIT_MKDIR_EXCL = 1,
92 GIT_MKDIR_PATH = 2,
93 GIT_MKDIR_CHMOD = 4,
94 GIT_MKDIR_CHMOD_PATH = 8,
331e7de9 95 GIT_MKDIR_SKIP_LAST = 16,
3c42e4ef
RB
96 GIT_MKDIR_SKIP_LAST2 = 32,
97 GIT_MKDIR_VERIFY_DIR = 64,
e74340b0 98 GIT_MKDIR_REMOVE_FILES = 128,
e579e0f7 99 GIT_MKDIR_REMOVE_SYMLINKS = 256
ca1b6e54
RB
100} git_futils_mkdir_flags;
101
1d50b364
ET
102struct git_futils_mkdir_perfdata
103{
104 size_t stat_calls;
105 size_t mkdir_calls;
106 size_t chmod_calls;
107};
108
500ec543
ET
109struct git_futils_mkdir_options
110{
111 git_strmap *dir_map;
112 git_pool *pool;
113 struct git_futils_mkdir_perfdata perfdata;
114};
115
ca1b6e54
RB
116/**
117 * Create a directory or entire path.
118 *
119 * This makes a directory (and the entire path leading up to it if requested),
120 * and optionally chmods the directory immediately after (or each part of the
121 * path if requested).
122 *
ac2fba0e 123 * @param path The path to create, relative to base.
ca1b6e54
RB
124 * @param base Root for relative path. These directories will never be made.
125 * @param mode The mode to use for created directories.
126 * @param flags Combination of the mkdir flags above.
ac2fba0e 127 * @param opts Extended options, or null.
ca1b6e54
RB
128 * @return 0 on success, else error code
129 */
ac2fba0e 130extern int git_futils_mkdir_relative(const char *path, const char *base, mode_t mode, uint32_t flags, struct git_futils_mkdir_options *opts);
1d50b364
ET
131
132/**
ac2fba0e 133 * Create a directory or entire path. Similar to `git_futils_mkdir_relative`
1d50b364
ET
134 * without performance data.
135 */
ac2fba0e 136extern int git_futils_mkdir(const char *path, mode_t mode, uint32_t flags);
f79026b4
VM
137
138/**
139 * Create all the folders required to contain
140 * the full path of a file
141 */
ce8cd006 142extern int git_futils_mkpath2file(const char *path, const mode_t mode);
f79026b4 143
331e7de9
RB
144/**
145 * Flags to pass to `git_futils_rmdir_r`.
146 *
147 * * GIT_RMDIR_EMPTY_HIERARCHY - the default; remove hierarchy of empty
148 * dirs and generate error if any files are found.
149 * * GIT_RMDIR_REMOVE_FILES - attempt to remove files in the hierarchy.
150 * * GIT_RMDIR_SKIP_NONEMPTY - skip non-empty directories with no error.
151 * * GIT_RMDIR_EMPTY_PARENTS - remove containing directories up to base
152 * if removing this item leaves them empty
ad9a921b 153 * * GIT_RMDIR_REMOVE_BLOCKERS - remove blocking file that causes ENOTDIR
219d3457 154 * * GIT_RMDIR_SKIP_ROOT - don't remove root directory itself
331e7de9 155 */
555aa453 156typedef enum {
331e7de9
RB
157 GIT_RMDIR_EMPTY_HIERARCHY = 0,
158 GIT_RMDIR_REMOVE_FILES = (1 << 0),
159 GIT_RMDIR_SKIP_NONEMPTY = (1 << 1),
160 GIT_RMDIR_EMPTY_PARENTS = (1 << 2),
ad9a921b 161 GIT_RMDIR_REMOVE_BLOCKERS = (1 << 3),
e579e0f7 162 GIT_RMDIR_SKIP_ROOT = (1 << 4)
331e7de9 163} git_futils_rmdir_flags;
555aa453 164
df743c7d 165/**
1744fafe 166 * Remove path and any files and directories beneath it.
555aa453 167 *
926acbcf 168 * @param path Path to the top level directory to process.
0d64bef9 169 * @param base Root for relative path.
331e7de9 170 * @param flags Combination of git_futils_rmdir_flags values
555aa453 171 * @return 0 on success; -1 on error.
df743c7d 172 */
331e7de9 173extern int git_futils_rmdir_r(const char *path, const char *base, uint32_t flags);
df743c7d 174
f79026b4 175/**
e579e0f7
MB
176 * Create and open a temporary file with a `_git2_` suffix in a
177 * protected directory; the file created will created will honor
178 * the current `umask`. Writes the filename into path_out.
179 *
180 * This function uses a high-quality PRNG seeded by the system's
181 * entropy pool _where available_ and falls back to a simple seed
182 * (time plus system information) when not. This is suitable for
183 * writing within a protected directory, but the system's safe
184 * temporary file creation functions should be preferred where
185 * available when writing into world-writable (temp) directories.
186 *
97769280 187 * @return On success, an open file descriptor, else an error code < 0.
f79026b4 188 */
e579e0f7 189extern int git_futils_mktmp(git_str *path_out, const char *filename, mode_t mode);
f79026b4 190
f79026b4
VM
191/**
192 * Move a file on the filesystem, create the
193 * destination path if it doesn't exist
194 */
ce8cd006 195extern int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode);
f79026b4 196
ca1b6e54 197/**
85bd1746 198 * Copy a file
ca1b6e54 199 *
85bd1746 200 * The filemode will be used for the newly created file.
ca1b6e54 201 */
85bd1746 202extern int git_futils_cp(
ca1b6e54
RB
203 const char *from,
204 const char *to,
85bd1746 205 mode_t filemode);
ca1b6e54 206
8f09a98e 207/**
27051d4e
ET
208 * Set the files atime and mtime to the given time, or the current time
209 * if `ts` is NULL.
8f09a98e 210 */
27051d4e 211extern int git_futils_touch(const char *path, time_t *when);
8f09a98e 212
ca1b6e54
RB
213/**
214 * Flags that can be passed to `git_futils_cp_r`.
18f08264
RB
215 *
216 * - GIT_CPDIR_CREATE_EMPTY_DIRS: create directories even if there are no
217 * files under them (otherwise directories will only be created lazily
218 * when a file inside them is copied).
219 * - GIT_CPDIR_COPY_SYMLINKS: copy symlinks, otherwise they are ignored.
220 * - GIT_CPDIR_COPY_DOTFILES: copy files with leading '.', otherwise ignored.
221 * - GIT_CPDIR_OVERWRITE: overwrite pre-existing files with source content,
222 * otherwise they are silently skipped.
223 * - GIT_CPDIR_CHMOD_DIRS: explicitly chmod directories to `dirmode`
224 * - GIT_CPDIR_SIMPLE_TO_MODE: default tries to replicate the mode of the
225 * source file to the target; with this flag, always use 0666 (or 0777 if
226 * source has exec bits set) for target.
94f742ba 227 * - GIT_CPDIR_LINK_FILES will try to use hardlinks for the files
ca1b6e54
RB
228 */
229typedef enum {
3c42e4ef
RB
230 GIT_CPDIR_CREATE_EMPTY_DIRS = (1u << 0),
231 GIT_CPDIR_COPY_SYMLINKS = (1u << 1),
232 GIT_CPDIR_COPY_DOTFILES = (1u << 2),
233 GIT_CPDIR_OVERWRITE = (1u << 3),
18f08264
RB
234 GIT_CPDIR_CHMOD_DIRS = (1u << 4),
235 GIT_CPDIR_SIMPLE_TO_MODE = (1u << 5),
e579e0f7 236 GIT_CPDIR_LINK_FILES = (1u << 6)
ca1b6e54
RB
237} git_futils_cpdir_flags;
238
239/**
240 * Copy a directory tree.
241 *
242 * This copies directories and files from one root to another. You can
e579e0f7 243 * pass a combination of GIT_CPDIR flags as defined above.
ca1b6e54
RB
244 *
245 * If you pass the CHMOD flag, then the dirmode will be applied to all
e579e0f7 246 * directories that are created during the copy, overriding the natural
ca1b6e54
RB
247 * permissions. If you do not pass the CHMOD flag, then the dirmode
248 * will actually be copied from the source files and the `dirmode` arg
249 * will be ignored.
250 */
251extern int git_futils_cp_r(
252 const char *from,
253 const char *to,
254 uint32_t flags,
255 mode_t dirmode);
256
ae9e29fd 257/**
deafee7b 258 * Open a file readonly and set error if needed.
ae9e29fd 259 */
deafee7b 260extern int git_futils_open_ro(const char *path);
ae9e29fd 261
eae0bfdc
PP
262/**
263 * Truncate a file, creating it if it doesn't exist.
264 */
265extern int git_futils_truncate(const char *path, int mode);
266
f79026b4
VM
267/**
268 * Get the filesize in bytes of a file
269 */
22a2d3d5 270extern int git_futils_filesize(uint64_t *out, git_file fd);
502acd16 271
c25aa7cd 272#define GIT_PERMS_IS_EXEC(MODE) (((MODE) & 0100) != 0)
a7fcc44d
RB
273#define GIT_PERMS_CANONICAL(MODE) (GIT_PERMS_IS_EXEC(MODE) ? 0755 : 0644)
274#define GIT_PERMS_FOR_WRITE(MODE) (GIT_PERMS_IS_EXEC(MODE) ? 0777 : 0666)
f240acce 275
74fa4bfa 276#define GIT_MODE_PERMS_MASK 0777
af22dabb
RB
277#define GIT_MODE_TYPE_MASK 0170000
278#define GIT_MODE_TYPE(MODE) ((MODE) & GIT_MODE_TYPE_MASK)
9be5be47 279#define GIT_MODE_ISBLOB(MODE) (GIT_MODE_TYPE(MODE) == GIT_MODE_TYPE(GIT_FILEMODE_BLOB))
74fa4bfa 280
b6c93aef
RB
281/**
282 * Convert a mode_t from the OS to a legal git mode_t value.
283 */
284extern mode_t git_futils_canonical_mode(mode_t raw_mode);
285
286
20e7f426
SP
287/**
288 * Read-only map all or part of a file into memory.
289 * When possible this function should favor a virtual memory
290 * style mapping over some form of malloc()+read(), as the
291 * data access will be random and is not likely to touch the
292 * majority of the region requested.
293 *
294 * @param out buffer to populate with the mapping information.
295 * @param fd open descriptor to configure the mapping from.
296 * @param begin first byte to map, this should be page aligned.
c05a55b0 297 * @param len number of bytes to map.
20e7f426 298 * @return
0d0fa7c3
RB
299 * - 0 on success;
300 * - -1 on error.
20e7f426 301 */
f79026b4 302extern int git_futils_mmap_ro(
79ca2edc 303 git_map *out,
20e7f426 304 git_file fd,
22a2d3d5 305 off64_t begin,
20e7f426
SP
306 size_t len);
307
74fa4bfa
RB
308/**
309 * Read-only map an entire file.
310 *
311 * @param out buffer to populate with the mapping information.
312 * @param path path to file to be opened.
313 * @return
0d0fa7c3
RB
314 * - 0 on success;
315 * - GIT_ENOTFOUND if not found;
316 * - -1 on an unspecified OS related error.
74fa4bfa
RB
317 */
318extern int git_futils_mmap_ro_file(
319 git_map *out,
320 const char *path);
321
20e7f426
SP
322/**
323 * Release the memory associated with a previous memory mapping.
324 * @param map the mapping description previously configured.
325 */
f79026b4 326extern void git_futils_mmap_free(git_map *map);
20e7f426 327
8651c10f
BS
328/**
329 * Create a "fake" symlink (text file containing the target path).
330 *
22a2d3d5
UG
331 * @param target original symlink target
332 * @param path symlink file to be created
8651c10f
BS
333 * @return 0 on success, -1 on error
334 */
22a2d3d5 335extern int git_futils_fake_symlink(const char *target, const char *path);
8651c10f 336
c8b511f3
RB
337/**
338 * A file stamp represents a snapshot of information about a file that can
339 * be used to test if the file changes. This portable implementation is
340 * based on stat data about that file, but it is possible that OS specific
341 * versions could be implemented in the future.
342 */
744cc03e 343typedef struct {
0226f7dd 344 struct timespec mtime;
22a2d3d5 345 uint64_t size;
744cc03e 346 unsigned int ino;
c1f61af6 347} git_futils_filestamp;
744cc03e
RB
348
349/**
350 * Compare stat information for file with reference info.
351 *
c8b511f3 352 * This function updates the file stamp to current data for the given path
7d490872
RB
353 * and returns 0 if the file is up-to-date relative to the prior setting,
354 * 1 if the file has been changed, or GIT_ENOTFOUND if the file doesn't
ac3d33df 355 * exist. This will not call git_error_set, so you must set the error if you
7d490872 356 * plan to return an error.
744cc03e 357 *
c8b511f3
RB
358 * @param stamp File stamp to be checked
359 * @param path Path to stat and check if changed
7d490872 360 * @return 0 if up-to-date, 1 if out-of-date, GIT_ENOTFOUND if cannot stat
744cc03e 361 */
c1f61af6
VM
362extern int git_futils_filestamp_check(
363 git_futils_filestamp *stamp, const char *path);
c8b511f3
RB
364
365/**
366 * Set or reset file stamp data
367 *
368 * This writes the target file stamp. If the source is NULL, this will set
369 * the target stamp to values that will definitely be out of date. If the
370 * source is not NULL, this copies the source values to the target.
371 *
372 * @param tgt File stamp to write to
373 * @param src File stamp to copy from or NULL to clear the target
374 */
c1f61af6
VM
375extern void git_futils_filestamp_set(
376 git_futils_filestamp *tgt, const git_futils_filestamp *src);
744cc03e 377
823c0e9c
RB
378/**
379 * Set file stamp data from stat structure
380 */
381extern void git_futils_filestamp_set_from_stat(
382 git_futils_filestamp *stamp, struct stat *st);
383
1229e1c4
ET
384/**
385 * `fsync` the parent directory of the given path, if `fsync` is
386 * supported for directories on this platform.
387 *
388 * @param path Path of the directory to sync.
389 * @return 0 on success, -1 on error
390 */
391extern int git_futils_fsync_dir(const char *path);
392
393/**
394 * `fsync` the parent directory of the given path, if `fsync` is
395 * supported for directories on this platform.
396 *
397 * @param path Path of the file whose parent directory should be synced.
398 * @return 0 on success, -1 on error
399 */
400extern int git_futils_fsync_parent(const char *path);
401
eae0bfdc 402#endif