[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:
Isaku Yamahata
2019-06-26 13:19:46 -07:00
committed by Dmitrii Kuvaiskii
parent dbfda19421
commit 58bc2a7813
2 changed files with 38 additions and 11 deletions
+19 -5
View File
@@ -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
+19 -6
View File
@@ -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