Example #1
0
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;
    }
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #4
0
File: start.c Project: rowhit/lxc
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;
}
Example #5
0
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;
}
Example #6
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;
}
Example #7
0
File: log.c Project: ElvisTulip/lxc
/*---------------------------------------------------------------------------*/
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;
}
Example #8
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;
}
Example #9
0
// 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;
}
Example #10
0
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);
}
Example #12
0
/**
 * 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;
}
Example #13
0
File: utils.c Project: Azendale/lxc
/*
 * 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;
}
Example #14
0
/* 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);
}
Example #15
0
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;
}
Example #16
0
/*
 * 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;
}
Example #17
0
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;
}
Example #18
0
/*
 * 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;
}
Example #19
0
/*
 * 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;
}
Example #20
0
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;
}
Example #21
0
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;
}
Example #22
0
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;
}
Example #23
0
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;
}
Example #24
0
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;
}
Example #25
0
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();
}
Example #26
0
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;
}
Example #27
0
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;
}
Example #28
0
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;
}
Example #29
0
File: parse.c Project: 4b42/lxc
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;
}
Example #30
0
/*
 * 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;
}