mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-09-10 07:44:54 -04:00
main: split the code in multiple files
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
53c165e6bd
commit
c2c2ac5b82
@ -11,7 +11,7 @@ CLEANFILES = fuse-overlayfs.1
|
|||||||
fuse_overlayfs_CFLAGS = -I . -I $(abs_srcdir)/lib $(FUSE_CFLAGS)
|
fuse_overlayfs_CFLAGS = -I . -I $(abs_srcdir)/lib $(FUSE_CFLAGS)
|
||||||
fuse_overlayfs_LDFLAGS =
|
fuse_overlayfs_LDFLAGS =
|
||||||
fuse_overlayfs_LDADD = lib/libgnu.a $(FUSE_LIBS)
|
fuse_overlayfs_LDADD = lib/libgnu.a $(FUSE_LIBS)
|
||||||
fuse_overlayfs_SOURCES = main.c
|
fuse_overlayfs_SOURCES = main.c direct.c utils.c
|
||||||
|
|
||||||
WD := $(shell pwd)
|
WD := $(shell pwd)
|
||||||
|
|
||||||
|
170
direct.c
Normal file
170
direct.c
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/* fuse-overlayfs: Overlay Filesystem in Userspace
|
||||||
|
|
||||||
|
Copyright (C) 2018 Giuseppe Scrivano <giuseppe@scrivano.org>
|
||||||
|
Copyright (C) 2018-2019 Red Hat Inc.
|
||||||
|
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "fuse-overlayfs.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/xattr.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_file_exists (struct ovl_layer *l, const char *pathname)
|
||||||
|
{
|
||||||
|
return file_exists_at (l->fd, pathname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_listxattr (struct ovl_layer *l, const char *path, char *buf, size_t size)
|
||||||
|
{
|
||||||
|
cleanup_close int fd = -1;
|
||||||
|
char full_path[PATH_MAX];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
full_path[0] = '\0';
|
||||||
|
ret = open_fd_or_get_path (l, path, full_path, &fd, O_RDONLY);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (fd >= 0)
|
||||||
|
return flistxattr (fd, buf, size);
|
||||||
|
|
||||||
|
return llistxattr (full_path, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_getxattr (struct ovl_layer *l, const char *path, const char *name, char *buf, size_t size)
|
||||||
|
{
|
||||||
|
cleanup_close int fd = -1;
|
||||||
|
char full_path[PATH_MAX];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
full_path[0] = '\0';
|
||||||
|
ret = open_fd_or_get_path (l, path, full_path, &fd, O_RDONLY);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (fd >= 0)
|
||||||
|
return fgetxattr (fd, name, buf, size);
|
||||||
|
|
||||||
|
return lgetxattr (full_path, name, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_fstat (struct ovl_layer *l, int fd, const char *path, struct stat *st)
|
||||||
|
{
|
||||||
|
return fstat (fd, st);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_statat (struct ovl_layer *l, const char *path, struct stat *st, int flags)
|
||||||
|
{
|
||||||
|
return TEMP_FAILURE_RETRY (fstatat (l->fd, path, st, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dirent *
|
||||||
|
direct_readdir (void *dirp)
|
||||||
|
{
|
||||||
|
return readdir (dirp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
direct_opendir (struct ovl_layer *l, const char *path)
|
||||||
|
{
|
||||||
|
cleanup_close int cleanup_fd = -1;
|
||||||
|
DIR *dp = NULL;
|
||||||
|
|
||||||
|
cleanup_fd = TEMP_FAILURE_RETRY (openat (l->fd, path, O_DIRECTORY));
|
||||||
|
if (cleanup_fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dp = fdopendir (cleanup_fd);
|
||||||
|
if (dp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cleanup_fd = -1;
|
||||||
|
|
||||||
|
return dp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_closedir (void *dirp)
|
||||||
|
{
|
||||||
|
return closedir (dirp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_openat (struct ovl_layer *l, const char *path, int flags, mode_t mode)
|
||||||
|
{
|
||||||
|
return TEMP_FAILURE_RETRY (openat (l->fd, path, flags, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
direct_readlinkat (struct ovl_layer *l, const char *path, char *buf, size_t bufsiz)
|
||||||
|
{
|
||||||
|
return TEMP_FAILURE_RETRY (readlinkat (l->fd, path, buf, bufsiz));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_load_data_source (struct ovl_layer *l, const char *opaque)
|
||||||
|
{
|
||||||
|
l->path = realpath (opaque, NULL);
|
||||||
|
if (l->path == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
l->fd = open (l->path, O_DIRECTORY);
|
||||||
|
if (l->fd < 0)
|
||||||
|
{
|
||||||
|
free (l->path);
|
||||||
|
l->path = NULL;
|
||||||
|
return l->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
direct_cleanup (struct ovl_layer *l)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct data_source direct_access_ds =
|
||||||
|
{
|
||||||
|
.load_data_source = direct_load_data_source,
|
||||||
|
.cleanup = direct_cleanup,
|
||||||
|
.file_exists = direct_file_exists,
|
||||||
|
.statat = direct_statat,
|
||||||
|
.fstat = direct_fstat,
|
||||||
|
.opendir = direct_opendir,
|
||||||
|
.readdir = direct_readdir,
|
||||||
|
.closedir = direct_closedir,
|
||||||
|
.openat = direct_openat,
|
||||||
|
.getxattr = direct_getxattr,
|
||||||
|
.listxattr = direct_listxattr,
|
||||||
|
.readlinkat = direct_readlinkat,
|
||||||
|
};
|
@ -109,6 +109,8 @@ struct ovl_layer
|
|||||||
/* a data_source defines the methods for accessing a lower layer. */
|
/* a data_source defines the methods for accessing a lower layer. */
|
||||||
struct data_source
|
struct data_source
|
||||||
{
|
{
|
||||||
|
int (*load_data_source)(struct ovl_layer *l, const char *opaque);
|
||||||
|
int (*cleanup)(struct ovl_layer *l);
|
||||||
int (*file_exists)(struct ovl_layer *l, const char *pathname);
|
int (*file_exists)(struct ovl_layer *l, const char *pathname);
|
||||||
int (*statat)(struct ovl_layer *l, const char *path, struct stat *st, int flags);
|
int (*statat)(struct ovl_layer *l, const char *path, struct stat *st, int flags);
|
||||||
int (*fstat)(struct ovl_layer *l, int fd, const char *path, struct stat *st);
|
int (*fstat)(struct ovl_layer *l, int fd, const char *path, struct stat *st);
|
||||||
|
191
main.c
191
main.c
@ -141,12 +141,6 @@ open_by_handle_at (int mount_fd, struct file_handle *handle, int flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
|
||||||
file_exists_at (int dirfd, const char *pathname)
|
|
||||||
{
|
|
||||||
return faccessat (dirfd, pathname, F_OK, AT_SYMLINK_NOFOLLOW|AT_EACCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef RENAME_EXCHANGE
|
#ifndef RENAME_EXCHANGE
|
||||||
# define RENAME_EXCHANGE (1 << 1)
|
# define RENAME_EXCHANGE (1 << 1)
|
||||||
# define RENAME_NOREPLACE (1 << 2)
|
# define RENAME_NOREPLACE (1 << 2)
|
||||||
@ -274,52 +268,6 @@ inode_to_node (struct ovl_data *lo, ino_t n)
|
|||||||
return lookup_inode (lo, n)->node;
|
return lookup_inode (lo, n)->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
strconcat3 (char *dest, size_t size, const char *s1, const char *s2, const char *s3)
|
|
||||||
{
|
|
||||||
size_t t;
|
|
||||||
char *current = dest;
|
|
||||||
|
|
||||||
size--;
|
|
||||||
|
|
||||||
if (s1)
|
|
||||||
{
|
|
||||||
t = strlen (s1);
|
|
||||||
if (t > size)
|
|
||||||
t = size;
|
|
||||||
|
|
||||||
memcpy (current, s1, t);
|
|
||||||
current += t;
|
|
||||||
|
|
||||||
size -= t;
|
|
||||||
}
|
|
||||||
if (s2)
|
|
||||||
{
|
|
||||||
t = strlen (s2);
|
|
||||||
if (t > size)
|
|
||||||
t = size;
|
|
||||||
|
|
||||||
memcpy (current, s2, t);
|
|
||||||
current += t;
|
|
||||||
|
|
||||||
size -= t;
|
|
||||||
}
|
|
||||||
if (s3)
|
|
||||||
{
|
|
||||||
t = strlen (s3);
|
|
||||||
if (t > size)
|
|
||||||
t = size;
|
|
||||||
|
|
||||||
memcpy (current, s3, t);
|
|
||||||
current += t;
|
|
||||||
|
|
||||||
size -= t;
|
|
||||||
}
|
|
||||||
*current = '\0';
|
|
||||||
|
|
||||||
return current - dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_can_mknod (struct ovl_data *lo)
|
check_can_mknod (struct ovl_data *lo)
|
||||||
{
|
{
|
||||||
@ -1602,14 +1550,10 @@ read_dirs (struct ovl_data *lo, char *path, bool low, struct ovl_layer *layers)
|
|||||||
|
|
||||||
l->ovl_data = lo;
|
l->ovl_data = lo;
|
||||||
|
|
||||||
|
l->path = NULL;
|
||||||
l->fd = -1;
|
l->fd = -1;
|
||||||
|
|
||||||
l->path = realpath (it, NULL);
|
if (l->ds->load_data_source (l, it) < 0)
|
||||||
if (l->path == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
l->fd = open (l->path, O_DIRECTORY);
|
|
||||||
if (l->fd < 0)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
l->low = low;
|
l->low = low;
|
||||||
@ -2912,23 +2856,6 @@ ovl_rmdir (fuse_req_t req, fuse_ino_t parent, const char *name)
|
|||||||
do_rm (req, parent, name, true);
|
do_rm (req, parent, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
open_fd_or_get_path (struct ovl_layer *l, const char *path, char *out, int *fd, int flags)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
out[0] = '\0';
|
|
||||||
|
|
||||||
*fd = l->ds->openat (l, path, O_NONBLOCK|O_NOFOLLOW|flags, 0755);
|
|
||||||
if (*fd < 0 && (errno == ELOOP || errno == EISDIR))
|
|
||||||
{
|
|
||||||
strconcat3 (out, PATH_MAX, l->path, "/", path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_setxattr (struct ovl_layer *l, const char *path, const char *name, const char *buf, size_t size, int flags)
|
direct_setxattr (struct ovl_layer *l, const char *path, const char *name, const char *buf, size_t size, int flags)
|
||||||
{
|
{
|
||||||
@ -4789,117 +4716,6 @@ ovl_copy_file_range (fuse_req_t req, fuse_ino_t ino_in, off_t off_in, struct fus
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
|
||||||
direct_file_exists (struct ovl_layer *l, const char *pathname)
|
|
||||||
{
|
|
||||||
return file_exists_at (l->fd, pathname);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
direct_listxattr (struct ovl_layer *l, const char *path, char *buf, size_t size)
|
|
||||||
{
|
|
||||||
cleanup_close int fd = -1;
|
|
||||||
char full_path[PATH_MAX];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
full_path[0] = '\0';
|
|
||||||
ret = open_fd_or_get_path (l, path, full_path, &fd, O_RDONLY);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (fd >= 0)
|
|
||||||
return flistxattr (fd, buf, size);
|
|
||||||
|
|
||||||
return llistxattr (full_path, buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
direct_getxattr (struct ovl_layer *l, const char *path, const char *name, char *buf, size_t size)
|
|
||||||
{
|
|
||||||
cleanup_close int fd = -1;
|
|
||||||
char full_path[PATH_MAX];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
full_path[0] = '\0';
|
|
||||||
ret = open_fd_or_get_path (l, path, full_path, &fd, O_RDONLY);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (fd >= 0)
|
|
||||||
return fgetxattr (fd, name, buf, size);
|
|
||||||
|
|
||||||
return lgetxattr (full_path, name, buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
direct_fstat (struct ovl_layer *l, int fd, const char *path, struct stat *st)
|
|
||||||
{
|
|
||||||
return fstat (fd, st);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
direct_statat (struct ovl_layer *l, const char *path, struct stat *st, int flags)
|
|
||||||
{
|
|
||||||
return TEMP_FAILURE_RETRY (fstatat (l->fd, path, st, flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dirent *
|
|
||||||
direct_readdir (void *dirp)
|
|
||||||
{
|
|
||||||
return readdir (dirp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
direct_opendir (struct ovl_layer *l, const char *path)
|
|
||||||
{
|
|
||||||
cleanup_close int cleanup_fd = -1;
|
|
||||||
DIR *dp = NULL;
|
|
||||||
|
|
||||||
cleanup_fd = TEMP_FAILURE_RETRY (openat (l->fd, path, O_DIRECTORY));
|
|
||||||
if (cleanup_fd < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dp = fdopendir (cleanup_fd);
|
|
||||||
if (dp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
cleanup_fd = -1;
|
|
||||||
|
|
||||||
return dp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
direct_closedir (void *dirp)
|
|
||||||
{
|
|
||||||
return closedir (dirp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
direct_openat (struct ovl_layer *l, const char *path, int flags, mode_t mode)
|
|
||||||
{
|
|
||||||
return TEMP_FAILURE_RETRY (openat (l->fd, path, flags, mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
direct_readlinkat (struct ovl_layer *l, const char *path, char *buf, size_t bufsiz)
|
|
||||||
{
|
|
||||||
return TEMP_FAILURE_RETRY (readlinkat (l->fd, path, buf, bufsiz));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct data_source direct_access_ds =
|
|
||||||
{
|
|
||||||
.file_exists = direct_file_exists,
|
|
||||||
.statat = direct_statat,
|
|
||||||
.fstat = direct_fstat,
|
|
||||||
.opendir = direct_opendir,
|
|
||||||
.readdir = direct_readdir,
|
|
||||||
.closedir = direct_closedir,
|
|
||||||
.openat = direct_openat,
|
|
||||||
.getxattr = direct_getxattr,
|
|
||||||
.listxattr = direct_listxattr,
|
|
||||||
.readlinkat = direct_readlinkat,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct fuse_lowlevel_ops ovl_oper =
|
static struct fuse_lowlevel_ops ovl_oper =
|
||||||
{
|
{
|
||||||
.statfs = ovl_statfs,
|
.statfs = ovl_statfs,
|
||||||
@ -5228,6 +5044,9 @@ err_out2:
|
|||||||
fuse_session_destroy (se);
|
fuse_session_destroy (se);
|
||||||
err_out1:
|
err_out1:
|
||||||
|
|
||||||
|
for (tmp_layer = lo.layers; tmp_layer; tmp_layer = tmp_layer->next)
|
||||||
|
tmp_layer->ds->cleanup (tmp_layer);
|
||||||
|
|
||||||
node_mark_all_free (lo.root);
|
node_mark_all_free (lo.root);
|
||||||
|
|
||||||
hash_free (lo.inodes);
|
hash_free (lo.inodes);
|
||||||
|
124
utils.c
Normal file
124
utils.c
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/* fuse-overlayfs: Overlay Filesystem in Userspace
|
||||||
|
|
||||||
|
Copyright (C) 2019 Red Hat Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
file_exists_at (int dirfd, const char *pathname)
|
||||||
|
{
|
||||||
|
return faccessat (dirfd, pathname, F_OK, AT_SYMLINK_NOFOLLOW|AT_EACCESS);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
strconcat3 (char *dest, size_t size, const char *s1, const char *s2, const char *s3)
|
||||||
|
{
|
||||||
|
size_t t;
|
||||||
|
char *current = dest;
|
||||||
|
|
||||||
|
size--;
|
||||||
|
|
||||||
|
if (s1)
|
||||||
|
{
|
||||||
|
t = strlen (s1);
|
||||||
|
if (t > size)
|
||||||
|
t = size;
|
||||||
|
|
||||||
|
memcpy (current, s1, t);
|
||||||
|
current += t;
|
||||||
|
|
||||||
|
size -= t;
|
||||||
|
}
|
||||||
|
if (s2)
|
||||||
|
{
|
||||||
|
t = strlen (s2);
|
||||||
|
if (t > size)
|
||||||
|
t = size;
|
||||||
|
|
||||||
|
memcpy (current, s2, t);
|
||||||
|
current += t;
|
||||||
|
|
||||||
|
size -= t;
|
||||||
|
}
|
||||||
|
if (s3)
|
||||||
|
{
|
||||||
|
t = strlen (s3);
|
||||||
|
if (t > size)
|
||||||
|
t = size;
|
||||||
|
|
||||||
|
memcpy (current, s3, t);
|
||||||
|
current += t;
|
||||||
|
|
||||||
|
size -= t;
|
||||||
|
}
|
||||||
|
*current = '\0';
|
||||||
|
|
||||||
|
return current - dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_freep (void *p)
|
||||||
|
{
|
||||||
|
void **pp = (void **) p;
|
||||||
|
free (*pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_filep (FILE **f)
|
||||||
|
{
|
||||||
|
FILE *file = *f;
|
||||||
|
if (file)
|
||||||
|
(void) fclose (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_closep (void *p)
|
||||||
|
{
|
||||||
|
int *pp = p;
|
||||||
|
if (*pp >= 0)
|
||||||
|
close (*pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_dirp (DIR **p)
|
||||||
|
{
|
||||||
|
DIR *dir = *p;
|
||||||
|
if (dir)
|
||||||
|
closedir (dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
open_fd_or_get_path (struct ovl_layer *l, const char *path, char *out, int *fd, int flags)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
out[0] = '\0';
|
||||||
|
|
||||||
|
*fd = l->ds->openat (l, path, O_NONBLOCK|O_NOFOLLOW|flags, 0755);
|
||||||
|
if (*fd < 0 && (errno == ELOOP || errno == EISDIR))
|
||||||
|
{
|
||||||
|
strconcat3 (out, PATH_MAX, l->path, "/", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *fd;
|
||||||
|
}
|
40
utils.h
40
utils.h
@ -18,36 +18,22 @@
|
|||||||
#ifndef UTILS_H
|
#ifndef UTILS_H
|
||||||
# define UTILS_H
|
# define UTILS_H
|
||||||
|
|
||||||
void
|
# include <unistd.h>
|
||||||
cleanup_freep (void *p)
|
# include <stdio.h>
|
||||||
{
|
# include <sys/types.h>
|
||||||
void **pp = (void **) p;
|
# include <dirent.h>
|
||||||
free (*pp);
|
# include <stdlib.h>
|
||||||
}
|
# include "fuse-overlayfs.h"
|
||||||
|
|
||||||
void
|
void cleanup_freep (void *p);
|
||||||
cleanup_filep (FILE **f)
|
void cleanup_filep (FILE **f);
|
||||||
{
|
void cleanup_closep (void *p);
|
||||||
FILE *file = *f;
|
void cleanup_dirp (DIR **p);
|
||||||
if (file)
|
|
||||||
(void) fclose (file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
int file_exists_at (int dirfd, const char *pathname);
|
||||||
cleanup_closep (void *p)
|
|
||||||
{
|
|
||||||
int *pp = p;
|
|
||||||
if (*pp >= 0)
|
|
||||||
close (*pp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
int strconcat3 (char *dest, size_t size, const char *s1, const char *s2, const char *s3);
|
||||||
cleanup_dirp (DIR **p)
|
int open_fd_or_get_path (struct ovl_layer *l, const char *path, char *out, int *fd, int flags);
|
||||||
{
|
|
||||||
DIR *dir = *p;
|
|
||||||
if (dir)
|
|
||||||
closedir (dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define cleanup_file __attribute__((cleanup (cleanup_filep)))
|
# define cleanup_file __attribute__((cleanup (cleanup_filep)))
|
||||||
# define cleanup_free __attribute__((cleanup (cleanup_freep)))
|
# define cleanup_free __attribute__((cleanup (cleanup_freep)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user