-
Notifications
You must be signed in to change notification settings - Fork 2k
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
cpu/native: make use of stdio_read() / stdio_write() #16822
Conversation
33827e3
to
1f50d08
Compare
Ok turns out guarding the read / write with |
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 to me. Some comments inline.
I had some hope this would help with #16834 but it does not. |
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 missing STDERR, which i assume should be handled similar to STDOUT.
Having a deeper look it i think:
the whole printf and getchar system seems to avoid going through riots VFS making them kind of disconnected from each other.
- Shouldn't _native_write call vfs.write?
Maybe someone with a better insight into this VFS (e.g.: @kaspar030) can comment on that.
That's somewhat the point, as |
I was thinking of that as a feature, but you are right that it's more consistent that way, fixed. |
The issue is that read() etc. are blocking syscalls, even when used as _native_read() etc. |
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.
With comments by miri64 and kaspar030, i think the non-blocking read is out of scope for this PR. I tried something with async_read in stdio_native and this patch helped in doing so.
This PR also changes how stdio works into the form someone reading the directory structure in native would expect it to do.
Lets avoid the scope creep. 🚀
cpu/native/syscalls.c
Outdated
ssize_t res = stdio_write(iov->iov_base, iov->iov_len); | ||
iov++; |
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.
I think res
needs to be compared to iov->iov_len
before advancing to next element,
(there are stdio implementations in RIOT that might not write everything given to them (avoid blocking))
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.
2402326 should fix this
(Is this function actually ever used in RIOT?)
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.
(Is this function actually ever used in RIOT?)
afaik there is/was something in glibc that uses it for something more common
cpu/native/syscalls.c
Outdated
ssize_t res = stdio_write((void *)((uintptr_t)iov->iov_base + offset), | ||
iov->iov_len - offset); | ||
if (res < 0) { | ||
return res; |
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.
return res; | |
if (r > 0 )return r; else return res; |
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.
Is that how writev
is supposed to behave oO?
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.
Manpage says:
On success, readv(), preadv(), and preadv2() return the number of bytes read;\
writev(), pwritev(), and pwritev2() return the number of bytes written.
Note that it is not an error for a successful call to transfer fewer bytes than\
requested (see read(2) and write(2))
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.
Spec is a bit different 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.
I am not sure about that since the the spec says return bytes written on success, which it does not defined by it, but the manpage does so, as any byte written is a success.
On the other hand the specs define the unsuccess (error) as the fd is not changed -> nothing is written?
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.
Please rephrase... not really sure what you mean.
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.
the spec says:
Upon successful completion, writev() shall return the number of bytes actually written.
but it does not define success,
but it defines the unsuccess (error) case
Otherwise, it shall return a value of -1, the file-pointer shall remain unchanged,\
and errno shall be set to indicate an error.
this says the the file-pointer shall remain unchanged
on error i am not sure if there is a file-point file/char-device content equality but if there is this means the nothing has to be written if -1 if returned.
the manpage on the other hand defines the success as a partial write
Note that it is not an error for a successful call to transfer fewer bytes than requested
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.
the write manpage (advertised by the writev page) goes into detail howto get the error state:
In the event of a partial write, the caller can make another write()\
call to transfer the remaining bytes. \
The subsequent call will either transfer further bytes or may result \
in an error (e.g., if the disk is now full)
cpu/native/syscalls.c
Outdated
size_t offset = 0; | ||
while (iov->iov_len > offset) { | ||
ssize_t res = stdio_write((void *)((uintptr_t)iov->iov_base + offset), | ||
iov->iov_len - offset); | ||
if (res < 0) { | ||
return res; | ||
} | ||
offset += res; | ||
} | ||
r += offset; |
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.
i would avoid the inner loop: (return on the first write that is less than it was asked to the app would be expected to repead the write as it is written in the manpage)
size_t offset = 0; | |
while (iov->iov_len > offset) { | |
ssize_t res = stdio_write((void *)((uintptr_t)iov->iov_base + offset), | |
iov->iov_len - offset); | |
if (res < 0) { | |
return res; | |
} | |
offset += res; | |
} | |
r += offset; | |
ssize_t res = stdio_write((void *)((uintptr_t)iov->iov_base), | |
iov->iov_len); | |
if( res >= 0 ){ | |
r += res; | |
} | |
if (res < iov->iov_len) { | |
return (r>=0) ? r : res; | |
} |
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.
Ok, changed it - this is a strange API
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 PR also changes how stdio works into the form someone reading the directory structure in native would expect it to do.
I tried something with async_read in stdio_native and this patch helped to do so.
please squash |
On `native` the functions stdio_read() / stdio_write() were not used. Those functions are intended for alternative stdio implementations. As a result, no alternative stdio could be used on `native`. To fix this, call the functions in `_native_read()` / `_native_write()` when dealing with stdio fds.
05f65a2
to
13e16fa
Compare
Contribution description
On
native
the functions stdio_read() / stdio_write() were not used.Those functions are intended for alternative stdio implementations.
As a result, no alternative stdio could be used on
native
.To fix this, call the functions in
_native_read()
/_native_write()
when dealing with stdio fds.Testing procedure
native
applications should work as before.But now alternative stdio implementations are possible.
Issues/PRs references
needed for #16723 to work on
native