Esempio n. 1
0
/* TODO: use recursive_action? */
static NOINLINE void edir(const char *directory_name)
{
	int wdir;
	DIR *dir;
	struct dirent *d;
	int fd;

	wdir = xopen(".", O_RDONLY | O_NDELAY);
	xchdir(directory_name);
	dir = xopendir(".");
	for (;;) {
		char buf[256];
		char *tail;
		int size;

		errno = 0;
		d = readdir(dir);
		if (!d) {
			if (errno)
				bb_perror_msg_and_die("readdir %s",
						directory_name);
			break;
		}
		if (d->d_name[0] == '.')
			continue;
		fd = open(d->d_name, O_RDONLY | O_NDELAY);
		if (fd < 0) {
			if ((errno == EISDIR) && directory_name) {
				if (option_mask32 & OPT_v)
					bb_perror_msg("warning: %s/%s is a directory",
						directory_name, d->d_name);
				continue;
			}
			bb_perror_msg_and_die("open %s/%s",
						directory_name, d->d_name);
		}
		size = full_read(fd, buf, sizeof(buf)-1);
		close(fd);
		if (size < 0)
			bb_perror_msg_and_die("read %s/%s",
					directory_name, d->d_name);
		if (size == 0) {
			unsetenv(d->d_name);
			continue;
		}
		buf[size] = '\n';
		tail = strchr(buf, '\n');
		/* skip trailing whitespace */
		while (1) {
			*tail = '\0';
			tail--;
			if (tail < buf || !isspace(*tail))
				break;
		}
		xsetenv(d->d_name, buf);
	}
	closedir(dir);
	xfchdir(wdir);
	close(wdir);
}
Esempio n. 2
0
static void do_procinit(void)
{
	DIR *procdir;
	struct dirent *entry;
	int pid;

	if (pidfile) {
		do_pidfile();
		return;
	}

	procdir = xopendir("/proc");

	pid = 0;
	while (1) {
		errno = 0; /* clear any previous error */
		entry = readdir(procdir);
// TODO: this check is too generic, it's better
// to check for exact errno(s) which mean that we got stale entry
		if (errno) /* Stale entry, process has died after opendir */
			continue;
		if (!entry) /* EOF, no more entries */
			break;
		pid = bb_strtou(entry->d_name, NULL, 10);
		if (errno) /* NaN */
			continue;
		check(pid);
	}
	closedir(procdir);
	if (!pid)
		bb_error_msg_and_die("nothing in /proc - not mounted?");
}
Esempio n. 3
0
int
pidof_main(const struct cmd_pidof_info* info)
{
    const char* name = info->name;
    DIR* procdir = xopendir("/proc");
    struct dirent* ent;
    unsigned long found_pid = 0;
    bool found = false;
    while ((ent = readdir(procdir)) != NULL) {
        SCOPED_RESLIST(rl);
        char* endptr = NULL;
        errno = 0;
        unsigned long pid = strtoul(ent->d_name, &endptr, 10);
        if (pid == 0 || errno != 0 || *endptr != '\0')
            continue;
        int cmdline_fd = try_xopen(xaprintf("/proc/%lu/cmdline", pid), O_RDONLY, 0);
        if (cmdline_fd == -1)
            continue;
        char* name = slurp_fd(cmdline_fd, NULL);
        if (strcmp(name, info->name) == 0) {
            if (found)
                die(EINVAL, "more than one process has name `%s'", name);
            found = true;
            found_pid = pid;
        }
    }

    if (!found)
        die(ENOENT, "no process has name `%s'", name);
    xprintf(xstdout, "%lu%s", found_pid, info->pidof.zero ? "" : "\n");
    xflush(xstdout);
    return 0;
}
Esempio n. 4
0
/* initiate a process table scan
 */
PROCTAB* openproc(int flags, ...) {
    va_list ap;
    PROCTAB* PT = xcalloc(NULL, sizeof(PROCTAB));
 
    if (Do(PID))
      PT->procfs = NULL;
    else if (!(PT->procfs = xopendir("/proc")))
      return NULL;
    PT->flags = flags;
    va_start(ap, flags);		/*  Init args list */
    if (Do(PID))
    	PT->pids = va_arg(ap, pid_t*);
    else if (Do(TTY))
	sprintf(path, "%s/%s", sub, name);
	archivefile(path);
}

//usage:#define smemcap_trivial_usage ">SMEMDATA.TAR"
//usage:#define smemcap_full_usage "\n\n"
//usage:       "Collect memory usage data in /proc and write it to stdout"

int smemcap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int smemcap_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
{
	DIR *d;
	struct dirent *de;

	xchdir("/proc");
	d = xopendir(".");

	archivefile("meminfo");
	archivefile("version");
	while ((de = readdir(d)) != NULL) {
		if (isdigit(de->d_name[0])) {
			struct stat s;
			memset(&s, 0, sizeof(s));
			s.st_mode = 0555;
			writeheader(de->d_name, &s, '5');
			archivejoin(de->d_name, "smaps");
			archivejoin(de->d_name, "cmdline");
			archivejoin(de->d_name, "stat");
		}
	}
Esempio n. 6
0
string
xgetcwd (void)
{
    /* If the system provides getcwd, use it.  If not, use getwd if
       available.  But provide a way not to use getcwd: on some systems
       getcwd forks, which is expensive and may in fact be impossible for
       large programs like tex.  If your system needs this define and it
       is not detected by configure, let me know.
                                       -- Olaf Weber <[email protected] */
#if defined (HAVE_GETCWD) && !defined (GETCWD_FORKS)
    char path[PATH_MAX + 1];
#if defined(WIN32)
    string pp;
#endif

    if (getcwd (path, PATH_MAX + 1) == NULL) {
        FATAL_PERROR ("getcwd");
    }

#if defined(WIN32)
    for (pp = path; *pp; pp++) {
        if (*pp == '\\')
            *pp = '/';
#if defined (KPSE_COMPAT_API)
        else if (IS_KANJI(pp))
            pp++;
#endif
    }
#endif

    return xstrdup (path);
#elif defined (HAVE_GETWD)
    char path[PATH_MAX + 1];

    if (getwd (path) == NULL) {
        FATAL_PERROR ("getwd");
    }

    return xstrdup (path);
#else /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */
    struct stat root_stat, cwd_stat;
    string cwd_path = (string)xmalloc(2); /* In case we assign "/" below.  */

    *cwd_path = 0;

    /* Find the inodes of the root and current directories.  */
    root_stat = xstat("/");
    cwd_stat  = xstat(".");

    /* Go up the directory hierarchy until we get to root, prepending each
       directory we pass through to `cwd_path'.  */
    while (!SAME_FILE_P(root_stat, cwd_stat)) {
        struct dirent *e;
        DIR *parent_dir;
        boolean found = false;

        xchdir("..");
        parent_dir = xopendir(".");

        /* Look through the parent directory for the entry with the same
           inode, so we can get its name.  */
        while ((e = readdir (parent_dir)) != NULL && !found) {
            struct stat test_stat;
            test_stat = xlstat(e->d_name);

            if (SAME_FILE_P(test_stat, cwd_stat)) {
                /* We've found it.  Prepend the pathname.  */
                string temp = cwd_path;
                cwd_path = concat3("/", e->d_name, cwd_path);
                free(temp);

                /* Set up to test the next parent.  */
                cwd_stat = xstat(".");

                /* Stop reading this directory.  */
                found = true;
            }
        }
        if (!found)
            LIB_FATAL2("No inode %d/device %d in parent directory",
                   cwd_stat.st_ino, cwd_stat.st_dev);

        xclosedir(parent_dir);
    }

    /* If the current directory is the root, cwd_path will be the empty
       string, and we will have not gone through the loop.  */
    if (*cwd_path == 0)
        strcpy(cwd_path, "/");
    else
        /* Go back to where we were.  */
        xchdir(cwd_path);

#ifdef DOSISH
    /* Prepend the drive letter to CWD_PATH, since this technique
       never tells us what the drive is.

       Note that on MS-DOS/MS-Windows, the branch that works around
       missing `getwd' will probably only work for DJGPP (which does
       have `getwd'), because only DJGPP reports meaningful
       st_ino numbers.  But someday, somebody might need this...  */
    {
        char drive[3];
        string temp = cwd_path;

        /* Make the drive letter lower-case, unless it is beyond Z: (yes,
           there ARE such drives, in case of Novell Netware on MS-DOS).  */
        drive[0] = root_stat.st_dev + (root_stat.st_dev < 26 ? 'a' : 'A');
        drive[1] = ':';
        drive[2] = '\0';

        cwd_path = concat(drive, cwd_path);
        free(temp);
    }
#endif

    return cwd_path;
#endif /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */
}
Esempio n. 7
0
procps_status_t* alloc_procps_scan(int flags)
{
	procps_status_t* sp = xzalloc(sizeof(procps_status_t));
	sp->dir = xopendir("/proc");
	return sp;
}