static void save_initpid(struct stat *sb, pid_t pid)
{
__do_free struct pidns_init_store *entry = NULL;
- __do_close_prot_errno int pidfd = -EBADF;
+ __do_close int pidfd = -EBADF;
char path[LXCFS_PROC_PID_LEN];
struct lxcfs_opts *opts = fuse_get_context()->private_data;
struct stat st;
*/
static void write_task_init_pid_exit(int sock, pid_t target)
{
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
char path[LXCFS_PROC_PID_NS_LEN];
pid_t pid;
static int pivot_enter()
{
- __do_close_prot_errno int oldroot = -EBADF, newroot = -EBADF;
+ __do_close int oldroot = -EBADF, newroot = -EBADF;
oldroot = open("/", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
if (oldroot < 0)
static void __attribute__((constructor)) lxcfs_init(void)
{
- __do_close_prot_errno int init_ns = -EBADF, root_fd = -EBADF,
+ __do_close int init_ns = -EBADF, root_fd = -EBADF,
pidfd = -EBADF;
int i = 0;
pid_t pid;
#include "cgroup2_devices.h"
#include "cgroup_utils.h"
-static void free_string_list(char **clist)
-{
- int i;
-
- if (!clist)
- return;
-
- for (i = 0; clist[i]; i++)
- free(clist[i]);
-
- free(clist);
-}
-
/* Given a pointer to a null-terminated array of pointers, realloc to add one
* entry, and point the new entry to NULL. Do not fail. Return the index to the
* second-to-last entry - that is, the one which is now available for use
static int cgfsng_get_cpuset_cpus(struct cgroup_ops *ops, const char *cgroup,
char **value)
{
- __do_close_prot_errno int cgroup_fd = -EBADF;
+ __do_close int cgroup_fd = -EBADF;
__do_free char *path = NULL;
char *v;
struct hierarchy *h;
const char *path, uint32_t flags)
{
__do_free char *copy = NULL;
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
union bpf_attr attr;
int ret;
int bpf_program_cgroup_detach(struct bpf_program *prog)
{
int ret;
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
if (!prog)
return 0;
*/
static int open_if_safe(int dirfd, const char *nextpath)
{
- __do_close_prot_errno int newfd = -EBADF;
+ __do_close int newfd = -EBADF;
newfd = openat(dirfd, nextpath, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
if (newfd >= 0) /* Was not a symlink, all good. */
*/
static int open_without_symlink(const char *target, const char *prefix_skip)
{
- __do_close_prot_errno int dirfd = -EBADF;
+ __do_close int dirfd = -EBADF;
__do_free char *dup = NULL;
int curlen = 0, fulllen, i;
int safe_mount(const char *src, const char *dest, const char *fstype,
unsigned long flags, const void *data, const char *rootfs)
{
- __do_close_prot_errno int destfd = -EBADF, srcfd = -EBADF;
+ __do_close int destfd = -EBADF, srcfd = -EBADF;
int ret;
/* Only needs enough for /proc/self/fd/<fd>. */
char srcbuf[50], destbuf[50];
FILE *fopen_cloexec(const char *path, const char *mode)
{
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
__do_fclose FILE *ret = NULL;
int open_mode = 0;
int step = 0;
char *readat_file(int dirfd, const char *path)
{
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
__do_free char *line = NULL;
__do_fclose FILE *f = NULL;
char *buf = NULL;
static int set_pidfile(char *pidfile)
{
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
char buf[INTTYPE_TO_STRLEN(long)];
int ret;
struct flock fl = {
int main(int argc, char *argv[])
{
- __do_close_prot_errno int pidfile_fd = -EBADF;
+ int pidfile_fd = -EBADF;
int ret = EXIT_FAILURE;
char *pidfile = NULL, *saveptr = NULL, *token = NULL, *v = NULL;
char pidfile_buf[STRLITERALLEN(RUNTIME_PATH) + STRLITERALLEN("/lxcfs.pid") + 1] = {};
dlclose(dlopen_handle);
if (pidfile)
unlink(pidfile);
+ close_prot_errno_disarm(pidfile_fd);
exit(ret);
}
? 20 \
: sizeof(int[-2 * (sizeof(type) > 8)])))
+#define move_ptr(ptr) \
+ ({ \
+ typeof(ptr) __internal_ptr__ = (ptr); \
+ (ptr) = NULL; \
+ __internal_ptr__; \
+ })
+
+#define move_fd(fd) \
+ ({ \
+ int __internal_fd__ = (fd); \
+ (fd) = -EBADF; \
+ __internal_fd__; \
+ })
+
#define ret_errno(__errno__) \
({ \
errno = __errno__; \
#ifndef __LXCFS_MEMORY_UTILS_H
#define __LXCFS_MEMORY_UTILS_H
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#ifndef FUSE_USE_VERSION
-#define FUSE_USE_VERSION 26
-#endif
-
-#define _FILE_OFFSET_BITS 64
-
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <unistd.h>
-#include "config.h"
#include "macro.h"
-static inline void __auto_free__(void *p)
-{
- free(*(void **)p);
-}
-
-static inline void __auto_fclose__(FILE **f)
-{
- if (*f)
- fclose(*f);
-}
+#define define_cleanup_function(type, cleaner) \
+ static inline void cleaner##_function(type *ptr) \
+ { \
+ if (*ptr) \
+ cleaner(*ptr); \
+ }
-static inline void __auto_closedir__(DIR **d)
-{
- if (*d)
- closedir(*d);
-}
+#define call_cleaner(cleaner) __attribute__((__cleanup__(cleaner##_function)))
#define close_prot_errno_disarm(fd) \
if (fd >= 0) { \
}
#define close_prot_errno_replace(fd, new_fd) \
- if (fd >= 0) { \
- int _e_ = errno; \
- close(fd); \
- errno = _e_; \
- fd = new_fd; \
- }
+ if (fd >= 0) { \
+ int _e_ = errno; \
+ close(fd); \
+ errno = _e_; \
+ fd = new_fd; \
+ }
+
+static inline void close_prot_errno_disarm_function(int *fd)
+{
+ close_prot_errno_disarm(*fd);
+}
+#define __do_close call_cleaner(close_prot_errno_disarm)
+
+define_cleanup_function(FILE *, fclose);
+#define __do_fclose call_cleaner(fclose)
+
+define_cleanup_function(DIR *, closedir);
+#define __do_closedir call_cleaner(closedir)
#define free_disarm(ptr) \
({ \
move_ptr(ptr); \
})
-static inline void __auto_close__(int *fd)
+static inline void free_disarm_function(void *ptr)
{
- close_prot_errno_disarm(*fd);
+ free_disarm(*(void **)ptr);
}
+#define __do_free call_cleaner(free_disarm)
-#define __do_close_prot_errno __attribute__((__cleanup__(__auto_close__)))
-#define __do_free __attribute__((__cleanup__(__auto_free__)))
-#define __do_fclose __attribute__((__cleanup__(__auto_fclose__)))
-#define __do_closedir __attribute__((__cleanup__(__auto_closedir__)))
+static inline void free_string_list(char **list)
+{
+ if (list) {
+ for (int i = 0; list[i]; i++)
+ free(list[i]);
+ free_disarm(list);
+ }
+}
+define_cleanup_function(char **, free_string_list);
+#define __do_free_string_list call_cleaner(free_string_list)
-#define move_ptr(ptr) \
- ({ \
- typeof(ptr) __internal_ptr__ = (ptr); \
- (ptr) = NULL; \
- __internal_ptr__; \
- })
+static inline void *memdup(const void *data, size_t len)
+{
+ void *copy = NULL;
-#define move_fd(fd) \
- ({ \
- int __internal_fd__ = (fd); \
- (fd) = -EBADF; \
- __internal_fd__; \
- })
+ copy = len ? malloc(len) : NULL;
+ return copy ? memcpy(copy, data, len) : NULL;
+}
#define zalloc(__size__) (calloc(1, __size__))
/* Note that "memory.stat" in cgroup2 is hierarchical by default. */
static bool cgroup_parse_memory_stat(const char *cgroup, struct memory_stat *mstat)
{
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
__do_fclose FILE *f = NULL;
__do_free char *line = NULL;
__do_free void *fdopen_cache = NULL;
{
__do_free char *path = NULL;
__do_free void *fdopen_cache = NULL;
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
__do_fclose FILE *f = NULL;
__do_closedir DIR *dir = NULL;
struct dirent *file;
*/
static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
{
- __do_close_prot_errno int ns_fd1 = -1, ns_fd2 = -1;
+ __do_close int ns_fd1 = -1, ns_fd2 = -1;
int ret = -1;
struct stat ns_st1, ns_st2;
bool wait_for_sock(int sock, int timeout)
{
- __do_close_prot_errno int epfd = -EBADF;
+ __do_close int epfd = -EBADF;
struct epoll_event ev;
int ret, now, starttime, deltatime;
static char *file_to_buf(const char *path, size_t *length)
{
- __do_close_prot_errno int fd = -EBADF;
+ __do_close int fd = -EBADF;
if (!length)
return NULL;