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