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 */ |