Date: Tue, 19 Dec 95 22:01:57 +0900 From: Mihoko Tanaka <m_tanaka@pa.yokogawa.co.jp> To: freebsd-hackers@freebsd.org Subject: shmget() problem Message-ID: <9512191301.AA05407@cabbage.pa.yokogawa.co.jp>
next in thread | raw e-mail | index | archive | help
Hello all,
I report a problem about shmget(). (I'm using FreeBSD-2.1.0R)
int shmget(key_t key, int size, int shmflg);
If the 'key' has already existed in the system and set 'shmflg'
as '(IPC_CREAT|IPC_EXC)', then shmget() must return the error 'EEXIST'.
But shmget() doesn't return 'EEXIST'. So I can allocate the shared
memory by using the same key, though it has already allocated by
another process.
In kern/sysv_shm.c:
static int
shmget_existing(p, uap, mode, segnum, retval)
struct proc *p;
struct shmget_args *uap;
int mode;
int segnum;
int *retval;
{
struct shmid_ds *shmseg;
struct ucred *cred = p->p_ucred;
int error;
shmseg = &shmsegs[segnum];
if (shmseg->shm_perm.mode & SHMSEG_REMOVED) {
/*
* This segment is in the process of being allocated. Wait
* until it's done, and look the key up again (in case the
* allocation failed or it was freed).
*/
shmseg->shm_perm.mode |= SHMSEG_WANTED;
error = tsleep((caddr_t)shmseg, PLOCK | PCATCH, "shmget", 0);
if (error)
return error;
return EAGAIN;
}
error = ipcperm(cred, &shmseg->shm_perm, mode);
if (error)
return error;
if (uap->size && uap->size > shmseg->shm_segsz)
return EINVAL;
if (uap->shmflg & (IPC_CREAT | IPC_EXCL) == (IPC_CREAT | IPC_EXCL))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return EEXIST;
*retval = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
return 0;
}
The priority of '==' is higher than that of '&'.
I guess that it should be as following:
if ((uap->shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
------------------------ cut cut cut -----------------------------------
--- sysv_shm.c Tue May 30 17:06:04 1995
+++ sysv_shm.c.new Tue Dec 19 21:51:07 1995
@@ -411,7 +411,7 @@
return error;
if (uap->size && uap->size > shmseg->shm_segsz)
return EINVAL;
- if (uap->shmflg & (IPC_CREAT | IPC_EXCL) == (IPC_CREAT | IPC_EXCL))
+ if ((uap->shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
return EEXIST;
*retval = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
return 0;
------------------------ cut cut cut -----------------------------------
--
Mihoko Tanaka
<m_tanaka@pa.yokogawa.co.jp>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9512191301.AA05407>
