xref: /titanic_51/usr/src/lib/libc/port/sys/open.c (revision 8fd04b8338ed5093ec2d1e668fa620b7de44c177)
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
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
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
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
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
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
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
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
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