1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
/*
* No copyright is claimed. This code is in the public domain; do with
* it what you wish.
**/
#ifndef UTIL_LINUX_FILEUTILS
#define UTIL_LINUX_FILEUTILS
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include "c.h"
extern int mkstemp_cloexec(char *template);
extern int xmkstemp(char **tmpname, const char *dir, const char *prefix);
static inline FILE *xfmkstemp(char **tmpname, const char *dir, const char *prefix)
{
int fd;
FILE *ret;
fd = xmkstemp(tmpname, dir, prefix);
if (fd == -1)
return NULL;
if (!(ret = fdopen(fd, "w+" UL_CLOEXECSTR))) {
close(fd);
return NULL;
}
return ret;
}
#ifdef HAVE_OPENAT
static inline FILE *fopen_at(int dir, const char *filename,
int flags, const char *mode)
{
int fd = openat(dir, filename, flags);
FILE *ret;
if (fd < 0)
return NULL;
ret = fdopen(fd, mode);
if (!ret)
close(fd);
return ret;
}
#endif
static inline int is_same_inode(const int fd, const struct stat *st)
{
struct stat f;
if (fstat(fd, &f) < 0)
return 0;
else if (f.st_dev != st->st_dev || f.st_ino != st->st_ino)
return 0;
return 1;
}
extern int dup_fd_cloexec(int oldfd, int lowfd);
extern unsigned int get_fd_tabsize(void);
extern int ul_mkdir_p(const char *path, mode_t mode);
extern char *stripoff_last_component(char *path);
/* This is readdir()-like function, but skips "." and ".." directory entries */
static inline struct dirent *xreaddir(DIR *dp)
{
struct dirent *d;
while ((d = readdir(dp))) {
if (!strcmp(d->d_name, ".") ||
!strcmp(d->d_name, ".."))
continue;
break;
}
return d;
}
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
# if !defined(HAVE_CLOSE_RANGE) && defined(SYS_close_range)
# include <sys/types.h>
static inline int close_range(unsigned int first, unsigned int last, int flags)
{
return syscall(SYS_close_range, first, last, flags);
}
# define HAVE_CLOSE_RANGE 1
# endif /* SYS_close_range */
# if !defined(HAVE_STATX) && defined(HAVE_STRUCT_STATX) && defined(SYS_statx)
static inline int statx(int fd, const char *restrict path, int flags,
unsigned int mask, struct statx *stx)
{
return syscall(SYS_statx, fd, path, flags, mask, stx);
}
# define HAVE_STATX 1
# endif /* SYS_statx */
#endif /* HAVE_SYS_SYSCALL_H */
extern void ul_close_all_fds(unsigned int first, unsigned int last);
#define UL_COPY_READ_ERROR (-1)
#define UL_COPY_WRITE_ERROR (-2)
int ul_copy_file(int from, int to);
extern int ul_reopen(int fd, int flags);
extern char *ul_basename(char *path);
extern char *ul_restricted_path_oper(const char *path,
int (*oper)(const char *path, char **result, void *data),
void *data);
/* return 1 if @d is "." or ".." */
static inline bool is_dotdir_dirent(const struct dirent *d)
{
return (d && d->d_name[0] == '.'
&& (d->d_name[1] == 0
|| (d->d_name[1] == '.' && d->d_name[2] == 0)));
}
#endif /* UTIL_LINUX_FILEUTILS */
|