libc_open.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
1N/A/*
1N/A * CDDL HEADER START
1N/A *
1N/A * The contents of this file are subject to the terms of the
1N/A * Common Development and Distribution License, Version 1.0 only
1N/A * (the "License"). You may not use this file except in compliance
1N/A * with the License.
1N/A *
1N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1N/A * or http://www.opensolaris.org/os/licensing.
1N/A * See the License for the specific language governing permissions
1N/A * and limitations under the License.
1N/A *
1N/A * When distributing Covered Code, include this CDDL HEADER in each
1N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1N/A * If applicable, add the following below this CDDL HEADER, with the
1N/A * fields enclosed by brackets "[]" replaced with your own identifying
1N/A * information: Portions Copyright [yyyy] [name of copyright owner]
1N/A *
1N/A * CDDL HEADER END
1N/A */
1N/A/*
1N/A * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
1N/A * Use is subject to license terms.
1N/A */
1N/A
1N/A/* Copyright (c) 1988 AT&T */
1N/A/* All Rights Reserved */
1N/A
1N/A#pragma ident "%Z%%M% %I% %E% SMI"
1N/A
1N/A#include "synonyms.h"
1N/A#include <sys/mkdev.h>
1N/A#include <limits.h>
1N/A#include <stdarg.h>
1N/A#include <unistd.h>
1N/A#include <strings.h>
1N/A#include <sys/stat.h>
1N/A#include <sys/stropts.h>
1N/A#include <sys/stream.h>
1N/A#include <sys/ptms.h>
1N/A
1N/A#if !defined(_LP64)
1N/Aextern int __open64(const char *fname, int oflag, mode_t mode);
1N/A#endif
1N/A
1N/Aextern int __xpg4; /* defined in port/gen/xpg4.c; 0 if not xpg4/xpg4v2 */
1N/A
1N/Aextern int __open(const char *fname, int oflag, mode_t mode);
1N/A
1N/Astatic void push_module(int fd);
1N/Astatic int isptsfd(int fd);
1N/Astatic void itoa(int i, char *ptr);
1N/A
1N/Aint
1N/A_open(const char *fname, int oflag, ...)
1N/A{
1N/A mode_t mode;
1N/A int fd;
1N/A va_list ap;
1N/A
1N/A va_start(ap, oflag);
1N/A mode = va_arg(ap, mode_t);
1N/A va_end(ap);
1N/A
1N/A /*
1N/A * XPG4v2 requires that open of a slave pseudo terminal device
1N/A * provides the process with an interface that is identical to
1N/A * the terminal interface. For a more detailed discussion,
1N/A * see bugid 4025044.
1N/A */
1N/A fd = __open(fname, oflag, mode);
1N/A if (__xpg4 != 0 && fd >= 0 && isptsfd(fd))
1N/A push_module(fd);
1N/A return (fd);
1N/A}
1N/A
1N/A#if !defined(_LP64)
1N/A/*
1N/A * The 32-bit APIs to large files require this interposition.
1N/A * The 64-bit APIs just fall back to _open() above.
1N/A */
1N/Aint
1N/A_open64(const char *fname, int oflag, ...)
1N/A{
1N/A mode_t mode;
1N/A int fd;
1N/A va_list ap;
1N/A
1N/A va_start(ap, oflag);
1N/A mode = va_arg(ap, mode_t);
1N/A va_end(ap);
1N/A
1N/A /*
1N/A * XPG4v2 requires that open of a slave pseudo terminal device
1N/A * provides the process with an interface that is identical to
1N/A * the terminal interface. For a more detailed discussion,
1N/A * see bugid 4025044.
1N/A */
1N/A fd = __open64(fname, oflag, mode);
1N/A if (__xpg4 != 0 && fd >= 0 && isptsfd(fd))
1N/A push_module(fd);
1N/A return (fd);
1N/A}
1N/A#endif /* !_LP64 */
1N/A
1N/A/*
1N/A * Checks if the file matches an entry in the /dev/pts directory
1N/A */
1N/Astatic int
1N/Aisptsfd(int fd)
1N/A{
1N/A static char buf[TTYNAME_MAX];
1N/A struct stat64 fsb, stb;
1N/A
1N/A if (fstat64(fd, &fsb) != 0 ||
1N/A (fsb.st_mode & S_IFMT) != S_IFCHR)
1N/A return (0);
1N/A
1N/A (void) strcpy(buf, "/dev/pts/");
1N/A itoa(minor(fsb.st_rdev), buf+strlen(buf));
1N/A
1N/A if (stat64(buf, &stb) != 0 ||
1N/A (fsb.st_mode & S_IFMT) != S_IFCHR)
1N/A return (0);
1N/A
1N/A return (stb.st_rdev == fsb.st_rdev);
1N/A}
1N/A
1N/A/*
1N/A * Converts a number to a string (null terminated).
1N/A */
1N/Astatic void
1N/Aitoa(int i, char *ptr)
1N/A{
1N/A int dig = 0;
1N/A int tempi;
1N/A
1N/A tempi = i;
1N/A do {
1N/A dig++;
1N/A tempi /= 10;
1N/A } while (tempi);
1N/A
1N/A ptr += dig;
1N/A *ptr = '\0';
1N/A while (--dig >= 0) {
1N/A *(--ptr) = i % 10 + '0';
1N/A i /= 10;
1N/A }
1N/A}
1N/A
1N/A/*
1N/A * Push modules to provide tty semantics
1N/A */
1N/Astatic void
1N/Apush_module(int fd)
1N/A{
1N/A struct strioctl istr;
1N/A
1N/A istr.ic_cmd = PTSSTTY;
1N/A istr.ic_len = 0;
1N/A istr.ic_timout = 0;
1N/A istr.ic_dp = NULL;
1N/A if (ioctl(fd, I_STR, &istr) != -1) {
1N/A (void) ioctl(fd, __I_PUSH_NOCTTY, "ptem");
1N/A (void) ioctl(fd, __I_PUSH_NOCTTY, "ldterm");
1N/A (void) ioctl(fd, __I_PUSH_NOCTTY, "ttcompat");
1N/A istr.ic_cmd = PTSSTTY;
1N/A istr.ic_len = 0;
1N/A istr.ic_timout = 0;
1N/A istr.ic_dp = NULL;
1N/A (void) ioctl(fd, I_STR, &istr);
1N/A }
1N/A}
1N/A