NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/58929: POSIX.1-2024 compliance: posix_close, POSIX_CLOSE_RESTART



The following reply was made to PR kern/58929; it has been noted by GNATS.

From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: kern/58929: POSIX.1-2024 compliance: posix_close, POSIX_CLOSE_RESTART
Date: Sat, 21 Dec 2024 22:07:19 +0000

 Correction: Our current close() -- and probably all existing close()
 implementations outside buggy proprietary Unix variants -- is not
 compliant with POSIX.1-2024, because if some underlying I/O is
 interrupted by a signal it can fail with EINTR even though the
 descriptor is unconditionally closed.  That is now forbidden (emphasis
 added):
 
 > If close() is interrupted by a signal that is to be caught, then it
 > is unspecified whether it returns -1 with errno set to [EINTR] and
 > fildes _remaining open_, or returns -1 with errno set to
 > [EINPROGRESS] and fildes being closed, or returns 0 to indicate
 > successful completion[...]
 > 
 > RATIONALE
 > 
 > [...] Note that the standard requires that close() and posix_close()
 > _must leave fildes open after [EINTR]_ (in the cases where [EINTR]
 > is permitted)
 
 So, in order to deal with POSIX.1-2024 having addressed the problem of
 its own failure to adequately specify semantics by breaking
 compatibility with every major OS on the planet, it looks like we'll
 have to do some symbol magic under _POSIX_C_SOURCE -- something like
 this:
 
 /* include/unistd.h */
 
 #if (_POSIX_C_SOURCE >= 202408L) && !defined(_NETBSD_SOURCE)
 int	close(int) __RENAME(__posixly_correct_close);
 int	posix_close(int, int);
 #define	POSIX_CLOSE_RESTART	0
 #else
 int	close(int);
 #endif
 
 /* lib/libc/sys/posixly_correct_close.c */
 
 int
 __posixly_correct_close(int d)
 {
 	const int ret = close(d);
 
 	if (ret == -1 && errno == EINTR)
 		errno = EINPROGRESS;
 
 	return ret;
 }
 
 int
 posix_close(int d, int flag)
 {
 	const int ret = __posixly_correct_close(d);
 
 	_DIAGASSERT(ret == 0 || errno != EINTR);
 
 	if (ret == 0 && flag != 0) {
 		errno = EINVAL;
 		ret = -1;
 	}
 	return ret;
 }
 
 What a colossal waste of effort -- and attack surface for new bugs to
 crawl onto -- to force everyone else to bend over backwards to
 accommodate bugs in proprietary implementations of close().
 


Home | Main Index | Thread Index | Old Index