On Monday, 18 September 2017 16:59:04 PDT torto...@gmail.com wrote:
> Possibly slightly off topic but bear with me.
> Do C, C++ and Posix require a way to re-open a file descriptor?
>
> The two common cases are:
> * I have a file and after reading it I may decide I want to write it after
> all.
> * I create a new file and having finished setting it up I want to make it
> read only.
There's no such API. The closest I can think of is fcntl(F_SETFL), which won't
work. http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
says for F_SETFL:
"Bits corresponding to the file access mode and the file creation flags, as
defined in <fcntl.h>, that are set in arg shall be ignored."
Other possibilities I investigated:
1) using openat(2) with an empty path and the open file descriptor as the dfd:
this results in ENOENT because of the empty path (openat has no field to pass
AT_EMPTY_PATH). If you pass any non-empty path, you get ENOTDIR.
2) using first open(2) with O_PATH (Linux-specific) and then trying to open
that. Also fails the same way.
However, on Linux, you can make it work by opening "/proc/self/fd/%d" with the
file descriptor number. This will work even if the file has been deleted or was
not even present in the file system somewhere you could find. It also works for
file descriptors of other processes.
> So my question is should we try make this possible?
> For example we might:
>
> * make the behaviour of freopen() fully defined for the case of converting
> a FILE* from read to write or write to read
> (something for WG14 not directly in scope for C++)
freopen doesn't help because it's a process-local thing. It's not an operating
system object. You can't pass FILE* over Unix sockets and child processes
can't inherit them.
> * add a new function to Posix like:
> int reopen(int fd, int flags)
> (something for ŧhe Austin group not directly in scope for C++)
First, you implement it in the major OSes to show it is possible. Then POSIX
may adopt it.
This was first one for O_CLOEXEC, which allows for thread-safe opening of file
descriptors. I also see O_NOSIGPIPE as a future standardisation possibility,
based on existing practice.
reopen() doesn't exist yet.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
On Tuesday, 19 September 2017 01:15:11 PDT torto...@gmail.com wrote:
> > I did find that trick but it is still opening a path. When I first tried
>
> it I had accidentally
> create the file with the wrong permissions and unsurprisingly got an EPERM.
> If you were really re-opening using the file descriptor that would not
> apply.
If the file can't be opened, it shouldn't be reopenable either. Note that you
can do open(O_RDWR, 0400).
Now, the details of your issue here are relevant. You're brushing them over,
so if you want a discussion of the use-case, go back and look at what you did
wrong when reopening /proc/self/fd/%d.
> I suppose my question here is, if its such am obvious and good idea why
> hasn't it been done already?
> I suspect as I discovered with accessing low level file descriptors there
> are some interesting corner cases to think about,
> especially as this is once again at the intersection of at least 3
> standards.
Because I suppose there isn't such a big need. There aren't many uses of file
descriptor passing to require this feature often enough. That's where you need
OS-provided enforcement.
If you meant protection against accidental writes, then updating FILE* and
std::fstream is fine. That's enforcement by the API, but with no protection
against malicious code doing write(fileno(fptr), "h4x0rz", 6).
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
Possibly slightly off topic but bear with me.
Do C, C++ and Posix require a way to re-open a file descriptor?
The two common cases are:
* I have a file and after reading it I may decide I want to write it after all.
* I create a new file and having finished setting it up I want to make it read only.
Recent discussions about race free file systems have made me more aware of the potential problems with this.
When going from read to write you do need a permission check but the other way around you do not.
Ideally you should be able to re-open based on the file handle or descriptor to avoid a race if the file is moved, renamed or deleted.
This is similar to the situation with moving locks from shared read to write and back that can also be weak on Posix.
I can't see this functionality in AFIO. Was it considered? Perhaps rejected because there is not currently a portable solution?
I can't see this functionality in AFIO. Was it considered? Perhaps rejected because there is not currently a portable solution?Honestly it's because nobody made me think of it until now.Expect to see it land by end of week at the latest :) It's trivially easy to implement. It's a good idea, and thanks for suggesting it.
> BTW Thiago you may be interested to learn that I wrote a template adapter
> which lets you adapt any afio::handle to no longer rely on path retrieval
> working (correctly/at all). It's on the user to instantiate adapted handles
> however as they incur significant runtime overhead.
My kernel developer colleagues advised against relying on readlink(2) on
/proc/self/fd. It's not meant for the purpose you want it to. So my
recommendation is that you redesign so that retrieving the path name is an
optional and possibly-failing feature.