]>
Commit | Line | Data |
---|---|---|
b168057a | 1 | /* Copyright (C) 1995-2015 Free Software Foundation, Inc. |
3e5f5557 UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. | |
28f540f4 | 4 | |
3e5f5557 | 5 | The GNU C Library is free software; you can redistribute it and/or |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
28f540f4 | 9 | |
3e5f5557 UD |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
28f540f4 | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
28f540f4 | 18 | |
e9dcb080 | 19 | #include <errno.h> |
d2f5be2a | 20 | #include <sys/shm.h> |
973209d8 | 21 | #include <ipc_priv.h> |
28f540f4 | 22 | |
e9dcb080 | 23 | #include <sysdep.h> |
0482576e | 24 | #include <string.h> |
e9dcb080 | 25 | #include <sys/syscall.h> |
0482576e | 26 | #include <bits/wordsize.h> |
b5567b2a | 27 | #include <shlib-compat.h> |
0482576e | 28 | |
6ddd37a4 | 29 | #include <kernel-features.h> |
e9dcb080 | 30 | |
973209d8 UD |
31 | struct __old_shmid_ds |
32 | { | |
33 | struct __old_ipc_perm shm_perm; /* operation permission struct */ | |
34 | int shm_segsz; /* size of segment in bytes */ | |
35 | __time_t shm_atime; /* time of last shmat() */ | |
36 | __time_t shm_dtime; /* time of last shmdt() */ | |
37 | __time_t shm_ctime; /* time of last change by shmctl() */ | |
38 | __ipc_pid_t shm_cpid; /* pid of creator */ | |
39 | __ipc_pid_t shm_lpid; /* pid of last shmop */ | |
40 | unsigned short int shm_nattch; /* number of current attaches */ | |
41 | unsigned short int __shm_npages; /* size of segment (pages) */ | |
70d9946a JM |
42 | unsigned long int *__shm_pages; /* array of ptrs to frames -> SHMMAX */ |
43 | struct vm_area_struct *__attaches; /* descriptors for attaches */ | |
973209d8 UD |
44 | }; |
45 | ||
46 | struct __old_shminfo | |
47 | { | |
48 | int shmmax; | |
49 | int shmmin; | |
50 | int shmmni; | |
51 | int shmseg; | |
52 | int shmall; | |
53 | }; | |
54 | ||
d2f5be2a | 55 | /* Provide operations to control over shared memory segments. */ |
93f9ef01 | 56 | #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) |
0482576e | 57 | int __old_shmctl (int, int, struct __old_shmid_ds *); |
b5567b2a | 58 | #endif |
0482576e | 59 | int __new_shmctl (int, int, struct shmid_ds *); |
28f540f4 | 60 | |
b5567b2a | 61 | #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) |
d2f5be2a | 62 | int |
d3a4a571 | 63 | attribute_compat_text_section |
0482576e | 64 | __old_shmctl (int shmid, int cmd, struct __old_shmid_ds *buf) |
d2f5be2a | 65 | { |
f3aae3f3 | 66 | return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0, buf); |
d2f5be2a | 67 | } |
b5567b2a UD |
68 | compat_symbol (libc, __old_shmctl, shmctl, GLIBC_2_0); |
69 | #endif | |
0482576e UD |
70 | |
71 | int | |
72 | __new_shmctl (int shmid, int cmd, struct shmid_ds *buf) | |
73 | { | |
a0386a0d | 74 | #if __ASSUME_IPC64 > 0 |
d347a4ab | 75 | return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd | __IPC_64, 0, |
f3aae3f3 | 76 | buf); |
0482576e UD |
77 | #else |
78 | switch (cmd) { | |
79 | case SHM_STAT: | |
80 | case IPC_STAT: | |
81 | case IPC_SET: | |
82 | #if __WORDSIZE != 32 | |
83 | case IPC_INFO: | |
84 | #endif | |
85 | break; | |
86 | default: | |
f3aae3f3 | 87 | return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0, buf); |
0482576e UD |
88 | } |
89 | ||
90 | { | |
91 | int save_errno = errno, result; | |
d347a4ab UD |
92 | union |
93 | { | |
94 | struct __old_shmid_ds ds; | |
95 | struct __old_shminfo info; | |
96 | } old; | |
0482576e UD |
97 | |
98 | /* Unfortunately there is no way how to find out for sure whether | |
99 | we should use old or new shmctl. */ | |
d347a4ab | 100 | result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd | __IPC_64, 0, |
f3aae3f3 | 101 | buf); |
0482576e UD |
102 | if (result != -1 || errno != EINVAL) |
103 | return result; | |
104 | ||
105 | __set_errno(save_errno); | |
106 | if (cmd == IPC_SET) | |
107 | { | |
d347a4ab UD |
108 | old.ds.shm_perm.uid = buf->shm_perm.uid; |
109 | old.ds.shm_perm.gid = buf->shm_perm.gid; | |
110 | old.ds.shm_perm.mode = buf->shm_perm.mode; | |
111 | if (old.ds.shm_perm.uid != buf->shm_perm.uid || | |
112 | old.ds.shm_perm.gid != buf->shm_perm.gid) | |
0482576e UD |
113 | { |
114 | __set_errno (EINVAL); | |
115 | return -1; | |
116 | } | |
117 | } | |
70d9946a | 118 | result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0, &old.ds); |
0482576e UD |
119 | if (result != -1 && (cmd == SHM_STAT || cmd == IPC_STAT)) |
120 | { | |
121 | memset(buf, 0, sizeof(*buf)); | |
d347a4ab UD |
122 | buf->shm_perm.__key = old.ds.shm_perm.__key; |
123 | buf->shm_perm.uid = old.ds.shm_perm.uid; | |
124 | buf->shm_perm.gid = old.ds.shm_perm.gid; | |
125 | buf->shm_perm.cuid = old.ds.shm_perm.cuid; | |
126 | buf->shm_perm.cgid = old.ds.shm_perm.cgid; | |
127 | buf->shm_perm.mode = old.ds.shm_perm.mode; | |
128 | buf->shm_perm.__seq = old.ds.shm_perm.__seq; | |
129 | buf->shm_atime = old.ds.shm_atime; | |
130 | buf->shm_dtime = old.ds.shm_dtime; | |
131 | buf->shm_ctime = old.ds.shm_ctime; | |
132 | buf->shm_segsz = old.ds.shm_segsz; | |
133 | buf->shm_nattch = old.ds.shm_nattch; | |
134 | buf->shm_cpid = old.ds.shm_cpid; | |
135 | buf->shm_lpid = old.ds.shm_lpid; | |
0482576e UD |
136 | } |
137 | #if __WORDSIZE != 32 | |
138 | else if (result != -1 && cmd == IPC_INFO) | |
139 | { | |
0482576e UD |
140 | struct shminfo *i = (struct shminfo *)buf; |
141 | ||
142 | memset(i, 0, sizeof(*i)); | |
d347a4ab UD |
143 | i->shmmax = old.info.shmmax; |
144 | i->shmmin = old.info.shmmin; | |
145 | i->shmmni = old.info.shmmni; | |
146 | i->shmseg = old.info.shmseg; | |
147 | i->shmall = old.info.shmall; | |
0482576e UD |
148 | } |
149 | #endif | |
150 | return result; | |
151 | } | |
152 | #endif | |
153 | } | |
154 | ||
b5567b2a | 155 | versioned_symbol (libc, __new_shmctl, shmctl, GLIBC_2_2); |