utils: fix print_r() debugging helper

parent 5bd52b01
...@@ -1846,19 +1846,34 @@ int fix_stdio_permissions(uid_t uid) ...@@ -1846,19 +1846,34 @@ int fix_stdio_permissions(uid_t uid)
int print_r(int fd, const char *path) int print_r(int fd, const char *path)
{ {
__do_close int dfd = -EBADF; __do_close int dfd = -EBADF, dfd_dup = -EBADF;
__do_closedir DIR *dir = NULL; __do_closedir DIR *dir = NULL;
int ret = 0; int ret = 0;
struct dirent *direntp; struct dirent *direntp;
struct stat st; struct stat st;
if (is_empty_string(path)) if (is_empty_string(path)) {
dfd = dup(fd); char buf[LXC_PROC_SELF_FD_LEN];
else
dfd = openat(fd, path, O_CLOEXEC | O_DIRECTORY); ret = strnprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
if (ret < 0)
return ret_errno(EIO);
/*
* O_PATH file descriptors can't be used so we need to re-open
* just in case.
*/
dfd = openat(-EBADF, buf, O_CLOEXEC | O_DIRECTORY, 0);
} else {
dfd = openat(fd, path, O_CLOEXEC | O_DIRECTORY, 0);
}
if (dfd < 0) if (dfd < 0)
return -1; return -1;
dfd_dup = dup_cloexec(dfd);
if (dfd_dup < 0)
return -1;
dir = fdopendir(dfd); dir = fdopendir(dfd);
if (!dir) if (!dir)
return -1; return -1;
...@@ -1870,26 +1885,29 @@ int print_r(int fd, const char *path) ...@@ -1870,26 +1885,29 @@ int print_r(int fd, const char *path)
!strcmp(direntp->d_name, "..")) !strcmp(direntp->d_name, ".."))
continue; continue;
ret = fstatat(dfd, direntp->d_name, &st, AT_SYMLINK_NOFOLLOW); ret = fstatat(dfd_dup, direntp->d_name, &st, AT_SYMLINK_NOFOLLOW);
if (ret < 0 && errno != ENOENT) if (ret < 0 && errno != ENOENT)
break; break;
ret = 0; ret = 0;
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
ret = print_r(dfd, direntp->d_name); ret = print_r(dfd_dup, direntp->d_name);
else else
INFO("mode(%o):uid(%d):gid(%d) -> %s/%s\n", INFO("mode(%o):uid(%d):gid(%d) -> %d/%s\n",
(st.st_mode & ~S_IFMT), st.st_uid, st.st_gid, path, (st.st_mode & ~S_IFMT), st.st_uid, st.st_gid, dfd_dup,
direntp->d_name); direntp->d_name);
if (ret < 0 && errno != ENOENT) if (ret < 0 && errno != ENOENT)
break; break;
} }
ret = fstatat(fd, path, &st, AT_SYMLINK_NOFOLLOW); if (is_empty_string(path))
ret = fstatat(fd, "", &st, AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH);
else
ret = fstatat(fd, path, &st, AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW);
if (ret) if (ret)
return -1; return -1;
else else
INFO("mode(%o):uid(%d):gid(%d) -> %s", INFO("mode(%o):uid(%d):gid(%d) -> %s",
(st.st_mode & ~S_IFMT), st.st_uid, st.st_gid, path); (st.st_mode & ~S_IFMT), st.st_uid, st.st_gid, maybe_empty(path));
return ret; return ret;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment