Re: Questions re the new mount_setattr(2) manual page
From: Michael Kerrisk (man-pages) <hidden>
Date: 2021-08-12 22:32:19
Also in:
linux-man, lkml
Hi Christian, [...] Thanks for checking the various wordinfs. [...]
quoted
quoted
quoted
quoted
quoted
quoted
int fd_tree = open_tree(-EBADF, source, OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH | (recursive ? AT_RECURSIVE : 0));??? What is the significance of -EBADF here? As far as I can tell, it is not meaningful to open_tree()?I always pass -EBADF for similar reasons to [2]. Feel free to just use -1.???? But here, both -EBADF and -1 seem to be wrong. This argument is a dirfd, and so should either be a file descriptor or the value AT_FDCWD, right?[1]: In this code "source" is expected to be absolute. If it's not absolute we should fail. This can be achieved by passing -1/-EBADF, afaict.D'oh! Okay. I hadn't considered that use case for an invalid dirfd. (And now I've done some adjustments to openat(2),which contains a rationale for the *at() functions.) So, now I understand your purpose, but still the code is obscure, since * You use a magic value (-EBADF) rather than (say) -1. * There's no explanation (comment about) of the fact that you want to prevent relative pathnames. So, I've changed the code to use -1, not -EBADF, and I've added some comments to explain that the intent is to prevent relative pathnames. Okay?Sounds good.quoted
But, there is still the meta question: what's the problem with using a relative pathname?Nothing per se. Ok, you asked so it's your fault: When writing programs I like to never use relative paths with AT_FDCWD because. Because making assumptions about the current working directory of the calling process is just too easy to get wrong; especially when pivot_root() or chroot() are in play. My absolut preference (joke intended) is to open a well-known starting point with an absolute path to get a dirfd and then scope all future operations beneath that dirfd. This already works with old-style openat() and _very_ cautious programming but openat2() and its resolve-flag space have made this **chef's kiss**. If I can't operate based on a well-known dirfd I use absolute paths with a -EBADF dirfd passed to *at() functions.
Thanks for the clarification. I've noted your rationale in a comment in the manual page source so that future maintainers will not be puzzled! Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/