diff options
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/Makefile | 1 | ||||
-rw-r--r-- | nptl/Versions | 1 | ||||
-rw-r--r-- | nptl/sem_open.c | 143 | ||||
-rw-r--r-- | nptl/sem_unlink.c | 36 | ||||
-rw-r--r-- | nptl/semaphoreP.h | 16 |
5 files changed, 21 insertions, 176 deletions
diff --git a/nptl/Makefile b/nptl/Makefile index ac76596ee0..3d61ec1a34 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -96,6 +96,7 @@ libpthread-routines = nptl-init vars events version \ old_pthread_atfork pthread_atfork \ pthread_getcpuclockid \ pthread_clock_gettime pthread_clock_settime \ + shm-directory \ sem_init sem_destroy \ sem_open sem_close sem_unlink \ sem_getvalue \ diff --git a/nptl/Versions b/nptl/Versions index b7d4a9b9d3..4e134fa42e 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -270,5 +270,6 @@ libpthread { __pthread_initialize_minimal; __pthread_clock_gettime; __pthread_clock_settime; __pthread_unwind; __pthread_get_minstack; + __shm_directory; } } diff --git a/nptl/sem_open.c b/nptl/sem_open.c index cf91859dab..621a6c3e80 100644 --- a/nptl/sem_open.c +++ b/nptl/sem_open.c @@ -18,8 +18,6 @@ #include <errno.h> #include <fcntl.h> -#include <mntent.h> -#include <paths.h> #include <pthread.h> #include <search.h> #include <semaphore.h> @@ -30,98 +28,8 @@ #include <unistd.h> #include <sys/mman.h> #include <sys/stat.h> -#include <sys/statfs.h> -#include <linux_fsinfo.h> #include "semaphoreP.h" - - - -/* Information about the mount point. */ -struct mountpoint_info mountpoint attribute_hidden; - -/* This is the default mount point. */ -static const char defaultmount[] = "/dev/shm"; -/* This is the default directory. */ -static const char defaultdir[] = "/dev/shm/sem."; - -/* Protect the `mountpoint' variable above. */ -pthread_once_t __namedsem_once attribute_hidden = PTHREAD_ONCE_INIT; - - -/* Determine where the shmfs is mounted (if at all). */ -void -attribute_hidden -__where_is_shmfs (void) -{ - char buf[512]; - struct statfs f; - struct mntent resmem; - struct mntent *mp; - FILE *fp; - - /* The canonical place is /dev/shm. This is at least what the - documentation tells everybody to do. */ - if (__statfs (defaultmount, &f) == 0 && (f.f_type == SHMFS_SUPER_MAGIC - || f.f_type == RAMFS_MAGIC)) - { - /* It is in the normal place. */ - mountpoint.dir = (char *) defaultdir; - mountpoint.dirlen = sizeof (defaultdir) - 1; - - return; - } - - /* OK, do it the hard way. Look through the /proc/mounts file and if - this does not exist through /etc/fstab to find the mount point. */ - fp = __setmntent ("/proc/mounts", "r"); - if (__glibc_unlikely (fp == NULL)) - { - fp = __setmntent (_PATH_MNTTAB, "r"); - if (__glibc_unlikely (fp == NULL)) - /* There is nothing we can do. Blind guesses are not helpful. */ - return; - } - - /* Now read the entries. */ - while ((mp = __getmntent_r (fp, &resmem, buf, sizeof buf)) != NULL) - /* The original name is "shm" but this got changed in early Linux - 2.4.x to "tmpfs". */ - if (strcmp (mp->mnt_type, "tmpfs") == 0 - || strcmp (mp->mnt_type, "shm") == 0) - { - /* Found it. There might be more than one place where the - filesystem is mounted but one is enough for us. */ - size_t namelen; - - /* First make sure this really is the correct entry. At least - some versions of the kernel give wrong information because - of the implicit mount of the shmfs for SysV IPC. */ - if (__statfs (mp->mnt_dir, &f) != 0 || (f.f_type != SHMFS_SUPER_MAGIC - && f.f_type != RAMFS_MAGIC)) - continue; - - namelen = strlen (mp->mnt_dir); - - if (namelen == 0) - /* Hum, maybe some crippled entry. Keep on searching. */ - continue; - - mountpoint.dir = (char *) malloc (namelen + 4 + 2); - if (mountpoint.dir != NULL) - { - char *cp = __mempcpy (mountpoint.dir, mp->mnt_dir, namelen); - if (cp[-1] != '/') - *cp++ = '/'; - cp = stpcpy (cp, "sem."); - mountpoint.dirlen = cp - mountpoint.dir; - } - - break; - } - - /* Close the stream. */ - __endmntent (fp); -} +#include <shm-directory.h> /* Comparison function for search of existing mapping. */ @@ -217,8 +125,9 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing) if (result != existing && existing != SEM_FAILED && existing != MAP_FAILED) { /* Do not disturb errno. */ - INTERNAL_SYSCALL_DECL (err); - INTERNAL_SYSCALL (munmap, err, 2, existing, sizeof (sem_t)); + int save = errno; + munmap (existing, sizeof (sem_t)); + errno = save; } return result; @@ -228,42 +137,17 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing) sem_t * sem_open (const char *name, int oflag, ...) { - char *finalname; - sem_t *result = SEM_FAILED; int fd; + sem_t *result; - /* Determine where the shmfs is mounted. */ - __pthread_once (&__namedsem_once, __where_is_shmfs); - - /* If we don't know the mount points there is nothing we can do. Ever. */ - if (mountpoint.dir == NULL) - { - __set_errno (ENOSYS); - return SEM_FAILED; - } - - /* Construct the filename. */ - while (name[0] == '/') - ++name; - - if (name[0] == '\0') - { - /* The name "/" is not supported. */ - __set_errno (EINVAL); - return SEM_FAILED; - } - size_t namelen = strlen (name) + 1; - - /* Create the name of the final file. */ - finalname = (char *) alloca (mountpoint.dirlen + namelen); - __mempcpy (__mempcpy (finalname, mountpoint.dir, mountpoint.dirlen), - name, namelen); + /* Create the name of the final file in local variable SHM_NAME. */ + SHM_GET_NAME (EINVAL, SEM_FAILED, SEM_SHM_PREFIX); /* If the semaphore object has to exist simply open it. */ if ((oflag & O_CREAT) == 0 || (oflag & O_EXCL) == 0) { try_again: - fd = __libc_open (finalname, + fd = __libc_open (shm_name, (oflag & ~(O_CREAT|O_ACCMODE)) | O_NOFOLLOW | O_RDWR); if (fd == -1) @@ -317,8 +201,8 @@ sem_open (const char *name, int oflag, ...) memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0', sizeof (sem_t) - sizeof (struct new_sem)); - tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1); - char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen); + tmpfname = __alloca (shm_dirlen + sizeof SEM_SHM_PREFIX + 6); + char *xxxxxx = __mempcpy (tmpfname, shm_dir, shm_dirlen); int retries = 0; #define NRETRIES 50 @@ -361,7 +245,7 @@ sem_open (const char *name, int oflag, ...) fd, 0)) != MAP_FAILED) { /* Create the file. Don't overwrite an existing file. */ - if (link (tmpfname, finalname) != 0) + if (link (tmpfname, shm_name) != 0) { /* Undo the mapping. */ (void) munmap (result, sizeof (sem_t)); @@ -402,8 +286,9 @@ sem_open (const char *name, int oflag, ...) if (fd != -1) { /* Do not disturb errno. */ - INTERNAL_SYSCALL_DECL (err); - INTERNAL_SYSCALL (close, err, 1, fd); + int save = errno; + __libc_close (fd); + errno = save; } return result; diff --git a/nptl/sem_unlink.c b/nptl/sem_unlink.c index 485a3b8d2a..04abd3159a 100644 --- a/nptl/sem_unlink.c +++ b/nptl/sem_unlink.c @@ -22,44 +22,16 @@ #include <string.h> #include <unistd.h> #include "semaphoreP.h" - +#include <shm-directory.h> int -sem_unlink (name) - const char *name; +sem_unlink (const char *name) { - char *fname; - size_t namelen; - - /* Determine where the shmfs is mounted. */ - __pthread_once (&__namedsem_once, __where_is_shmfs); - - /* If we don't know the mount points there is nothing we can do. Ever. */ - if (mountpoint.dir == NULL) - { - __set_errno (ENOSYS); - return -1; - } - /* Construct the filename. */ - while (name[0] == '/') - ++name; - - if (name[0] == '\0') - { - /* The name "/" is not supported. */ - __set_errno (ENOENT); - return -1; - } - namelen = strlen (name); - - /* Create the name of the file. */ - fname = (char *) alloca (mountpoint.dirlen + namelen + 1); - __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen), - name, namelen + 1); + SHM_GET_NAME (ENOENT, -1, SEM_SHM_PREFIX); /* Now try removing it. */ - int ret = unlink (fname); + int ret = unlink (shm_name); if (ret < 0 && errno == EPERM) __set_errno (EACCES); return ret; diff --git a/nptl/semaphoreP.h b/nptl/semaphoreP.h index 5e6a701970..7ab50391cb 100644 --- a/nptl/semaphoreP.h +++ b/nptl/semaphoreP.h @@ -19,13 +19,7 @@ #include <semaphore.h> #include "pthreadP.h" - -/* Mount point of the shared memory filesystem. */ -struct mountpoint_info -{ - char *dir; - size_t dirlen; -}; +#define SEM_SHM_PREFIX "sem." /* Keeping track of currently used mappings. */ struct inuse_sem @@ -38,11 +32,6 @@ struct inuse_sem }; -/* Variables used in multiple interfaces. */ -extern struct mountpoint_info mountpoint attribute_hidden; - -extern pthread_once_t __namedsem_once attribute_hidden; - /* The search tree for existing mappings. */ extern void *__sem_mappings attribute_hidden; @@ -50,9 +39,6 @@ extern void *__sem_mappings attribute_hidden; extern int __sem_mappings_lock attribute_hidden; -/* Initializer for mountpoint. */ -extern void __where_is_shmfs (void) attribute_hidden; - /* Comparison function for search in tree with existing mappings. */ extern int __sem_search (const void *a, const void *b) attribute_hidden; |