]> git.saurik.com Git - apple/libc.git/blame_incremental - stdlib/grantpt.c
Libc-1439.100.3.tar.gz
[apple/libc.git] / stdlib / grantpt.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include <os/assumes.h>
25#include <os/once_private.h>
26#include <pthread.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/ioctl.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <errno.h>
33
34/*
35 * posix_openpt call for cloning pty implementation.
36 *
37 * Just open /dev/ptmx
38 */
39int
40posix_openpt(int flags)
41{
42 int fd = open("/dev/ptmx", flags);
43 if (fd >= 0)
44 return fd;
45 return -1;
46}
47
48/*
49 * grantpt call for cloning pty implementation.
50 *
51 * Change UID and GID of slave pty associated with master pty whose
52 * fd is provided, to the real UID and real GID of the calling thread.
53 */
54int
55grantpt(int fd)
56{
57 return ioctl(fd, TIOCPTYGRANT);
58}
59
60// defined by TIOCPTYGNAME
61#define PTSNAME_MAX_SIZE 128
62
63static pthread_key_t ptsname_buffer_specific_key;
64static os_once_t ptsname_once;
65
66static void
67ptsname_once_init(void *ctx __unused)
68{
69 int ret = pthread_key_create(&ptsname_buffer_specific_key, free);
70 os_assert_zero(ret);
71}
72
73/*
74 * ptsname call for cloning pty implementation.
75 *
76 * NOTE: Returns a pointer to a static buffer, which will be overwritten on
77 * subsequent calls.
78 */
79char *
80ptsname(int fd)
81{
82 os_once(&ptsname_once, NULL, ptsname_once_init);
83 char *ptsnamebuf = pthread_getspecific(ptsname_buffer_specific_key);
84
85 if (ptsnamebuf == NULL) {
86 ptsnamebuf = malloc(PTSNAME_MAX_SIZE);
87 os_assert(ptsnamebuf);
88
89 int error = pthread_setspecific(ptsname_buffer_specific_key, ptsnamebuf);
90 os_assert_zero(error);
91 }
92
93 int error = ptsname_r(fd, ptsnamebuf, PTSNAME_MAX_SIZE);
94
95 return error ? NULL : ptsnamebuf;
96}
97
98int
99ptsname_r(int fd, char *buffer, size_t buflen)
100{
101 int error;
102 struct stat sbuf;
103 char ptsnamebuf[PTSNAME_MAX_SIZE];
104
105 if (!buffer) {
106 errno = EINVAL;
107 return -1;
108 }
109
110 error = ioctl(fd, TIOCPTYGNAME, ptsnamebuf);
111 if (error) {
112 return -1;
113 }
114
115 /*
116 * XXX TSD
117 *
118 * POSIX: Handle device rename test case, which is expected
119 * to fail if the pty has been renamed.
120 */
121 error = stat(ptsnamebuf, &sbuf);
122 if (error) {
123 return -1;
124 }
125
126 size_t len = strlen(ptsnamebuf) + 1;
127 if (buflen < len) {
128 errno = ERANGE;
129 return -1;
130 }
131
132 memcpy(buffer, ptsnamebuf, len);
133
134 return 0;
135}
136
137/*
138 * unlockpt call for cloning pty implementation.
139 *
140 * Unlock the slave pty associated with the master to which fd refers.
141 */
142int
143unlockpt(int fd)
144{
145 return ioctl(fd, TIOCPTYUNLK);
146}