static void intrevent_alloc(int num, int system_running) { int i; INTREVENT *irp; INTREVENT *head; INTREVENT **tail; tail = &head; for(i = 0 ; i < num ; ++i) { irp = _scalloc(sizeof(*irp)); if(irp == NULL) break; *tail = irp; tail = &irp->next; } // Want to keep interrupts disabled while we're initializing if(system_running) { INTR_LOCK(&intrevent_lock); } *tail = intrevent_free; intrevent_free = head; num_pev_free += i; if(system_running) { INTR_UNLOCK(&intrevent_lock); } num_pev_alloc += i; // Get more when we're down to 1/4 of the total number of entries on // the free list num_pev_trigger = num_pev_alloc / 4; }
/* * Initialse msgpass xfer slots */ void xfer_init() { xfer_slots = _scalloc(_syspage_ptr->num_cpu * sizeof(*xfer_slots)); if (xfer_slots == 0) { crash(); } }
char *procmgr_init_objects(void) { SESSION *sep; if(!(sep = _scalloc(sizeof *sep))) { return "No Memory"; } sep->links = 1; sep->leader = PROCMGR_PID; sep->pgrp = PROCMGR_PID; sep->fd = -2; procmgr_prp->session = sep; return 0; }
IOFUNC_OCB_T * iofunc_ocb_calloc(resmgr_context_t *ctp, IOFUNC_ATTR_T *attr) { devi_ocb_t *ocb; if(!(ocb = _scalloc(sizeof *ocb))) { errno = ENFILE; } if (add_ocb(attr, ocb) < 0) { free(ocb); return (NULL); } pthread_mutex_lock(&attr->line->mutex); ocb->read_ptr = attr->line->head; pthread_mutex_unlock(&attr->line->mutex); return (ocb); }
int tymem_open(resmgr_context_t *ctp, io_open_t *msg, void *handle, void *extra) { struct mem_ocb *ocb; unsigned tflags; unsigned count; if (msg->connect.path_len + sizeof(*msg) >= ctp->msg_max_size) { return ENAMETOOLONG; } if((msg->connect.eflag & _IO_CONNECT_EFLAG_DIR) || msg->connect.path[0] == '\0') { if(msg->connect.ioflag & _IO_FLAG_WR) { return EISDIR; } //RUSH3: Simply fakes "/dev/tymem" as empty copy of "/dev/shmem". if(resmgr_open_bind(ctp, 0, &mem_io_funcs) == -1) { return errno; } return EOK; } if(msg->connect.extra_type != _IO_CONNECT_EXTRA_TYMEM) { return ENOTSUP; } if(msg->connect.extra_len != sizeof(uint32_t)) { return ENOTSUP; } if(msg->connect.ioflag & ~(O_ACCMODE | O_CREAT | O_NOCTTY)) { return EINVAL; } #define ALL_TMEM (POSIX_TYPED_MEM_ALLOCATE|POSIX_TYPED_MEM_ALLOCATE_CONTIG|POSIX_TYPED_MEM_MAP_ALLOCATABLE) tflags = *(uint32_t *)extra; count = 0; if(tflags & POSIX_TYPED_MEM_ALLOCATE) ++count; if(tflags & POSIX_TYPED_MEM_ALLOCATE_CONTIG) ++count; if(tflags & POSIX_TYPED_MEM_MAP_ALLOCATABLE) ++count; if((count > 1) || (tflags & ~ALL_TMEM)) { return EINVAL; } if(!(tflags & (POSIX_TYPED_MEM_ALLOCATE|POSIX_TYPED_MEM_ALLOCATE_CONTIG))) { if(!proc_isaccess(0, &ctp->info)) { // Only root processes are allowed to specify direct offsets return EPERM; } } ocb = _scalloc(sizeof *ocb); if(ocb == NULL) { errno = ENOMEM; goto fail1; } ocb->tflags = tflags; ocb->ioflag = msg->connect.ioflag; errno = memmgr_tymem_open(msg->connect.path, ocb->tflags, &ocb->object, proc_lookup_pid(ctp->info.pid)); if(errno != EOK) goto fail2; //RUSH1: need permission checking on path ctp->id = mem_handle; if(resmgr_open_bind(ctp, ocb, &tymem_io_funcs) == -1) goto fail3; pathmgr_object_clone(ocb->object); return EOK; fail3: memmgr_tymem_close(ocb->object); fail2: _sfree(ocb, sizeof(*ocb)); fail1: return errno; }
int mem_open(resmgr_context_t *ctp, io_open_t *msg, void *handle, void *extra) { OBJECT *object = handle; struct mem_ocb *ocb; if(object) { /* Only set the ownership the first time around */ if(msg->connect.ioflag & O_CREAT && !object->mem.pm.mode) { struct _client_info info; ConnectClientInfo(ctp->info.scoid, &info, 0); object->mem.pm.uid = info.cred.euid; object->mem.pm.gid = info.cred.egid; object->mem.pm.mode = ((msg->connect.file_type == _FTYPE_SHMEM) ? S_IFNAM : S_IFREG) | (msg->connect.mode & ~S_IFMT); /* Only check perms on things which we have set permission on ... */ } else if (object->mem.pm.mode != 0) { int ret = 0; ret |= (msg->connect.ioflag & _IO_FLAG_RD) ? S_IRUSR : 0; ret |= (msg->connect.ioflag & _IO_FLAG_WR) ? S_IWUSR : 0; if(ret != 0) { ret = devmem_check_perm(ctp, object->mem.pm.mode, object->mem.pm.uid, object->mem.pm.gid, ret); } if(ret != 0) { return ret; } } if((msg->connect.ioflag & O_TRUNC) && OBJECT_SIZE(object)) { int status; status = memmgr.resize(object, 0); if(status != 0) { return status; } } } else if((msg->connect.ioflag & (_IO_FLAG_RD | _IO_FLAG_WR)) && !proc_isaccess(0, &ctp->info)) { return EPERM; } #if 0 /* This breaks spawn ... need to check to see if the is proper behaviour */ /* Check our access mode all opens are assumed as read/write */ if (object) { int sflag = msg->connect.sflag & SH_MASK; if(((sflag == SH_DENYRW || sflag == SH_DENYRD) && object->mem.count > 1 /*rcount*/) || ((sflag == SH_DENYRW || sflag == SH_DENYWR) && object->mem.count > 1 /*wcount*/)) { return EBUSY; } } #endif if(!(ocb = _scalloc(sizeof *ocb))) { return ENOMEM; } ocb->ioflag = msg->connect.ioflag; ocb->object = (object != NULL) ? pathmgr_object_clone(object) : NULL; ctp->id = mem_handle; if(resmgr_open_bind(ctp, ocb, &mem_io_funcs) == -1) { if(object) { pathmgr_object_done(object); } return errno; } return EOK; }