Annotation of coherent/b/kernel/io.386/shm.c, revision 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.