Beispiel #1
0
/*
 * resolve /proc/$pid/cwd
 */
int
proc_cwd(pid_t pid, char **buf)
{
	int ret;
	char *cwd, *linkcwd;
	struct stat s;

	assert(pid >= 1);
	assert(buf);

	if (asprintf(&linkcwd, "/proc/%lu/cwd", (unsigned long)pid) < 0)
		return -ENOMEM;

	ret = readlink_alloc(linkcwd, &cwd);
	free(linkcwd);
	if (ret)
		return ret;

	/* If the current working directory of a process is removed after the
	 * process started, /proc/$pid/cwd is a dangling symbolic link and
	 * points to "/path/to/current/working/directory (deleted)".
	 */
	if (stat(cwd, &s) && errno == ENOENT) {
		char *c;
		if ((c = strrchr(cwd, ' ')))
			cwd[c - cwd] = '\0';
	}

	*buf = cwd;
	return 0;
}
Beispiel #2
0
static char *readlink_slash_alloc(char *path) {
    char *p, *q, c;
    for (p = path + strlen(path); p != path && p[-1] == '/'; --p) {}
    if (p == path) return NULL;
    for (q = p; q != path && q[-1] == '/'; --q) {}
    for (; q != path && q[-1] != '/'; --q) {}
    /* Don't follow symlink if ends with /.. or /. */
    if (q[0] == '.' && (q[1] == '/' || q[1] == '\0' ||
                        (q[1] == '.' && (q[2] == '/' || q[2] == '\0')))) return NULL;
    c = *p;
    *p = '\0';
    q = readlink_alloc(path);
    *p = c;
    return q;
}
Beispiel #3
0
/* Resolve symlinks until a non-symlink is found. */
static char *readlink_alloc_all(const char *path) {
    char *path2, *path1 = strdup(path);
    while ((path2 = readlink_alloc(path1))) {
        if (path2[0] != '/') {
            char *p;
            for (p = path1 + strlen(path1); p != path1 && p[-1] != '/'; --p) {}
            if (p != path1) {
                *p = '\0';  /* Remove basename from path1. */
                p = combine_paths_dotdot_alloc(path1, path2);
                free(path2);
                path2 = p;
            }
        }
        free(path1);
        path1 = path2;
    }
    return path1;
}
Beispiel #4
0
/*
 * resolve /proc/$pid/fd/$dirfd
 */
int
proc_fd(pid_t pid, int dfd, char **buf)
{
	int ret;
	char *fd, *linkdir;

	assert(pid >= 1);
	assert(dfd >= 0);
	assert(buf);

	if (asprintf(&linkdir, "/proc/%lu/fd/%d", (unsigned long)pid, dfd) < 0)
		return -ENOMEM;

	ret = readlink_alloc(linkdir, &fd);
	free(linkdir);
	if (!ret)
		*buf = fd;
	return ret;
}
Beispiel #5
0
static char *get_up_dir_alloc(const char *dir) {
    char *dirup = NULL, *p;
    if (0 == strcmp(dir, "..") || (dirup = readlink_alloc(dir))) {
        free(dirup);
        return strdupcat(dir, "/..", "");
    }
    dirup = strdupcat(dir, ".", "");
    for (p = dirup + strlen(dirup) - 1; p != dirup && p[-1] != '/'; --p) {}
    if (p == dirup) {
        *p++ = '.';
        if (0 == strcmp(dir, ".")) *p++ = '.';
        *p = '\0';
    } else if (dirup[0] == '/' && dirup[1] == '\0') {
        fdprint(2, strdupcat("xstatic: error: no parent dir for: ", dir, "\n"));
        exit(122);
    } else {
        p[-1] = '\0';  /* Remove basename of dirup. */
    }
    return dirup;
}