mirror of
https://github.com/clearlinux/graphene.git
synced 2026-10-04 16:08:22 +00:00
[Pal/{Linux,FreeBSD}] Force _DkReceiveHandle() to return PAL_ERROR_TRYAGAIN on interrupt
Previously, if an interrupt happened during recvmsg() syscall while receiving object handles on parent-child socket, syscall was interrupted, the handle was only partially initialized, but Pal ignored this error. This commit forces _DkReceiveHandle() to return PAL_ERROR_TRYAGAIN in case of such an interrupt (or return PAL_ERROR_DENIED on "impossible" case of receiving a partial header).
This commit is contained in:
committed by
Dmitrii Kuvaiskii
parent
dbfda19421
commit
58bc2a7813
@@ -384,12 +384,26 @@ int _DkReceiveHandle(PAL_HANDLE hdl, PAL_HANDLE * cargo)
|
||||
hdr.msg_flags = 0;
|
||||
|
||||
int ret = INLINE_SYSCALL(recvmsg, 3, ch, &hdr, 0);
|
||||
if (IS_ERR(ret) || ret < sizeof(struct hdl_header)) {
|
||||
if (!IS_ERR(ret))
|
||||
if (IS_ERR(ret))
|
||||
return unix_to_pal_error(ERRNO(ret));
|
||||
if (ret < sizeof(struct hdl_header)) {
|
||||
/*
|
||||
* This code block is just in case to cover all the possibilities.
|
||||
* We know that the file descriptor is an unix domain socket with
|
||||
* blocking mode and that the sender, _DkSendHandle() above, sends the
|
||||
* header with single sendmsg syscall which transfers message atomically.
|
||||
*
|
||||
* read size == 0: return error for the caller to try again.
|
||||
* It should result in EINTR.
|
||||
*
|
||||
* read size > 0: return error for the caller to give up this file
|
||||
* descriptor.
|
||||
* If the header can't be send atomically for some
|
||||
* reason, the sender should get EMSGSIZE.
|
||||
*/
|
||||
if (!ret)
|
||||
return -PAL_ERROR_TRYAGAIN;
|
||||
|
||||
if (ERRNO(ret) != EINTR && ERRNO(ret) != ERESTART)
|
||||
return -ERRNO(ret);
|
||||
return -PAL_ERROR_DENIED;
|
||||
}
|
||||
|
||||
// initialize variables to get body
|
||||
|
||||
@@ -392,13 +392,26 @@ int _DkReceiveHandle(PAL_HANDLE hdl, PAL_HANDLE * cargo)
|
||||
hdr.msg_flags = 0;
|
||||
|
||||
int ret = INLINE_SYSCALL(recvmsg, 3, ch, &hdr, 0);
|
||||
|
||||
if (IS_ERR(ret) || (size_t)ret < sizeof(struct hdl_header)) {
|
||||
if (!IS_ERR(ret))
|
||||
if (IS_ERR(ret))
|
||||
return unix_to_pal_error(ERRNO(ret));
|
||||
if ((size_t)ret < sizeof(struct hdl_header)) {
|
||||
/*
|
||||
* This code block is just in case to cover all the possibilities.
|
||||
* We know that the file descriptor is an unix domain socket with
|
||||
* blocking mode and that the sender, _DkSendHandle() above, sends the
|
||||
* header with single sendmsg syscall which transfers message atomically.
|
||||
*
|
||||
* read size == 0: return error for the caller to try again.
|
||||
* It should result in EINTR.
|
||||
*
|
||||
* read size > 0: return error for the caller to give up this file
|
||||
* descriptor.
|
||||
* If the header can't be send atomically for some
|
||||
* reason, the sender should get EMSGSIZE.
|
||||
*/
|
||||
if (!ret)
|
||||
return -PAL_ERROR_TRYAGAIN;
|
||||
|
||||
if (ERRNO(ret) != EINTR && ERRNO(ret) != ERESTART)
|
||||
return -ERRNO(ret);
|
||||
return -PAL_ERROR_DENIED;
|
||||
}
|
||||
|
||||
// initialize variables to get body
|
||||
|
||||
Reference in New Issue
Block a user