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