Annotation of coherent/b/kernel/io.386/shm.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * System V Compatible Shared Memory Device Driver
                      3:  *
                      4:  *     This device driver provides System V compatible shared memory operations.
                      5:  *     Operations are performed through the shared memory device (/dev/shm).
                      6:  *     and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
                      7:  *     utilities.
                      8:  *
                      9:  *     Author: Allan Cornish.
                     10:  *
                     11:  */
                     12: 
                     13: #include <sys/coherent.h>
                     14: #include <sys/sched.h>
                     15: #include <sys/types.h>
                     16: #include <sys/uproc.h>
                     17: #include <errno.h>
                     18: #include <sys/stat.h>
                     19: #include <sys/con.h>
                     20: #include <sys/seg.h>
                     21: #include <sys/shm.h>
                     22: #include <stdlib.h>
                     23: 
                     24: #ifndef        EIDRM
                     25: #define        EIDRM   EDOM
                     26: #endif
                     27: 
                     28: 
                     29: extern unsigned NSHMID;
                     30: extern struct shmid_ds *shmids;
                     31: extern struct seg **shmsegs;
                     32: 
                     33: /*
                     34:  * Shmctl - Shared Memory Control Operations.
                     35:  */
                     36: 
                     37: ushmctl(shmid, cmd, buf)
                     38: #ifdef _I386
                     39: int shmid, cmd;
                     40: #else
                     41: unsigned shmid;
                     42: int cmd;
                     43: #endif
                     44: struct shmid_ds *buf;
                     45: 
                     46: {
                     47:        register struct shmid_ds *idp;
                     48:        int ret = 0;
                     49: 
                     50:        if (u.u_error)
                     51:                return -1;
                     52: 
                     53:        if (shmid >= NSHMID) {
                     54:                u.u_error = EINVAL;
                     55:                return -1;
                     56:        }
                     57: 
                     58:        idp = &shmids[shmid];
                     59: 
                     60:        if ((idp->shm_perm.mode & IPC_ALLOC) == 0) {
                     61:                u.u_error = EINVAL;
                     62:                return -1;
                     63:        }
                     64: 
                     65:        switch (cmd) {
                     66: 
                     67:        case IPC_STAT:
                     68:                if ((ipcaccess(&idp->shm_perm) & SHM_R) == 0) {
                     69:                        u.u_error = EACCES;
                     70:                        return -1;
                     71:                }
                     72:                kucopy(idp, buf, sizeof(struct shmid_ds));
                     73:                ret = 0;
                     74:                break;
                     75: 
                     76:        case IPC_SET:
                     77:                if ((u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid)) {
                     78:                        u.u_error = EPERM;
                     79:                        ret = -1;
                     80:                        break;
                     81:                }
                     82:                idp->shm_perm.uid   = getuwd(&(buf->shm_perm.uid));
                     83:                idp->shm_perm.gid   = getuwd(&(buf->shm_perm.gid));
                     84:                idp->shm_perm.mode &= ~0777;
                     85:                idp->shm_perm.mode |= getuwd(&(buf->shm_perm.mode)) & 0777;
                     86:                ret = 0;
                     87:                break;
                     88: 
                     89:        case IPC_RMID:
                     90:                if ((u.u_uid != 0) && (u.u_uid != idp->shm_perm.uid)) {
                     91:                        u.u_error = EPERM;
                     92:                        ret = -1;
                     93:                        break;
                     94:                }
                     95:                idp->shm_perm.seq++;
                     96:                kfree(shmsegs[shmid]);
                     97:                idp->shm_perm.mode = 0;
                     98:                ret = 0;
                     99:                break;
                    100: 
                    101:        default:
                    102:                u.u_error = EINVAL;
                    103:                ret = -1;
                    104:        }
                    105: 
                    106:        return ret;
                    107: }
                    108: 
                    109: /*
                    110:  * Shmget - Get Shared Memory Segment
                    111:  */
                    112: 
                    113: ushmget(skey, size, shmflg)
                    114: 
                    115: key_t skey;
                    116: #ifdef _I386
                    117: int size, shmflg;
                    118: #else
                    119: unsigned size;
                    120: int shmflg;
                    121: #endif
                    122: {
                    123:        register struct shmid_ds *idp;
                    124:        struct shmid_ds *freeidp = 0;
                    125: 
                    126:        if (u.u_error)
                    127:                return -1;
                    128: 
                    129:        for (idp = &shmids[NSHMID]; --idp >= shmids;) {
                    130: 
                    131:                if ((idp->shm_perm.mode & IPC_ALLOC) == 0) {
                    132: 
                    133:                        if ((freeidp == 0) ||
                    134:                            (freeidp->shm_ctime > idp->shm_ctime))
                    135:                                freeidp = idp;
                    136:                        continue;
                    137:                }
                    138: 
                    139: #ifdef IPC_PRIVATE
                    140:                if (skey == IPC_PRIVATE)
                    141:                        continue;
                    142: #endif
                    143: 
                    144:                if (skey == idp->shm_perm.key) {                /* found! */
                    145: 
                    146:                        if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
                    147: 
                    148:                                u.u_error = EEXIST;
                    149:                                return -1;
                    150:                        }
                    151: 
                    152:                        if ((idp->shm_perm.mode & shmflg) != (shmflg&0777)) {
                    153: 
                    154:                                u.u_error = EACCES;
                    155:                                return -1;
                    156:                        }
                    157: 
                    158:                        if (idp->shm_segsz < size) {
                    159: 
                    160:                                u.u_error = EINVAL;
                    161:                                return -1;
                    162:                        }
                    163: 
                    164:                        return idp - shmids;
                    165:                }
                    166:        }
                    167: 
                    168:        if (!(shmflg & IPC_CREAT)) {
                    169:                u.u_error = ENOENT;
                    170:                return -1;
                    171:        }
                    172: 
                    173:        if (freeidp == 0) { /* error if no structs available */
                    174:                u.u_error = ENOSPC;
                    175:                return -1;
                    176:        }
                    177: 
                    178:        idp = freeidp;
                    179: 
                    180:        /* allocate space for shared memory segment */
                    181:        if ((shmsegs[idp - shmids] = kalloc((size_t) size)) == NULL){
                    182:                u.u_error = ENOSPC;
                    183:                return -1;
                    184:        }
                    185: 
                    186: 
                    187:        idp->shm_segsz = size;
                    188:        idp->shm_atime = 0;
                    189:        idp->shm_dtime = 0;
                    190:        idp->shm_ctime = timer.t_time;
                    191:        idp->shm_cpid  = SELF->p_pid;
                    192:        idp->shm_perm.cuid = idp->shm_perm.uid = u.u_uid;
                    193:        idp->shm_perm.cgid = idp->shm_perm.gid = u.u_gid;
                    194:        idp->shm_perm.mode = (shmflg & 0777) | IPC_ALLOC;
                    195:        idp->shm_perm.key  = skey;
                    196: 
                    197: #ifdef IPC_PRIVATE
                    198:        if (skey == IPC_PRIVATE)
                    199:                idp->shm_perm.mode |= SHM_DEST;
                    200: #endif
                    201: 
                    202:        return idp - shmids;
                    203: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.