#include <sys/un.h>
#include "log.h"
-#include "lxclock.h"
lxc_log_define(lxc_af_unix, lxc);
if (flags & O_TRUNC)
unlink(path);
- process_lock();
fd = socket(PF_UNIX, type, 0);
- process_unlock();
if (fd < 0)
return -1;
len = strlen(&path[1]) + 1;
if (len >= sizeof(addr.sun_path) - 1) {
- process_lock();
close(fd);
- process_unlock();
errno = ENAMETOOLONG;
return -1;
}
if (bind(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len)) {
int tmp = errno;
- process_lock();
close(fd);
- process_unlock();
errno = tmp;
return -1;
}
if (type == SOCK_STREAM && listen(fd, 100)) {
int tmp = errno;
- process_lock();
close(fd);
- process_unlock();
errno = tmp;
return -1;
}
addr.sun_path[0])
unlink(addr.sun_path);
- process_lock();
close(fd);
- process_unlock();
return 0;
}
size_t len;
struct sockaddr_un addr;
- process_lock();
fd = socket(PF_UNIX, SOCK_STREAM, 0);
- process_unlock();
if (fd < 0)
return -1;
len = strlen(&path[1]) + 1;
if (len >= sizeof(addr.sun_path) - 1) {
- process_lock();
close(fd);
- process_unlock();
errno = ENAMETOOLONG;
return -1;
}
/* special case to connect to older containers */
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0)
return fd;
- process_lock();
close(fd);
- process_unlock();
errno = tmp;
return -1;
}
/* read capabilities */
snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", pid);
- process_lock();
proc_file = fopen(proc_fn, "r");
- process_unlock();
if (!proc_file) {
SYSERROR("Could not open %s", proc_fn);
goto out_error;
if (line)
free(line);
- process_lock();
fclose(proc_file);
- process_unlock();
if (!found) {
SYSERROR("Could not read capability bounding set from %s", proc_fn);
/* read personality */
snprintf(proc_fn, MAXPATHLEN, "/proc/%d/personality", pid);
- process_lock();
proc_file = fopen(proc_fn, "r");
- process_unlock();
if (!proc_file) {
SYSERROR("Could not open %s", proc_fn);
goto out_error;
}
ret = fscanf(proc_file, "%lx", &info->personality);
- process_lock();
fclose(proc_file);
- process_unlock();
if (ret == EOF || ret == 0) {
SYSERROR("Could not read personality from %s", proc_fn);
}
snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]);
- process_lock();
fd[i] = open(path, O_RDONLY | O_CLOEXEC);
- process_unlock();
if (fd[i] < 0) {
saved_errno = errno;
/* close all already opened file descriptors before
* we return an error, so we don't leak them
*/
- process_lock();
for (j = 0; j < i; j++)
close(fd[j]);
- process_unlock();
errno = saved_errno;
SYSERROR("failed to open '%s'", path);
return -1;
}
- process_lock();
close(fd[i]);
- process_unlock();
}
return 0;
* getent program, and we need to capture its
* output, so we use a pipe for that purpose
*/
- process_lock();
ret = pipe(pipes);
- process_unlock();
if (ret < 0)
return NULL;
pid = fork();
if (pid < 0) {
- process_lock();
close(pipes[0]);
close(pipes[1]);
- process_unlock();
return NULL;
}
int found = 0;
int status;
- process_lock();
close(pipes[1]);
- process_unlock();
- process_lock();
pipe_f = fdopen(pipes[0], "r");
- process_unlock();
while (getline(&line, &line_bufsz, pipe_f) != -1) {
char *token;
char *saveptr = NULL;
}
free(line);
- process_lock();
fclose(pipe_f);
- process_unlock();
again:
if (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR)
* close socket close socket
* run program
*/
- process_lock();
ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
- process_unlock();
if (ret < 0) {
SYSERROR("could not set up required IPC mechanism for attaching");
free(cwd);
/* inital thread, we close the socket that is for the
* subprocesses
*/
- process_lock();
close(ipc_sockets[1]);
- process_unlock();
free(cwd);
/* get pid from intermediate process */
/* now shut down communication with child, we're done */
shutdown(ipc_sockets[0], SHUT_RDWR);
- process_lock();
close(ipc_sockets[0]);
- process_unlock();
lxc_proc_put_context_info(init_ctx);
/* we're done, the child process should now execute whatever
* otherwise the pid we're waiting for may never exit
*/
shutdown(ipc_sockets[0], SHUT_RDWR);
- process_lock();
close(ipc_sockets[0]);
- process_unlock();
if (to_cleanup_pid)
(void) wait_for_pid(to_cleanup_pid);
lxc_proc_put_context_info(init_ctx);
if (strcmp(bdev->type, "loop") == 0)
path = bdev->src + 5;
- process_lock();
fd = open(path, O_RDONLY);
- process_unlock();
if (fd < 0)
return -1;
ret = ioctl(fd, BLKGETSIZE64, size);
- process_lock();
close(fd);
- process_unlock();
return ret;
}
if (strcmp(bdev->type, "loop") == 0)
srcdev = bdev->src + 5;
- process_lock();
ret = pipe(p);
- process_unlock();
if (ret < 0)
return -1;
if ((pid = fork()) < 0)
return -1;
if (pid > 0) {
int status;
- process_lock();
close(p[1]);
- process_unlock();
memset(type, 0, len);
ret = read(p[0], type, len-1);
- process_lock();
close(p[0]);
- process_unlock();
if (ret < 0) {
SYSERROR("error reading from pipe");
wait(&status);
struct lxc_popen_FILE *f;
int found=0;
- process_lock();
f = lxc_popen("zfs list 2> /dev/null");
- process_unlock();
if (f == NULL) {
SYSERROR("popen failed");
return 0;
break;
}
}
- process_lock();
(void) lxc_pclose(f);
- process_unlock();
return found;
}
ERROR("lvm uuid pathname too long");
return 0;
}
- process_lock();
fout = fopen(devp, "r");
- process_unlock();
if (!fout)
return 0;
ret = fread(buf, 1, 4, fout);
- process_lock();
fclose(fout);
- process_unlock();
if (ret != 4 || strncmp(buf, "LVM-", 4) != 0)
return 0;
return 1;
if (ret < 0 || ret >= len)
return -1;
- process_lock();
f = lxc_popen(cmd);
- process_unlock();
if (f == NULL) {
SYSERROR("popen failed");
ret = fgets(output, 12, f->f) == NULL;
- process_lock();
status = lxc_pclose(f);
- process_unlock();
if (ret || WEXITSTATUS(status))
// Assume either vg or lvs do not exist, default
struct btrfs_ioctl_space_args sargs;
// make sure this is a btrfs filesystem
- process_lock();
fd = open(path, O_RDONLY);
- process_unlock();
if (fd < 0)
return false;
sargs.space_slots = 0;
sargs.total_spaces = 0;
ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, &sargs);
- process_lock();
close(fd);
- process_unlock();
if (ret < 0)
return false;
}
*p = '\0';
- process_lock();
fd = open(newfull, O_RDONLY);
- process_unlock();
if (fd < 0) {
ERROR("Error opening %s", newfull);
free(newfull);
INFO("btrfs: snapshot create ioctl returned %d", ret);
free(newfull);
- process_lock();
close(fd);
- process_unlock();
return ret;
}
}
newname = basename(newfull);
newdir = dirname(newfull);
- process_lock();
fd = open(orig, O_RDONLY);
- fddst = open(newdir, O_RDONLY);
- process_unlock();
if (fd < 0) {
SYSERROR("Error opening original rootfs %s", orig);
goto out;
}
+ fddst = open(newdir, O_RDONLY);
if (fddst < 0) {
SYSERROR("Error opening new container dir %s", newdir);
goto out;
INFO("btrfs: snapshot create ioctl returned %d", ret);
out:
- process_lock();
if (fddst != -1)
close(fddst);
if (fd != -1)
close(fd);
- process_unlock();
if (newfull)
free(newfull);
return ret;
}
*p = '\0';
- process_lock();
fd = open(newfull, O_RDONLY);
- process_unlock();
if (fd < 0) {
ERROR("Error opening %s", newfull);
free(newfull);
INFO("btrfs: snapshot create ioctl returned %d", ret);
free(newfull);
- process_lock();
close(fd);
- process_unlock();
return ret;
}
DIR *dir;
int fd = -1;
- process_lock();
dir = opendir("/dev");
- process_unlock();
if (!dir) {
SYSERROR("Error opening /dev");
return -1;
break;
if (strncmp(direntp->d_name, "loop", 4) != 0)
continue;
- process_lock();
fd = openat(dirfd(dir), direntp->d_name, O_RDWR);
- process_unlock();
if (fd < 0)
continue;
if (ioctl(fd, LOOP_GET_STATUS64, &lo) == 0 || errno != ENXIO) {
- process_lock();
close(fd);
- process_unlock();
fd = -1;
continue;
}
snprintf(namep, 100, "/dev/%s", direntp->d_name);
break;
}
- process_lock();
closedir(dir);
- process_unlock();
if (fd == -1) {
ERROR("No loop device found");
return -1;
if (find_free_loopdev(&lfd, loname) < 0)
return -22;
- process_lock();
ffd = open(bdev->src + 5, O_RDWR);
- process_unlock();
if (ffd < 0) {
SYSERROR("Error opening backing file %s\n", bdev->src);
goto out;
bdev->lofd = lfd;
out:
- process_lock();
if (ffd > -1)
close(ffd);
if (ret < 0) {
close(lfd);
bdev->lofd = -1;
}
- process_unlock();
return ret;
}
return -22;
ret = umount(bdev->dest);
if (bdev->lofd >= 0) {
- process_lock();
close(bdev->lofd);
- process_unlock();
bdev->lofd = -1;
}
return ret;
{
int fd, ret;
// create the new loopback file.
- process_lock();
fd = creat(path, S_IRUSR|S_IWUSR);
- process_unlock();
if (fd < 0)
return -1;
if (lseek(fd, size, SEEK_SET) < 0) {
close(fd);
return -1;
}
- process_lock();
ret = close(fd);
- process_unlock();
if (ret < 0) {
SYSERROR("Error closing new loop file");
return -1;
#include "config.h"
#include "log.h"
-#include "lxclock.h"
lxc_log_define(lxc_caps, lxc);
/* try to get the maximum capability over the kernel
* interface introduced in v3.2 */
- process_lock();
fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
- process_unlock();
if (fd >= 0) {
char buf[32];
char *ptr;
result = -1;
}
- process_lock();
close(fd);
- process_unlock();
}
/* try to get it manually by trying to get the status of
#include "conf.h"
#include "utils.h"
#include "bdev.h"
-#include "lxclock.h"
#include <lxc/log.h>
#include <lxc/cgroup.h>
size_t kernel_subsystems_capacity = 0;
int r;
- process_lock();
proc_cgroups = fopen_cloexec("/proc/cgroups", "r");
- process_unlock();
if (!proc_cgroups)
return false;
bret = true;
out:
- process_lock();
fclose(proc_cgroups);
- process_unlock();
free(line);
return bret;
}
bool bret = false;
size_t hierarchy_capacity = 0;
- process_lock();
proc_self_cgroup = fopen_cloexec("/proc/self/cgroup", "r");
/* if for some reason (because of setns() and pid namespace for example),
* /proc/self is not valid, we try /proc/1/cgroup... */
if (!proc_self_cgroup)
proc_self_cgroup = fopen_cloexec("/proc/1/cgroup", "r");
- process_unlock();
if (!proc_self_cgroup)
return false;
bret = true;
out:
- process_lock();
fclose(proc_self_cgroup);
- process_unlock();
free(line);
return bret;
}
size_t token_capacity = 0;
int r;
- process_lock();
proc_self_mountinfo = fopen_cloexec("/proc/self/mountinfo", "r");
/* if for some reason (because of setns() and pid namespace for example),
* /proc/self is not valid, we try /proc/1/cgroup... */
if (!proc_self_mountinfo)
proc_self_mountinfo = fopen_cloexec("/proc/1/mountinfo", "r");
- process_unlock();
if (!proc_self_mountinfo)
return false;
bret = true;
out:
- process_lock();
fclose(proc_self_mountinfo);
- process_unlock();
free(tokens);
free(line);
return bret;
struct cgroup_process_info **cptr = &result;
struct cgroup_process_info *entry = NULL;
- process_lock();
proc_pid_cgroup = fopen_cloexec(proc_pid_cgroup_str, "r");
- process_unlock();
if (!proc_pid_cgroup)
return NULL;
entry = NULL;
}
- process_lock();
fclose(proc_pid_cgroup);
- process_unlock();
free(line);
return result;
out_error:
saved_errno = errno;
- process_lock();
if (proc_pid_cgroup)
fclose(proc_pid_cgroup);
- process_unlock();
lxc_cgroup_process_info_free(result);
lxc_cgroup_process_info_free(entry);
free(line);
return false;
}
- process_lock();
devices_list = fopen_cloexec(path, "r");
- process_unlock();
if (!devices_list) {
free(path);
return false;
}
out:
- process_lock();
fclose(devices_list);
- process_unlock();
free(line);
free(path);
return ret;
if (!dent_buf)
return -1;
- process_lock();
d = opendir(cgroup_path);
- process_unlock();
if (!d) {
free(dent_buf);
return 0;
continue;
sub_path = lxc_string_join("/", parts, false);
if (!sub_path) {
- process_lock();
closedir(d);
- process_unlock();
free(dent_buf);
return -1;
}
r = stat(sub_path, &st);
if (r < 0) {
- process_lock();
closedir(d);
- process_unlock();
free(dent_buf);
free(sub_path);
return -1;
}
free(sub_path);
}
- process_lock();
closedir(d);
- process_unlock();
free(dent_buf);
return n;
size_t sz = 0;
int n = 0;
- process_lock();
f = fopen_cloexec(fn, "r");
- process_unlock();
if (!f)
return -1;
n++;
}
free(line);
- process_lock();
fclose(f);
- process_unlock();
return n;
}
#include "mainloop.h"
#include "af_unix.h"
#include "config.h"
-#include "lxclock.h"
/*
* This file provides the different functions for clients to
{
lxc_console_free(handler->conf, fd);
lxc_mainloop_del_handler(descr, fd);
- process_lock();
close(fd);
- process_unlock();
}
static int lxc_cmd_handler(int fd, uint32_t events, void *data,
{
int opt = 1, ret = -1, connection;
- process_lock();
connection = accept(fd, NULL, 0);
- process_unlock();
if (connection < 0) {
SYSERROR("failed to accept connection");
return -1;
return ret;
out_close:
- process_lock();
close(connection);
- process_unlock();
goto out;
}
if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
SYSERROR("failed to set sigfd to close-on-exec");
- process_lock();
close(fd);
- process_unlock();
return -1;
}
ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler);
if (ret) {
ERROR("failed to add handler for command socket");
- process_lock();
close(fd);
- process_unlock();
}
return ret;
char *output;
int ret;
- process_lock();
f = lxc_popen(buffer);
- process_unlock();
if (!f) {
SYSERROR("popen failed");
return -1;
output = malloc(LXC_LOG_BUFFER_SIZE);
if (!output) {
ERROR("failed to allocate memory for script output");
- process_lock();
lxc_pclose(f);
- process_unlock();
return -1;
}
free(output);
- process_lock();
ret = lxc_pclose(f);
- process_unlock();
if (ret == -1) {
SYSERROR("Script exited on error");
return -1;
int rfd;
int ret = -1;
- process_lock();
rfd = open(rootfs, O_RDWR);
- process_unlock();
if (rfd < 0) {
SYSERROR("failed to open '%s'", rootfs);
return -1;
ret = 0;
out:
- process_lock();
close(rfd);
- process_unlock();
return ret;
}
DIR *dir;
char path[MAXPATHLEN];
- process_lock();
dir = opendir("/dev");
- process_unlock();
if (!dir) {
SYSERROR("failed to open '/dev'");
return -1;
if (rc < 0 || rc >= MAXPATHLEN)
continue;
- process_lock();
fd = open(path, O_RDWR);
- process_unlock();
if (fd < 0)
continue;
if (ioctl(fd, LOOP_GET_STATUS64, &loinfo) == 0) {
- process_lock();
close(fd);
- process_unlock();
continue;
}
if (errno != ENXIO) {
WARN("unexpected error for ioctl on '%s': %m",
direntp->d_name);
- process_lock();
close(fd);
- process_unlock();
continue;
}
ret = setup_lodev(rootfs, fd, &loinfo);
if (!ret)
ret = mount_unknow_fs(path, target, 0);
- process_lock();
close(fd);
- process_unlock();
break;
}
- process_lock();
if (closedir(dir))
WARN("failed to close directory");
- process_unlock();
return ret;
}
if (ret >= MAXPATHLEN)
return -1;
- process_lock();
fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR);
- process_unlock();
if (fd < 0)
return fd;
(void)unlink(absrootfspin);
ERROR("pathname too long for ttys");
return -1;
}
- process_lock();
ret = creat(lxcpath, 0660);
- process_unlock();
if (ret==-1 && errno != EEXIST) {
SYSERROR("error creating %s\n", lxcpath);
return -1;
}
- process_lock();
if (ret >= 0)
close(ret);
- process_unlock();
ret = unlink(path);
if (ret && errno != ENOENT) {
SYSERROR("error unlinking %s\n", path);
} else {
/* If we populated /dev, then we need to create /dev/ttyN */
if (access(path, F_OK)) {
- process_lock();
ret = creat(path, 0660);
- process_unlock();
if (ret==-1) {
SYSERROR("error creating %s\n", path);
/* this isn't fatal, continue */
} else {
- process_lock();
close(ret);
- process_unlock();
}
}
if (mount(pty_info->name, path, "none", MS_BIND, 0)) {
return 0;
}
- process_lock();
f = fopen("/proc/self/mounts", "r");
- process_unlock();
if (!f)
return 0;
while ((p = fgets(buf, LINELEN, f))) {
}
}
- process_lock();
fclose(f);
- process_unlock();
DEBUG("mount_check_fs returning %d last %s\n", found_fs, fstype);
int i;
char *p2;
- process_lock();
f = fopen("/proc/self/mountinfo", "r");
- process_unlock();
if (!f)
return 0;
while ((p = fgets(buf, LINELEN, f))) {
// this is '/'. is it shared?
p = index(p2+1, ' ');
if (p && strstr(p, "shared:")) {
- process_lock();
fclose(f);
- process_unlock();
return 1;
}
}
}
- process_lock();
fclose(f);
- process_unlock();
return 0;
}
return -1;
}
- process_lock();
ret = creat(lxcpath, 0660);
- process_unlock();
if (ret==-1 && errno != EEXIST) {
SYSERROR("error %d creating %s\n", errno, lxcpath);
return -1;
}
- process_lock();
if (ret >= 0)
close(ret);
- process_unlock();
if (console->master < 0) {
INFO("no console");
if (!fstab)
return 0;
- process_lock();
file = setmntent(fstab, "r");
- process_unlock();
if (!file) {
SYSERROR("failed to use '%s'", fstab);
return -1;
ret = mount_file_entries(rootfs, file, lxc_name);
- process_lock();
endmntent(file);
- process_unlock();
return ret;
}
char *mount_entry;
int ret;
- process_lock();
file = tmpfile();
- process_unlock();
if (!file) {
ERROR("tmpfile error: %m");
return -1;
ret = mount_file_entries(rootfs, file, lxc_name);
- process_lock();
fclose(file);
- process_unlock();
return ret;
}
ifr.ifr_name[IFNAMSIZ-1] = '\0';
memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr));
- process_lock();
fd = socket(AF_INET, SOCK_DGRAM, 0);
- process_unlock();
if (fd < 0) {
ERROR("socket failure : %s", strerror(errno));
return -1;
}
ret = ioctl(fd, SIOCSIFHWADDR, &ifr);
- process_lock();
close(fd);
- process_unlock();
if (ret)
ERROR("ioctl failure : %s", strerror(errno));
fprintf(stderr, "%s: path name too long", __func__);
return -E2BIG;
}
- process_lock();
f = fopen(path, "w");
- process_unlock();
if (!f) {
perror("open");
return -EINVAL;
ret = fwrite(buf, buf_size, 1, f);
if (ret < 0)
SYSERROR("writing id mapping");
- process_lock();
closeret = fclose(f);
- process_unlock();
if (closeret)
SYSERROR("writing id mapping");
return ret < 0 ? ret : closeret;
for (i = 0; i < tty_info->nbtty; i++) {
struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
- process_lock();
close(pty_info->master);
close(pty_info->slave);
- process_unlock();
}
free(tty_info->pty_info);
int p[2];
struct lxc_list *idmap;
- process_lock();
ret = pipe(p);
- process_unlock();
if (ret < 0) {
SYSERROR("opening pipe");
return -1;
pid = lxc_clone(run_userns_fn, &d, CLONE_NEWUSER);
if (pid < 0)
goto err;
- process_lock();
close(p[0]);
- process_unlock();
p[0] = -1;
if ((idmap = idmap_add_id(conf, geteuid())) == NULL) {
goto err;
}
err:
- process_lock();
if (p[0] != -1)
close(p[0]);
close(p[1]);
- process_unlock();
return -1;
}
static void lxc_console_sigwinch_fini(struct lxc_tty_state *ts)
{
if (ts->sigfd >= 0) {
- process_lock();
close(ts->sigfd);
- process_unlock();
}
lxc_list_del(&ts->node);
sigprocmask(SIG_SETMASK, &ts->oldmask, NULL);
if (!r) {
INFO("console client on fd %d has exited", fd);
lxc_mainloop_del_handler(descr, fd);
- process_lock();
close(fd);
- process_unlock();
return 0;
}
lxc_console_sigwinch_fini(console->tty_state);
console->tty_state = NULL;
}
- process_lock();
close(console->peerpty.master);
close(console->peerpty.slave);
- process_unlock();
console->peerpty.master = -1;
console->peerpty.slave = -1;
console->peerpty.busy = -1;
*/
if (!path && !access("/dev/tty", F_OK)) {
int fd;
- process_lock();
fd = open("/dev/tty", O_RDWR);
if (fd >= 0) {
close(fd);
path = "/dev/tty";
}
- process_unlock();
}
if (!path)
goto out;
DEBUG("opening %s for console peer", path);
- process_lock();
console->peer = lxc_unpriv(open(path, O_CLOEXEC | O_RDWR | O_CREAT |
O_APPEND, 0600));
- process_unlock();
if (console->peer < 0)
goto out;
free(console->tios);
console->tios = NULL;
err1:
- process_lock();
close(console->peer);
- process_unlock();
console->peer = -1;
out:
DEBUG("no console peer");
free(console->tios);
console->tios = NULL;
- process_lock();
close(console->peer);
close(console->master);
close(console->slave);
if (console->log_fd >= 0)
close(console->log_fd);
- process_unlock();
console->peer = -1;
console->master = -1;
lxc_console_peer_default(console);
if (console->log_path) {
- process_lock();
console->log_fd = lxc_unpriv(open(console->log_path,
O_CLOEXEC | O_RDWR |
O_CREAT | O_APPEND, 0600));
- process_unlock();
if (console->log_fd < 0) {
SYSERROR("failed to open '%s'", console->log_path);
goto err;
err3:
lxc_console_sigwinch_fini(ts);
err2:
- process_lock();
close(masterfd);
close(ttyfd);
- process_unlock();
err1:
tcsetattr(stdinfd, TCSAFLUSH, &oldtios);
#include "error.h"
#include "state.h"
#include "monitor.h"
-#include "lxclock.h"
#include <lxc/log.h>
#include <lxc/cgroup.h>
return -1;
}
- process_lock();
fd = open(freezer, O_RDWR);
- process_unlock();
if (fd < 0) {
SYSERROR("failed to open freezer at '%s'", nsgroup);
return -1;
}
out:
- process_lock();
close(fd);
- process_unlock();
return ret;
}
#include "log.h"
#include "caps.h"
#include "utils.h"
-#include "lxclock.h"
#define LXC_LOG_PREFIX_SIZE 32
#define LXC_LOG_BUFFER_SIZE 512
int fd;
int newfd;
- process_lock();
fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY |
O_APPEND | O_CLOEXEC, 0666));
- process_unlock();
if (fd == -1) {
ERROR("failed to open log file \"%s\" : %s", name,
strerror(errno));
if (newfd == -1)
ERROR("failed to dup log fd %d : %s", fd, strerror(errno));
- process_lock();
close(fd);
- process_unlock();
return newfd;
}
{
if (lxc_log_fd != -1) {
// we are overriding the default.
- process_lock();
close(lxc_log_fd);
- process_unlock();
free(log_fname);
}
#include <sys/mount.h>
#include <sys/apparmor.h>
#include "log.h"
-#include "lxclock.h"
#include "lsm/lsm.h"
lxc_log_define(lxc_apparmor, lxc);
ret = stat(AA_MOUNT_RESTR, &statbuf);
if (ret != 0)
return 0;
- process_lock();
fin = fopen(AA_ENABLED_FILE, "r");
- process_unlock();
if (!fin)
return 0;
ret = fscanf(fin, "%c", &e);
- process_lock();
fclose(fin);
- process_unlock();
if (ret == 1 && e == 'Y')
return 1;
return 0;
return NULL;
}
again:
- process_lock();
f = fopen(path, "r");
- process_unlock();
if (!f) {
SYSERROR("opening %s\n", path);
if (buf)
if (!newbuf) {
free(buf);
ERROR("out of memory");
- process_lock();
fclose(f);
- process_unlock();
return NULL;
}
buf = newbuf;
memset(buf, 0, sz);
ret = fread(buf, 1, sz - 1, f);
- process_lock();
fclose(f);
- process_unlock();
if (ret < 0) {
ERROR("reading %s\n", path);
free(buf);
if (!file_exists(path))
return 0;
- process_lock();
fd = open(path, O_RDWR);
- process_unlock();
if (fd < 0) {
// give benefit of the doubt
SYSERROR("Error opening partial file");
lk.l_pid = -1;
if (fcntl(fd, F_GETLK, &lk) == 0 && lk.l_pid != -1) {
// create is still ongoing
- process_lock();
close(fd);
- process_unlock();
return 1;
}
// create completed but partial is still there.
- process_lock();
close(fd);
- process_unlock();
return 2;
}
ERROR("Error writing partial pathname");
return -1;
}
- process_lock();
if ((fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0755)) < 0) {
SYSERROR("Erorr creating partial file");
- process_unlock();
return -1;
}
lk.l_type = F_WRLCK;
if (fcntl(fd, F_SETLKW, &lk) < 0) {
SYSERROR("Error locking partial file %s", path);
close(fd);
- process_unlock();
return -1;
}
- process_unlock();
return fd;
}
char *path = alloca(len);
int ret;
- process_lock();
close(fd);
- process_unlock();
ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
if (ret < 0 || ret >= len) {
ERROR("Error writing partial pathname");
DIR *dir;
int count=0;
- process_lock();
dir = opendir("/proc/self/task");
- process_unlock();
if (!dir) {
INFO("failed to open /proc/self/task");
return false;
if (++count > 1)
break;
}
- process_lock();
closedir(dir);
- process_unlock();
return count == 1;
}
char *tpath;
#endif
- process_lock();
f = fopen(path, "r");
- process_unlock();
if (f == NULL)
return false;
goto out_free_contents;
contents[flen] = '\0';
- process_lock();
ret = fclose(f);
- process_unlock();
f = NULL;
if (ret < 0)
goto out_free_contents;
free(tpath);
#endif
- process_lock();
f = fopen(path, "w");
- process_unlock();
if (f == NULL) {
SYSERROR("reopening config for writing");
free(contents);
if (fwrite(contents, 1, flen, f) != flen) {
SYSERROR("Writing original contents");
free(contents);
- process_lock();
fclose(f);
- process_unlock();
return false;
}
ret = 0;
out_error:
if (f) {
int newret;
- process_lock();
newret = fclose(f);
- process_unlock();
if (ret == 0)
ret = newret;
}
/* Switch back to original netns */
if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
SYSERROR("failed to setns");
- process_lock();
if (*new_netns >= 0)
close(*new_netns);
if (*old_netns >= 0)
close(*old_netns);
- process_unlock();
}
static inline bool enter_to_ns(struct lxc_container *c, int *old_netns, int *new_netns) {
goto out;
/* Save reference to old netns */
- process_lock();
*old_netns = open("/proc/self/ns/net", O_RDONLY);
- process_unlock();
if (*old_netns < 0) {
SYSERROR("failed to open /proc/self/ns/net");
goto out;
if (ret < 0 || ret >= MAXPATHLEN)
goto out;
- process_lock();
*new_netns = open(new_netns_path, O_RDONLY);
- process_unlock();
if (*new_netns < 0) {
SYSERROR("failed to open %s", new_netns_path);
goto out;
if (lret)
return false;
- process_lock();
fout = fopen(alt_file, "w");
- process_unlock();
if (!fout)
goto out;
write_config(fout, c->lxc_conf);
- process_lock();
fclose(fout);
- process_unlock();
ret = true;
out:
c->name);
if (ret < 0 || ret > MAXPATHLEN)
goto out;
- process_lock();
f = fopen(path, "r");
- process_unlock();
if (f) {
ret = fscanf(f, "%d", &v);
- process_lock();
fclose(f);
- process_unlock();
if (ret != 1) {
ERROR("Corrupted file %s", path);
goto out;
}
}
v += inc ? 1 : -1;
- process_lock();
f = fopen(path, "w");
- process_unlock();
if (!f)
goto out;
if (fprintf(f, "%d\n", v) < 0) {
ERROR("Error writing new snapshots value");
- process_lock();
fclose(f);
- process_unlock();
goto out;
}
- process_lock();
ret = fclose(f);
- process_unlock();
if (ret != 0) {
SYSERROR("Error writing to or closing snapshots file");
goto out;
ERROR("Path name too long");
return;
}
- process_lock();
f = fopen(path, "r");
- process_unlock();
if (f == NULL)
return;
while (getline(&lxcpath, &pathlen, f) != -1) {
out:
if (lxcpath) free(lxcpath);
if (lxcname) free(lxcname);
- process_lock();
fclose(f);
- process_unlock();
}
static bool has_snapshots(struct lxc_container *c)
c->name);
if (ret < 0 || ret > MAXPATHLEN)
goto out;
- process_lock();
f = fopen(path, "r");
- process_unlock();
if (!f)
goto out;
ret = fscanf(f, "%d", &v);
- process_lock();
fclose(f);
- process_unlock();
if (ret != 1)
goto out;
bret = v != 0;
return -1;
}
- process_lock();
in = open(old, O_RDONLY);
- process_unlock();
if (in < 0) {
SYSERROR("Error opening original file %s", old);
return -1;
}
- process_lock();
out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644);
- process_unlock();
if (out < 0) {
SYSERROR("Error opening new file %s", new);
- process_lock();
close(in);
- process_unlock();
return -1;
}
goto err;
}
}
- process_lock();
close(in);
close(out);
- process_unlock();
// we set mode, but not owner/group
ret = chmod(new, sbuf.st_mode);
return 0;
err:
- process_lock();
close(in);
close(out);
- process_unlock();
return -1;
}
static void new_hwaddr(char *hwaddr)
{
FILE *f;
- process_lock();
f = fopen("/dev/urandom", "r");
- process_unlock();
if (f) {
unsigned int seed;
int ret = fread(&seed, sizeof(seed), 1, f);
if (ret != 1)
seed = time(NULL);
- process_lock();
fclose(f);
- process_unlock();
srand(seed);
} else
srand(time(NULL));
c->name);
if (ret < 0 || ret >= MAXPATHLEN)
return false;
- process_lock();
f = fopen(path, "a");
- process_unlock();
if (!f)
return false;
bret = true;
// if anything goes wrong, just return an error
if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0)
bret = false;
- process_lock();
if (fclose(f) != 0)
bret = false;
- process_unlock();
return bret;
}
}
// copy the configuration, tweak it as needed,
- process_lock();
fout = fopen(newpath, "w");
- process_unlock();
if (!fout) {
SYSERROR("open %s", newpath);
goto out;
}
write_config(fout, c->lxc_conf);
- process_lock();
fclose(fout);
- process_unlock();
sprintf(newpath, "%s/%s/rootfs", l, n);
if (mkdir(newpath, 0755) < 0) {
char *dfnam = alloca(strlen(snappath) + strlen(newname) + 5);
sprintf(dfnam, "%s/%s/ts", snappath, newname);
- process_lock();
f = fopen(dfnam, "w");
- process_unlock();
if (!f) {
ERROR("Failed to open %s\n", dfnam);
return -1;
fclose(f);
return -1;
}
- process_lock();
ret = fclose(f);
- process_unlock();
if (ret != 0) {
SYSERROR("Writing timestamp");
return -1;
ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name);
if (ret < 0 || ret >= MAXPATHLEN)
return NULL;
- process_lock();
fin = fopen(path, "r");
- process_unlock();
if (!fin)
return NULL;
(void) fseek(fin, 0, SEEK_END);
}
}
}
- process_lock();
fclose(fin);
- process_unlock();
return s;
}
ERROR("path name too long");
return -1;
}
- process_lock();
dir = opendir(snappath);
- process_unlock();
if (!dir) {
INFO("failed to open %s - assuming no snapshots", snappath);
return 0;
count++;
}
- process_lock();
if (closedir(dir))
WARN("failed to close directory");
- process_unlock();
*ret_snaps = snaps;
return count;
lxcsnap_free(&snaps[i]);
free(snaps);
}
- process_lock();
if (closedir(dir))
WARN("failed to close directory");
- process_unlock();
return -1;
}
if (!lxcpath)
lxcpath = default_lxc_path();
- process_lock();
dir = opendir(lxcpath);
- process_unlock();
-
if (!dir) {
SYSERROR("opendir on lxcpath");
return -1;
nfound++;
}
- process_lock();
closedir(dir);
- process_unlock();
return nfound;
free_bad:
lxc_container_put((*cret)[i]);
free(*cret);
}
- process_lock();
closedir(dir);
- process_unlock();
return -1;
}
if (nret)
*nret = NULL;
- process_lock();
FILE *f = fopen("/proc/net/unix", "r");
- process_unlock();
if (!f)
return -1;
if (line)
free(line);
- process_lock();
fclose(f);
- process_unlock();
return ret;
}
free(dest);
return NULL;
}
- process_lock();
ret = mkdir_p(dest, 0755);
- process_unlock();
if (ret < 0) {
free(dest);
return NULL;
ret = -2;
goto out;
}
- process_lock();
if (l->u.f.fd == -1) {
l->u.f.fd = open(l->u.f.fname, O_RDWR|O_CREAT,
S_IWUSR | S_IRUSR);
if (l->u.f.fd == -1) {
- process_unlock();
ERROR("Error opening %s", l->u.f.fname);
goto out;
}
lk.l_start = 0;
lk.l_len = 0;
ret = fcntl(l->u.f.fd, F_SETLKW, &lk);
- process_unlock();
if (ret == -1)
saved_errno = errno;
break;
}
break;
case LXC_LOCK_FLOCK:
- process_lock();
if (l->u.f.fd != -1) {
lk.l_type = F_UNLCK;
lk.l_whence = SEEK_SET;
l->u.f.fd = -1;
} else
ret = -2;
- process_unlock();
break;
}
}
break;
case LXC_LOCK_FLOCK:
- process_lock();
if (l->u.f.fd != -1) {
close(l->u.f.fd);
l->u.f.fd = -1;
}
- process_unlock();
if (l->u.f.fname) {
free(l->u.f.fname);
l->u.f.fname = NULL;
#include "mainloop.h"
#include "lxc.h"
#include "log.h"
-#include "lxclock.h"
#ifndef __USE_GNU
#define __USE_GNU
memset(utmp_data, 0, sizeof(struct lxc_utmp));
- process_lock();
fd = inotify_init();
- process_unlock();
if (fd < 0) {
SYSERROR("failed to inotify_init");
goto out;
return 0;
out_close:
- process_lock();
close(fd);
- process_unlock();
out:
free(utmp_data);
return -1;
struct itimerspec timeout;
struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
- process_lock();
fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
- process_unlock();
if (fd < 0) {
SYSERROR("failed to create timer");
return -1;
if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) {
SYSERROR("failed to add utmp timer to mainloop");
- process_lock();
close(fd);
- process_unlock();
return -1;
}
SYSERROR("failed to del utmp timer from mainloop");
/* shutdown timer_fd */
- process_lock();
close(utmp_data->timer_fd);
- process_unlock();
utmp_data->timer_fd = -1;
if (result < 0)
#include <sys/epoll.h>
#include "mainloop.h"
-#include "lxclock.h"
struct mainloop_handler {
lxc_mainloop_callback_t callback;
int lxc_mainloop_open(struct lxc_epoll_descr *descr)
{
/* hint value passed to epoll create */
- process_lock();
descr->epfd = epoll_create(2);
- process_unlock();
if (descr->epfd < 0)
return -1;
if (fcntl(descr->epfd, F_SETFD, FD_CLOEXEC)) {
- process_lock();
close(descr->epfd);
- process_unlock();
return -1;
}
int lxc_mainloop_close(struct lxc_epoll_descr *descr)
{
struct lxc_list *iterator, *next;
- int ret;
iterator = descr->handlers.next;
while (iterator != &descr->handlers) {
iterator = next;
}
- process_lock();
- ret = close(descr->epfd);
- process_unlock();
- return ret;
+ return close(descr->epfd);
}
ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
return -1;
}
- process_lock();
ret = mkdir_p(fifo_path, 0755);
- process_unlock();
if (ret < 0) {
ERROR("unable to create monitor fifo dir %s", fifo_path);
return ret;
if (ret < 0)
return;
- process_lock();
fd = open(fifo_path, O_WRONLY);
- process_unlock();
if (fd < 0) {
/* it is normal for this open to fail when there is no monitor
* running, so we don't log it
ret = write(fd, msg, sizeof(*msg));
if (ret != sizeof(*msg)) {
- process_lock();
close(fd);
- process_unlock();
SYSERROR("failed to write monitor fifo %s", fifo_path);
return;
}
- process_lock();
close(fd);
- process_unlock();
}
void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath)
/* routines used by monitor subscribers (lxc-monitor) */
int lxc_monitor_close(int fd)
{
- int ret;
-
- process_lock();
- ret = close(fd);
- process_unlock();
- return ret;
+ return close(fd);
}
/* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
return -1;
- process_lock();
fd = socket(PF_UNIX, SOCK_STREAM, 0);
- process_unlock();
if (fd < 0) {
ERROR("socket : %s", strerror(errno));
return -1;
}
return fd;
err1:
- process_lock();
close(fd);
- process_unlock();
return ret;
}
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include "nl.h"
#include "network.h"
#include "conf.h"
-#include "lxclock.h"
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
{
int fd, err = 0;
- process_lock();
fd = open(path, O_WRONLY);
- process_unlock();
if (fd < 0)
return -errno;
if (write(fd, value, strlen(value)) < 0)
err = -errno;
- process_lock();
close(fd);
- process_unlock();
return err;
}
if (!index)
return -EINVAL;
- process_lock();
fd = socket(AF_INET, SOCK_STREAM, 0);
- process_unlock();
if (fd < 0)
return -errno;
ifr.ifr_name[IFNAMSIZ-1] = '\0';
ifr.ifr_ifindex = index;
err = ioctl(fd, SIOCBRADDIF, &ifr);
- process_lock();
close(fd);
- process_unlock();
if (err)
err = -errno;
getifaddrs(&ifaddr);
/* Initialize the random number generator */
- process_lock();
urandom = fopen ("/dev/urandom", "r");
- process_unlock();
if (urandom != NULL) {
if (fread (&seed, sizeof(seed), 1, urandom) <= 0)
seed = time(0);
- process_lock();
fclose(urandom);
- process_unlock();
}
else
seed = time(0);
int err;
int sockfd;
- process_lock();
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
- process_unlock();
if (sockfd < 0)
return -errno;
snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) {
- process_lock();
close(sockfd);
- process_unlock();
return -errno;
}
ifr.ifr_hwaddr.sa_data[0] = 0xfe;
err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
- process_lock();
close(sockfd);
- process_unlock();
if (err < 0)
return -errno;
#include <linux/rtnetlink.h>
#include "nl.h"
-#include "lxclock.h"
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
memset(handler, 0, sizeof(*handler));
- process_lock();
handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
- process_unlock();
if (handler->fd < 0)
return -errno;
extern int netlink_close(struct nl_handler *handler)
{
- process_lock();
close(handler->fd);
- process_unlock();
handler->fd = -1;
return 0;
}
#include "parse.h"
#include "config.h"
#include "utils.h"
-#include "lxclock.h"
#include <lxc/log.h>
/* Workaround for the broken signature of alphasort() in bionic.
char *line = NULL;
size_t len = 0;
- process_lock();
f = fopen(file, "r");
- process_unlock();
if (!f) {
SYSERROR("failed to open %s", file);
return -1;
if (line)
free(line);
- process_lock();
fclose(f);
- process_unlock();
return err;
}
#include <seccomp.h>
#include "config.h"
#include "lxcseccomp.h"
-#include "lxclock.h"
#include "log.h"
return -1;
}
- process_lock();
f = fopen(conf->seccomp, "r");
- process_unlock();
if (!f) {
SYSERROR("failed to open seccomp policy file %s\n", conf->seccomp);
return -1;
}
ret = parse_config(f, conf);
- process_lock();
fclose(f);
- process_unlock();
return ret;
}
#include "namespace.h"
#include "lxcseccomp.h"
#include "caps.h"
-#include "lxclock.h"
#include "lsm/lsm.h"
lxc_log_define(lxc_start, lxc);
static void close_ns(int ns_fd[LXC_NS_MAX]) {
int i;
- process_lock();
for (i = 0; i < LXC_NS_MAX; i++) {
if (ns_fd[i] > -1) {
close(ns_fd[i]);
ns_fd[i] = -1;
}
}
- process_unlock();
}
static int preserve_ns(int ns_fd[LXC_NS_MAX], int clone_flags) {
if ((clone_flags & ns_info[i].clone_flag) == 0)
continue;
snprintf(path, MAXPATHLEN, "/proc/self/ns/%s", ns_info[i].proc_name);
- process_lock();
ns_fd[i] = open(path, O_RDONLY | O_CLOEXEC);
- process_unlock();
if (ns_fd[i] < 0)
goto error;
}
DIR *dir;
restart:
- process_lock();
dir = opendir("/proc/self/fd");
- process_unlock();
if (!dir) {
WARN("failed to open directory: %m");
return -1;
continue;
if (conf->close_all_fds) {
- process_lock();
close(fd);
closedir(dir);
- process_unlock();
INFO("closed inherited fd %d", fd);
goto restart;
}
WARN("inherited fd %d", fd);
}
- process_lock();
closedir(dir); /* cannot fail */
- process_unlock();
return 0;
}
out_mainloop_open:
lxc_mainloop_close(&descr);
out_sigfd:
- process_lock();
close(sigfd);
- process_unlock();
return -1;
}
out_aborting:
lxc_set_state(name, handler, ABORTING);
out_close_maincmd_fd:
- process_lock();
close(conf->maincmd_fd);
- process_unlock();
conf->maincmd_fd = -1;
out_free_name:
free(handler->name);
lxc_console_delete(&handler->conf->console);
lxc_delete_tty(&handler->conf->tty_info);
- process_lock();
close(handler->conf->maincmd_fd);
- process_unlock();
handler->conf->maincmd_fd = -1;
free(handler->name);
if (handler->cgroup) {
int status;
pid_t pid;
- process_lock();
f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
- process_unlock();
if (!f) {
DEBUG("failed to open /proc/sys/kernel/ctrl-alt-del");
return 1;
}
ret = fscanf(f, "%d", &v);
- process_lock();
fclose(f);
- process_unlock();
if (ret != 1) {
DEBUG("Failed to read /proc/sys/kernel/ctrl-alt-del");
return 1;
/* don't leak the pinfd to the container */
if (handler->pinfd >= 0) {
- process_lock();
close(handler->pinfd);
- process_unlock();
}
/* Tell the parent task it can begin to configure the
goto out_warn_father;
}
- process_lock();
close(handler->sigfd);
- process_unlock();
/* after this call, we are in error because this
* ops should not return as it execs */
lxc_abort(name, handler);
lxc_sync_fini(handler);
if (handler->pinfd >= 0) {
- process_lock();
close(handler->pinfd);
- process_unlock();
handler->pinfd = -1;
}
lxc_rename_phys_nics_on_shutdown(handler->conf);
if (handler->pinfd >= 0) {
- process_lock();
close(handler->pinfd);
- process_unlock();
handler->pinfd = -1;
}
#include <lxc/monitor.h>
#include "commands.h"
#include "config.h"
-#include "lxclock.h"
lxc_log_define(lxc_state, lxc);
if (ret < 0 || ret >= MAXPATHLEN)
goto out;
- process_lock();
file = fopen(freezer, "r");
- process_unlock();
if (!file) {
ret = -1;
goto out;
}
ret = fscanf(file, "%s", status);
- process_lock();
fclose(file);
- process_unlock();
if (ret == EOF) {
SYSERROR("failed to read %s", freezer);
#include "log.h"
#include "start.h"
-#include "lxclock.h"
lxc_log_define(lxc_sync, lxc);
{
int ret;
- process_lock();
ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sv);
- process_unlock();
if (ret) {
SYSERROR("failed to create synchronization socketpair");
return -1;
void lxc_sync_fini_child(struct lxc_handler *handler)
{
if (handler->sv[0] != -1) {
- process_lock();
close(handler->sv[0]);
- process_unlock();
handler->sv[0] = -1;
}
}
void lxc_sync_fini_parent(struct lxc_handler *handler)
{
if (handler->sv[1] != -1) {
- process_lock();
close(handler->sv[1]);
- process_unlock();
handler->sv[1] = -1;
}
}
int ret, failed=0;
char pathname[MAXPATHLEN];
- process_lock();
dir = opendir(dirname);
- process_unlock();
if (!dir) {
ERROR("%s: failed to open %s", __func__, dirname);
return -1;
failed=1;
}
- process_lock();
ret = closedir(dir);
- process_unlock();
if (ret) {
ERROR("%s: failed to close directory %s", __func__, dirname);
failed=1;
}
static_unlock();
- process_lock();
fin = fopen_cloexec(user_config_path, "r");
free(user_config_path);
- process_unlock();
if (fin) {
while (fgets(buf, 1024, fin)) {
if (buf[0] == '#')
static_unlock();
out:
- process_lock();
if (fin)
fclose(fin);
- process_unlock();
static_lock();
value = values[i];
return ret;
}
-static inline int lock_fclose(FILE *f)
-{
- int ret;
- process_lock();
- ret = fclose(f);
- process_unlock();
- return ret;
-}
-
#if HAVE_LIBGNUTLS
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
if (!fnam)
return -1;
- process_lock();
f = fopen_cloexec(fnam, "r");
- process_unlock();
if (!f) {
SYSERROR("Error opening template");
return -1;
}
if (fseek(f, 0, SEEK_END) < 0) {
SYSERROR("Error seeking to end of template");
- lock_fclose(f);
+ fclose(f);
return -1;
}
if ((flen = ftell(f)) < 0) {
SYSERROR("Error telling size of template");
- lock_fclose(f);
+ fclose(f);
return -1;
}
if (fseek(f, 0, SEEK_SET) < 0) {
SYSERROR("Error seeking to start of template");
- lock_fclose(f);
+ fclose(f);
return -1;
}
if ((buf = malloc(flen+1)) == NULL) {
SYSERROR("Out of memory");
- lock_fclose(f);
+ fclose(f);
return -1;
}
if (fread(buf, 1, flen, f) != flen) {
SYSERROR("Failure reading template");
free(buf);
- lock_fclose(f);
+ fclose(f);
return -1;
}
- if (lock_fclose(f) < 0) {
+ if (fclose(f) < 0) {
SYSERROR("Failre closing template");
free(buf);
return -1;
return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
}
-/*
- * fopen_cloexec: must be called with process_lock() held
- * if it is needed.
- */
FILE *fopen_cloexec(const char *path, const char *mode)
{
int open_mode = 0;
return ret;
}
-/* must be called with process_lock() held */
extern struct lxc_popen_FILE *lxc_popen(const char *command)
{
struct lxc_popen_FILE *fp = NULL;
return NULL;
}
-/* must be called with process_lock() held */
extern int lxc_pclose(struct lxc_popen_FILE *fp)
{
FILE *f = NULL;
int fd, saved_errno;
ssize_t ret;
- process_lock();
fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
- process_unlock();
if (fd < 0)
return -1;
ret = lxc_write_nointr(fd, buf, count);
if (ret != 1)
goto out_error;
}
- process_lock();
close(fd);
- process_unlock();
return 0;
out_error:
saved_errno = errno;
- process_lock();
close(fd);
- process_unlock();
errno = saved_errno;
return -1;
}
int fd = -1, saved_errno;
ssize_t ret;
- process_lock();
fd = open(filename, O_RDONLY | O_CLOEXEC);
- process_unlock();
if (fd < 0)
return -1;
ERROR("read %s: %s", filename, strerror(errno));
saved_errno = errno;
- process_lock();
close(fd);
- process_unlock();
errno = saved_errno;
return ret;
}
* via sigprocmask(2) (unblocks all signals) after fork(2) but prior to calling exec(3).
* In short, popen(command, "re") does pipe() + fork() + exec()
* while lxc_popen(command) does pipe() + fork() + sigprocmask() + exec().
- * Must be called with process_lock() held.
* Returns pointer to struct lxc_popen_FILE, that should be freed with lxc_pclose().
* On error returns NULL.
*/
* returned by lxc_popen().
* Waits for associated process to terminate, returns its exit status and
* frees resources, pointed to by struct lxc_popen_FILE *.
- * Must be called with process_lock() held.
*/
extern int lxc_pclose(struct lxc_popen_FILE *fp);