From af32408ac10e0b2b3fafa1eecdd43773915d3904 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Fri, 1 Mar 2019 21:24:31 +0100 Subject: [PATCH] CODING_STYLE: update Signed-off-by: Christian Brauner --- CODING_STYLE.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/CODING_STYLE.md b/CODING_STYLE.md index 54ac6d4ad..fb5022c49 100644 --- a/CODING_STYLE.md +++ b/CODING_STYLE.md @@ -662,3 +662,123 @@ int lxc_attach_run_command(void *payload) return ret; } ``` + +## 24) Never use `fgets()` + +LXC does not allow the use of `fgets()`. Use `getline()` or other methods +instead. + +## 25) Never allocate memory on the stack + +This specifically forbids any usage of `alloca()` in the codebase. + +## 26) Use cleanup macros supported by `gcc` and `clang` + +LXC has switched from manually cleaning up resources to using cleanup macros +supported by `gcc` and `clang`: +```c +__attribute__((__cleanup__())) +``` +We do not allow manually cleanups anymore if there are appropriate macros. +Currently the following macros are supported: +```c +/* close file descriptor */ +__do_close_prot_errno + +/* free allocated memory */ +__do_free __attribute__((__cleanup__(__auto_free__))) + +/* close FILEs */ +__do_fclose __attribute__((__cleanup__(__auto_fclose__))) + +/* close DIRs */ +__do_closedir __attribute__((__cleanup__(__auto_closedir__))) +``` +For example: +```c +void remount_all_slave(void) +{ + __do_free char *line = NULL; + __do_fclose FILE *f = NULL; + __do_close_prot_errno int memfd = -EBADF, mntinfo_fd = -EBADF; + int ret; + ssize_t copied; + size_t len = 0; + + mntinfo_fd = open("/proc/self/mountinfo", O_RDONLY | O_CLOEXEC); + if (mntinfo_fd < 0) { + SYSERROR("Failed to open \"/proc/self/mountinfo\""); + return; + } + + memfd = memfd_create(".lxc_mountinfo", MFD_CLOEXEC); + if (memfd < 0) { + char template[] = P_tmpdir "/.lxc_mountinfo_XXXXXX"; + + if (errno != ENOSYS) { + SYSERROR("Failed to create temporary in-memory file"); + return; + } + + memfd = lxc_make_tmpfile(template, true); + if (memfd < 0) { + WARN("Failed to create temporary file"); + return; + } + } + +again: + copied = lxc_sendfile_nointr(memfd, mntinfo_fd, NULL, LXC_SENDFILE_MAX); + if (copied < 0) { + if (errno == EINTR) + goto again; + + SYSERROR("Failed to copy \"/proc/self/mountinfo\""); + return; + } + + ret = lseek(memfd, 0, SEEK_SET); + if (ret < 0) { + SYSERROR("Failed to reset file descriptor offset"); + return; + } + + f = fdopen(memfd, "r"); + if (!f) { + SYSERROR("Failed to open copy of \"/proc/self/mountinfo\" to mark all shared. Continuing"); + return; + } + + /* + * After a successful fdopen() memfd will be closed when calling + * fclose(f). Calling close(memfd) afterwards is undefined. + */ + move_fd(memfd); + + while (getline(&line, &len, f) != -1) { + char *opts, *target; + + target = get_field(line, 4); + if (!target) + continue; + + opts = get_field(target, 2); + if (!opts) + continue; + + null_endofword(opts); + if (!strstr(opts, "shared")) + continue; + + null_endofword(target); + ret = mount(NULL, target, NULL, MS_SLAVE, NULL); + if (ret < 0) { + SYSERROR("Failed to make \"%s\" MS_SLAVE", target); + ERROR("Continuing..."); + continue; + } + TRACE("Remounted \"%s\" as MS_SLAVE", target); + } + TRACE("Remounted all mount table entries as MS_SLAVE"); +} +``` -- 2.47.2