void redirect_fd(int fd, int to_fd) { if (fd == to_fd || fd < 0) return; if (close(to_fd) < 0) { SYSERROR("Can`t close old fd: %d", fd); throw -1; } if (dup2(fd, to_fd) == -1) { SYSERROR("can`t redirect fd %d to %d", fd, to_fd); throw -1; } }
static int freezer_state(const char *name) { char *nsgroup; char freezer[MAXPATHLEN]; char status[MAXPATHLEN]; FILE *file; int err; err = lxc_cgroup_path_get(&nsgroup, "freezer", name); if (err) return -1; err = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); if (err < 0 || err >= MAXPATHLEN) return -1; file = fopen(freezer, "r"); if (!file) return -1; err = fscanf(file, "%s", status); fclose(file); if (err == EOF) { SYSERROR("failed to read %s", freezer); return -1; } return lxc_str2state(status); }
int do_mkfs_exec_wrapper(void *args) { int ret; char *mkfs; char **data = args; /* strlen("mkfs.") * + * strlen(data[0]) * + * \0 */ size_t len = 5 + strlen(data[0]) + 1; mkfs = malloc(len); if (!mkfs) return -1; ret = snprintf(mkfs, len, "mkfs.%s", data[0]); if (ret < 0 || (size_t)ret >= len) { free(mkfs); return -1; } TRACE("Executing \"%s %s\"", mkfs, data[1]); execlp(mkfs, mkfs, data[1], (char *)NULL); SYSERROR("Failed to run \"%s %s\"", mkfs, data[1]); free(mkfs); return -1; }
static int preserve_ns(int ns_fd[LXC_NS_MAX], int clone_flags) { int i, saved_errno; char path[MAXPATHLEN]; for (i = 0; i < LXC_NS_MAX; i++) ns_fd[i] = -1; if (access("/proc/self/ns", X_OK)) { WARN("Kernel does not support attach; preserve_ns ignored"); return 0; } for (i = 0; i < LXC_NS_MAX; i++) { if ((clone_flags & ns_info[i].clone_flag) == 0) continue; snprintf(path, MAXPATHLEN, "/proc/self/ns/%s", ns_info[i].proc_name); ns_fd[i] = open(path, O_RDONLY | O_CLOEXEC); if (ns_fd[i] < 0) goto error; } return 0; error: saved_errno = errno; close_ns(ns_fd); errno = saved_errno; SYSERROR("failed to open '%s'", path); return -1; }
static int stdin_tios_setup(void) { struct termios newtios; if (!isatty(0)) { ERROR("stdin is not a tty"); return -1; } if (tcgetattr(0, &oldtios)) { SYSERROR("failed to get current terminal settings"); return -1; } newtios = oldtios; /* turn off echo and line buffering */ newtios.c_iflag &= ~IGNBRK; newtios.c_iflag &= BRKINT; newtios.c_lflag &= ~(ECHO|ICANON); newtios.c_cc[VMIN] = 1; newtios.c_cc[VTIME] = 0; if (tcsetattr(0, TCSAFLUSH, &newtios)) { ERROR("failed to set new terminal settings"); return -1; } return 0; }
static int lsm_openat(int procfd, pid_t pid, int on_exec) { int ret = -1; int labelfd = -1; const char *name; char path[__LSMATTRLEN]; name = lsm_name(); if (strcmp(name, "nop") == 0) return 0; if (strcmp(name, "none") == 0) return 0; /* We don't support on-exec with AppArmor */ if (strcmp(name, "AppArmor") == 0) on_exec = 0; if (on_exec) ret = snprintf(path, __LSMATTRLEN, "%d/attr/exec", pid); else ret = snprintf(path, __LSMATTRLEN, "%d/attr/current", pid); if (ret < 0 || ret >= __LSMATTRLEN) return -1; labelfd = openat(procfd, path, O_RDWR); if (labelfd < 0) { SYSERROR("Unable to open file descriptor to set LSM label."); return -1; } return labelfd; }
/*---------------------------------------------------------------------------*/ static int build_dir(const char *name) { char *n = strdup(name); // because we'll be modifying it char *p, *e; int ret; if (!n) { ERROR("Out of memory while creating directory '%s'.", name); return -1; } e = &n[strlen(n)]; for (p = n+1; p < e; p++) { if (*p != '/') continue; *p = '\0'; if (access(n, F_OK)) { ret = lxc_unpriv(mkdir(n, 0755)); if (ret && errno != EEXIST) { SYSERROR("failed to create directory '%s'.", n); free(n); return -1; } } *p = '/'; } free(n); return 0; }
static int get_cgroup_mount(const char *mtab, char *mnt) { struct mntent *mntent; FILE *file = NULL; int err = -1; file = setmntent(mtab, "r"); if (!file) { SYSERROR("failed to open %s", mtab); return -1; } while ((mntent = getmntent(file))) { /* there is a cgroup mounted named "lxc" */ if (!strcmp(mntent->mnt_fsname, "lxc") && !strcmp(mntent->mnt_type, "cgroup")) { strcpy(mnt, mntent->mnt_dir); err = 0; break; } /* fallback to the first non-lxc cgroup found */ if (!strcmp(mntent->mnt_type, "cgroup") && err) { strcpy(mnt, mntent->mnt_dir); err = 0; } }; DEBUG("using cgroup mounted at '%s'", mnt); fclose(file); return err; }
// Returns a newly-allocated array containing the raw header bytes for the // given extension. char* anqfits_header_get_data(const anqfits_t* qf, int ext, int* Nbytes) { FILE* fid; off_t N, nr; char* data; off_t start; start = anqfits_header_start(qf, ext); if (start == -1) return NULL; N = anqfits_header_size(qf, ext); if (N == -1) return NULL; fid = fopen(qf->filename, "rb"); if (!fid) { return NULL; } data = malloc(N + 1); if (start) { if (fseeko(fid, start, SEEK_SET)) { SYSERROR("Failed to seek to start of FITS header: byte %li in %s", (long int)start, qf->filename); return NULL; } } nr = fread(data, 1, N, fid); fclose(fid); if (nr != N) { free(data); return NULL; } data[N] = '\0'; if (Nbytes) *Nbytes = N; return data; }
extern int mkdir_p(char *dir, mode_t mode) { int ret; char *d; if (!strcmp(dir, "/")) return 0; d = strdup(dir); if (!d) return -1; ret = mkdir_p(dirname(d), mode); free(d); if (ret) return -1; if (!access(dir, F_OK)) return 0; if (mkdir(dir, mode)) { SYSERROR("failed to create directory '%s'\n", dir); return -1; } return 0; }
bool SybCTnewDAImpl::IntDoGetConnection(SybCTnewDA *&pSyb, bool &bIsOpen, const String &server, const String &user) { StartTrace(SybCTnewDAImpl.IntDoGetConnection); pSyb = NULL; bIsOpen = false; if ( !server.Length() || !user.Length() || !IntGetOpen(pSyb, bIsOpen, server, user) ) { // favour unused connection against open connection of different server/user if ( fgListOfSybCT["Unused"].GetSize() ) { Trace("removing first unused element"); pSyb = SafeCast(fgListOfSybCT["Unused"][0L].AsIFAObject(), SybCTnewDA); fgListOfSybCT["Unused"].Remove(0L); } else { String strEmpty; if ( IntGetOpen(pSyb, bIsOpen, strEmpty, strEmpty) ) { Trace("connection of different server or user"); // if this call would return false we could possibly delete and recreate an object pSyb->Close(); } } } Trace("returning &" << (long)(IFAObject *)pSyb); if ( pSyb == NULL ) { SYSERROR("could not get a valid SybCTnewDA"); } return (pSyb != NULL); }
/** * Get cgroup path for group cgroup_name in specified subsystem * * @param path where to write result */ void cgroup_get_path(const char *subsystem, const char *cgroup_name, char *path) { struct mntent *mntent; FILE *file = NULL; file = setmntent(MTAB, "r"); if (!file) { SYSERROR("failed to open %s", MTAB); throw -1; } while ((mntent = getmntent(file))) { if (strcmp(mntent->mnt_type, "cgroup")) continue; if (!subsystem || hasmntopt(mntent, subsystem)) { snprintf(path, MAXPATHLEN, "%s/%s", mntent->mnt_dir, cgroup_name); fclose(file); DEBUG("using cgroup at '%s'", path); return; } }; DEBUG("Failed to find cgroup for %s\n", subsystem ? subsystem : "(NULL)"); fclose(file); throw -1; }
/* * Given the '-t' template option to lxc-create, figure out what to * do. If the template is a full executable path, use that. If it * is something like 'sshd', then return $templatepath/lxc-sshd. * On success return the template, on error return NULL. */ char *get_template_path(const char *t) { int ret, len; char *tpath; if (t[0] == '/' && access(t, X_OK) == 0) { tpath = strdup(t); return tpath; } len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1; tpath = malloc(len); if (!tpath) return NULL; ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t); if (ret < 0 || ret >= len) { free(tpath); return NULL; } if (access(tpath, X_OK) < 0) { SYSERROR("bad template: %s", t); free(tpath); return NULL; } return tpath; }
/* routines used by monitor publishers (containers) */ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath) { int fd,ret; char fifo_path[PATH_MAX]; BUILD_BUG_ON(sizeof(*msg) > PIPE_BUF); /* write not guaranteed atomic */ ret = snprintf(fifo_path, sizeof(fifo_path), "%s/monitor-fifo", lxcpath); if (ret < 0 || ret >= sizeof(fifo_path)) { ERROR("lxcpath too long to open monitor fifo"); return; } fd = open(fifo_path, O_WRONLY); if (fd < 0) { /* it is normal for this open to fail when there is no monitor * running, so we don't log it */ return; } ret = write(fd, msg, sizeof(*msg)); if (ret != sizeof(*msg)) { close(fd); SYSERROR("failed to write monitor fifo %s", fifo_path); return; } close(fd); }
int get_hostarch(void) { struct utsname uts; if (uname(&uts) < 0) { SYSERROR("Failed to read host arch."); return -1; } if (strcmp(uts.machine, "i686") == 0) return lxc_seccomp_arch_i386; // no x32 kernels else if (strcmp(uts.machine, "x86_64") == 0) return lxc_seccomp_arch_amd64; else if (strncmp(uts.machine, "armv7", 5) == 0) return lxc_seccomp_arch_arm; else if (strncmp(uts.machine, "aarch64", 7) == 0) return lxc_seccomp_arch_arm64; else if (strncmp(uts.machine, "ppc64le", 7) == 0) return lxc_seccomp_arch_ppc64le; else if (strncmp(uts.machine, "ppc64", 5) == 0) return lxc_seccomp_arch_ppc64; else if (strncmp(uts.machine, "ppc", 3) == 0) return lxc_seccomp_arch_ppc; else if (strncmp(uts.machine, "mips64", 6) == 0) return MIPS_ARCH_N64; else if (strncmp(uts.machine, "mips", 4) == 0) return MIPS_ARCH_O32; else if (strncmp(uts.machine, "s390x", 5) == 0) return lxc_seccomp_arch_s390x; return lxc_seccomp_arch_unknown; }
/* * for each mounted cgroup, destroy the cgroup for the container */ int lxc_cgroup_destroy(const char *cgpath) { struct mntent *mntent; FILE *file = NULL; int err, retv = 0; file = setmntent(MTAB, "r"); if (!file) { SYSERROR("failed to open %s", MTAB); return -1; } while ((mntent = getmntent(file))) { if (strcmp(mntent->mnt_type, "cgroup")) continue; if (!mount_has_subsystem(mntent)) continue; err = lxc_one_cgroup_destroy(mntent, cgpath); if (err) // keep trying to clean up the others retv = -1; } endmntent(file); return retv; }
int lxc_cgroup_nrtasks(const char *name) { char *nsgroup; char path[MAXPATHLEN]; int pid, ret, count = 0; FILE *file; ret = lxc_cgroup_path_get(&nsgroup, name); if (ret) return -1; snprintf(path, MAXPATHLEN, "%s/tasks", nsgroup); file = fopen(path, "r"); if (!file) { SYSERROR("fopen '%s' failed", path); return -1; } while (fscanf(file, "%d", &pid) != EOF) count++; fclose(file); return count; }
/* * for each mounted cgroup, create a cgroup for the container */ int lxc_cgroup_create(const char *name, pid_t pid) { struct mntent *mntent; FILE *file = NULL; int err = -1; file = setmntent(MTAB, "r"); if (!file) { SYSERROR("failed to open %s", MTAB); return -1; } while ((mntent = getmntent(file))) { DEBUG("checking '%s' (%s)", mntent->mnt_dir, mntent->mnt_type); if (!strcmp(mntent->mnt_type, "cgroup")) { INFO("found cgroup mounted at '%s'", mntent->mnt_dir); err = lxc_one_cgroup_create(name, mntent, pid); if (err) goto out; } }; out: endmntent(file); return err; }
/* * for each mounted cgroup, destroy the cgroup for the container */ int lxc_cgroup_destroy(const char *name) { struct mntent *mntent; FILE *file = NULL; int ret, err = -1; file = setmntent(MTAB, "r"); if (!file) { SYSERROR("failed to open %s", MTAB); return -1; } while ((mntent = getmntent(file))) { if (!strcmp(mntent->mnt_type, "cgroup")) { DEBUG("destroying %s %s\n", mntent->mnt_dir, name); ret = lxc_one_cgroup_destroy(mntent->mnt_dir, name); if (ret) { fclose(file); return ret; } err = 0; } } fclose(file); return err; }
static int get_cgroup_mount(const char *subsystem, char *mnt) { struct mntent *mntent; FILE *file = NULL; file = setmntent(MTAB, "r"); if (!file) { SYSERROR("failed to open %s", MTAB); return -1; } while ((mntent = getmntent(file))) { if (strcmp(mntent->mnt_type, "cgroup")) continue; if (!subsystem || hasmntopt(mntent, subsystem)) { strcpy(mnt, mntent->mnt_dir); fclose(file); DEBUG("using cgroup mounted at '%s'", mnt); return 0; } }; DEBUG("Failed to find cgroup for %s\n", subsystem ? subsystem : "(NULL)"); fclose(file); return -1; }
int lxc_attach_run_shell(void* payload) { uid_t uid; struct passwd *passwd; char *user_shell; /* Ignore payload parameter. */ (void)payload; uid = getuid(); passwd = getpwuid(uid); /* This probably happens because of incompatible nss implementations in * host and container (remember, this code is still using the host's * glibc but our mount namespace is in the container) we may try to get * the information by spawning a [getent passwd uid] process and parsing * the result. */ if (!passwd) user_shell = lxc_attach_getpwshell(uid); else user_shell = passwd->pw_shell; if (user_shell) execlp(user_shell, user_shell, (char *)NULL); /* Executed if either no passwd entry or execvp fails, we will fall back * on /bin/sh as a default shell. */ execlp("/bin/sh", "/bin/sh", (char *)NULL); SYSERROR("Failed to exec shell."); return -1; }
int lxc_dir_for_each(const char *name, const char *directory, lxc_dir_cb callback, void *data) { struct dirent **namelist; int n, ret = 0; #ifdef IS_BIONIC n = scandir(directory, &namelist, dir_filter, bionic_alphasort); #else n = scandir(directory, &namelist, dir_filter, alphasort); #endif if (n < 0) { SYSERROR("failed to scan %s directory", directory); return -1; } while (n--) { if (!ret && callback(name, directory, namelist[n]->d_name, data)) { ERROR("callback failed"); ret = -1; } free(namelist[n]); } free(namelist); return ret; }
static codefile_t* new_codefile(const char* fn, anbool writing, anbool inmem) { fitsbin_chunk_t chunk; codefile_t* cf = calloc(1, sizeof(codefile_t)); if (!cf) { SYSERROR("Couldn't calloc a codefile struct"); return NULL; } cf->healpix = -1; cf->hpnside = 1; if (inmem) { cf->fb = fitsbin_open_in_memory(); } else { if (writing) cf->fb = fitsbin_open_for_writing(fn); else cf->fb = fitsbin_open(fn); } if (!cf->fb) { ERROR("Failed to create fitsbin"); return NULL; } fitsbin_chunk_init(&chunk); chunk.tablename = "codes"; chunk.required = 1; chunk.callback_read_header = callback_read_header; chunk.userdata = cf; fitsbin_add_chunk(cf->fb, &chunk); fitsbin_chunk_clean(&chunk); return cf; }
int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) { FILE *f; int err = 0; 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; } while (getline(&line, &len, f) != -1) { err = callback(line, data); if (err) { ERROR("Failed to parse config: %s", line); break; } } if (line) free(line); process_lock(); fclose(f); process_unlock(); return err; }
static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath) { int fd,ret; char fifo_path[PATH_MAX]; BUILD_BUG_ON(sizeof(*msg) > PIPE_BUF); /* write not guaranteed atomic */ ret = lxc_monitor_fifo_name(lxcpath, fifo_path, sizeof(fifo_path), 0); 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 */ return; } 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(); }
static qidxfile* new_qidxfile(const char* fn, anbool writing) { qidxfile* qf; fitsbin_chunk_t chunk; qf = calloc(1, sizeof(qidxfile)); if (!qf) { SYSERROR("Couldn't malloc a qidxfile struct"); return NULL; } // default qf->dimquads = 4; if (writing) qf->fb = fitsbin_open_for_writing(fn); else qf->fb = fitsbin_open(fn); if (!qf->fb) { ERROR("Failed to create fitsbin"); return NULL; } fitsbin_chunk_init(&chunk); chunk.tablename = "qidx"; chunk.required = 1; chunk.callback_read_header = callback_read_header; chunk.userdata = qf; chunk.itemsize = sizeof(uint32_t); fitsbin_add_chunk(qf->fb, &chunk); fitsbin_chunk_clean(&chunk); return qf; }
static dc_status_t serial_ftdi_sleep (void *io, unsigned int timeout) { ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; INFO (device->context, "Sleep: value=%u", timeout); #ifdef _WIN32 Sleep((DWORD)timeout); #else struct timespec ts; ts.tv_sec = (timeout / 1000); ts.tv_nsec = (timeout % 1000) * 1000000; while (nanosleep (&ts, &ts) != 0) { if (errno != EINTR ) { SYSERROR (device->context, errno); return DC_STATUS_IO; } } #endif return DC_STATUS_SUCCESS; }
int lxc_cgroup_nrtasks(const char *cgpath) { char *dpath; char path[MAXPATHLEN]; int pid, ret, count = 0; FILE *file; int rc; ret = cgroup_path_get(&dpath, NULL, cgpath); if (ret) return -1; rc = snprintf(path, MAXPATHLEN, "%s/tasks", dpath); if (rc < 0 || rc >= MAXPATHLEN) { ERROR("pathname too long"); return -1; } file = fopen(path, "r"); if (!file) { SYSERROR("fopen '%s' failed", path); return -1; } while (fscanf(file, "%d", &pid) != EOF) count++; fclose(file); return count; }
int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) { FILE *f; int err = 0; char *line = NULL; size_t len = 0; f = fopen(file, "r"); if (!f) { SYSERROR("failed to open %s", file); return -1; } while (getline(&line, &len, f) != -1) { err = callback(line, data); if (err) { // callback rv > 0 means stop here // callback rv < 0 means error if (err < 0) ERROR("Failed to parse config: %s", line); break; } } free(line); fclose(f); return err; }
/* * for each mounted cgroup, destroy the cgroup for the container */ int lxc_cgroup_destroy(const char *name) { struct mntent *mntent; FILE *file = NULL; int err = -1; file = setmntent(MTAB, "r"); if (!file) { SYSERROR("failed to open %s", MTAB); return -1; } while ((mntent = getmntent(file))) { if (strcmp(mntent->mnt_type, "cgroup")) continue; if (!mount_has_subsystem(mntent)) continue; err = lxc_one_cgroup_destroy(mntent, name); if (err) break; } endmntent(file); return err; }