X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/6465356a983ac139f81d3b7913cdb548477c346c..fc56b708803d28b949a9181528bb0da4d25b3b7b:/stdlib/grantpt.c diff --git a/stdlib/grantpt.c b/stdlib/grantpt.c index c8653ec..bbc52cb 100644 --- a/stdlib/grantpt.c +++ b/stdlib/grantpt.c @@ -21,7 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include +#include +#include #include +#include #include #include #include @@ -53,6 +57,19 @@ grantpt(int fd) return ioctl(fd, TIOCPTYGRANT); } +// defined by TIOCPTYGNAME +#define PTSNAME_MAX_SIZE 128 + +static pthread_key_t ptsname_buffer_specific_key; +static os_once_t ptsname_once; + +static void +ptsname_once_init(void *ctx __unused) +{ + int ret = pthread_key_create(&ptsname_buffer_specific_key, free); + os_assert_zero(ret); +} + /* * ptsname call for cloning pty implementation. * @@ -62,29 +79,59 @@ grantpt(int fd) char * ptsname(int fd) { - static char *ptsnamebuf = NULL; + os_once(&ptsname_once, NULL, ptsname_once_init); + char *ptsnamebuf = pthread_getspecific(ptsname_buffer_specific_key); + + if (ptsnamebuf == NULL) { + ptsnamebuf = malloc(PTSNAME_MAX_SIZE); + os_assert(ptsnamebuf); + + int error = pthread_setspecific(ptsname_buffer_specific_key, ptsnamebuf); + os_assert_zero(error); + } + + int error = ptsname_r(fd, ptsnamebuf, PTSNAME_MAX_SIZE); + + return error ? NULL : ptsnamebuf; +} + +int +ptsname_r(int fd, char *buffer, size_t buflen) +{ int error; - char *retval = NULL; struct stat sbuf; + char ptsnamebuf[PTSNAME_MAX_SIZE]; - if (ptsnamebuf == NULL) { - ptsnamebuf = malloc(128); // defined by TIOCPTYGNAME + if (!buffer) { + errno = EINVAL; + return -1; } - + error = ioctl(fd, TIOCPTYGNAME, ptsnamebuf); - if (!error) { - /* - * XXX TSD - * - * POSIX: Handle device rename test case, which is expected - * to fail if the pty has been renamed. - */ - if (stat(ptsnamebuf, &sbuf) == 0) { - retval = ptsnamebuf; - } + if (error) { + return -1; } - return (retval); + /* + * XXX TSD + * + * POSIX: Handle device rename test case, which is expected + * to fail if the pty has been renamed. + */ + error = stat(ptsnamebuf, &sbuf); + if (error) { + return -1; + } + + size_t len = strlen(ptsnamebuf) + 1; + if (buflen < len) { + errno = ERANGE; + return -1; + } + + memcpy(buffer, ptsnamebuf, len); + + return 0; } /*