1*8fd04b83SRoger A. Faulkner /*
2*8fd04b83SRoger A. Faulkner * CDDL HEADER START
3*8fd04b83SRoger A. Faulkner *
4*8fd04b83SRoger A. Faulkner * The contents of this file are subject to the terms of the
5*8fd04b83SRoger A. Faulkner * Common Development and Distribution License (the "License").
6*8fd04b83SRoger A. Faulkner * You may not use this file except in compliance with the License.
7*8fd04b83SRoger A. Faulkner *
8*8fd04b83SRoger A. Faulkner * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*8fd04b83SRoger A. Faulkner * or http://www.opensolaris.org/os/licensing.
10*8fd04b83SRoger A. Faulkner * See the License for the specific language governing permissions
11*8fd04b83SRoger A. Faulkner * and limitations under the License.
12*8fd04b83SRoger A. Faulkner *
13*8fd04b83SRoger A. Faulkner * When distributing Covered Code, include this CDDL HEADER in each
14*8fd04b83SRoger A. Faulkner * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*8fd04b83SRoger A. Faulkner * If applicable, add the following below this CDDL HEADER, with the
16*8fd04b83SRoger A. Faulkner * fields enclosed by brackets "[]" replaced with your own identifying
17*8fd04b83SRoger A. Faulkner * information: Portions Copyright [yyyy] [name of copyright owner]
18*8fd04b83SRoger A. Faulkner *
19*8fd04b83SRoger A. Faulkner * CDDL HEADER END
20*8fd04b83SRoger A. Faulkner */
21*8fd04b83SRoger A. Faulkner
22*8fd04b83SRoger A. Faulkner /*
23*8fd04b83SRoger A. Faulkner * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24*8fd04b83SRoger A. Faulkner * Use is subject to license terms.
25*8fd04b83SRoger A. Faulkner */
26*8fd04b83SRoger A. Faulkner
27*8fd04b83SRoger A. Faulkner /* Copyright (c) 1988 AT&T */
28*8fd04b83SRoger A. Faulkner /* All Rights Reserved */
29*8fd04b83SRoger A. Faulkner
30*8fd04b83SRoger A. Faulkner #include "lint.h"
31*8fd04b83SRoger A. Faulkner #include <sys/mkdev.h>
32*8fd04b83SRoger A. Faulkner #include <limits.h>
33*8fd04b83SRoger A. Faulkner #include <stdarg.h>
34*8fd04b83SRoger A. Faulkner #include <unistd.h>
35*8fd04b83SRoger A. Faulkner #include <strings.h>
36*8fd04b83SRoger A. Faulkner #include <errno.h>
37*8fd04b83SRoger A. Faulkner #include <sys/stat.h>
38*8fd04b83SRoger A. Faulkner #include <sys/fcntl.h>
39*8fd04b83SRoger A. Faulkner #include <sys/stropts.h>
40*8fd04b83SRoger A. Faulkner #include <sys/stream.h>
41*8fd04b83SRoger A. Faulkner #include <sys/ptms.h>
42*8fd04b83SRoger A. Faulkner #include <sys/syscall.h>
43*8fd04b83SRoger A. Faulkner #include "libc.h"
44*8fd04b83SRoger A. Faulkner
45*8fd04b83SRoger A. Faulkner static int xpg4_fixup(int fd);
46*8fd04b83SRoger A. Faulkner static void push_module(int fd);
47*8fd04b83SRoger A. Faulkner static int isptsfd(int fd);
48*8fd04b83SRoger A. Faulkner static void itoa(int i, char *ptr);
49*8fd04b83SRoger A. Faulkner
50*8fd04b83SRoger A. Faulkner int
__openat(int dfd,const char * path,int oflag,mode_t mode)51*8fd04b83SRoger A. Faulkner __openat(int dfd, const char *path, int oflag, mode_t mode)
52*8fd04b83SRoger A. Faulkner {
53*8fd04b83SRoger A. Faulkner int fd = syscall(SYS_openat, dfd, path, oflag, mode);
54*8fd04b83SRoger A. Faulkner return (xpg4_fixup(fd));
55*8fd04b83SRoger A. Faulkner }
56*8fd04b83SRoger A. Faulkner
57*8fd04b83SRoger A. Faulkner int
__open(const char * path,int oflag,mode_t mode)58*8fd04b83SRoger A. Faulkner __open(const char *path, int oflag, mode_t mode)
59*8fd04b83SRoger A. Faulkner {
60*8fd04b83SRoger A. Faulkner #if defined(_RETAIN_OLD_SYSCALLS)
61*8fd04b83SRoger A. Faulkner int fd = syscall(SYS_open, path, oflag, mode);
62*8fd04b83SRoger A. Faulkner return (xpg4_fixup(fd));
63*8fd04b83SRoger A. Faulkner #else
64*8fd04b83SRoger A. Faulkner return (__openat(AT_FDCWD, path, oflag, mode));
65*8fd04b83SRoger A. Faulkner #endif
66*8fd04b83SRoger A. Faulkner }
67*8fd04b83SRoger A. Faulkner
68*8fd04b83SRoger A. Faulkner #if !defined(_LP64)
69*8fd04b83SRoger A. Faulkner
70*8fd04b83SRoger A. Faulkner int
__openat64(int dfd,const char * path,int oflag,mode_t mode)71*8fd04b83SRoger A. Faulkner __openat64(int dfd, const char *path, int oflag, mode_t mode)
72*8fd04b83SRoger A. Faulkner {
73*8fd04b83SRoger A. Faulkner int fd = syscall(SYS_openat64, dfd, path, oflag, mode);
74*8fd04b83SRoger A. Faulkner return (xpg4_fixup(fd));
75*8fd04b83SRoger A. Faulkner }
76*8fd04b83SRoger A. Faulkner
77*8fd04b83SRoger A. Faulkner int
__open64(const char * path,int oflag,mode_t mode)78*8fd04b83SRoger A. Faulkner __open64(const char *path, int oflag, mode_t mode)
79*8fd04b83SRoger A. Faulkner {
80*8fd04b83SRoger A. Faulkner #if defined(_RETAIN_OLD_SYSCALLS)
81*8fd04b83SRoger A. Faulkner int fd = syscall(SYS_open64, path, oflag, mode);
82*8fd04b83SRoger A. Faulkner return (xpg4_fixup(fd));
83*8fd04b83SRoger A. Faulkner #else
84*8fd04b83SRoger A. Faulkner return (__openat64(AT_FDCWD, path, oflag, mode));
85*8fd04b83SRoger A. Faulkner #endif
86*8fd04b83SRoger A. Faulkner }
87*8fd04b83SRoger A. Faulkner
88*8fd04b83SRoger A. Faulkner #endif /* !_LP64 */
89*8fd04b83SRoger A. Faulkner
90*8fd04b83SRoger A. Faulkner /*
91*8fd04b83SRoger A. Faulkner * XPG4v2 requires that open of a slave pseudo terminal device
92*8fd04b83SRoger A. Faulkner * provides the process with an interface that is identical to
93*8fd04b83SRoger A. Faulkner * the terminal interface. For a more detailed discussion,
94*8fd04b83SRoger A. Faulkner * see bugid 4025044.
95*8fd04b83SRoger A. Faulkner */
96*8fd04b83SRoger A. Faulkner static int
xpg4_fixup(int fd)97*8fd04b83SRoger A. Faulkner xpg4_fixup(int fd)
98*8fd04b83SRoger A. Faulkner {
99*8fd04b83SRoger A. Faulkner if (libc__xpg4 != 0 && fd >= 0 && isptsfd(fd))
100*8fd04b83SRoger A. Faulkner push_module(fd);
101*8fd04b83SRoger A. Faulkner return (fd);
102*8fd04b83SRoger A. Faulkner }
103*8fd04b83SRoger A. Faulkner
104*8fd04b83SRoger A. Faulkner /*
105*8fd04b83SRoger A. Faulkner * Check if the file matches an entry in the /dev/pts directory.
106*8fd04b83SRoger A. Faulkner * Be careful to preserve errno.
107*8fd04b83SRoger A. Faulkner */
108*8fd04b83SRoger A. Faulkner static int
isptsfd(int fd)109*8fd04b83SRoger A. Faulkner isptsfd(int fd)
110*8fd04b83SRoger A. Faulkner {
111*8fd04b83SRoger A. Faulkner char buf[TTYNAME_MAX];
112*8fd04b83SRoger A. Faulkner char *str1 = buf;
113*8fd04b83SRoger A. Faulkner const char *str2 = "/dev/pts/";
114*8fd04b83SRoger A. Faulkner struct stat64 fsb, stb;
115*8fd04b83SRoger A. Faulkner int oerrno = errno;
116*8fd04b83SRoger A. Faulkner int rval = 0;
117*8fd04b83SRoger A. Faulkner
118*8fd04b83SRoger A. Faulkner if (fstat64(fd, &fsb) == 0 && S_ISCHR(fsb.st_mode)) {
119*8fd04b83SRoger A. Faulkner /*
120*8fd04b83SRoger A. Faulkner * Do this without strcpy() or strlen(),
121*8fd04b83SRoger A. Faulkner * to avoid invoking the dynamic linker.
122*8fd04b83SRoger A. Faulkner */
123*8fd04b83SRoger A. Faulkner while (*str2 != '\0')
124*8fd04b83SRoger A. Faulkner *str1++ = *str2++;
125*8fd04b83SRoger A. Faulkner /*
126*8fd04b83SRoger A. Faulkner * Inline version of minor(dev), to avoid the dynamic linker.
127*8fd04b83SRoger A. Faulkner */
128*8fd04b83SRoger A. Faulkner itoa(fsb.st_rdev & MAXMIN, str1);
129*8fd04b83SRoger A. Faulkner if (stat64(buf, &stb) == 0)
130*8fd04b83SRoger A. Faulkner rval = (stb.st_rdev == fsb.st_rdev);
131*8fd04b83SRoger A. Faulkner }
132*8fd04b83SRoger A. Faulkner errno = oerrno;
133*8fd04b83SRoger A. Faulkner return (rval);
134*8fd04b83SRoger A. Faulkner }
135*8fd04b83SRoger A. Faulkner
136*8fd04b83SRoger A. Faulkner /*
137*8fd04b83SRoger A. Faulkner * Converts a number to a string (null terminated).
138*8fd04b83SRoger A. Faulkner */
139*8fd04b83SRoger A. Faulkner static void
itoa(int i,char * ptr)140*8fd04b83SRoger A. Faulkner itoa(int i, char *ptr)
141*8fd04b83SRoger A. Faulkner {
142*8fd04b83SRoger A. Faulkner int dig = 0;
143*8fd04b83SRoger A. Faulkner int tempi;
144*8fd04b83SRoger A. Faulkner
145*8fd04b83SRoger A. Faulkner tempi = i;
146*8fd04b83SRoger A. Faulkner do {
147*8fd04b83SRoger A. Faulkner dig++;
148*8fd04b83SRoger A. Faulkner tempi /= 10;
149*8fd04b83SRoger A. Faulkner } while (tempi);
150*8fd04b83SRoger A. Faulkner
151*8fd04b83SRoger A. Faulkner ptr += dig;
152*8fd04b83SRoger A. Faulkner *ptr = '\0';
153*8fd04b83SRoger A. Faulkner while (--dig >= 0) {
154*8fd04b83SRoger A. Faulkner *(--ptr) = i % 10 + '0';
155*8fd04b83SRoger A. Faulkner i /= 10;
156*8fd04b83SRoger A. Faulkner }
157*8fd04b83SRoger A. Faulkner }
158*8fd04b83SRoger A. Faulkner
159*8fd04b83SRoger A. Faulkner /*
160*8fd04b83SRoger A. Faulkner * Push modules to provide tty semantics
161*8fd04b83SRoger A. Faulkner */
162*8fd04b83SRoger A. Faulkner static void
push_module(int fd)163*8fd04b83SRoger A. Faulkner push_module(int fd)
164*8fd04b83SRoger A. Faulkner {
165*8fd04b83SRoger A. Faulkner struct strioctl istr;
166*8fd04b83SRoger A. Faulkner int oerrno = errno;
167*8fd04b83SRoger A. Faulkner
168*8fd04b83SRoger A. Faulkner istr.ic_cmd = PTSSTTY;
169*8fd04b83SRoger A. Faulkner istr.ic_len = 0;
170*8fd04b83SRoger A. Faulkner istr.ic_timout = 0;
171*8fd04b83SRoger A. Faulkner istr.ic_dp = NULL;
172*8fd04b83SRoger A. Faulkner if (ioctl(fd, I_STR, &istr) != -1) {
173*8fd04b83SRoger A. Faulkner (void) ioctl(fd, __I_PUSH_NOCTTY, "ptem");
174*8fd04b83SRoger A. Faulkner (void) ioctl(fd, __I_PUSH_NOCTTY, "ldterm");
175*8fd04b83SRoger A. Faulkner (void) ioctl(fd, __I_PUSH_NOCTTY, "ttcompat");
176*8fd04b83SRoger A. Faulkner istr.ic_cmd = PTSSTTY;
177*8fd04b83SRoger A. Faulkner istr.ic_len = 0;
178*8fd04b83SRoger A. Faulkner istr.ic_timout = 0;
179*8fd04b83SRoger A. Faulkner istr.ic_dp = NULL;
180*8fd04b83SRoger A. Faulkner (void) ioctl(fd, I_STR, &istr);
181*8fd04b83SRoger A. Faulkner }
182*8fd04b83SRoger A. Faulkner errno = oerrno;
183*8fd04b83SRoger A. Faulkner }
184