1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Unix routine to do an "fopen" on file descriptor 32 * The mode has to be repeated because you can't query its 33 * status 34 */ 35 36 #define _LARGEFILE64_SOURCE 1 37 38 #pragma weak _fdopen = fdopen 39 40 #include "lint.h" 41 #include <mtlib.h> 42 #include "file64.h" 43 #include <sys/types.h> 44 #include <unistd.h> 45 #include <stdio.h> 46 #include <limits.h> 47 #include <thread.h> 48 #include <synch.h> 49 #include "stdiom.h" 50 #include <errno.h> 51 #include <fcntl.h> 52 53 FILE * 54 fdopen(int fd, const char *type) /* associate file desc. with stream */ 55 { 56 /* iop doesn't need locking since this function is creating it */ 57 FILE *iop; 58 char plus; 59 unsigned char flag; 60 61 /* Sets EBADF for bad fds */ 62 if (fcntl(fd, F_GETFD) == -1) 63 return (NULL); 64 65 if ((iop = _findiop()) == 0) { 66 errno = ENOMEM; 67 return (NULL); 68 } 69 70 switch (type[0]) { 71 default: 72 iop->_flag = 0; /* release iop */ 73 errno = EINVAL; 74 return (NULL); 75 case 'r': 76 flag = _IOREAD; 77 break; 78 case 'a': 79 (void) lseek64(fd, (off64_t)0, SEEK_END); 80 /*FALLTHROUGH*/ 81 case 'w': 82 flag = _IOWRT; 83 break; 84 } 85 if ((plus = type[1]) == 'b') /* Unix ignores 'b' ANSI std */ 86 plus = type[2]; 87 if (plus == '+') 88 flag = _IORW; 89 iop->_flag = flag; 90 91 #ifdef _LP64 92 iop->_file = fd; 93 #else 94 if (fd <= _FILE_FD_MAX) { 95 SET_FILE(iop, fd); 96 } else if (_file_set(iop, fd, type) != 0) { 97 /* errno set by _file_set () */ 98 iop->_flag = 0; /* release iop */ 99 return (NULL); 100 } 101 #endif /* _LP64 */ 102 103 return (iop); 104 } 105