Skip site navigation (1)Skip section navigation (2)
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>