diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2016-10-26 16:55:39 -0200 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2016-12-28 20:31:04 -0200 |
commit | 40c0a780687b3387e02caadc8545b21347cffc7e (patch) | |
tree | f224f19b04a41e7b645ce78a2e44d09315a972b9 /sysdeps/unix/sysv/linux/semctl.c | |
parent | 59c900c54b8db3638bc5e9e90784552aab4e2df4 (diff) | |
download | glibc-40c0a780687b3387e02caadc8545b21347cffc7e.tar glibc-40c0a780687b3387e02caadc8545b21347cffc7e.tar.gz glibc-40c0a780687b3387e02caadc8545b21347cffc7e.tar.bz2 glibc-40c0a780687b3387e02caadc8545b21347cffc7e.zip |
Consolidate Linux semctl implementation
This patch consolidates the semctl Linux implementation in only
one default file, sysdeps/unix/sysv/linux/semctl.c. If tries to use
the direct syscall if it is supported, otherwise will use the old ipc
multiplex mechanism.
The patch also simplify header inclusion and reorganize internal
compat symbol to be built only if old ipc is defined.
Checked on x86_64, i686, powerpc64le, aarch64, and armhf.
* sysdeps/unix/sysv/linux/alpha/Makefile (sysdeps_routines): Remove
oldsemctl.
* sysdeps/unix/sysv/linux/alpha/semctl.c: Remove file.
* sysdeps/unix/sysv/linux/arm/semctl.c: Likewise.
* sysdeps/unix/sysv/linux/microblaze/semctl.c: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/semctl.c: Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/semctl.c: Use defaulf
implementation.
* sysdeps/unix/sysv/linux/semctl.c (__new_semctl): Use semctl
syscall if it is defined.
* sysdeps/unix/sysv/linux/generic/syscalls.list (semctl): Remove.
* sysdeps/unix/sysv/linux/alpha/syscalls.list (semctl): Likewise.
* sysdeps/unix/sysv/linux/hppa/syscalls.list (semctl): Likewise.
* sysdeps/unix/sysv/linux/ia64/syscalls.list (semctl): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list (semctl):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/syscalls.list (semctl): Likewise.
Diffstat (limited to 'sysdeps/unix/sysv/linux/semctl.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/semctl.c | 71 |
1 files changed, 30 insertions, 41 deletions
diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c index ee84a1e316..dde224105b 100644 --- a/sysdeps/unix/sysv/linux/semctl.c +++ b/sysdeps/unix/sysv/linux/semctl.c @@ -16,29 +16,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <stdarg.h> #include <sys/sem.h> +#include <stdarg.h> #include <ipc_priv.h> - #include <sysdep.h> -#include <string.h> -#include <sys/syscall.h> #include <shlib-compat.h> - -#include <kernel-features.h> - -struct __old_semid_ds -{ - struct __old_ipc_perm sem_perm; /* operation permission struct */ - __time_t sem_otime; /* last semop() time */ - __time_t sem_ctime; /* last time changed by semctl() */ - struct sem *__sembase; /* ptr to first semaphore in array */ - struct sem_queue *__sem_pending; /* pending operations */ - struct sem_queue *__sem_pending_last; /* last pending operation */ - struct sem_undo *__undo; /* ondo requests on this array */ - unsigned short int sem_nsems; /* number of semaphores in set */ -}; +#include <errno.h> /* Define a `union semun' suitable for Linux here. */ union semun @@ -47,26 +30,19 @@ union semun struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ unsigned short int *array; /* array for GETALL & SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ - struct __old_semid_ds *__old_buf; }; -/* Return identifier for array of NSEMS semaphores associated with - KEY. */ -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) -int __old_semctl (int semid, int semnum, int cmd, ...); +#ifndef DEFAULT_VERSION +# define DEFAULT_VERSION GLIBC_2_2 #endif -int __new_semctl (int semid, int semnum, int cmd, ...); -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) int -attribute_compat_text_section -__old_semctl (int semid, int semnum, int cmd, ...) +__new_semctl (int semid, int semnum, int cmd, ...) { - union semun arg; + union semun arg = { 0 }; va_list ap; /* Get the argument only if required. */ - arg.buf = NULL; switch (cmd) { case SETVAL: /* arg.val */ @@ -83,20 +59,29 @@ __old_semctl (int semid, int semnum, int cmd, ...) break; } - return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd, - &arg); -} -compat_symbol (libc, __old_semctl, semctl, GLIBC_2_0); +#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, + arg.array); +#else + return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, + SEMCTL_ARG_ADDRESS (arg)); #endif +} +versioned_symbol (libc, __new_semctl, semctl, DEFAULT_VERSION); + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +/* Since semctl use a variadic argument for semid_ds there is not need to + define and tie the compatibility symbol to the old 'union semun' + definition. */ int -__new_semctl (int semid, int semnum, int cmd, ...) +attribute_compat_text_section +__old_semctl (int semid, int semnum, int cmd, ...) { - union semun arg; + union semun arg = { 0 }; va_list ap; /* Get the argument only if required. */ - arg.buf = NULL; switch (cmd) { case SETVAL: /* arg.val */ @@ -113,8 +98,12 @@ __new_semctl (int semid, int semnum, int cmd, ...) break; } - return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64, - &arg); +# ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd, arg.array); +# else + return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd, + SEMCTL_ARG_ADDRESS (arg)); +# endif } - -versioned_symbol (libc, __new_semctl, semctl, GLIBC_2_2); +compat_symbol (libc, __old_semctl, semctl, GLIBC_2_0); +#endif |