Deleted Added
full compact
sysv_sem.c (194910) sysv_sem.c (205323)
1/*-
2 * Implementation of SVID semaphores
3 *
4 * Author: Daniel Boulet
5 *
6 * This software is provided ``AS IS'' without any warranties of any kind.
7 */
8/*-

--- 23 unchanged lines hidden (view full) ---

32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39#include <sys/cdefs.h>
1/*-
2 * Implementation of SVID semaphores
3 *
4 * Author: Daniel Boulet
5 *
6 * This software is provided ``AS IS'' without any warranties of any kind.
7 */
8/*-

--- 23 unchanged lines hidden (view full) ---

32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: head/sys/kern/sysv_sem.c 194910 2009-06-24 21:10:52Z jhb $");
40__FBSDID("$FreeBSD: head/sys/kern/sysv_sem.c 205323 2010-03-19 11:04:42Z kib $");
41
42#include "opt_compat.h"
43#include "opt_sysvipc.h"
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/sysproto.h>
48#include <sys/eventhandler.h>

--- 16 unchanged lines hidden (view full) ---

65static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
66
67#ifdef SEM_DEBUG
68#define DPRINTF(a) printf a
69#else
70#define DPRINTF(a)
71#endif
72
41
42#include "opt_compat.h"
43#include "opt_sysvipc.h"
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/sysproto.h>
48#include <sys/eventhandler.h>

--- 16 unchanged lines hidden (view full) ---

65static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
66
67#ifdef SEM_DEBUG
68#define DPRINTF(a) printf a
69#else
70#define DPRINTF(a)
71#endif
72
73static void seminit(void);
73static int seminit(void);
74static int sysvsem_modload(struct module *, int, void *);
75static int semunload(void);
76static void semexit_myhook(void *arg, struct proc *p);
77static int sysctl_sema(SYSCTL_HANDLER_ARGS);
78static int semvalid(int semid, struct semid_kernel *semakptr);
79
80#ifndef _SYS_SYSPROTO_H_
81struct __semctl_args;

--- 127 unchanged lines hidden (view full) ---

209 "Size in bytes of undo structure");
210SYSCTL_INT(_kern_ipc, OID_AUTO, semvmx, CTLFLAG_RW, &seminfo.semvmx, 0,
211 "Semaphore maximum value");
212SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0,
213 "Adjust on exit max value");
214SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD,
215 NULL, 0, sysctl_sema, "", "");
216
74static int sysvsem_modload(struct module *, int, void *);
75static int semunload(void);
76static void semexit_myhook(void *arg, struct proc *p);
77static int sysctl_sema(SYSCTL_HANDLER_ARGS);
78static int semvalid(int semid, struct semid_kernel *semakptr);
79
80#ifndef _SYS_SYSPROTO_H_
81struct __semctl_args;

--- 127 unchanged lines hidden (view full) ---

209 "Size in bytes of undo structure");
210SYSCTL_INT(_kern_ipc, OID_AUTO, semvmx, CTLFLAG_RW, &seminfo.semvmx, 0,
211 "Semaphore maximum value");
212SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0,
213 "Adjust on exit max value");
214SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD,
215 NULL, 0, sysctl_sema, "", "");
216
217static void
217static struct syscall_helper_data sem_syscalls[] = {
218 SYSCALL_INIT_HELPER(__semctl),
219 SYSCALL_INIT_HELPER(semget),
220 SYSCALL_INIT_HELPER(semop),
221#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
222 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
223 SYSCALL_INIT_HELPER(semsys),
224 SYSCALL_INIT_HELPER(freebsd7___semctl),
225#endif
226 SYSCALL_INIT_LAST
227};
228
229#ifdef COMPAT_FREEBSD32
230#include <compat/freebsd32/freebsd32.h>
231#include <compat/freebsd32/freebsd32_ipc.h>
232#include <compat/freebsd32/freebsd32_proto.h>
233#include <compat/freebsd32/freebsd32_signal.h>
234#include <compat/freebsd32/freebsd32_syscall.h>
235#include <compat/freebsd32/freebsd32_util.h>
236
237static struct syscall_helper_data sem32_syscalls[] = {
238 SYSCALL32_INIT_HELPER(freebsd32_semctl),
239 SYSCALL32_INIT_HELPER(semget),
240 SYSCALL32_INIT_HELPER(semop),
241 SYSCALL32_INIT_HELPER(freebsd32_semsys),
242#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
243 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
244 SYSCALL32_INIT_HELPER(freebsd7_freebsd32_semctl),
245#endif
246 SYSCALL_INIT_LAST
247};
248#endif
249
250static int
218seminit(void)
219{
251seminit(void)
252{
220 int i;
253 int i, error;
221
222 TUNABLE_INT_FETCH("kern.ipc.semmap", &seminfo.semmap);
223 TUNABLE_INT_FETCH("kern.ipc.semmni", &seminfo.semmni);
224 TUNABLE_INT_FETCH("kern.ipc.semmns", &seminfo.semmns);
225 TUNABLE_INT_FETCH("kern.ipc.semmnu", &seminfo.semmnu);
226 TUNABLE_INT_FETCH("kern.ipc.semmsl", &seminfo.semmsl);
227 TUNABLE_INT_FETCH("kern.ipc.semopm", &seminfo.semopm);
228 TUNABLE_INT_FETCH("kern.ipc.semume", &seminfo.semume);

--- 24 unchanged lines hidden (view full) ---

253 suptr->un_proc = NULL;
254 LIST_INSERT_HEAD(&semu_free_list, suptr, un_next);
255 }
256 LIST_INIT(&semu_list);
257 mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
258 mtx_init(&sem_undo_mtx, "semu", NULL, MTX_DEF);
259 semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
260 EVENTHANDLER_PRI_ANY);
254
255 TUNABLE_INT_FETCH("kern.ipc.semmap", &seminfo.semmap);
256 TUNABLE_INT_FETCH("kern.ipc.semmni", &seminfo.semmni);
257 TUNABLE_INT_FETCH("kern.ipc.semmns", &seminfo.semmns);
258 TUNABLE_INT_FETCH("kern.ipc.semmnu", &seminfo.semmnu);
259 TUNABLE_INT_FETCH("kern.ipc.semmsl", &seminfo.semmsl);
260 TUNABLE_INT_FETCH("kern.ipc.semopm", &seminfo.semopm);
261 TUNABLE_INT_FETCH("kern.ipc.semume", &seminfo.semume);

--- 24 unchanged lines hidden (view full) ---

286 suptr->un_proc = NULL;
287 LIST_INSERT_HEAD(&semu_free_list, suptr, un_next);
288 }
289 LIST_INIT(&semu_list);
290 mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
291 mtx_init(&sem_undo_mtx, "semu", NULL, MTX_DEF);
292 semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
293 EVENTHANDLER_PRI_ANY);
294
295 error = syscall_helper_register(sem_syscalls);
296 if (error != 0)
297 return (error);
298#ifdef COMPAT_FREEBSD32
299 error = syscall32_helper_register(sem32_syscalls);
300 if (error != 0)
301 return (error);
302#endif
303 return (0);
261}
262
263static int
264semunload(void)
265{
266 int i;
267
268 /* XXXKIB */
269 if (semtot != 0)
270 return (EBUSY);
271
304}
305
306static int
307semunload(void)
308{
309 int i;
310
311 /* XXXKIB */
312 if (semtot != 0)
313 return (EBUSY);
314
315#ifdef COMPAT_FREEBSD32
316 syscall32_helper_unregister(sem32_syscalls);
317#endif
318 syscall_helper_unregister(sem_syscalls);
272 EVENTHANDLER_DEREGISTER(process_exit, semexit_tag);
273#ifdef MAC
274 for (i = 0; i < seminfo.semmni; i++)
275 mac_sysvsem_destroy(&sema[i]);
276#endif
277 free(sem, M_SEM);
278 free(sema, M_SEM);
279 free(semu, M_SEM);

--- 7 unchanged lines hidden (view full) ---

287
288static int
289sysvsem_modload(struct module *module, int cmd, void *arg)
290{
291 int error = 0;
292
293 switch (cmd) {
294 case MOD_LOAD:
319 EVENTHANDLER_DEREGISTER(process_exit, semexit_tag);
320#ifdef MAC
321 for (i = 0; i < seminfo.semmni; i++)
322 mac_sysvsem_destroy(&sema[i]);
323#endif
324 free(sem, M_SEM);
325 free(sema, M_SEM);
326 free(semu, M_SEM);

--- 7 unchanged lines hidden (view full) ---

334
335static int
336sysvsem_modload(struct module *module, int cmd, void *arg)
337{
338 int error = 0;
339
340 switch (cmd) {
341 case MOD_LOAD:
295 seminit();
342 error = seminit();
343 if (error != 0)
344 semunload();
296 break;
297 case MOD_UNLOAD:
298 error = semunload();
299 break;
300 case MOD_SHUTDOWN:
301 break;
302 default:
303 error = EINVAL;
304 break;
305 }
306 return (error);
307}
308
309static moduledata_t sysvsem_mod = {
310 "sysvsem",
311 &sysvsem_modload,
312 NULL
313};
314
345 break;
346 case MOD_UNLOAD:
347 error = semunload();
348 break;
349 case MOD_SHUTDOWN:
350 break;
351 default:
352 error = EINVAL;
353 break;
354 }
355 return (error);
356}
357
358static moduledata_t sysvsem_mod = {
359 "sysvsem",
360 &sysvsem_modload,
361 NULL
362};
363
315SYSCALL_MODULE_HELPER(__semctl);
316SYSCALL_MODULE_HELPER(semget);
317SYSCALL_MODULE_HELPER(semop);
318
319DECLARE_MODULE(sysvsem, sysvsem_mod, SI_SUB_SYSV_SEM, SI_ORDER_FIRST);
320MODULE_VERSION(sysvsem, 1);
321
322/*
323 * Allocate a new sem_undo structure for a process
324 * (returns ptr to structure or NULL if no more room)
325 */
326

--- 984 unchanged lines hidden (view full) ---

1311{
1312
1313 return (SYSCTL_OUT(req, sema,
1314 sizeof(struct semid_kernel) * seminfo.semmni));
1315}
1316
1317#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1318 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
364DECLARE_MODULE(sysvsem, sysvsem_mod, SI_SUB_SYSV_SEM, SI_ORDER_FIRST);
365MODULE_VERSION(sysvsem, 1);
366
367/*
368 * Allocate a new sem_undo structure for a process
369 * (returns ptr to structure or NULL if no more room)
370 */
371

--- 984 unchanged lines hidden (view full) ---

1356{
1357
1358 return (SYSCTL_OUT(req, sema,
1359 sizeof(struct semid_kernel) * seminfo.semmni));
1360}
1361
1362#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1363 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1319SYSCALL_MODULE_HELPER(semsys);
1320SYSCALL_MODULE_HELPER(freebsd7___semctl);
1321
1322/* XXX casting to (sy_call_t *) is bogus, as usual. */
1323static sy_call_t *semcalls[] = {
1324 (sy_call_t *)freebsd7___semctl, (sy_call_t *)semget,
1325 (sy_call_t *)semop
1326};
1327
1328/*

--- 17 unchanged lines hidden (view full) ---

1346 return (ENOSYS);
1347 if (uap->which < 0 ||
1348 uap->which >= sizeof(semcalls)/sizeof(semcalls[0]))
1349 return (EINVAL);
1350 error = (*semcalls[uap->which])(td, &uap->a2);
1351 return (error);
1352}
1353
1364
1365/* XXX casting to (sy_call_t *) is bogus, as usual. */
1366static sy_call_t *semcalls[] = {
1367 (sy_call_t *)freebsd7___semctl, (sy_call_t *)semget,
1368 (sy_call_t *)semop
1369};
1370
1371/*

--- 17 unchanged lines hidden (view full) ---

1389 return (ENOSYS);
1390 if (uap->which < 0 ||
1391 uap->which >= sizeof(semcalls)/sizeof(semcalls[0]))
1392 return (EINVAL);
1393 error = (*semcalls[uap->which])(td, &uap->a2);
1394 return (error);
1395}
1396
1397#ifndef CP
1354#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
1398#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
1399#endif
1355
1356#ifndef _SYS_SYSPROTO_H_
1357struct freebsd7___semctl_args {
1358 int semid;
1359 int semnum;
1360 int cmd;
1361 union semun_old *arg;
1362};

--- 64 unchanged lines hidden (view full) ---

1427 break;
1428 }
1429
1430 if (error == 0)
1431 td->td_retval[0] = rval;
1432 return (error);
1433}
1434
1400
1401#ifndef _SYS_SYSPROTO_H_
1402struct freebsd7___semctl_args {
1403 int semid;
1404 int semnum;
1405 int cmd;
1406 union semun_old *arg;
1407};

--- 64 unchanged lines hidden (view full) ---

1472 break;
1473 }
1474
1475 if (error == 0)
1476 td->td_retval[0] = rval;
1477 return (error);
1478}
1479
1435#undef CP
1480#endif /* COMPAT_FREEBSD{4,5,6,7} */
1436
1481
1437#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
1438 COMPAT_FREEBSD7 */
1482#ifdef COMPAT_FREEBSD32
1483
1484int
1485freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
1486{
1487
1488#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1489 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1490 switch (uap->which) {
1491 case 0:
1492 return (freebsd7_freebsd32_semctl(td,
1493 (struct freebsd7_freebsd32_semctl_args *)&uap->a2));
1494 default:
1495 return (semsys(td, (struct semsys_args *)uap));
1496 }
1497#else
1498 return (nosys(td, NULL));
1499#endif
1500}
1501
1502#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1503 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1504int
1505freebsd7_freebsd32_semctl(struct thread *td,
1506 struct freebsd7_freebsd32_semctl_args *uap)
1507{
1508 struct semid_ds32_old dsbuf32;
1509 struct semid_ds dsbuf;
1510 union semun semun;
1511 union semun32 arg;
1512 register_t rval;
1513 int error;
1514
1515 switch (uap->cmd) {
1516 case SEM_STAT:
1517 case IPC_SET:
1518 case IPC_STAT:
1519 case GETALL:
1520 case SETVAL:
1521 case SETALL:
1522 error = copyin(uap->arg, &arg, sizeof(arg));
1523 if (error)
1524 return (error);
1525 break;
1526 }
1527
1528 switch (uap->cmd) {
1529 case SEM_STAT:
1530 case IPC_STAT:
1531 semun.buf = &dsbuf;
1532 break;
1533 case IPC_SET:
1534 error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
1535 if (error)
1536 return (error);
1537 freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
1538 PTRIN_CP(dsbuf32, dsbuf, sem_base);
1539 CP(dsbuf32, dsbuf, sem_nsems);
1540 CP(dsbuf32, dsbuf, sem_otime);
1541 CP(dsbuf32, dsbuf, sem_ctime);
1542 semun.buf = &dsbuf;
1543 break;
1544 case GETALL:
1545 case SETALL:
1546 semun.array = PTRIN(arg.array);
1547 break;
1548 case SETVAL:
1549 semun.val = arg.val;
1550 break;
1551 }
1552
1553 error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
1554 &rval);
1555 if (error)
1556 return (error);
1557
1558 switch (uap->cmd) {
1559 case SEM_STAT:
1560 case IPC_STAT:
1561 bzero(&dsbuf32, sizeof(dsbuf32));
1562 freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
1563 PTROUT_CP(dsbuf, dsbuf32, sem_base);
1564 CP(dsbuf, dsbuf32, sem_nsems);
1565 CP(dsbuf, dsbuf32, sem_otime);
1566 CP(dsbuf, dsbuf32, sem_ctime);
1567 error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
1568 break;
1569 }
1570
1571 if (error == 0)
1572 td->td_retval[0] = rval;
1573 return (error);
1574}
1575#endif
1576
1577int
1578freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
1579{
1580 struct semid_ds32 dsbuf32;
1581 struct semid_ds dsbuf;
1582 union semun semun;
1583 union semun32 arg;
1584 register_t rval;
1585 int error;
1586
1587 switch (uap->cmd) {
1588 case SEM_STAT:
1589 case IPC_SET:
1590 case IPC_STAT:
1591 case GETALL:
1592 case SETVAL:
1593 case SETALL:
1594 error = copyin(uap->arg, &arg, sizeof(arg));
1595 if (error)
1596 return (error);
1597 break;
1598 }
1599
1600 switch (uap->cmd) {
1601 case SEM_STAT:
1602 case IPC_STAT:
1603 semun.buf = &dsbuf;
1604 break;
1605 case IPC_SET:
1606 error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
1607 if (error)
1608 return (error);
1609 freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
1610 PTRIN_CP(dsbuf32, dsbuf, sem_base);
1611 CP(dsbuf32, dsbuf, sem_nsems);
1612 CP(dsbuf32, dsbuf, sem_otime);
1613 CP(dsbuf32, dsbuf, sem_ctime);
1614 semun.buf = &dsbuf;
1615 break;
1616 case GETALL:
1617 case SETALL:
1618 semun.array = PTRIN(arg.array);
1619 break;
1620 case SETVAL:
1621 semun.val = arg.val;
1622 break;
1623 }
1624
1625 error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
1626 &rval);
1627 if (error)
1628 return (error);
1629
1630 switch (uap->cmd) {
1631 case SEM_STAT:
1632 case IPC_STAT:
1633 bzero(&dsbuf32, sizeof(dsbuf32));
1634 freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
1635 PTROUT_CP(dsbuf, dsbuf32, sem_base);
1636 CP(dsbuf, dsbuf32, sem_nsems);
1637 CP(dsbuf, dsbuf32, sem_otime);
1638 CP(dsbuf, dsbuf32, sem_ctime);
1639 error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
1640 break;
1641 }
1642
1643 if (error == 0)
1644 td->td_retval[0] = rval;
1645 return (error);
1646}
1647
1648#endif /* COMPAT_FREEBSD32 */