
- switch to the NetBSD identifier system; it is not only better, but also required for porting NetBSD ipcs(1) and ipcrm(1); however, it requires that slots not be moved, and that results in some changes; - synchronize some other things with NetBSD: where keys are kept, as well as various non-permission mode flags; - fix semctl(2) vararg retrieval and message field type; - use SUSPEND instead of weird reply exceptions in the call table; - fix several memory leaks and at least one missing permission check; - improve the atomicity of semop(2) by a small amount, even though its atomicity is still broken at a fundamental level; - use the new cheaper way to retrieve the current time; - resolve all level-5 LLVM warnings. Change-Id: I0c47aacde478b23bb77d628384aeab855a22fdbf
112 lines
2.0 KiB
C
112 lines
2.0 KiB
C
#define _SYSTEM 1
|
|
#define _MINIX_SYSTEM 1
|
|
|
|
#include <sys/cdefs.h>
|
|
#include <lib.h>
|
|
#include "namespace.h"
|
|
|
|
#include <lib.h>
|
|
#include <minix/rs.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/sem.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
static int get_ipc_endpt(endpoint_t *pt)
|
|
{
|
|
return minix_rs_lookup("ipc", pt);
|
|
}
|
|
|
|
/* Get semaphore. */
|
|
int semget(key_t key, int nsems, int semflag)
|
|
{
|
|
message m;
|
|
endpoint_t ipc_pt;
|
|
int r;
|
|
|
|
if (get_ipc_endpt(&ipc_pt) != OK) {
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
memset(&m, 0, sizeof(m));
|
|
m.m_lc_ipc_semget.key = key;
|
|
m.m_lc_ipc_semget.nr = nsems;
|
|
m.m_lc_ipc_semget.flag = semflag;
|
|
|
|
r = _syscall(ipc_pt, IPC_SEMGET, &m);
|
|
if (r != OK)
|
|
return r;
|
|
|
|
return m.m_lc_ipc_semget.retid;
|
|
}
|
|
|
|
/* Semaphore control operation. */
|
|
int semctl(int semid, int semnum, int cmd, ...)
|
|
{
|
|
message m;
|
|
endpoint_t ipc_pt;
|
|
va_list ap;
|
|
int r;
|
|
|
|
if (get_ipc_endpt(&ipc_pt) != OK) {
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
memset(&m, 0, sizeof(m));
|
|
m.m_lc_ipc_semctl.id = semid;
|
|
m.m_lc_ipc_semctl.num = semnum;
|
|
m.m_lc_ipc_semctl.cmd = cmd;
|
|
va_start(ap, cmd);
|
|
switch (cmd) {
|
|
case SETVAL:
|
|
m.m_lc_ipc_semctl.opt = (vir_bytes)va_arg(ap, int);
|
|
break;
|
|
case IPC_STAT:
|
|
case IPC_SET:
|
|
case IPC_INFO:
|
|
case SEM_INFO:
|
|
case SEM_STAT:
|
|
case GETALL:
|
|
case SETALL:
|
|
m.m_lc_ipc_semctl.opt = (vir_bytes)va_arg(ap, void *);
|
|
break;
|
|
default:
|
|
m.m_lc_ipc_semctl.opt = 0;
|
|
break;
|
|
}
|
|
va_end(ap);
|
|
|
|
r = _syscall(ipc_pt, IPC_SEMCTL, &m);
|
|
if ((r != -1) && (cmd == GETNCNT || cmd == GETZCNT || cmd == GETPID ||
|
|
cmd == GETVAL || cmd == IPC_INFO || cmd == SEM_INFO ||
|
|
cmd == SEM_STAT))
|
|
return m.m_lc_ipc_semctl.ret;
|
|
return r;
|
|
}
|
|
|
|
/* Operate on semaphore. */
|
|
int semop(int semid, struct sembuf *sops, size_t nsops)
|
|
{
|
|
message m;
|
|
endpoint_t ipc_pt;
|
|
|
|
if (get_ipc_endpt(&ipc_pt) != OK) {
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
memset(&m, 0, sizeof(m));
|
|
m.m_lc_ipc_semop.id = semid;
|
|
m.m_lc_ipc_semop.ops = sops;
|
|
m.m_lc_ipc_semop.size = nsops;
|
|
|
|
return _syscall(ipc_pt, IPC_SEMOP, &m);
|
|
}
|
|
|