-
Notifications
You must be signed in to change notification settings - Fork 98
Bind fdopendir and openat
#110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a6894f6 to
a570f74
Compare
|
ping |
|
Sorry haven't yet had time to review this. I'm a bit worried about two things here: a) routing everything through Are we sure all non-EOL'ed target platforms provide/support |
|
The package description specifies POSIX.1-2008. Is somewhere a list of supported platforms of this package? I checked all supported Unix platforms of GHC and they all have both |
|
I only mentioned POSIX.1-2008 because this means these could be recent enough that some less mainstream platforms we support may not have supported them yet. And if that's the case, we'd need to consider conditional compilation & autoconf tests. Unfortunately I don't have a comprehensive list of supported platforms but we also support e.g. AIX, Solaris, OpenBSD and Android |
|
PTAL |
|
ping |
1 similar comment
|
ping |
|
@hvr ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hvr what is blocking this? This is required to fix dangerous bugs in the directory package: haskell/directory#97 and #134
System/Posix/Directory/Common.hsc
Outdated
| module System.Posix.Directory.Common ( | ||
| DirStream(..), CDir, CDirent, DirStreamOffset(..), | ||
| #ifdef HAVE_FDOPENDIR | ||
| openDirStreamFd, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, this should be in its own module System.Posix.Directory.Fd, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
System/Posix/Directory/Common.hsc
Outdated
| data {-# CTYPE "struct dirent" #-} CDirent | ||
|
|
||
| #ifdef HAVE_FDOPENDIR | ||
| -- | @openDirStreamFd fd@ calls @fdopendir@ to obtain a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should document that you must not close the file descriptor afterwards with a link to the POSIX documentation and that the file descriptor is closed when the stream is closed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
@Rufflewind @hvr ping |
|
@hvr ping |
|
Guys, why is no one responding here? It's discouraging for contributors to wait 2 years for actionable input. |
| OpenMode(..), | ||
| OpenFileFlags(..), defaultFileFlags, | ||
| openFd, createFile, | ||
| openFd, openFdAt, createFile, createFileAt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not openFdAt and createFileAt be guarded by #ifdef HAVE_OPENAT?
System/Posix/IO.hsc
Outdated
| -> IO Fd | ||
| openFd = openFdAt Nothing | ||
|
|
||
| openFdAt :: Maybe Fd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add a haddock comment for openFdAt.
System/Posix/IO.hsc
Outdated
| createFile :: FilePath -> FileMode -> IO Fd | ||
| createFile = createFileAt Nothing | ||
|
|
||
| createFileAt :: Maybe Fd -> FilePath -> FileMode -> IO Fd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add a haddock comment for createFileAt.
System/Posix/IO/ByteString.hsc
Outdated
| -> IO Fd | ||
| openFd = openFdAt Nothing | ||
|
|
||
| openFdAt :: Maybe Fd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add a haddock comment for openFdAt.
System/Posix/IO/ByteString.hsc
Outdated
| createFile :: RawFilePath -> FileMode -> IO Fd | ||
| createFile = createFileAt Nothing | ||
|
|
||
| createFileAt :: Maybe Fd -> RawFilePath -> FileMode -> IO Fd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add a haddock comment for createFileAt.
| OpenMode(..), | ||
| OpenFileFlags(..), defaultFileFlags, | ||
| openFd, createFile, | ||
| openFd, openFdAt, createFile, createFileAt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not openFdAt and createFileAt be guarded by #ifdef HAVE_OPENAT?
|
thank you for getting this rolling @Bodigrim |
|
Please double check this code on mac! I have a similar code: https://github.com/hasufell/hpath/blob/06b5a46cf81371204870ad3ebf78af2e59fbbdd7/hpath-posix/src/System/Posix/RawFilePath/Directory/Traversals.hs#L179 And https://travis-ci.org/github/hasufell/hpath/jobs/674795844#L1167-L1168 I'm not sure why. The use of EDIT: @cartazio debugged this and it appears there are two possible functions for fdopendir https://opensource.apple.com/source/Libc/Libc-1244.1.7/include/dirent.h.auto.html One of them crashes hard and the above code will trigger it. The fix was to use: foreign import capi unsafe "dirent.h fdopendir"
c_fdopendir :: Posix.Fd -> IO (Ptr CDir) |
|
emphasizing what @hasufell says, at least on OSX, a number of newer unix calls really need to be bound via capi (an implicit header aware c wrapper) or an explicit c call with the correct system headers included reproducing the example also mentioned above that i cooked up and shared with julian: foreign import capi unsafe "dirent.h fdopendir"
c_fdopendir :: Posix.Fd -> IO (Ptr CDir)the header part of the capi syntax is crucial for this to compile and link correctly! (its actually impossible to bind the correct underlying system call symbol directly) |
|
wtf just merge it already |
The code is broken. See above. |
|
The code works on linux and doesn't break anything. If it's bugged on some other platform, it could be addressed separately as a bugfix. Meanwhile, MacOS doesn't even strive to be POSIX these days it seems: https://www.quora.com/Is-Mac-OS-X-more-POSIX-compliant-than-Linux/answer/Madars-Oz |
|
Julian and I figured out how to correctly bind some of this stuff on OS X. But incorrectly binding it will make programs flat out crash and silently corrupt data. A pr that does the capi indirection would be safe to merge. But this pr is flat out wrong. Someone prepare a pr that does the capi stuff and then we can make it work |
|
Cc @Bodigrim and victor |
|
@l29ah currently the only OS forbidden to use Lines 67 to 71 in f7b956c
So even if MacOS is not POSIX compliant, we cannot just silently break it. |
|
Also the function definition can be put under a conditional if you don't want to create a false hope for Mac users. |
|
Bodigrim: it looks like the binding is capi based now. @hasufell what was the min version of mac we found that supported this call? |
|
@l29ah Providing conditional API is an option, but so far |
|
I've rebased this PR on master and pushed two fixup commits to address the All CI targets now pass. It just remains to do a final closer review, but we should be able to merge this (perhaps squashed) soon barring unexpected issues. |
hs-viktor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is almost done, but I am concerned about the conditionally defined functions. I don't see how a dependent application or library can safely make use of these functions, in the sense that it will at least reliably compile on all platforms. Do they need to also run configure and use HAVE_OPENAT, ...?
There should likely be some way to discover whether these are available at runtime. So some sort of stub implementation needs to exist, and some way to test whether the function is expected to work, or whether the caller should take an alternative code path (or give up).
Perhaps just simple boolean predicates that are exported along with these?
Unless we've reached the point where the only supported Posix platforms all have openat, et. al. and we just fail to build unix otherwise. So that these are then always available.
System/Posix/Directory/Common.hsc
Outdated
| #ifdef HAVE_FDOPENDIR | ||
| -- | @unsafeOpenDirStreamFd fd@ calls @fdopendir@ to obtain a directory stream | ||
| -- for @fd@. @fd@ must not be otherwise used after this; see | ||
| -- <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html POSIX>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps worth mentioning that if an exception is thrown here, closing the file descriptor remains the responsibility of the caller, who may need to use something like bracketOnError to handle this possibility.
Alternatively, perhaps this function should arrange to close the descriptor if c_fdopendir fails. This way the descriptor is never leaked. I'm inclined to recommend this approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Bodigrim I see you've approved the MR, but perhaps you did not notice the above issue/question amidst the flurry of activity to resolve the easier obstacles. I do think we still need to do something here...
One simple way to handle these is to export a case getOpenFdAt of
Just f -> f ...
Nothing -> ...which, with appropriate inlining, will optimise out the test and take just the appropriate branch. |
|
The openat function was added in:
Has it been established long enough that we can just require it unconditionally? |
|
The timeline for
Pretty much the same, but slightly older with NetBSD. So if we can require |
Yes, I believe 5+ years are enough. It is better to enable it unconditionally now than have a breaking switch from |
|
Sounds good to me
…On Mon, Feb 15, 2021 at 5:05 PM Bodigrim ***@***.***> wrote:
Has it been established long enough that we can just require it
unconditionally?
Yes, I believe 5+ years are enough. It is better to enable it
unconditionally now than have a breaking switch from Maybe T to T in
future, or pay for Maybe infinitely long.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#110 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAABBQTHZFYQYHQJE24MGKTS7GLEHANCNFSM4E6YBVTQ>
.
|
|
The latest commit drops the Separately from this MR, I really dislike the way that the file open flags are handled. We only support a fixed subset, hard-code as a list of booleans in a structure. This is IMHO awful. It screams out for pattern synonyms and a single numeric flag field, that users can set to values that are not yet known to the library, if they know what they're doing. I should open a separate issue... |
hs-viktor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disposition of file descriptor passed to fdopendir when the call fails remains as yet unaddressed. Should it be automatically closed (I think so), but otherwise callers need to know that they have to catch the exception and do something with the descriptor.
|
I'm in favor of closing it automatically. |
OK, I'll arrange to close it with Nothing in |
This way the caller never ends up owning the fd after the call. Otherwise, cleanup of either the DirStream or else the file-descriptor would be difficult to implement correctly.
|
Final cut:
Looking at the surrounding code makes me wish for a time-machine to address other issues that will require some care, but not in this PR. :-( |
Bodigrim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
No description provided.