|
|
1.1 root 1: /* $Header: /usr/src/sys/i8086/drv/RCS/shm.c,v 2.1 88/09/03 13:12:17 src Exp $
2: *
3: * The information contained herein is a trade secret of INETCO
4: * Systems, and is confidential information. It is provided under
5: * a license agreement, and may be copied or disclosed only under
6: * the terms of that agreement. Any reproduction or disclosure of
7: * this material without the express written authorization of
8: * INETCO Systems or persuant to the license agreement is unlawful.
9: *
10: * Copyright (c) 1985, 1984
11: * An unpublished work by INETCO Systems, Ltd.
12: * All rights reserved.
13: */
14:
15: /*
16: * System V Compatible Shared Memory Device Driver
17: *
18: * This device driver provides System V compatible shared memory operations.
19: * Operations are performed through the shared memory device (/dev/shm).
20: * and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
21: * utilities.
22: *
23: * Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
24: *
25: * $Log: /usr/src/sys/i8086/drv/RCS/shm.c,v $
26: * Revision 2.1 88/09/03 13:12:17 src
27: * *** empty log message ***
28: *
29: * Revision 1.1 88/03/24 17:06:32 src
30: * Initial revision
31: *
32: * 85/10/16 Allan Cornish
33: * Driver split into shmcon.c, shm.c [driver implementation, System V shm].
34: *
35: * 85/07/22 Allan Cornish
36: * Shmget, shmctl now return immediately if u.u_error is set.
37: *
38: * 85/07/19 Allan Cornish
39: * Separation of io_seek into shmid and off improved through type casting.
40: * Errno set to EFAULT if fucopy() or ufcopy() report no bytes transferred.
41: * This would occur if an user address fault occurred.
42: *
43: * 85/07/03 Allan Cornish
44: * Replaced use of EDOM with EIDRM.
45: * Replaced shmaccess() by calls to ipcaccess(), increasing shared ipc code.
46: * Eliminated shmlock() and shmunlock(), as shared memory use is synchronous.
47: */
48:
49: #include <coherent.h>
50: #include <sched.h>
51: #include <types.h>
52: #include <uproc.h>
53: #include <errno.h>
54: #include <stat.h>
55: #include <con.h>
56: #include <seg.h>
57: #include <shm.h>
58:
59: #ifndef EIDRM
60: #define EIDRM EDOM
61: #endif
62:
63:
64: extern unsigned NSHMID;
65: extern struct shmid_ds *shmids;
66: extern struct seg **shmsegs;
67:
68: /*
69: * Shmctl - Shared Memory Control Operations.
70: */
71:
72: ushmctl( shmid, cmd, buf )
73:
74: unsigned shmid;
75: int cmd;
76: struct shmid_ds *buf;
77:
78: {
79: register struct shmid_ds *idp;
80: int ret = 0;
81:
82: if ( u.u_error )
83: return -1;
84:
85: if ( shmid >= NSHMID ) {
86: u.u_error = EINVAL;
87: return -1;
88: }
89:
90: idp = &shmids[shmid];
91:
92: if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
93: u.u_error = EINVAL;
94: return -1;
95: }
96:
97: switch ( cmd ) {
98:
99: case IPC_STAT:
100: if ( ( ipcaccess( &idp->shm_perm ) & SHM_R ) == 0 ) {
101: u.u_error = EACCES;
102: return -1;
103: }
104: kucopy( idp, buf, sizeof(struct shmid_ds) );
105: ret = 0;
106: break;
107:
108: case IPC_SET:
109: if ( (u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid) ) {
110: u.u_error = EPERM;
111: ret = -1;
112: break;
113: }
114: idp->shm_perm.uid = getuwd( &(buf->shm_perm.uid ) );
115: idp->shm_perm.gid = getuwd( &(buf->shm_perm.gid ) );
116: idp->shm_perm.mode &= ~0777;
117: idp->shm_perm.mode |= getuwd(&(buf->shm_perm.mode)) & 0777;
118: ret = 0;
119: break;
120:
121: case IPC_RMID:
122: if ( (u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid) ) {
123: u.u_error = EPERM;
124: ret = -1;
125: break;
126: }
127: idp->shm_perm.seq++;
128: sfree(shmsegs[shmid]);
129: idp->shm_perm.mode = 0;
130: ret = 0;
131: break;
132:
133: default:
134: u.u_error = EINVAL;
135: ret = -1;
136: }
137:
138: return ret;
139: }
140:
141: /*
142: * Shmget - Get Shared Memory Segment
143: */
144:
145: ushmget( skey, size, shmflg )
146:
147: key_t skey;
148: unsigned size;
149: int shmflg;
150:
151: {
152: register struct shmid_ds *idp;
153: struct shmid_ds *freeidp = 0;
154:
155: if ( u.u_error )
156: return -1;
157:
158: for ( idp = &shmids[NSHMID]; --idp >= shmids; ) {
159:
160: if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
161:
162: if ((freeidp == 0) ||
163: (freeidp->shm_ctime > idp->shm_ctime))
164: freeidp = idp;
165: continue;
166: }
167:
168: #ifdef IPC_PRIVATE
169: if (skey == IPC_PRIVATE)
170: continue;
171: #endif
172:
173: if (skey == idp->shm_perm.key) { /* found! */
174:
175: if ( (shmflg & IPC_CREAT) && (shmflg & IPC_EXCL) ) {
176:
177: u.u_error = EEXIST;
178: return -1;
179: }
180:
181: if ((idp->shm_perm.mode & shmflg) != (shmflg&0777)) {
182:
183: u.u_error = EACCES;
184: return -1;
185: }
186:
187: if ( idp->shm_segsz < size ) {
188:
189: u.u_error = EINVAL;
190: return -1;
191: }
192:
193: return idp - shmids;
194: }
195: }
196:
197: if ( !(shmflg & IPC_CREAT) ) {
198: u.u_error = ENOENT;
199: return -1;
200: }
201:
202: if ( freeidp == 0 ) {
203: u.u_error = ENOSPC;
204: return -1;
205: }
206:
207: idp = freeidp;
208:
209: if ((shmsegs[idp - shmids] = salloc((size_t) size, SFNSWP)) == NULL){
210: u.u_error = ENOSPC;
211: return -1;
212: }
213:
214: idp->shm_segsz = size;
215: idp->shm_atime = 0;
216: idp->shm_dtime = 0;
217: idp->shm_ctime = timer.t_time;
218: idp->shm_cpid = SELF->p_pid;
219: idp->shm_perm.cuid = idp->shm_perm.uid = u.u_uid;
220: idp->shm_perm.cgid = idp->shm_perm.gid = u.u_gid;
221: idp->shm_perm.mode = (shmflg & 0777) | IPC_ALLOC;
222: idp->shm_perm.key = skey;
223:
224: #ifdef IPC_PRIVATE
225: if ( skey == IPC_PRIVATE )
226: idp->shm_perm.mode |= SHM_DEST;
227: #endif
228:
229: return idp - shmids;
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.