1433d6423SLionel Sambuc #include "inc.h" 2433d6423SLionel Sambuc 34d272e5aSDavid van Moolenbroek /* Private shm_perm.mode flags, synchronized with NetBSD kernel values */ 44d272e5aSDavid van Moolenbroek #define SHM_ALLOC 0x0800 /* slot is in use (SHMSEG_ALLOCATED) */ 5433d6423SLionel Sambuc 6433d6423SLionel Sambuc struct shm_struct { 7433d6423SLionel Sambuc struct shmid_ds shmid_ds; 8433d6423SLionel Sambuc vir_bytes page; 94d272e5aSDavid van Moolenbroek phys_bytes vm_id; 10433d6423SLionel Sambuc }; 114d272e5aSDavid van Moolenbroek static struct shm_struct shm_list[SHMMNI]; 124d272e5aSDavid van Moolenbroek static unsigned int shm_list_nr = 0; /* highest in-use slot number plus one */ 13433d6423SLionel Sambuc 14*0baafa0eSDavid van Moolenbroek static struct shm_struct * 15*0baafa0eSDavid van Moolenbroek shm_find_key(key_t key) 16433d6423SLionel Sambuc { 174d272e5aSDavid van Moolenbroek unsigned int i; 184d272e5aSDavid van Moolenbroek 19433d6423SLionel Sambuc if (key == IPC_PRIVATE) 20433d6423SLionel Sambuc return NULL; 21*0baafa0eSDavid van Moolenbroek 224d272e5aSDavid van Moolenbroek for (i = 0; i < shm_list_nr; i++) { 234d272e5aSDavid van Moolenbroek if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) 244d272e5aSDavid van Moolenbroek continue; 254d272e5aSDavid van Moolenbroek if (shm_list[i].shmid_ds.shm_perm._key == key) 264d272e5aSDavid van Moolenbroek return &shm_list[i]; 274d272e5aSDavid van Moolenbroek } 28*0baafa0eSDavid van Moolenbroek 29433d6423SLionel Sambuc return NULL; 30433d6423SLionel Sambuc } 31433d6423SLionel Sambuc 32*0baafa0eSDavid van Moolenbroek static struct shm_struct * 33*0baafa0eSDavid van Moolenbroek shm_find_id(int id) 34433d6423SLionel Sambuc { 354d272e5aSDavid van Moolenbroek struct shm_struct *shm; 364d272e5aSDavid van Moolenbroek unsigned int i; 374d272e5aSDavid van Moolenbroek 384d272e5aSDavid van Moolenbroek i = IPCID_TO_IX(id); 394d272e5aSDavid van Moolenbroek if (i >= shm_list_nr) 40433d6423SLionel Sambuc return NULL; 414d272e5aSDavid van Moolenbroek 424d272e5aSDavid van Moolenbroek shm = &shm_list[i]; 434d272e5aSDavid van Moolenbroek if (!(shm->shmid_ds.shm_perm.mode & SHM_ALLOC)) 444d272e5aSDavid van Moolenbroek return NULL; 454d272e5aSDavid van Moolenbroek if (shm->shmid_ds.shm_perm._seq != IPCID_TO_SEQ(id)) 464d272e5aSDavid van Moolenbroek return NULL; 474d272e5aSDavid van Moolenbroek return shm; 48433d6423SLionel Sambuc } 49433d6423SLionel Sambuc 50*0baafa0eSDavid van Moolenbroek int 51*0baafa0eSDavid van Moolenbroek do_shmget(message * m) 52433d6423SLionel Sambuc { 53433d6423SLionel Sambuc struct shm_struct *shm; 544d272e5aSDavid van Moolenbroek unsigned int i, seq; 554d272e5aSDavid van Moolenbroek key_t key; 564d272e5aSDavid van Moolenbroek size_t size, old_size; 57433d6423SLionel Sambuc int flag; 584d272e5aSDavid van Moolenbroek void *page; 59433d6423SLionel Sambuc 60433d6423SLionel Sambuc key = m->m_lc_ipc_shmget.key; 61433d6423SLionel Sambuc old_size = size = m->m_lc_ipc_shmget.size; 62433d6423SLionel Sambuc flag = m->m_lc_ipc_shmget.flag; 63433d6423SLionel Sambuc 64*0baafa0eSDavid van Moolenbroek if ((shm = shm_find_key(key)) != NULL) { 65*0baafa0eSDavid van Moolenbroek if (!check_perm(&shm->shmid_ds.shm_perm, m->m_source, flag)) 66433d6423SLionel Sambuc return EACCES; 67433d6423SLionel Sambuc if ((flag & IPC_CREAT) && (flag & IPC_EXCL)) 68433d6423SLionel Sambuc return EEXIST; 69433d6423SLionel Sambuc if (size && shm->shmid_ds.shm_segsz < size) 70433d6423SLionel Sambuc return EINVAL; 714d272e5aSDavid van Moolenbroek i = shm - shm_list; 72433d6423SLionel Sambuc } else { /* no key found */ 73433d6423SLionel Sambuc if (!(flag & IPC_CREAT)) 74433d6423SLionel Sambuc return ENOENT; 75433d6423SLionel Sambuc if (size <= 0) 76433d6423SLionel Sambuc return EINVAL; 77*0baafa0eSDavid van Moolenbroek size = roundup(size, PAGE_SIZE); 78433d6423SLionel Sambuc if (size <= 0) 79433d6423SLionel Sambuc return EINVAL; 80433d6423SLionel Sambuc 814d272e5aSDavid van Moolenbroek /* Find a free entry. */ 824d272e5aSDavid van Moolenbroek for (i = 0; i < __arraycount(shm_list); i++) 834d272e5aSDavid van Moolenbroek if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) 844d272e5aSDavid van Moolenbroek break; 854d272e5aSDavid van Moolenbroek if (i == __arraycount(shm_list)) 86433d6423SLionel Sambuc return ENOSPC; 87433d6423SLionel Sambuc 884d272e5aSDavid van Moolenbroek /* 894d272e5aSDavid van Moolenbroek * Allocate memory to share. For now, we store the page 904d272e5aSDavid van Moolenbroek * reference as a numerical value so as to avoid issues with 914d272e5aSDavid van Moolenbroek * live update. TODO: a proper solution. 924d272e5aSDavid van Moolenbroek */ 934d272e5aSDavid van Moolenbroek page = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); 944d272e5aSDavid van Moolenbroek if (page == MAP_FAILED) 954d272e5aSDavid van Moolenbroek return ENOMEM; 964d272e5aSDavid van Moolenbroek memset(page, 0, size); 974d272e5aSDavid van Moolenbroek 984d272e5aSDavid van Moolenbroek /* Initialize the entry. */ 994d272e5aSDavid van Moolenbroek shm = &shm_list[i]; 1004d272e5aSDavid van Moolenbroek seq = shm->shmid_ds.shm_perm._seq; 101*0baafa0eSDavid van Moolenbroek memset(shm, 0, sizeof(*shm)); 1024d272e5aSDavid van Moolenbroek 1034d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_perm._key = key; 104433d6423SLionel Sambuc shm->shmid_ds.shm_perm.cuid = 105*0baafa0eSDavid van Moolenbroek shm->shmid_ds.shm_perm.uid = getnuid(m->m_source); 106433d6423SLionel Sambuc shm->shmid_ds.shm_perm.cgid = 107*0baafa0eSDavid van Moolenbroek shm->shmid_ds.shm_perm.gid = getngid(m->m_source); 1084d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_perm.mode = SHM_ALLOC | (flag & ACCESSPERMS); 1094d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_perm._seq = (seq + 1) & 0x7fff; 110433d6423SLionel Sambuc shm->shmid_ds.shm_segsz = old_size; 111433d6423SLionel Sambuc shm->shmid_ds.shm_atime = 0; 112433d6423SLionel Sambuc shm->shmid_ds.shm_dtime = 0; 1134d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_ctime = clock_time(NULL); 114*0baafa0eSDavid van Moolenbroek shm->shmid_ds.shm_cpid = getnpid(m->m_source); 115433d6423SLionel Sambuc shm->shmid_ds.shm_lpid = 0; 116433d6423SLionel Sambuc shm->shmid_ds.shm_nattch = 0; 1174d272e5aSDavid van Moolenbroek shm->page = (vir_bytes)page; 1184d272e5aSDavid van Moolenbroek shm->vm_id = vm_getphys(sef_self(), page); 119433d6423SLionel Sambuc 1204d272e5aSDavid van Moolenbroek assert(i <= shm_list_nr); 1214d272e5aSDavid van Moolenbroek if (i == shm_list_nr) 122433d6423SLionel Sambuc shm_list_nr++; 123433d6423SLionel Sambuc } 124433d6423SLionel Sambuc 1254d272e5aSDavid van Moolenbroek m->m_lc_ipc_shmget.retid = IXSEQ_TO_IPCID(i, shm->shmid_ds.shm_perm); 126433d6423SLionel Sambuc return OK; 127433d6423SLionel Sambuc } 128433d6423SLionel Sambuc 129*0baafa0eSDavid van Moolenbroek int 130*0baafa0eSDavid van Moolenbroek do_shmat(message * m) 131433d6423SLionel Sambuc { 132433d6423SLionel Sambuc int id, flag; 133433d6423SLionel Sambuc vir_bytes addr; 134433d6423SLionel Sambuc void *ret; 135433d6423SLionel Sambuc struct shm_struct *shm; 136433d6423SLionel Sambuc 137433d6423SLionel Sambuc id = m->m_lc_ipc_shmat.id; 138433d6423SLionel Sambuc addr = (vir_bytes)m->m_lc_ipc_shmat.addr; 139433d6423SLionel Sambuc flag = m->m_lc_ipc_shmat.flag; 140433d6423SLionel Sambuc 141*0baafa0eSDavid van Moolenbroek if (addr % PAGE_SIZE) { 142433d6423SLionel Sambuc if (flag & SHM_RND) 143*0baafa0eSDavid van Moolenbroek addr -= addr % PAGE_SIZE; 144433d6423SLionel Sambuc else 145433d6423SLionel Sambuc return EINVAL; 146433d6423SLionel Sambuc } 147433d6423SLionel Sambuc 148*0baafa0eSDavid van Moolenbroek if ((shm = shm_find_id(id)) == NULL) 149433d6423SLionel Sambuc return EINVAL; 150433d6423SLionel Sambuc 151433d6423SLionel Sambuc if (flag & SHM_RDONLY) 152433d6423SLionel Sambuc flag = 0444; 153433d6423SLionel Sambuc else 154433d6423SLionel Sambuc flag = 0666; 155*0baafa0eSDavid van Moolenbroek if (!check_perm(&shm->shmid_ds.shm_perm, m->m_source, flag)) 156433d6423SLionel Sambuc return EACCES; 157433d6423SLionel Sambuc 158*0baafa0eSDavid van Moolenbroek ret = vm_remap(m->m_source, sef_self(), (void *)addr, 159*0baafa0eSDavid van Moolenbroek (void *)shm->page, shm->shmid_ds.shm_segsz); 160433d6423SLionel Sambuc if (ret == MAP_FAILED) 161433d6423SLionel Sambuc return ENOMEM; 162433d6423SLionel Sambuc 1634d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_atime = clock_time(NULL); 164*0baafa0eSDavid van Moolenbroek shm->shmid_ds.shm_lpid = getnpid(m->m_source); 165*0baafa0eSDavid van Moolenbroek /* nattch is updated lazily */ 166433d6423SLionel Sambuc 167433d6423SLionel Sambuc m->m_lc_ipc_shmat.retaddr = ret; 168433d6423SLionel Sambuc return OK; 169433d6423SLionel Sambuc } 170433d6423SLionel Sambuc 171*0baafa0eSDavid van Moolenbroek void 172*0baafa0eSDavid van Moolenbroek update_refcount_and_destroy(void) 173433d6423SLionel Sambuc { 174433d6423SLionel Sambuc u8_t rc; 1754d272e5aSDavid van Moolenbroek unsigned int i; 1764d272e5aSDavid van Moolenbroek 1774d272e5aSDavid van Moolenbroek for (i = 0; i < shm_list_nr; i++) { 1784d272e5aSDavid van Moolenbroek if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) 1794d272e5aSDavid van Moolenbroek continue; 180433d6423SLionel Sambuc 181433d6423SLionel Sambuc rc = vm_getrefcount(sef_self(), (void *)shm_list[i].page); 182433d6423SLionel Sambuc if (rc == (u8_t)-1) { 183433d6423SLionel Sambuc printf("IPC: can't find physical region.\n"); 184433d6423SLionel Sambuc continue; 185433d6423SLionel Sambuc } 186433d6423SLionel Sambuc shm_list[i].shmid_ds.shm_nattch = rc - 1; 187433d6423SLionel Sambuc 1884d272e5aSDavid van Moolenbroek if (shm_list[i].shmid_ds.shm_nattch == 0 && 1894d272e5aSDavid van Moolenbroek (shm_list[i].shmid_ds.shm_perm.mode & SHM_DEST)) { 190*0baafa0eSDavid van Moolenbroek munmap((void *)shm_list[i].page, 191*0baafa0eSDavid van Moolenbroek roundup(shm_list[i].shmid_ds.shm_segsz, 192*0baafa0eSDavid van Moolenbroek PAGE_SIZE)); 1934d272e5aSDavid van Moolenbroek /* Mark the entry as free. */ 1944d272e5aSDavid van Moolenbroek shm_list[i].shmid_ds.shm_perm.mode &= ~SHM_ALLOC; 195433d6423SLionel Sambuc } 196433d6423SLionel Sambuc } 1974d272e5aSDavid van Moolenbroek 1984d272e5aSDavid van Moolenbroek /* 1994d272e5aSDavid van Moolenbroek * Now that we may have removed an arbitrary set of slots, ensure that 2004d272e5aSDavid van Moolenbroek * shm_list_nr again equals the highest in-use slot number plus one. 2014d272e5aSDavid van Moolenbroek */ 2024d272e5aSDavid van Moolenbroek while (shm_list_nr > 0 && 2034d272e5aSDavid van Moolenbroek !(shm_list[shm_list_nr - 1].shmid_ds.shm_perm.mode & SHM_ALLOC)) 2044d272e5aSDavid van Moolenbroek shm_list_nr--; 205433d6423SLionel Sambuc } 206433d6423SLionel Sambuc 207*0baafa0eSDavid van Moolenbroek int 208*0baafa0eSDavid van Moolenbroek do_shmdt(message * m) 209433d6423SLionel Sambuc { 2104d272e5aSDavid van Moolenbroek struct shm_struct *shm; 211433d6423SLionel Sambuc vir_bytes addr; 212433d6423SLionel Sambuc phys_bytes vm_id; 2134d272e5aSDavid van Moolenbroek unsigned int i; 214433d6423SLionel Sambuc 215433d6423SLionel Sambuc addr = (vir_bytes)m->m_lc_ipc_shmdt.addr; 216433d6423SLionel Sambuc 217*0baafa0eSDavid van Moolenbroek if ((vm_id = vm_getphys(m->m_source, (void *)addr)) == 0) 218433d6423SLionel Sambuc return EINVAL; 219433d6423SLionel Sambuc 220433d6423SLionel Sambuc for (i = 0; i < shm_list_nr; i++) { 2214d272e5aSDavid van Moolenbroek shm = &shm_list[i]; 222433d6423SLionel Sambuc 2234d272e5aSDavid van Moolenbroek if (!(shm->shmid_ds.shm_perm.mode & SHM_ALLOC)) 2244d272e5aSDavid van Moolenbroek continue; 2254d272e5aSDavid van Moolenbroek 2264d272e5aSDavid van Moolenbroek if (shm->vm_id == vm_id) { 2274d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_atime = clock_time(NULL); 228*0baafa0eSDavid van Moolenbroek shm->shmid_ds.shm_lpid = getnpid(m->m_source); 229433d6423SLionel Sambuc /* nattch is updated lazily */ 230433d6423SLionel Sambuc 231*0baafa0eSDavid van Moolenbroek vm_unmap(m->m_source, (void *)addr); 232433d6423SLionel Sambuc break; 233433d6423SLionel Sambuc } 234433d6423SLionel Sambuc } 235433d6423SLionel Sambuc if (i == shm_list_nr) 236*0baafa0eSDavid van Moolenbroek printf("IPC: do_shmdt: ID %lu not found\n", vm_id); 237433d6423SLionel Sambuc 238433d6423SLionel Sambuc update_refcount_and_destroy(); 239433d6423SLionel Sambuc 240433d6423SLionel Sambuc return OK; 241433d6423SLionel Sambuc } 242433d6423SLionel Sambuc 243*0baafa0eSDavid van Moolenbroek int 244*0baafa0eSDavid van Moolenbroek do_shmctl(message * m) 245433d6423SLionel Sambuc { 246433d6423SLionel Sambuc struct shmid_ds tmp_ds; 2474d272e5aSDavid van Moolenbroek struct shm_struct *shm; 248433d6423SLionel Sambuc struct shminfo sinfo; 249433d6423SLionel Sambuc struct shm_info s_info; 250*0baafa0eSDavid van Moolenbroek vir_bytes buf; 2514d272e5aSDavid van Moolenbroek unsigned int i; 252433d6423SLionel Sambuc uid_t uid; 2534d272e5aSDavid van Moolenbroek int r, id, cmd; 254433d6423SLionel Sambuc 2554d272e5aSDavid van Moolenbroek id = m->m_lc_ipc_shmctl.id; 2564d272e5aSDavid van Moolenbroek cmd = m->m_lc_ipc_shmctl.cmd; 257*0baafa0eSDavid van Moolenbroek buf = (vir_bytes)m->m_lc_ipc_shmctl.buf; 2584d272e5aSDavid van Moolenbroek 2594d272e5aSDavid van Moolenbroek /* 2604d272e5aSDavid van Moolenbroek * For stat calls, sure that all information is up-to-date. Since this 2614d272e5aSDavid van Moolenbroek * may free the slot, do this before mapping from ID to slot below. 2624d272e5aSDavid van Moolenbroek */ 2634d272e5aSDavid van Moolenbroek if (cmd == IPC_STAT || cmd == SHM_STAT) 264433d6423SLionel Sambuc update_refcount_and_destroy(); 265433d6423SLionel Sambuc 2664d272e5aSDavid van Moolenbroek switch (cmd) { 2674d272e5aSDavid van Moolenbroek case IPC_INFO: 2684d272e5aSDavid van Moolenbroek case SHM_INFO: 2694d272e5aSDavid van Moolenbroek shm = NULL; 2704d272e5aSDavid van Moolenbroek break; 2714d272e5aSDavid van Moolenbroek case SHM_STAT: 2724d272e5aSDavid van Moolenbroek if (id < 0 || (unsigned int)id >= shm_list_nr) 273433d6423SLionel Sambuc return EINVAL; 2744d272e5aSDavid van Moolenbroek shm = &shm_list[id]; 2754d272e5aSDavid van Moolenbroek if (!(shm->shmid_ds.shm_perm.mode & SHM_ALLOC)) 2764d272e5aSDavid van Moolenbroek return EINVAL; 2774d272e5aSDavid van Moolenbroek break; 2784d272e5aSDavid van Moolenbroek default: 279*0baafa0eSDavid van Moolenbroek if ((shm = shm_find_id(id)) == NULL) 2804d272e5aSDavid van Moolenbroek return EINVAL; 2814d272e5aSDavid van Moolenbroek break; 2824d272e5aSDavid van Moolenbroek } 283433d6423SLionel Sambuc 284433d6423SLionel Sambuc switch (cmd) { 285433d6423SLionel Sambuc case IPC_STAT: 2864d272e5aSDavid van Moolenbroek case SHM_STAT: 2874d272e5aSDavid van Moolenbroek /* Check whether the caller has read permission. */ 288*0baafa0eSDavid van Moolenbroek if (!check_perm(&shm->shmid_ds.shm_perm, m->m_source, 0444)) 289433d6423SLionel Sambuc return EACCES; 290*0baafa0eSDavid van Moolenbroek if ((r = sys_datacopy(SELF, (vir_bytes)&shm->shmid_ds, 291*0baafa0eSDavid van Moolenbroek m->m_source, buf, sizeof(shm->shmid_ds))) != OK) 2924d272e5aSDavid van Moolenbroek return r; 2934d272e5aSDavid van Moolenbroek if (cmd == SHM_STAT) 2944d272e5aSDavid van Moolenbroek m->m_lc_ipc_shmctl.ret = 2954d272e5aSDavid van Moolenbroek IXSEQ_TO_IPCID(id, shm->shmid_ds.shm_perm); 296433d6423SLionel Sambuc break; 297433d6423SLionel Sambuc case IPC_SET: 298*0baafa0eSDavid van Moolenbroek uid = getnuid(m->m_source); 299433d6423SLionel Sambuc if (uid != shm->shmid_ds.shm_perm.cuid && 300*0baafa0eSDavid van Moolenbroek uid != shm->shmid_ds.shm_perm.uid && uid != 0) 301433d6423SLionel Sambuc return EPERM; 302*0baafa0eSDavid van Moolenbroek if ((r = sys_datacopy(m->m_source, buf, SELF, 303*0baafa0eSDavid van Moolenbroek (vir_bytes)&tmp_ds, sizeof(tmp_ds))) != OK) 3044d272e5aSDavid van Moolenbroek return r; 305433d6423SLionel Sambuc shm->shmid_ds.shm_perm.uid = tmp_ds.shm_perm.uid; 306433d6423SLionel Sambuc shm->shmid_ds.shm_perm.gid = tmp_ds.shm_perm.gid; 3074d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_perm.mode &= ~ACCESSPERMS; 3084d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_perm.mode |= 3094d272e5aSDavid van Moolenbroek tmp_ds.shm_perm.mode & ACCESSPERMS; 3104d272e5aSDavid van Moolenbroek shm->shmid_ds.shm_ctime = clock_time(NULL); 311433d6423SLionel Sambuc break; 312433d6423SLionel Sambuc case IPC_RMID: 313*0baafa0eSDavid van Moolenbroek uid = getnuid(m->m_source); 314433d6423SLionel Sambuc if (uid != shm->shmid_ds.shm_perm.cuid && 315*0baafa0eSDavid van Moolenbroek uid != shm->shmid_ds.shm_perm.uid && uid != 0) 316433d6423SLionel Sambuc return EPERM; 317433d6423SLionel Sambuc shm->shmid_ds.shm_perm.mode |= SHM_DEST; 318*0baafa0eSDavid van Moolenbroek /* Destroy if possible. */ 319433d6423SLionel Sambuc update_refcount_and_destroy(); 320433d6423SLionel Sambuc break; 321433d6423SLionel Sambuc case IPC_INFO: 3224d272e5aSDavid van Moolenbroek memset(&sinfo, 0, sizeof(sinfo)); 323433d6423SLionel Sambuc sinfo.shmmax = (unsigned long) -1; 324433d6423SLionel Sambuc sinfo.shmmin = 1; 3254d272e5aSDavid van Moolenbroek sinfo.shmmni = __arraycount(shm_list); 326433d6423SLionel Sambuc sinfo.shmseg = (unsigned long) -1; 327433d6423SLionel Sambuc sinfo.shmall = (unsigned long) -1; 328*0baafa0eSDavid van Moolenbroek if ((r = sys_datacopy(SELF, (vir_bytes)&sinfo, m->m_source, 329*0baafa0eSDavid van Moolenbroek buf, sizeof(sinfo))) != OK) 3304d272e5aSDavid van Moolenbroek return r; 3314d272e5aSDavid van Moolenbroek if (shm_list_nr > 0) 3324d272e5aSDavid van Moolenbroek m->m_lc_ipc_shmctl.ret = shm_list_nr - 1; 3334d272e5aSDavid van Moolenbroek else 334433d6423SLionel Sambuc m->m_lc_ipc_shmctl.ret = 0; 335433d6423SLionel Sambuc break; 336433d6423SLionel Sambuc case SHM_INFO: 3374d272e5aSDavid van Moolenbroek memset(&s_info, 0, sizeof(s_info)); 338433d6423SLionel Sambuc s_info.used_ids = shm_list_nr; 339433d6423SLionel Sambuc s_info.shm_tot = 0; 340433d6423SLionel Sambuc for (i = 0; i < shm_list_nr; i++) 341433d6423SLionel Sambuc s_info.shm_tot += 342433d6423SLionel Sambuc shm_list[i].shmid_ds.shm_segsz / PAGE_SIZE; 343433d6423SLionel Sambuc s_info.shm_rss = s_info.shm_tot; 344433d6423SLionel Sambuc s_info.shm_swp = 0; 345433d6423SLionel Sambuc s_info.swap_attempts = 0; 346433d6423SLionel Sambuc s_info.swap_successes = 0; 347*0baafa0eSDavid van Moolenbroek if ((r = sys_datacopy(SELF, (vir_bytes)&s_info, m->m_source, 348*0baafa0eSDavid van Moolenbroek buf, sizeof(s_info))) != OK) 3494d272e5aSDavid van Moolenbroek return r; 3504d272e5aSDavid van Moolenbroek if (shm_list_nr > 0) 351433d6423SLionel Sambuc m->m_lc_ipc_shmctl.ret = shm_list_nr - 1; 3524d272e5aSDavid van Moolenbroek else 353433d6423SLionel Sambuc m->m_lc_ipc_shmctl.ret = 0; 354433d6423SLionel Sambuc break; 355433d6423SLionel Sambuc default: 356433d6423SLionel Sambuc return EINVAL; 357433d6423SLionel Sambuc } 358433d6423SLionel Sambuc return OK; 359433d6423SLionel Sambuc } 360433d6423SLionel Sambuc 361433d6423SLionel Sambuc #if 0 362*0baafa0eSDavid van Moolenbroek static void 363*0baafa0eSDavid van Moolenbroek list_shm_ds(void) 364433d6423SLionel Sambuc { 3654d272e5aSDavid van Moolenbroek unsigned int i; 366*0baafa0eSDavid van Moolenbroek 367433d6423SLionel Sambuc printf("key\tid\tpage\n"); 3684d272e5aSDavid van Moolenbroek for (i = 0; i < shm_list_nr; i++) { 3694d272e5aSDavid van Moolenbroek if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) 3704d272e5aSDavid van Moolenbroek continue; 371433d6423SLionel Sambuc printf("%ld\t%d\t%lx\n", 3724d272e5aSDavid van Moolenbroek shm_list[i].shmid_ds.shm_perm._key, 3734d272e5aSDavid van Moolenbroek IXSEQ_TO_IPCID(i, shm_list[i].shmid_ds.shm_perm), 374433d6423SLionel Sambuc shm_list[i].page); 375433d6423SLionel Sambuc } 3764d272e5aSDavid van Moolenbroek } 377433d6423SLionel Sambuc #endif 378433d6423SLionel Sambuc 379*0baafa0eSDavid van Moolenbroek int 380*0baafa0eSDavid van Moolenbroek is_shm_nil(void) 381433d6423SLionel Sambuc { 382*0baafa0eSDavid van Moolenbroek 383433d6423SLionel Sambuc return (shm_list_nr == 0); 384433d6423SLionel Sambuc } 385