xref: /minix/minix/lib/libc/sys/sem.c (revision e1cdaee1)
1 #define _SYSTEM	1
2 #define _MINIX_SYSTEM	1
3 
4 #include <sys/cdefs.h>
5 #include <lib.h>
6 #include "namespace.h"
7 
8 #include <lib.h>
9 #include <minix/rs.h>
10 
11 #include <sys/types.h>
12 #include <sys/ipc.h>
13 #include <sys/sem.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 #include <errno.h>
17 #include <string.h>
18 
19 static int get_ipc_endpt(endpoint_t *pt)
20 {
21 	return minix_rs_lookup("ipc", pt);
22 }
23 
24 /* Get semaphore.  */
25 int semget(key_t key, int nsems, int semflag)
26 {
27 	message m;
28 	endpoint_t ipc_pt;
29 	int r;
30 
31 	if (get_ipc_endpt(&ipc_pt) != OK) {
32 		errno = ENOSYS;
33 		return -1;
34 	}
35 
36 	memset(&m, 0, sizeof(m));
37 	m.m_lc_ipc_semget.key = key;
38 	m.m_lc_ipc_semget.nr = nsems;
39 	m.m_lc_ipc_semget.flag = semflag;
40 
41 	r = _syscall(ipc_pt, IPC_SEMGET, &m);
42 	if (r != OK)
43 		return r;
44 
45 	return m.m_lc_ipc_semget.retid;
46 }
47 
48 /* Semaphore control operation.  */
49 int semctl(int semid, int semnum, int cmd, ...)
50 {
51 	message m;
52 	endpoint_t ipc_pt;
53 	va_list ap;
54 	int r;
55 
56 	if (get_ipc_endpt(&ipc_pt) != OK) {
57 		errno = ENOSYS;
58 		return -1;
59 	}
60 
61 	memset(&m, 0, sizeof(m));
62 	m.m_lc_ipc_semctl.id = semid;
63 	m.m_lc_ipc_semctl.num = semnum;
64 	m.m_lc_ipc_semctl.cmd = cmd;
65 	va_start(ap, cmd);
66 	switch (cmd) {
67 	case SETVAL:
68 		m.m_lc_ipc_semctl.opt = (vir_bytes)va_arg(ap, int);
69 		break;
70 	case IPC_STAT:
71 	case IPC_SET:
72 	case IPC_INFO:
73 	case SEM_INFO:
74 	case SEM_STAT:
75 	case GETALL:
76 	case SETALL:
77 		m.m_lc_ipc_semctl.opt = (vir_bytes)va_arg(ap, void *);
78 		break;
79 	default:
80 		m.m_lc_ipc_semctl.opt = 0;
81 		break;
82 	}
83 	va_end(ap);
84 
85 	r = _syscall(ipc_pt, IPC_SEMCTL, &m);
86 	if ((r != -1) && (cmd == GETNCNT || cmd == GETZCNT || cmd == GETPID ||
87 		cmd == GETVAL || cmd == IPC_INFO || cmd == SEM_INFO ||
88 		cmd == SEM_STAT))
89 		return m.m_lc_ipc_semctl.ret;
90 	return r;
91 }
92 
93 /* Operate on semaphore.  */
94 int semop(int semid, struct sembuf *sops, size_t nsops)
95 {
96 	message m;
97 	endpoint_t ipc_pt;
98 
99 	if (get_ipc_endpt(&ipc_pt) != OK) {
100 		errno = ENOSYS;
101 		return -1;
102 	}
103 
104 	memset(&m, 0, sizeof(m));
105 	m.m_lc_ipc_semop.id = semid;
106 	m.m_lc_ipc_semop.ops = sops;
107 	m.m_lc_ipc_semop.size = nsops;
108 
109 	return _syscall(ipc_pt, IPC_SEMOP, &m);
110 }
111 
112