1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984 AT&T */
28 /* All Rights Reserved */
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #include <sys/syscall.h>
33 #include <stdarg.h>
34 #include <sys/types.h>
35 #include <sys/ipc.h>
36 #include <sys/shm.h>
37 #include <errno.h>
38
39
40 /* shmsys dispatch argument */
41 #define SHMAT 0
42 #define SHMCTL 1
43 #define SHMDT 2
44 #define SHMGET 3
45
46 struct shmid_sv {
47 struct ipc_perm shm_perm;
48 int shm_segsz;
49 struct anon_map *shm_amp;
50 unsigned short shm_lkcnt;
51 char pad[2];
52 short shm_lpid;
53 short shm_cpid;
54 unsigned short shm_nattch;
55 unsigned short shm_cnattch;
56 time_t shm_atime;
57 time_t shm_dtime;
58 time_t shm_ctime;
59 };
60
61
62 char *
shmat(int shmid,char * shmaddr,int shmflg)63 shmat(int shmid, char *shmaddr, int shmflg)
64 {
65 return ((char *)_syscall(SYS_shmsys, SHMAT, shmid, shmaddr, shmflg));
66 }
67
68 int
shmctl(int shmid,int cmd,struct shmid_ds * buf)69 shmctl(int shmid, int cmd, struct shmid_ds *buf)
70 {
71 struct shmid_sv n_buf;
72 int ret;
73
74 if (buf == (struct shmid_ds *)-1) {
75 errno = EFAULT;
76 return (-1);
77 }
78
79 if (buf == 0) {
80 ret = _syscall(SYS_shmsys, SHMCTL, shmid, cmd, 0);
81 } else {
82 n_buf.shm_perm = buf->shm_perm;
83 n_buf.shm_segsz = buf->shm_segsz;
84 n_buf.shm_amp = buf->shm_amp;
85 n_buf.shm_lpid = buf->shm_lpid;
86 n_buf.shm_cpid = buf->shm_cpid;
87 n_buf.shm_nattch = buf->shm_nattch;
88 n_buf.shm_atime = buf->shm_atime;
89 n_buf.shm_dtime = buf->shm_dtime;
90 n_buf.shm_ctime = buf->shm_ctime;
91 n_buf.shm_lkcnt = 0;
92 n_buf.shm_cnattch = 0;
93
94 ret = _syscall(SYS_shmsys, SHMCTL, shmid, cmd, &n_buf);
95
96 buf->shm_perm = n_buf.shm_perm;
97 buf->shm_segsz = n_buf.shm_segsz;
98 buf->shm_amp = n_buf.shm_amp;
99 buf->shm_lpid = n_buf.shm_lpid;
100 buf->shm_cpid = n_buf.shm_cpid;
101 buf->shm_nattch = n_buf.shm_nattch;
102 buf->shm_atime = n_buf.shm_atime;
103 buf->shm_dtime = n_buf.shm_dtime;
104 buf->shm_ctime = n_buf.shm_ctime;
105 }
106
107 return (ret);
108 }
109
110 int
shmdt(char * shmaddr)111 shmdt(char *shmaddr)
112 {
113 return (_syscall(SYS_shmsys, SHMDT, shmaddr));
114 }
115
116 int
shmget(key_t key,int size,int shmflg)117 shmget(key_t key, int size, int shmflg)
118 {
119 return (_syscall(SYS_shmsys, SHMGET, key, size, shmflg));
120 }
121
122 int
shmsys(int sysnum,...)123 shmsys(int sysnum, ...)
124 {
125 va_list ap;
126 int shmid, shmflg, cmd, size;
127 char *shmaddr;
128 struct shmid_ds *buf;
129 key_t key;
130
131 va_start(ap, sysnum);
132 switch (sysnum) {
133 case SHMAT:
134 shmid = va_arg(ap, int);
135 shmaddr = va_arg(ap, char *);
136 shmflg = va_arg(ap, int);
137 va_end(ap);
138 return ((int)shmat(shmid, shmaddr, shmflg));
139 case SHMCTL:
140 shmid = va_arg(ap, int);
141 cmd = va_arg(ap, int);
142 buf = va_arg(ap, struct shmid_ds *);
143 va_end(ap);
144 return (shmctl(shmid, cmd, buf));
145 case SHMDT:
146 shmaddr = va_arg(ap, char *);
147 va_end(ap);
148 return (shmdt(shmaddr));
149 case SHMGET:
150 key = va_arg(ap, key_t);
151 size = va_arg(ap, int);
152 shmflg = va_arg(ap, int);
153 va_end(ap);
154 return (shmget(key, size, shmflg));
155 }
156 va_end(ap);
157 return (-1);
158 }
159