From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/13147 Path: news.gmane.org!.POSTED!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: [PATCH] Preserve select() behavior on arm64 Date: Wed, 29 Aug 2018 18:42:47 -0400 Message-ID: <20180829224247.GQ1878@brightrain.aerifal.cx> References: <20180525205240.20319-1-peter@meraki.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: blaine.gmane.org 1535582459 21959 195.159.176.226 (29 Aug 2018 22:40:59 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 29 Aug 2018 22:40:59 +0000 (UTC) User-Agent: Mutt/1.5.21 (2010-09-15) To: musl@lists.openwall.com Original-X-From: musl-return-13163-gllmg-musl=m.gmane.org@lists.openwall.com Thu Aug 30 00:40:55 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1fv98x-0005ca-8r for gllmg-musl@m.gmane.org; Thu, 30 Aug 2018 00:40:55 +0200 Original-Received: (qmail 29895 invoked by uid 550); 29 Aug 2018 22:43:01 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 29864 invoked from network); 29 Aug 2018 22:43:00 -0000 Content-Disposition: inline In-Reply-To: <20180525205240.20319-1-peter@meraki.com> Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:13147 Archived-At: On Fri, May 25, 2018 at 01:52:40PM -0700, Peter Hurley wrote: > On Linux, all the select-related syscalls update the timeout value to > indicate how much elapsed time the syscall consumed, and many programs > expect this behavior when running on Linux. > > Newer archs like arm64 have deprecated the select syscall because the > pselect syscall is a superset implementation of the select syscall. > > A complication of implementing select() with the pselect syscall is > that the timeouts are specified in different units; select() accepts > a struct timeval ptr whereas the pselect syscall takes a struct > timespec ptr. These are trivial convertible; struct timeval is > specified in seconds + microseconds and struct timespec is in > seconds + nanoseconds. > > For kernel configurations without select syscall available, update the > caller's struct timeval argument after the pselect syscall. > --- > src/select/select.c | 17 +++++++++-------- > 1 file changed, 9 insertions(+), 8 deletions(-) > > diff --git a/src/select/select.c b/src/select/select.c > index 7b5f6dcf7a53..45d4cb7a3d0a 100644 > --- a/src/select/select.c > +++ b/src/select/select.c > @@ -12,15 +12,16 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict > #else > syscall_arg_t data[2] = { 0, _NSIG/8 }; > struct timespec ts; > + int result; > if (tv) { > - if (tv->tv_sec < 0 || tv->tv_usec < 0) > - return __syscall_ret(-EINVAL); > - time_t extra_secs = tv->tv_usec / 1000000; > - ts.tv_nsec = tv->tv_usec % 1000000 * 1000; > - const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1; > - ts.tv_sec = extra_secs > max_time - tv->tv_sec ? > - max_time : tv->tv_sec + extra_secs; > + ts->tv_sec = tv->tv_sec; > + ts->tv_nsec = tv->usec * 1000; > } > - return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data); > + result = syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data); > + if (tv) { > + tv->tv_sec = ts->tv_sec; > + tv->tv_usec = ts->tv_nsec / 1000; > + } > + return result; > #endif > } > -- > 2.14.2 Sorry for not replying to this sooner. I was unsure what to say at first and then it just slipped my mind to go back to it. Normally we don't aim to duplicate behavior that is explicitly documented as non-portable, because programs depending on it should be fixed (they're already broken on many non-linux systems). Where it varies by arch because of implementation details like the above (whether there's a SYS_select or SYS_pselect has to be used) maybe the principle of consistent behavior across archs has something to say here. I'd almost rather do it the opposite (modern/pselect-like) direction, making a copy of the struct to pass to SYS_select so the caller's copy doesn't get clobbered, but maybe you like that even less.. Thoughts from anyone else? Rich