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