diff --git a/include/stdlib.h b/include/stdlib.h --- a/include/stdlib.h +++ b/include/stdlib.h @@ -242,8 +242,18 @@ char *ptsname(int); int unlockpt(int); #endif /* __XSI_VISIBLE */ -#if __BSD_VISIBLE -/* ptsname_r will be included in POSIX issue 8 */ +/* + * ptsname_r is included in POSIX issue 8 (IEEE Std 1003.1-2024). + * posix_ptsname_r() is the POSIX-compliant interface (returns error number). + * ptsname_r() is the traditional FreeBSD interface (returns -1 and sets errno). + * When _POSIX_C_SOURCE >= 202405, ptsname_r is aliased to posix_ptsname_r. + */ +#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 202405) || __BSD_VISIBLE +int posix_ptsname_r(int, char *, size_t); +#endif +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 202405 +#define ptsname_r posix_ptsname_r +#elif __BSD_VISIBLE int ptsname_r(int, char *, size_t); #endif diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -133,6 +133,7 @@ FBSD_1.9 { memalignment; + posix_ptsname_r; recallocarray; strtonumx; tdestroy; diff --git a/lib/libc/stdlib/ptsname.3 b/lib/libc/stdlib/ptsname.3 --- a/lib/libc/stdlib/ptsname.3 +++ b/lib/libc/stdlib/ptsname.3 @@ -29,7 +29,7 @@ .\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS .\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 14, 2023 +.Dd February 15, 2026 .Dt PTSNAME 3 .Os .Sh NAME @@ -116,15 +116,21 @@ The .Fn ptsname_r function returns the value 0 if successful; -otherwise a nonzero value is returned and the global variable +otherwise an error number is returned to indicate the error. +.Pp +As a +.Fx +extension, the global variable .Va errno -is set to indicate the error. -Note: +is also set to indicate the error for convenience, +even though +.St -p1003.1-2024 +only requires the error number to be returned. +.Pp +When compiled without POSIX.1-2024 visibility, .Fn ptsname_r -was previously documented as returning -1 on error. -In the future it will be changed to return an error number, for POSIX -compatibility. -Therefore, callers should not check for -1. +uses the legacy FreeBSD ABI and returns -1 on error while setting +.Va errno . .Sh ERRORS The .Fn grantpt , @@ -141,7 +147,14 @@ is not a valid open file descriptor. .It Bq Er EINVAL .Fa fildes -is not a master pseudo-terminal device. +is not a master pseudo-terminal device, +or +.Po +for +.Fn ptsname_r +.Pc +.Fa buffer +is a null pointer. .El .Pp In addition, the @@ -173,6 +186,16 @@ function conforms to .St -p1003.1-2008 . .Pp +The +.Fn ptsname_r +function conforms to +.St -p1003.1-2024 , +except that +.Fx +also sets +.Va errno +as an extension. +.Pp This implementation of .Fn grantpt and @@ -195,3 +218,14 @@ .Fn unlockpt functions appeared in .Fx 5.0 . +.Pp +The +.Fn ptsname_r +function appeared in +.Fx 13.0 . +In +.Fx 16.0 , +the function was changed to return the error number directly +to conform with +.St -p1003.1-2024 , +while maintaining binary compatibility with earlier versions. diff --git a/lib/libc/stdlib/ptsname.c b/lib/libc/stdlib/ptsname.c --- a/lib/libc/stdlib/ptsname.c +++ b/lib/libc/stdlib/ptsname.c @@ -67,21 +67,27 @@ __strong_reference(__isptmaster, unlockpt); /* - * ptsname_r(): return the pathname of the slave pseudo-terminal device - * associated with the specified master. + * posix_ptsname_r(): return the pathname of the slave pseudo-terminal device + * associated with the specified master. + * POSIX-compliant: returns 0 on success, error number on failure. */ int -__ptsname_r(int fildes, char *buffer, size_t buflen) +posix_ptsname_r(int fildes, char *buffer, size_t buflen) { + if (buffer == NULL) { + errno = EINVAL; + return (errno); + } + if (buflen <= sizeof(_PATH_DEV)) { errno = ERANGE; - return (-1); + return (errno); } /* Make sure fildes points to a master device. */ if (__isptmaster(fildes) != 0) - return (-1); + return (errno); memcpy(buffer, _PATH_DEV, sizeof(_PATH_DEV)); buffer += sizeof(_PATH_DEV) - 1; @@ -90,13 +96,23 @@ if (fdevname_r(fildes, buffer, buflen) == NULL) { if (errno == EINVAL) errno = ERANGE; - return (-1); + return (errno); } return (0); } -__strong_reference(__ptsname_r, ptsname_r); +/* + * Prior to FreeBSD 16 we returned -1 on error, not an error number as is now + * specified by POSIX. + */ +int +ptsname_r(int fildes, char *buffer, size_t buflen) +{ + if (posix_ptsname_r(fildes, buffer, buflen) != 0) + return (-1); + return (0); +} /* * ptsname(): return the pathname of the slave pseudo-terminal device @@ -107,7 +123,7 @@ { static char pt_slave[sizeof(_PATH_DEV) + SPECNAMELEN]; - if (__ptsname_r(fildes, pt_slave, sizeof(pt_slave)) == 0) + if (posix_ptsname_r(fildes, pt_slave, sizeof(pt_slave)) == 0) return (pt_slave); return (NULL);