#ifndef _SYS_SHM_H
#define _SYS_SHM_H

#include <sys/ipc.h>
#include <sys/types.h>

struct shmid_ds {
        struct ipc_perm shm_perm;       /* operation perms */
        int     shm_segsz;              /* size of segment (bytes) */
        time_t  shm_atime;              /* last attach time */
        time_t  shm_dtime;              /* last detach time */
        time_t  shm_ctime;              /* last change time */
        unsigned short  shm_cpid;       /* pid of creator */
        unsigned short  shm_lpid;       /* pid of last operator */
        short   shm_nattch;             /* no. of current attaches */
        /* private */
        void   *shm_pages;
};

/* permission flag for shmget */
#define SHM_R           0400    /* or S_IRUGO from <linux/stat.h> */
#define SHM_W           0200    /* or S_IWUGO from <linux/stat.h> */

/* mode for attach */
#define SHM_RDONLY      010000  /* read-only access */

/* not supported */
#ifndef __EMX__
#define SHM_RND         020000  /* round attach address to SHMLBA boundary */
#define SHM_REMAP       040000  /* take-over region on attach */
#endif

/* super user shmctl commands */
#define SHM_LOCK        11
#define SHM_UNLOCK      12

struct  shminfo {
    int shmmax;
    int shmmin;
    int shmmni;
    int shmseg;
    int shmall;
};

#define SHM_ID_SHIFT    8
/* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
   there is a static array of size SHMMNI. */
#define _SHM_ID_BITS    7
#define SHM_ID_MASK     ((1<<_SHM_ID_BITS)-1)

#define SHM_IDX_SHIFT   (SHM_ID_SHIFT+_SHM_ID_BITS)
#define _SHM_IDX_BITS   15
#define SHM_IDX_MASK    ((1<<_SHM_IDX_BITS)-1)

/* We must have SHM_ID_SHIFT + _SHM_ID_BITS + _SHM_IDX_BITS <= 32
   and SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). */

#define SHMMAX 0x3fa000                         /* max shared seg size (bytes) */
#define SHMMIN 1         /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS)                /* max num of segs system wide */
#define SHMALL (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))/* max shm system wide (pages) */
#define SHMLBA 0x1000                           /* attach addr a multiple of this */
#define SHMSEG SHMMNI                           /* max shared segs per process */

/* shm_mode upper byte flags */
#define SHM_DEST        01000   /* segment will be destroyed on last detach */
#define SHM_LOCKED      02000   /* segment will not be swapped */

/* ipcs ctl commands */
#define SHM_STAT        13
#define SHM_INFO        14

extern int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf);
extern int shmget(key_t __key, int __size, int __flag);
extern char *shmat(int __shmid, char *__shmaddr, int __shmflg);
extern int shmdt(char *__shmaddr);

#endif /* _SYS_SHM_H */
