1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 3453 raf * Common Development and Distribution License (the "License"). 6 3453 raf * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 3453 raf 22 0 stevel /* 23 5891 raf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 28 0 stevel 29 0 stevel /* 30 5323 raf * fdopendir, dirfd -- C library extension routines 31 0 stevel * 32 0 stevel * We use lmalloc()/lfree() rather than malloc()/free() in 33 0 stevel * order to allow opendir()/readdir()/closedir() to be called 34 0 stevel * while holding internal libc locks. 35 0 stevel */ 36 0 stevel 37 6812 raf #pragma weak _fdopendir = fdopendir 38 0 stevel 39 6812 raf #include "lint.h" 40 0 stevel #include <mtlib.h> 41 0 stevel #include <dirent.h> 42 0 stevel #include <sys/stat.h> 43 0 stevel #include <fcntl.h> 44 0 stevel #include <stdlib.h> 45 0 stevel #include <unistd.h> 46 0 stevel #include <errno.h> 47 0 stevel #include "libc.h" 48 0 stevel 49 0 stevel DIR * 50 0 stevel fdopendir(int fd) 51 0 stevel { 52 3453 raf private_DIR *pdirp = lmalloc(sizeof (*pdirp)); 53 3453 raf DIR *dirp = (DIR *)pdirp; 54 0 stevel void *buf = lmalloc(DIRBUF); 55 0 stevel int error = 0; 56 0 stevel struct stat64 sbuf; 57 0 stevel 58 3453 raf if (pdirp == NULL || buf == NULL) 59 0 stevel goto fail; 60 0 stevel /* 61 0 stevel * POSIX mandated behavior 62 0 stevel * close on exec if using file descriptor 63 0 stevel */ 64 5891 raf if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) 65 0 stevel goto fail; 66 0 stevel if (fstat64(fd, &sbuf) < 0) 67 0 stevel goto fail; 68 0 stevel if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { 69 0 stevel error = ENOTDIR; 70 0 stevel goto fail; 71 0 stevel } 72 0 stevel dirp->dd_buf = buf; 73 0 stevel dirp->dd_fd = fd; 74 3453 raf dirp->dd_loc = 0; 75 3453 raf dirp->dd_size = 0; 76 3453 raf (void) mutex_init(&pdirp->dd_lock, USYNC_THREAD, NULL); 77 0 stevel return (dirp); 78 0 stevel 79 0 stevel fail: 80 3453 raf if (pdirp != NULL) 81 3453 raf lfree(pdirp, sizeof (*pdirp)); 82 0 stevel if (buf != NULL) 83 0 stevel lfree(buf, DIRBUF); 84 0 stevel if (error) 85 0 stevel errno = error; 86 0 stevel return (NULL); 87 0 stevel } 88 5323 raf 89 5323 raf int 90 5323 raf dirfd(DIR *dirp) 91 5323 raf { 92 5323 raf return (dirp->dd_fd); 93 5323 raf } 94