diff options
author | mr <mr@FreeBSD.org> | 2001-10-28 09:29:10 +0000 |
---|---|---|
committer | mr <mr@FreeBSD.org> | 2001-10-28 09:29:10 +0000 |
commit | f757fda60d8e586e6ba39ba525f615b8cb3fe0ce (patch) | |
tree | 13b4e909deffbd1c8f2a34c63dcc244b37e32d6b /sys/kern/sysv_shm.c | |
parent | 315406dcf8c8a2619b51a673f41f5e666863fcdd (diff) | |
download | FreeBSD-src-f757fda60d8e586e6ba39ba525f615b8cb3fe0ce.zip FreeBSD-src-f757fda60d8e586e6ba39ba525f615b8cb3fe0ce.tar.gz |
Introduce [IPC|SHM]_[INFO|STAT] to shmctl to make
`/compat/linux/usr/bin/ipcs -m` happy.
Diffstat (limited to 'sys/kern/sysv_shm.c')
-rw-r--r-- | sys/kern/sysv_shm.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 74743e5..dc4fa3b 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -96,6 +96,7 @@ struct shmmap_state { static void shm_deallocate_segment __P((struct shmid_ds *)); static int shm_find_segment_by_key __P((key_t)); static struct shmid_ds *shm_find_segment_by_shmid __P((int)); +static struct shmid_ds *shm_find_segment_by_shmidx __P((int)); static int shm_delete_mapping __P((struct proc *p, struct shmmap_state *)); static void shmrealloc __P((void)); static void shminit __P((void)); @@ -179,6 +180,20 @@ shm_find_segment_by_shmid(shmid) return shmseg; } +static struct shmid_ds * +shm_find_segment_by_shmidx(int segnum) +{ + struct shmid_ds *shmseg; + + if (segnum < 0 || segnum >= shmalloced) + return NULL; + shmseg = &shmsegs[segnum]; + if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED)) + != SHMSEG_ALLOCATED ) + return NULL; + return shmseg; +} + static void shm_deallocate_segment(shmseg) struct shmid_ds *shmseg; @@ -476,12 +491,38 @@ shmctl(td, uap) error = ENOSYS; goto done2; } - shmseg = shm_find_segment_by_shmid(uap->shmid); + switch (uap->cmd) { + case IPC_INFO: + error = copyout( (caddr_t)&shminfo, uap->buf, sizeof( shminfo ) ); + if (error) + goto done2; + td->td_retval[0] = shmalloced; + goto done2; + case SHM_INFO: { + struct shm_info shm_info; + shm_info.used_ids = shm_nused; + shm_info.shm_rss = 0; /*XXX where to get from ? */ + shm_info.shm_tot = 0; /*XXX where to get from ? */ + shm_info.shm_swp = 0; /*XXX where to get from ? */ + shm_info.swap_attempts = 0; /*XXX where to get from ? */ + shm_info.swap_successes = 0; /*XXX where to get from ? */ + error = copyout( (caddr_t)&shm_info, uap->buf, sizeof( shm_info ) ); + if (error) + goto done2; + td->td_retval[0] = shmalloced; + goto done2; + } + } + if( (uap->cmd) == SHM_STAT ) + shmseg = shm_find_segment_by_shmidx(uap->shmid); + else + shmseg = shm_find_segment_by_shmid(uap->shmid); if (shmseg == NULL) { error = EINVAL; goto done2; } switch (uap->cmd) { + case SHM_STAT: case IPC_STAT: error = ipcperm(td, &shmseg->shm_perm, IPC_R); if (error) @@ -489,6 +530,8 @@ shmctl(td, uap) error = copyout((caddr_t)shmseg, uap->buf, sizeof(inbuf)); if (error) goto done2; + else if( (uap->cmd) == SHM_STAT ) + td->td_retval[0] = IXSEQ_TO_IPCID( uap->shmid, shmseg->shm_perm ); break; case IPC_SET: error = ipcperm(td, &shmseg->shm_perm, IPC_M); |