-
Couldn't load subscription status.
- Fork 8.1k
lib: posix: syscall for pipe(2) #24433
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
lib: posix: syscall for pipe(2) #24433
Conversation
|
Does anyone have a pointer on how to quickly test code either natively or virtually (with Qemu)? Is there a BOARD that just runs an image inside of Qemu that allows you to step debug? |
|
Some checks failed. Please fix and resubmit. checkpatch issuesTip: The bot edits this comment instead of posting a new one, so you can check the comment's history to see earlier messages. |
Yes, standard BOARD=qemu_x86 allows debugging using gdb, by following instructions in the Zephyr docs: https://docs.zephyrproject.org/latest/application/index.html?highlight=gdb#id1 . (Disclaimer: I don't do gdb debugging too frequently, and didn't do it for a while, but any time I did, following instructions worked for me. If you face any issues, let us know.) |
Ack. More specifically, "via private (Zephyr kernel-only) request codes using ioctl". That's done to not bloat vmethod table for fd types (and thus save some ROM space (including function prologs/epilogs)): only performance-bottleneck operations like read/write are worth separate vmethod, less frequent operation can be multiplexed via a single vmethod (ioctl). |
That sounds good, but I'd suggest to split stat-related changes into a separate commit, as they're not directly related to pipe(). |
|
Also I see that you make changes to libc/minimal/include/sys/stat.h, that's again good, but please don't forget that this code should work also with |
lib/posix/pipe.c
Outdated
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.
Do we really need a level of indirection here? Why don't store struct pipe_fd_object* directly here?
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.
My initial thought was that I should be able to look up the other end of the pipe with some reliability other than just dereferencing a (possibly invalid) pointer, because closing a pipe from the write end does not automatically close the read end, and vice-versa.
From http://man7.org/linux/man-pages/man7/pipe.7.html :
If all file descriptors referring to the write end of a pipe have been closed, then an attempt to read(2) from the pipe will see end- of-file (read(2) will return 0). If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process. If the calling process is ignoring this signal, then write(2) fails with the error EPIPE.
There are possible race conditions though.
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.
Let me ask first - does k_pipe have a semaphore or mutex?
I'm not author of k_pipe, and don't keep entire picture of Zephyr kernel in mind, so to answer that, would need to consult docs and/or source, which hopefully you can get to earlier than me (working on sth else now).
Is it possible to notify a thread that is waiting on it? I haven't gotten there yet, so just thought it would be useful to consider a situation where I need to check whether a fd is valid.
Not sure how that would be related to check whether a fd is valid. You'd definitely need to block on an empty k_pipe in POSIX read() implementation. And for robust impl, would apparently need to cancel such a read in case write end is closed. Both are possible with k_fifo (which socket code uses), not sure about k_pipe, would need to check docs.
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.
Hmm... I might need to look into k_fifo then. k_pipe definitely is a little wonky in its API. E.g. K_FOREVER and min_xfer == 1 block indefinitely, even when min_xfer can be satisfied.
Those macros were copied from newlib ;-) |
WIP implementation for pipe(2). Fixes #24426. Signed-off-by: Christopher Friedt <[email protected]>
|
Couldn't get tests running with qemu_x86 because it was complaining about toolchain variables, so I just went with qemu_cortex_m3. The pipe(), write(), read(), close() tests are working (see below). However, I noticed a some weird things.
|
|
the read and write functions are so similar that I should really try to combine them. |
|
@cfriedt: Thanks for the patch. I would like to check that you're still interested to proceed with this patch given the discussion at #24426 (comment) . If you're, first thing please fix review comments from our codestyle bot. (It's pretty much a default process that human reviewers chime into review process after the codestyle and CI checks pass.) |
|
Going to close this for the time being since I opted to implement socketpair(2) without using pipe(2). |
This is a WIP. Just putting it out there to see if there are any pointers.
I don't feel like it will be difficult to implement the
read,writeorioctlcallbacks.FWIU,
close(2)andfcntl(2)are implemented usingioctl.I did add the st_mode field for
struct statas well as a few related macros.The read end of the file descriptor will have the
S_IRUSRbit set, while the write end of the pipe will have theS_IWUSRbit set.Functions would be able to easily tell it was a pipe (or socket or regular file) if we also had
fstat(2).Also, this is a requirement for #24367 .