diff options
author | raf <none@none> | 2007-01-20 14:04:24 -0800 |
---|---|---|
committer | raf <none@none> | 2007-01-20 14:04:24 -0800 |
commit | 494a4c5197688884a8a9a926ffc8d6627ba3bc1b (patch) | |
tree | dcef4477de9bfa3bc115b955c51863ea92e0abea /usr/src/lib/libc | |
parent | 2b00275a1c0875b5d39428c53dec6df4d68bb1fa (diff) | |
download | illumos-joyent-494a4c5197688884a8a9a926ffc8d6627ba3bc1b.tar.gz |
6513772 readdir_r() and associates should use per-DIR locking
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/inc/libc.h | 18 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/closedir.c | 14 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/fdopendir.c | 22 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/opendir.c | 13 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/pt.c | 9 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/readdir.c | 83 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/readdir_r.c | 171 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/rewinddir.c | 10 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/seekdir.c | 57 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/telldir.c | 48 |
10 files changed, 203 insertions, 242 deletions
diff --git a/usr/src/lib/libc/inc/libc.h b/usr/src/lib/libc/inc/libc.h index d09aae7ce0..65f68f7e2c 100644 --- a/usr/src/lib/libc/inc/libc.h +++ b/usr/src/lib/libc/inc/libc.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,7 +36,7 @@ #include <thread.h> #include <stdio.h> -#include <sys/dirent.h> +#include <dirent.h> #include <ucontext.h> #include <nsswitch.h> #include <stddef.h> @@ -86,6 +85,15 @@ extern int _pollsys(struct pollfd *, nfds_t, const timespec_t *, const sigset_t *); extern void _private_testcancel(void); +/* + * The private_DIR structure is the same as the DIR structure, + * with the addition of a mutex lock for libc's internal use. + */ +typedef struct { + DIR dd_dir; + mutex_t dd_lock; +} private_DIR; + #if !defined(_LP64) /* * getdents64 transitional interface is intentionally internal to libc diff --git a/usr/src/lib/libc/port/gen/closedir.c b/usr/src/lib/libc/port/gen/closedir.c index 94212c7825..780c1f3a84 100644 --- a/usr/src/lib/libc/port/gen/closedir.c +++ b/usr/src/lib/libc/port/gen/closedir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - /* * closedir -- C library extension routine * @@ -41,7 +40,6 @@ #pragma weak closedir = _closedir #include "synonyms.h" -#include <sys/types.h> #include <dirent.h> #include <stdlib.h> #include <unistd.h> @@ -50,9 +48,11 @@ int closedir(DIR *dirp) { + private_DIR *pdirp = (private_DIR *)(uintptr_t)dirp; int fd = dirp->dd_fd; + mutex_destroy(&pdirp->dd_lock); lfree(dirp->dd_buf, DIRBUF); - lfree(dirp, sizeof (DIR)); + lfree(pdirp, sizeof (*pdirp)); return (close(fd)); } diff --git a/usr/src/lib/libc/port/gen/fdopendir.c b/usr/src/lib/libc/port/gen/fdopendir.c index 08191c4b0a..7e251b8f55 100644 --- a/usr/src/lib/libc/port/gen/fdopendir.c +++ b/usr/src/lib/libc/port/gen/fdopendir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,7 +38,6 @@ #include "synonyms.h" #include <mtlib.h> -#include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <fcntl.h> @@ -52,12 +51,13 @@ extern int __fcntl(int fd, int cmd, intptr_t arg); DIR * fdopendir(int fd) { - DIR *dirp = lmalloc(sizeof (DIR)); + private_DIR *pdirp = lmalloc(sizeof (*pdirp)); + DIR *dirp = (DIR *)pdirp; void *buf = lmalloc(DIRBUF); int error = 0; struct stat64 sbuf; - if (dirp == NULL || buf == NULL) + if (pdirp == NULL || buf == NULL) goto fail; /* * POSIX mandated behavior @@ -73,12 +73,14 @@ fdopendir(int fd) } dirp->dd_buf = buf; dirp->dd_fd = fd; - dirp->dd_loc = dirp->dd_size = 0; + dirp->dd_loc = 0; + dirp->dd_size = 0; + (void) mutex_init(&pdirp->dd_lock, USYNC_THREAD, NULL); return (dirp); fail: - if (dirp != NULL) - lfree(dirp, sizeof (DIR)); + if (pdirp != NULL) + lfree(pdirp, sizeof (*pdirp)); if (buf != NULL) lfree(buf, DIRBUF); if (error) diff --git a/usr/src/lib/libc/port/gen/opendir.c b/usr/src/lib/libc/port/gen/opendir.c index b74abf95aa..ca5b93b3ac 100644 --- a/usr/src/lib/libc/port/gen/opendir.c +++ b/usr/src/lib/libc/port/gen/opendir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - /* * opendir -- C library extension routine * @@ -41,14 +40,10 @@ #pragma weak opendir = _opendir #include "synonyms.h" -#include <sys/types.h> #include <dirent.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> -#include <synch.h> - -mutex_t _dirent_lock = DEFAULTMUTEX; DIR * opendir(const char *filename) diff --git a/usr/src/lib/libc/port/gen/pt.c b/usr/src/lib/libc/port/gen/pt.c index 1272c947eb..f3ba9ee922 100644 --- a/usr/src/lib/libc/port/gen/pt.c +++ b/usr/src/lib/libc/port/gen/pt.c @@ -18,6 +18,7 @@ * * CDDL HEADER END */ + /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. @@ -28,19 +29,18 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - #pragma weak ptsname = _ptsname #pragma weak grantpt = _grantpt #pragma weak unlockpt = _unlockpt #pragma weak posix_openpt = _posix_openpt #include "synonyms.h" -#include <mtlib.h> +#include "libc.h" +#include "mtlib.h" #include <sys/types.h> #include <signal.h> #include <sys/param.h> #include <sys/mkdev.h> -#include <sys/fs/ufs_fsdir.h> #include <sys/stream.h> #include <sys/stropts.h> #include <sys/wait.h> @@ -53,10 +53,7 @@ #include <stdlib.h> #include <unistd.h> #include <wait.h> -#include <synch.h> -#include <thread.h> #include <spawn.h> -#include <libc.h> #include <grp.h> #include "tsd.h" diff --git a/usr/src/lib/libc/port/gen/readdir.c b/usr/src/lib/libc/port/gen/readdir.c index 9eaf9f5752..9b392e6c89 100644 --- a/usr/src/lib/libc/port/gen/readdir.c +++ b/usr/src/lib/libc/port/gen/readdir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -50,25 +50,23 @@ #endif #pragma weak readdir = _readdir -#include "synonyms.h" -#include <sys/types.h> -#include <sys/dirent.h> -#include <dirent.h> -#include <limits.h> -#include <errno.h> -#include "libc.h" +#include "synonyms.h" +#include <dirent.h> +#include <limits.h> +#include <errno.h> +#include "libc.h" #ifdef _LP64 -struct dirent * +dirent_t * readdir(DIR *dirp) { - struct dirent *dp; /* -> directory data */ + dirent_t *dp; /* -> directory data */ int saveloc = 0; if (dirp->dd_size != 0) { - dp = (struct dirent *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; - saveloc = dirp->dd_loc; /* save for possible EOF */ + dp = (dirent_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + saveloc = dirp->dd_loc; /* save for possible EOF */ dirp->dd_loc += (int)dp->d_reclen; } if (dirp->dd_loc >= dirp->dd_size) @@ -76,14 +74,13 @@ readdir(DIR *dirp) if (dirp->dd_size == 0 && /* refill buffer */ (dirp->dd_size = getdents(dirp->dd_fd, - (struct dirent *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { - if (dirp->dd_size == 0) /* This means EOF */ - dirp->dd_loc = saveloc; /* EOF so save for */ - /* telldir */ - return (NULL); /* error or EOF */ + (dirent_t *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { + if (dirp->dd_size == 0) /* This means EOF */ + dirp->dd_loc = saveloc; /* so save for telldir */ + return (NULL); /* error or EOF */ } - return ((struct dirent *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]); + return ((dirent_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]); } #else /* _LP64 */ @@ -92,26 +89,25 @@ readdir(DIR *dirp) * Welcome to the complicated world of large files on a small system. */ -struct dirent64 * +dirent64_t * readdir64(DIR *dirp) { - struct dirent64 *dp64; /* -> directory data */ + dirent64_t *dp64; /* -> directory data */ int saveloc = 0; if (dirp->dd_size != 0) { - dp64 = (struct dirent64 *) - (uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + dp64 = (dirent64_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; /* was converted by readdir and needs to be reversed */ if (dp64->d_ino == (ino64_t)-1) { - struct dirent *dp32; + dirent_t *dp32; - dp32 = (struct dirent *)(&dp64->d_off); + dp32 = (dirent_t *)(&dp64->d_off); dp64->d_ino = (ino64_t)dp32->d_ino; dp64->d_off = (off64_t)dp32->d_off; dp64->d_reclen = (unsigned short)(dp32->d_reclen + - ((char *)&dp64->d_off - (char *)dp64)); + ((char *)&dp64->d_off - (char *)dp64)); } - saveloc = dirp->dd_loc; /* save for possible EOF */ + saveloc = dirp->dd_loc; /* save for possible EOF */ dirp->dd_loc += (int)dp64->d_reclen; } if (dirp->dd_loc >= dirp->dd_size) @@ -119,14 +115,13 @@ readdir64(DIR *dirp) if (dirp->dd_size == 0 && /* refill buffer */ (dirp->dd_size = getdents64(dirp->dd_fd, - (struct dirent64 *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { - if (dirp->dd_size == 0) /* This means EOF */ - dirp->dd_loc = saveloc; /* EOF so save for */ - /* telldir */ - return (NULL); /* error or EOF */ + (dirent64_t *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { + if (dirp->dd_size == 0) /* This means EOF */ + dirp->dd_loc = saveloc; /* so save for telldir */ + return (NULL); /* error or EOF */ } - dp64 = (struct dirent64 *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + dp64 = (dirent64_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; return (dp64); } @@ -135,11 +130,11 @@ readdir64(DIR *dirp) * We rely on the fact that dirents are smaller than dirent64s and we * reuse the space accordingly. */ -struct dirent * +dirent_t * readdir(DIR *dirp) { - struct dirent64 *dp64; /* -> directory data */ - struct dirent *dp32; /* -> directory data */ + dirent64_t *dp64; /* -> directory data */ + dirent_t *dp32; /* -> directory data */ if ((dp64 = readdir64(dirp)) == NULL) return (NULL); @@ -148,18 +143,18 @@ readdir(DIR *dirp) * Make sure that the offset fits in 32 bits. */ if (((off_t)dp64->d_off != dp64->d_off && - (uint64_t)dp64->d_off > (uint64_t)UINT32_MAX) || - (dp64->d_ino > SIZE_MAX)) { - errno = EOVERFLOW; - return (NULL); + (uint64_t)dp64->d_off > (uint64_t)UINT32_MAX) || + dp64->d_ino > SIZE_MAX) { + errno = EOVERFLOW; + return (NULL); } - dp32 = (struct dirent *)(&dp64->d_off); + dp32 = (dirent_t *)(&dp64->d_off); dp32->d_off = (off_t)dp64->d_off; dp32->d_ino = (ino_t)dp64->d_ino; dp32->d_reclen = (unsigned short)(dp64->d_reclen - ((char *)&dp64->d_off - (char *)dp64)); - dp64->d_ino = (ino64_t)-1; /* flag as converted for readdir64 */ + dp64->d_ino = (ino64_t)-1; /* flag as converted for readdir64 */ /* d_name d_reclen should not move */ return (dp32); } diff --git a/usr/src/lib/libc/port/gen/readdir_r.c b/usr/src/lib/libc/port/gen/readdir_r.c index 884a164fcf..8b4f3758c4 100644 --- a/usr/src/lib/libc/port/gen/readdir_r.c +++ b/usr/src/lib/libc/port/gen/readdir_r.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - /* * readdir_r -- C library extension routine */ @@ -41,22 +40,14 @@ #endif #pragma weak readdir_r = _readdir_r -#include "synonyms.h" -#include <mtlib.h> -#include <sys/types.h> -#include <sys/dirent.h> -#include <dirent.h> -#include <thread.h> -#include <string.h> -#include <synch.h> -#include <stdio.h> -#include <limits.h> -#include <errno.h> -#include "libc.h" - -extern mutex_t _dirent_lock; - -#define LBUFSIZE (sizeof (struct dirent64) + _POSIX_PATH_MAX + 1) +#include "synonyms.h" +#include "libc.h" +#include <mtlib.h> +#include <unistd.h> +#include <dirent.h> +#include <string.h> +#include <limits.h> +#include <errno.h> #ifdef _LP64 @@ -65,15 +56,16 @@ extern mutex_t _dirent_lock; */ int -readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +readdir_r(DIR *dirp, dirent_t *entry, dirent_t **result) { - struct dirent *dp; /* -> directory data */ + private_DIR *pdirp = (private_DIR *)dirp; + dirent_t *dp; /* -> directory data */ int saveloc = 0; - lmutex_lock(&_dirent_lock); + lmutex_lock(&pdirp->dd_lock); if (dirp->dd_size != 0) { - dp = (struct dirent *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; - saveloc = dirp->dd_loc; /* save for possible EOF */ + dp = (dirent_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + saveloc = dirp->dd_loc; /* save for possible EOF */ dirp->dd_loc += (int)dp->d_reclen; } @@ -82,21 +74,21 @@ readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) if (dirp->dd_size == 0 && /* refill buffer */ (dirp->dd_size = getdents(dirp->dd_fd, - (struct dirent *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { - if (dirp->dd_size == 0) { /* This means EOF */ - dirp->dd_loc = saveloc; /* EOF so save for telldir */ - lmutex_unlock(&_dirent_lock); + (dirent_t *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { + if (dirp->dd_size == 0) { /* This means EOF */ + dirp->dd_loc = saveloc; /* so save for telldir */ + lmutex_unlock(&pdirp->dd_lock); *result = NULL; - return (0); /* EOF */ + return (0); } - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); *result = NULL; - return (errno); /* error */ + return (errno); /* error */ } - dp = (struct dirent *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + dp = (dirent_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; (void) memcpy(entry, dp, (size_t)dp->d_reclen); - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); *result = entry; return (0); } @@ -109,26 +101,26 @@ readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) */ int -readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result) +readdir64_r(DIR *dirp, dirent64_t *entry, dirent64_t **result) { - struct dirent64 *dp64; /* -> directory data */ + private_DIR *pdirp = (private_DIR *)(uintptr_t)dirp; + dirent64_t *dp64; /* -> directory data */ int saveloc = 0; - lmutex_lock(&_dirent_lock); + lmutex_lock(&pdirp->dd_lock); if (dirp->dd_size != 0) { - dp64 = (struct dirent64 *) - (uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + dp64 = (dirent64_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; /* was converted by readdir and needs to be reversed */ if (dp64->d_ino == (ino64_t)-1) { - struct dirent *dp32; /* -> 32 bit directory data */ + dirent_t *dp32; /* -> 32 bit directory data */ - dp32 = (struct dirent *)(&dp64->d_off); + dp32 = (dirent_t *)(&dp64->d_off); dp64->d_ino = (ino64_t)dp32->d_ino; dp64->d_off = (off64_t)dp32->d_off; dp64->d_reclen = (unsigned short)(dp32->d_reclen + - ((char *)&dp64->d_off - (char *)dp64)); + ((char *)&dp64->d_off - (char *)dp64)); } - saveloc = dirp->dd_loc; /* save for possible EOF */ + saveloc = dirp->dd_loc; /* save for possible EOF */ dirp->dd_loc += (int)dp64->d_reclen; } @@ -137,75 +129,48 @@ readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result) if (dirp->dd_size == 0 && /* refill buffer */ (dirp->dd_size = getdents64(dirp->dd_fd, - (struct dirent64 *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { - if (dirp->dd_size == 0) { /* This means EOF */ - dirp->dd_loc = saveloc; /* EOF so save for telldir */ - lmutex_unlock(&_dirent_lock); + (dirent64_t *)(uintptr_t)dirp->dd_buf, DIRBUF)) <= 0) { + if (dirp->dd_size == 0) { /* This means EOF */ + dirp->dd_loc = saveloc; /* so save for telldir */ + lmutex_unlock(&pdirp->dd_lock); *result = NULL; - return (0); /* EOF */ + return (0); } - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); *result = NULL; - return (errno); /* error */ + return (errno); /* error */ } - dp64 = (struct dirent64 *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + dp64 = (dirent64_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; (void) memcpy(entry, dp64, (size_t)dp64->d_reclen); *result = entry; - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); return (0); } /* - * POSIX.1c Draft-6 version of the function readdir_r. - * It was implemented by Solaris 2.3. - */ - -struct dirent * -readdir_r(DIR *dirp, struct dirent *entry) -{ - long buf[LBUFSIZE / sizeof (long) + 1]; - struct dirent64 *dp64; - - if (readdir64_r(dirp, (struct dirent64 *)(uintptr_t)buf, &dp64) != 0 || - dp64 == NULL) - return (NULL); - - if ((dp64->d_ino > SIZE_MAX) || ((uint64_t)dp64->d_off > - (uint64_t)UINT32_MAX)) { - errno = EOVERFLOW; - return (NULL); - } - - entry->d_ino = (ino_t)dp64->d_ino; - entry->d_off = (off_t)dp64->d_off; - entry->d_reclen = (unsigned short)((((char *)entry->d_name - - (char *)entry) + strlen(dp64->d_name) + 1 + 3) & ~3); - (void) strcpy(entry->d_name, dp64->d_name); - - return (entry); -} - -/* - * POSIX.1c standard version of the thr function readdir_r. + * POSIX.1c standard version of the function readdir_r. * User gets it via static readdir_r from header file. */ int -__posix_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +__posix_readdir_r(DIR *dirp, dirent_t *entry, dirent_t **result) { - long buf[LBUFSIZE / sizeof (long) + 1]; - struct dirent64 *dp64; - int ret; - - ret = readdir64_r(dirp, (struct dirent64 *)(uintptr_t)buf, &dp64); - if (ret != 0 || dp64 == NULL) { + int error; + dirent64_t *dp64; + struct { + dirent64_t dirent64; + char chars[MAXNAMLEN]; + } buf; + + error = readdir64_r(dirp, (dirent64_t *)&buf, &dp64); + if (error != 0 || dp64 == NULL) { *result = NULL; - return (ret); + return (error); } - if ((dp64->d_ino > SIZE_MAX) || ((uint64_t)dp64->d_off > - (uint64_t)UINT32_MAX)) { + if (dp64->d_ino > SIZE_MAX || + (uint64_t)dp64->d_off > (uint64_t)UINT32_MAX) { *result = NULL; return (EOVERFLOW); } @@ -213,10 +178,26 @@ __posix_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) entry->d_ino = (ino_t)dp64->d_ino; entry->d_off = (off_t)dp64->d_off; entry->d_reclen = (unsigned short)((((char *)entry->d_name - - (char *)entry) + strlen(dp64->d_name) + 1 + 3) & ~3); + (char *)entry) + strlen(dp64->d_name) + 1 + 3) & ~3); (void) strcpy(entry->d_name, dp64->d_name); *result = entry; return (0); } +/* + * POSIX.1c Draft-6 version of the function readdir_r. + * It was implemented by Solaris 2.3. + */ + +dirent_t * +readdir_r(DIR *dirp, dirent_t *entry) +{ + int error; + dirent_t *result; + + if ((error = __posix_readdir_r(dirp, entry, &result)) != 0) + errno = error; + return (result); +} + #endif /* _LP64 */ diff --git a/usr/src/lib/libc/port/gen/rewinddir.c b/usr/src/lib/libc/port/gen/rewinddir.c index 9ae58768c9..e87634f140 100644 --- a/usr/src/lib/libc/port/gen/rewinddir.c +++ b/usr/src/lib/libc/port/gen/rewinddir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - /* * rewinddir -- C library extension routine */ @@ -37,7 +36,6 @@ #pragma weak rewinddir = _rewinddir #include "synonyms.h" -#include <sys/types.h> #include <dirent.h> void diff --git a/usr/src/lib/libc/port/gen/seekdir.c b/usr/src/lib/libc/port/gen/seekdir.c index 37548e8ccc..29d1c0f491 100644 --- a/usr/src/lib/libc/port/gen/seekdir.c +++ b/usr/src/lib/libc/port/gen/seekdir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - /* * seekdir -- C library extension routine */ @@ -41,30 +40,25 @@ #endif #pragma weak seekdir = _seekdir -#include "synonyms.h" -#include <mtlib.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdio.h> -#include <dirent.h> -#include <thread.h> -#include <synch.h> - - -extern mutex_t _dirent_lock; +#include "synonyms.h" +#include "libc.h" +#include <mtlib.h> +#include <dirent.h> +#include <fcntl.h> +#include <unistd.h> #ifdef _LP64 void seekdir(DIR *dirp, long loc) { - struct dirent *dp; + private_DIR *pdirp = (private_DIR *)dirp; + dirent_t *dp; off_t off = 0; - lmutex_lock(&_dirent_lock); + lmutex_lock(&pdirp->dd_lock); if (lseek(dirp->dd_fd, 0, SEEK_CUR) != 0) { - dp = (struct dirent *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + dp = (dirent_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; off = dp->d_off; } if (off != loc) { @@ -76,9 +70,9 @@ seekdir(DIR *dirp, long loc) * Save seek offset in d_off field, in case telldir * follows seekdir with no intervening call to readdir */ - ((struct dirent *)(uintptr_t)&dirp->dd_buf[0])->d_off = loc; + ((dirent_t *)(uintptr_t)&dirp->dd_buf[0])->d_off = loc; } - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); } #else /* _LP64 */ @@ -86,23 +80,22 @@ seekdir(DIR *dirp, long loc) static void seekdir64(DIR *dirp, off64_t loc) { - struct dirent64 *dp64; + private_DIR *pdirp = (private_DIR *)(uintptr_t)dirp; + dirent64_t *dp64; off64_t off = 0; - lmutex_lock(&_dirent_lock); + lmutex_lock(&pdirp->dd_lock); if (lseek64(dirp->dd_fd, 0, SEEK_CUR) != 0) { - dp64 = (struct dirent64 *) - (uintptr_t)&dirp->dd_buf[dirp->dd_loc]; + dp64 = (dirent64_t *)(uintptr_t)&dirp->dd_buf[dirp->dd_loc]; /* was converted by readdir and needs to be reversed */ if (dp64->d_ino == (ino64_t)-1) { - struct dirent *dp32; + dirent_t *dp32; - dp32 = (struct dirent *) - ((uintptr_t)dp64 + sizeof (ino64_t)); + dp32 = (dirent_t *)((uintptr_t)dp64 + sizeof (ino64_t)); dp64->d_ino = (ino64_t)dp32->d_ino; dp64->d_off = (off64_t)dp32->d_off; dp64->d_reclen = (unsigned short)(dp32->d_reclen + - ((char *)&dp64->d_off - (char *)dp64)); + ((char *)&dp64->d_off - (char *)dp64)); } off = dp64->d_off; } @@ -115,9 +108,9 @@ seekdir64(DIR *dirp, off64_t loc) * Save seek offset in d_off field, in case telldir * follows seekdir with no intervening call to readdir */ - ((struct dirent64 *)(uintptr_t)&dirp->dd_buf[0])->d_off = loc; + ((dirent64_t *)(uintptr_t)&dirp->dd_buf[0])->d_off = loc; } - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); } void diff --git a/usr/src/lib/libc/port/gen/telldir.c b/usr/src/lib/libc/port/gen/telldir.c index 40bb090e97..93cbb32f7c 100644 --- a/usr/src/lib/libc/port/gen/telldir.c +++ b/usr/src/lib/libc/port/gen/telldir.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - /* * telldir -- C library extension routine */ @@ -42,35 +41,30 @@ #pragma weak telldir = _telldir #include "synonyms.h" +#include "libc.h" #include <mtlib.h> -#include <sys/types.h> #include <dirent.h> -#include <thread.h> #include <errno.h> #include <limits.h> -#include <synch.h> #include <fcntl.h> -#include <stdio.h> #include <unistd.h> -#include <inttypes.h> - -extern mutex_t _dirent_lock; #ifdef _LP64 long telldir(DIR *dirp) { - struct dirent *dp; - off_t off = 0; + private_DIR *pdirp = (private_DIR *)dirp; + dirent_t *dp; + off_t off = 0; - lmutex_lock(&_dirent_lock); + lmutex_lock(&pdirp->dd_lock); /* if at beginning of dir, return 0 */ if (lseek(dirp->dd_fd, 0, SEEK_CUR) != 0) { - dp = (struct dirent *)(uintptr_t)(&dirp->dd_buf[dirp->dd_loc]); + dp = (dirent_t *)(uintptr_t)(&dirp->dd_buf[dirp->dd_loc]); off = dp->d_off; } - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); return (off); } @@ -79,28 +73,27 @@ telldir(DIR *dirp) static off64_t telldir64(DIR *dirp) { - struct dirent64 *dp64; + private_DIR *pdirp = (private_DIR *)(uintptr_t)dirp; + dirent64_t *dp64; off64_t off = 0; - lmutex_lock(&_dirent_lock); + lmutex_lock(&pdirp->dd_lock); /* if at beginning of dir, return 0 */ if (lseek64(dirp->dd_fd, 0, SEEK_CUR) != 0) { - dp64 = (struct dirent64 *) - (uintptr_t)(&dirp->dd_buf[dirp->dd_loc]); + dp64 = (dirent64_t *)(uintptr_t)(&dirp->dd_buf[dirp->dd_loc]); /* was converted by readdir and needs to be reversed */ if (dp64->d_ino == (ino64_t)-1) { - struct dirent *dp32; + dirent_t *dp32; - dp32 = (struct dirent *) - ((uintptr_t)dp64 + sizeof (ino64_t)); + dp32 = (dirent_t *)((uintptr_t)dp64 + sizeof (ino64_t)); dp64->d_ino = (ino64_t)dp32->d_ino; dp64->d_off = (off64_t)dp32->d_off; dp64->d_reclen = (unsigned short)(dp32->d_reclen + - ((char *)&dp64->d_off - (char *)dp64)); + ((char *)&dp64->d_off - (char *)dp64)); } off = dp64->d_off; } - lmutex_unlock(&_dirent_lock); + lmutex_unlock(&pdirp->dd_lock); return (off); } @@ -114,8 +107,7 @@ telldir(DIR *dirp) /* * Make sure that the offset fits in 32 bits. */ - if ((long)off != off && - (uint64_t)off > (uint64_t)UINT32_MAX) { + if ((long)off != off && (uint64_t)off > (uint64_t)UINT32_MAX) { errno = EOVERFLOW; return (-1); } |