summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2020-11-09 01:56:06 +0000
committerXin LI <delphij@FreeBSD.org>2020-11-09 01:56:06 +0000
commit2daa7f9495773e2876d43d7c58670bf04fd0db6d (patch)
tree32c1663f8abf8f35e77214f1666e1f9cf12d07ad
parentec4116bfb65e40e00756bfd0dce8296c4525f30b (diff)
downloadsrc-test2-2daa7f9495773e2876d43d7c58670bf04fd0db6d.tar.gz
src-test2-2daa7f9495773e2876d43d7c58670bf04fd0db6d.zip
MFC r366781, r366866: Implement ptsname_r.
Notes
Notes: svn path=/stable/11/; revision=367512
-rw-r--r--include/stdlib.h13
-rw-r--r--lib/libc/stdlib/Makefile.inc2
-rw-r--r--lib/libc/stdlib/Symbol.map4
-rw-r--r--lib/libc/stdlib/ptsname.331
-rw-r--r--lib/libc/stdlib/ptsname.c48
5 files changed, 80 insertions, 18 deletions
diff --git a/include/stdlib.h b/include/stdlib.h
index 1e94672a94fa..c55f35f5b990 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -205,7 +205,6 @@ double drand48(void);
double erand48(unsigned short[3]);
/* char *fcvt(double, int, int * __restrict, int * __restrict); */
/* char *gcvt(double, int, int * __restrict, int * __restrict); */
-int grantpt(int);
char *initstate(unsigned long /* XSI requires u_int */, char *, long);
long jrand48(unsigned short[3]);
char *l64a(long);
@@ -217,8 +216,6 @@ char *mktemp(char *);
#endif
long mrand48(void);
long nrand48(unsigned short[3]);
-int posix_openpt(int);
-char *ptsname(int);
int putenv(char *);
long random(void);
unsigned short
@@ -230,8 +227,18 @@ int setkey(const char *);
char *setstate(/* const */ char *);
void srand48(long);
void srandom(unsigned long);
+#endif /* __XSI_VISIBLE */
+
+#if __XSI_VISIBLE
+int grantpt(int);
+int posix_openpt(int);
+char *ptsname(int);
int unlockpt(int);
#endif /* __XSI_VISIBLE */
+#if __BSD_VISIBLE
+/* ptsname_r will be included in POSIX issue 8 */
+int ptsname_r(int, char *, size_t);
+#endif
#if __BSD_VISIBLE
extern const char *malloc_conf;
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index ee6d98e9cf6a..bc4bb61d88d9 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -50,7 +50,7 @@ MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3
MLINKS+=hcreate.3 hcreate_r.3 hcreate.3 hdestroy_r.3 hcreate.3 hsearch_r.3
MLINKS+=insque.3 remque.3
MLINKS+=lsearch.3 lfind.3
-MLINKS+=ptsname.3 grantpt.3 ptsname.3 unlockpt.3
+MLINKS+=ptsname.3 grantpt.3 ptsname.3 ptsname_r.3 ptsname.3 unlockpt.3
MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 qsort.3 qsort_r.3
MLINKS+=rand.3 rand_r.3 rand.3 srand.3 rand.3 sranddev.3
MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
index 8682901bca6d..ee02167eae98 100644
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -124,6 +124,10 @@ FBSD_1.5 {
set_constraint_handler_s;
};
+FBSD_1.6 {
+ ptsname_r;
+};
+
FBSDprivate_1.0 {
__system;
_system;
diff --git a/lib/libc/stdlib/ptsname.3 b/lib/libc/stdlib/ptsname.3
index 8e8ec07d1e53..cbd0a99de58d 100644
--- a/lib/libc/stdlib/ptsname.3
+++ b/lib/libc/stdlib/ptsname.3
@@ -31,12 +31,13 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 20, 2008
+.Dd October 17, 2020
.Dt PTSNAME 3
.Os
.Sh NAME
.Nm grantpt ,
.Nm ptsname ,
+.Nm ptsname_r ,
.Nm unlockpt
.Nd pseudo-terminal access functions
.Sh LIBRARY
@@ -47,6 +48,8 @@
.Fn grantpt "int fildes"
.Ft "char *"
.Fn ptsname "int fildes"
+.Ft "int"
+.Fn ptsname_r "int fildes" "char *buffer" "size_t buflen"
.Ft int
.Fn unlockpt "int fildes"
.Sh DESCRIPTION
@@ -87,12 +90,23 @@ and
have been called.
.Pp
The
+.Fn ptsname_r
+function is the thread-safe version of
+.Fn ptsname .
+The caller must provide storage for the results of the full pathname of
+the slave device in the
+.Fa buffer
+and
+.Fa bufsize
+arguments.
+.Pp
+The
.Fn unlockpt
function clears the lock held on the pseudo-terminal pair
for the master device specified with
.Fa fildes .
.Sh RETURN VALUES
-.Rv -std grantpt unlockpt
+.Rv -std grantpt ptsname_r unlockpt
.Pp
The
.Fn ptsname
@@ -103,7 +117,8 @@ pointer is returned.
.Sh ERRORS
The
.Fn grantpt ,
-.Fn ptsname
+.Fn ptsname ,
+.Fn ptsname_r
and
.Fn unlockpt
functions may fail and set
@@ -119,6 +134,16 @@ is not a master pseudo-terminal device.
.El
.Pp
In addition, the
+.Fn ptsname_r
+function may set
+.Va errno
+to:
+.Bl -tag -width Er
+.It Bq Er ERANGE
+The buffer was too small.
+.El
+.Pp
+In addition, the
.Fn grantpt
function may set
.Va errno
diff --git a/lib/libc/stdlib/ptsname.c b/lib/libc/stdlib/ptsname.c
index 3e4d4c096ef5..63f651ce441e 100644
--- a/lib/libc/stdlib/ptsname.c
+++ b/lib/libc/stdlib/ptsname.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <paths.h>
#include <stdlib.h>
+#include <string.h>
#include "un-namespace.h"
/*
@@ -69,23 +70,48 @@ __strong_reference(__isptmaster, grantpt);
__strong_reference(__isptmaster, unlockpt);
/*
+ * ptsname_r(): return the pathname of the slave pseudo-terminal device
+ * associated with the specified master.
+ */
+int
+__ptsname_r(int fildes, char *buffer, size_t buflen)
+{
+
+ if (buflen <= sizeof(_PATH_DEV)) {
+ errno = ERANGE;
+ return (-1);
+ }
+
+ /* Make sure fildes points to a master device. */
+ if (__isptmaster(fildes) != 0)
+ return (-1);
+
+ memcpy(buffer, _PATH_DEV, sizeof(_PATH_DEV));
+ buffer += sizeof(_PATH_DEV) - 1;
+ buflen -= sizeof(_PATH_DEV) - 1;
+
+ if (fdevname_r(fildes, buffer, buflen) == NULL) {
+ if (errno == EINVAL)
+ errno = ERANGE;
+ return (-1);
+ }
+
+ return (0);
+}
+
+__strong_reference(__ptsname_r, ptsname_r);
+
+/*
* ptsname(): return the pathname of the slave pseudo-terminal device
* associated with the specified master.
*/
char *
ptsname(int fildes)
{
- static char pt_slave[sizeof _PATH_DEV + SPECNAMELEN] = _PATH_DEV;
- char *ret = NULL;
-
- /* Make sure fildes points to a master device. */
- if (__isptmaster(fildes) != 0)
- goto done;
+ static char pt_slave[sizeof(_PATH_DEV) + SPECNAMELEN];
- if (fdevname_r(fildes, pt_slave + (sizeof _PATH_DEV - 1),
- sizeof pt_slave - (sizeof _PATH_DEV - 1)) != NULL)
- ret = pt_slave;
+ if (__ptsname_r(fildes, pt_slave, sizeof(pt_slave)) == 0)
+ return (pt_slave);
-done:
- return (ret);
+ return (NULL);
}