#if defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
#define KEY __key
#else
-#define KEY key
+#define KEY _key
#endif
#define LIMITS 1
#include <sys/featuretest.h>
#include <sys/types.h>
-/* Data structure used to pass permission information to IPC operations. */
struct ipc_perm {
- key_t key; /* Key. */
uid_t uid; /* user id */
gid_t gid; /* group id */
uid_t cuid; /* creator user id */
gid_t cgid; /* creator group id */
- unsigned short int mode; /* Reader/write permission. */
- unsigned short int __seq; /* Sequence number. */
+ mode_t mode; /* r/w permission */
+
+ /*
+ * These members are private and used only in the internal
+ * implementation of this interface.
+ */
+ unsigned short _seq; /* sequence # (to generate unique
+ msg/sem/shm id) */
+ key_t _key; /* user specified msg/sem/shm key */
+};
+
+#if defined(_NETBSD_SOURCE)
+/* Warning: 64-bit structure padding is needed here */
+struct ipc_perm_sysctl {
+ uint64_t _key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ mode_t mode;
+ int16_t _seq;
+ int16_t pad;
};
+#endif /* _NETBSD_SOURCE */
+
+/* Common access type bits, used with ipcperm(). */
+#define IPC_R 000400 /* read permission */
+#define IPC_W 000200 /* write/alter permission */
+#define IPC_M 010000 /* permission to change control info */
/* X/Open required constants (same values as system 5) */
#define IPC_CREAT 001000 /* create entry if key does not exist */
#define IPC_STAT 2 /* get options */
#ifdef __minix
-#define IPC_INFO 3 /* See ipcs. */
+#define IPC_INFO 500 /* See ipcs. */
#endif /* !__minix */
/*
#define IXSEQ_TO_IPCID(ix,perm) (((perm._seq) << 16) | (ix & 0xffff))
#endif
+#ifdef _KERNEL
+#define IPCID_TO_IX(id) ((id) & 0xffff)
+#define IPCID_TO_SEQ(id) (((id) >> 16) & 0xffff)
+
+struct kauth_cred;
+int ipcperm(struct kauth_cred *, struct ipc_perm *, int);
+
+void sysvipcinit(void);
+
+/*
+ * sysctl helper routine for kern.ipc.sysvipc_info subtree.
+ */
+
+#define SYSCTL_FILL_PERM(src, dst) do { \
+ (dst)._key = (src)._key; \
+ (dst).uid = (src).uid; \
+ (dst).gid = (src).gid; \
+ (dst).cuid = (src).cuid; \
+ (dst).cgid = (src).cgid; \
+ (dst).mode = (src).mode; \
+ (dst)._seq = (src)._seq; \
+} while (/*CONSTCOND*/ 0);
+
+#endif /* _KERNEL */
+
+#ifndef _KERNEL
#include <sys/cdefs.h>
__BEGIN_DECLS
key_t ftok(const char *, int);
__END_DECLS
-
+#endif
#endif /* !_SYS_IPC_H_ */
#include <sys/ipc.h>
+#ifdef _KERNEL
+struct __sem {
+ unsigned short semval; /* semaphore value */
+ pid_t sempid; /* pid of last operation */
+ unsigned short semncnt; /* # awaiting semval > cval */
+ unsigned short semzcnt; /* # awaiting semval = 0 */
+};
+#endif /* _KERNEL */
+
struct semid_ds {
- struct ipc_perm sem_perm; /* operation permission struct */
- time_t sem_otime; /* last semop() time */
- unsigned long int __unused1;
- time_t sem_ctime; /* last time changed by semctl() */
- unsigned long int __unused2;
- unsigned long int sem_nsems; /* number of semaphores in set */
- unsigned long int __unused3;
- unsigned long int __unused4;
+ struct ipc_perm sem_perm; /* operation permission structure */
+ unsigned short sem_nsems; /* number of semaphores in set */
+ time_t sem_otime; /* last semop() time */
+ time_t sem_ctime; /* last time changed by semctl() */
+
+ /*
+ * These members are private and used only in the internal
+ * implementation of this interface.
+ */
+ struct __sem *_sem_base; /* pointer to first semaphore in set */
};
/*
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
-#define SEM_UNDO 0x1000 /* undo changes on process exit */
+#define SEM_UNDO 010000 /* undo changes on process exit */
/*
* commands for semctl
*/
-#define GETPID 11 /* get sempid */
-#define GETVAL 12 /* get semval */
-#define GETALL 13 /* get all semval's */
-#define GETNCNT 14 /* get semncnt */
-#define GETZCNT 15 /* get semzcnt */
-#define SETVAL 16 /* set semval */
-#define SETALL 17 /* set all semval's */
+#define GETNCNT 3 /* Return the value of semncnt {READ} */
+#define GETPID 4 /* Return the value of sempid {READ} */
+#define GETVAL 5 /* Return the value of semval {READ} */
+#define GETALL 6 /* Return semvals into arg.array {READ} */
+#define GETZCNT 7 /* Return the value of semzcnt {READ} */
+#define SETVAL 8 /* Set the value of semval to arg.val {ALTER} */
+#define SETALL 9 /* Set semvals from arg.array {ALTER} */
+
+#if defined(_KERNEL) || defined(__minix)
+/*
+ * Kernel implementation stuff
+ */
+#define SEMVMX 32767 /* semaphore maximum value */
+#define SEMAEM 16384 /* adjust on exit max value */
-#ifdef __USE_MISC
+/*
+ * Permissions
+ */
+#define SEM_A 0200 /* alter permission */
+#define SEM_R 0400 /* read permission */
-/* ipcs ctl cmds */
-# define SEM_STAT 18
-# define SEM_INFO 19
+/*
+ * Undo structure (one per process)
+ */
+struct sem_undo {
+ struct sem_undo *un_next; /* ptr to next active undo structure */
+ struct proc *un_proc; /* owner of this structure */
+ short un_cnt; /* # of active entries */
+ struct undo {
+ short un_adjval; /* adjust on exit values */
+ short un_num; /* semaphore # */
+ int un_id; /* semid */
+ } un_ent[1]; /* undo entries */
+};
+#endif /* _KERNEL */
+#if defined(_NETBSD_SOURCE)
/*
* semaphore info struct
*/
int32_t semaem; /* adjust on exit max value */
};
-#endif /* __USE_MISC */
+/* Warning: 64-bit structure padding is needed here */
+struct semid_ds_sysctl {
+ struct ipc_perm_sysctl sem_perm;
+ int16_t sem_nsems;
+ int16_t pad2;
+ int32_t pad3;
+ time_t sem_otime;
+ time_t sem_ctime;
+};
+struct sem_sysctl_info {
+ struct seminfo seminfo;
+ struct semid_ds_sysctl semids[1];
+};
+
+/*
+ * Internal "mode" bits. The first of these is used by ipcs(1), and so
+ * is defined outside the kernel as well.
+ */
+#define SEM_ALLOC 01000 /* semaphore is allocated */
+#endif /* !_POSIX_C_SOURCE && !_XOPEN_SOURCE */
+
+#if defined(_KERNEL) || defined(__minix)
+#define SEM_DEST 02000 /* semaphore will be destroyed on last detach */
/*
* Configuration parameters
*/
-#define SEMMNI 128
-#define SEMMSL 250
-#define SEMMNS (SEMMSL*SEMMNI)
+#ifndef SEMMNI
+#define SEMMNI 10 /* # of semaphore identifiers */
+#endif
+#ifndef SEMMNS
+#define SEMMNS 60 /* # of semaphores in system */
+#endif
+#ifndef SEMUME
+#define SEMUME 10 /* max # of undo entries per process */
+#endif
+#ifndef SEMMNU
+#define SEMMNU 30 /* # of undo structures in system */
+#endif
+
+/* shouldn't need tuning */
+#ifndef SEMMAP
+#define SEMMAP 30 /* # of entries in semaphore map */
+#endif
+#ifndef SEMMSL
+#define SEMMSL SEMMNS /* max # of semaphores per id */
+#endif
+#ifndef SEMOPM
+#define SEMOPM 100 /* max # of operations per semop call */
+#endif
+
+/* actual size of an undo structure */
+#define SEMUSZ (sizeof(struct sem_undo)+sizeof(struct undo)*SEMUME)
+
+/*
+ * Structures allocated in machdep.c
+ */
+extern struct seminfo seminfo;
+extern struct semid_ds *sema; /* semaphore id pool */
-#define SEMOPM 32
-#define SEMVMX 32767
+/*
+ * Parameters to the semconfig system call
+ */
+#define SEM_CONFIG_FREEZE 0 /* Freeze the semaphore facility. */
+#define SEM_CONFIG_THAW 1 /* Thaw the semaphore facility. */
+
+#define SYSCTL_FILL_SEM(src, dst) do { \
+ SYSCTL_FILL_PERM((src).sem_perm, (dst).sem_perm); \
+ (dst).sem_nsems = (src).sem_nsems; \
+ (dst).sem_otime = (src).sem_otime; \
+ (dst).sem_ctime = (src).sem_ctime; \
+} while (/*CONSTCOND*/ 0)
+
+#endif /* _KERNEL */
+#ifdef __minix
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+#endif
+#ifndef _KERNEL
#include <sys/cdefs.h>
__BEGIN_DECLS
-int semctl(int, int, int, ...);
+#ifndef __LIBC12_SOURCE__
+int semctl(int, int, int, ...) __RENAME(__semctl50);
+#endif
int semget(key_t, int, int);
int semop(int, struct sembuf *, size_t);
+#if defined(_NETBSD_SOURCE)
+int semconfig(int);
+#endif
__END_DECLS
+#else
+void seminit(void);
+void semexit(struct proc *, void *);
+
+int semctl1(struct lwp *, int, int, int, void *, register_t *);
+#define get_semctl_arg(cmd, sembuf, arg) \
+ ((cmd) == IPC_SET || (cmd) == IPC_STAT ? (void *)sembuf \
+ : (cmd) == GETALL || (cmd) == SETVAL || (cmd) == SETALL ? (void *)arg \
+ : NULL)
+#endif /* !_KERNEL */
#endif /* !_SYS_SEM_H_ */
#define SHM_RDONLY 010000 /* Attach read-only (else read-write) */
#define SHM_RND 020000 /* Round attach address to SHMLBA */
+#ifdef _KERNEL
+#define _SHM_RMLINGER 040000 /* Attach even if segment removed */
+#endif
/* Segment low boundry address multiple */
-#define SHMLBA getpagesize()
-#define SHMMNI 4096
-#define SHMSEG 32 /* max shared segs per process */
+#if defined(_KERNEL) || defined(_STANDALONE) || defined(_MODULE)
+#define SHMLBA PAGE_SIZE
+#else
+/*
+ * SHMLBA uses libc's internal __sysconf() to retrieve the machine's
+ * page size. The value of _SC_PAGESIZE is 28 -- we hard code it so we do not
+ * need to include unistd.h
+ */
+__BEGIN_DECLS
+long __sysconf(int);
+__END_DECLS
+#define SHMLBA (__sysconf(28))
+#endif
typedef unsigned int shmatt_t;
struct shmid_ds {
struct ipc_perm shm_perm; /* operation permission structure */
size_t shm_segsz; /* size of segment in bytes */
+ pid_t shm_lpid; /* process ID of last shm operation */
+ pid_t shm_cpid; /* process ID of creator */
+ shmatt_t shm_nattch; /* number of current attaches */
time_t shm_atime; /* time of last shmat() */
time_t shm_dtime; /* time of last shmdt() */
time_t shm_ctime; /* time of last change by shmctl() */
- pid_t shm_cpid; /* process ID of creator */
- pid_t shm_lpid; /* process ID of last shm operation */
- shmatt_t shm_nattch; /* number of current attaches */
-};
-
-/* 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
+ /*
+ * These members are private and used only in the internal
+ * implementation of this interface.
+ */
+ void *_shm_internal;
+};
+#if defined(_NETBSD_SOURCE)
+/*
+ * Some systems (e.g. HP-UX) take these as the second (cmd) arg to shmctl().
+ */
+#define SHM_LOCK 3 /* Lock segment in memory. */
+#define SHM_UNLOCK 4 /* Unlock a segment locked by SHM_LOCK. */
+#endif /* _NETBSD_SOURCE */
-#if defined(_NETBSD_SOURCE) || defined(__minix)
+#if defined(_NETBSD_SOURCE)
/*
* Permission definitions used in shmflag arguments to shmat(2) and shmget(2).
* Provided for source compatibility only; do not use in new code!
*/
-#define SHM_R 0400
-#define SHM_W 0200
+#define SHM_R IPC_R /* S_IRUSR, R for owner */
+#define SHM_W IPC_W /* S_IWUSR, W for owner */
/*
* System 5 style catch-all structure for shared memory constants that
* might be of interest to user programs. Do we really want/need this?
*/
struct shminfo {
- unsigned long int shmmax; /* max shared memory segment size (bytes) */
- unsigned long int shmmin; /* min shared memory segment size (bytes) */
- unsigned long int shmmni; /* max number of shared memory identifiers */
- unsigned long int shmseg; /* max shared memory segments per process */
- unsigned long int shmall; /* max amount of shared memory (pages) */
+ uint64_t shmmax; /* max shared memory segment size (bytes) */
+ uint32_t shmmin; /* min shared memory segment size (bytes) */
+ uint32_t shmmni; /* max number of shared memory identifiers */
+ uint32_t shmseg; /* max shared memory segments per process */
+ uint32_t shmall; /* max amount of shared memory (pages) */
};
-#ifdef __minix
-struct shm_info
-{
- int used_ids;
- unsigned long int shm_tot; /* total allocated shm */
- unsigned long int shm_rss; /* total resident shm */
- unsigned long int shm_swp; /* total swapped shm */
- unsigned long int swap_attempts;
- unsigned long int swap_successes;
+/* Warning: 64-bit structure padding is needed here */
+struct shmid_ds_sysctl {
+ struct ipc_perm_sysctl shm_perm;
+ uint64_t shm_segsz;
+ pid_t shm_lpid;
+ pid_t shm_cpid;
+ time_t shm_atime;
+ time_t shm_dtime;
+ time_t shm_ctime;
+ uint32_t shm_nattch;
+};
+struct shm_sysctl_info {
+ struct shminfo shminfo;
+ struct shmid_ds_sysctl shmids[1];
};
-#endif /* __minix */
-
#endif /* _NETBSD_SOURCE */
+#ifdef _KERNEL
+extern struct shminfo shminfo;
+extern struct shmid_ds *shmsegs;
+extern int shm_nused;
+
+#define SHMSEG_FREE 0x0200
+#define SHMSEG_REMOVED 0x0400
+#define SHMSEG_ALLOCATED 0x0800
+#define SHMSEG_WANTED 0x1000
+#define SHMSEG_RMLINGER 0x2000
+#define SHMSEG_WIRED 0x4000
+
+struct vmspace;
+
+void shminit(void);
+void shmfork(struct vmspace *, struct vmspace *);
+void shmexit(struct vmspace *);
+int shmctl1(struct lwp *, int, int, struct shmid_ds *);
+
+#define SYSCTL_FILL_SHM(src, dst) do { \
+ SYSCTL_FILL_PERM((src).shm_perm, (dst).shm_perm); \
+ (dst).shm_segsz = (src).shm_segsz; \
+ (dst).shm_lpid = (src).shm_lpid; \
+ (dst).shm_cpid = (src).shm_cpid; \
+ (dst).shm_atime = (src).shm_atime; \
+ (dst).shm_dtime = (src).shm_dtime; \
+ (dst).shm_ctime = (src).shm_ctime; \
+ (dst).shm_nattch = (src).shm_nattch; \
+} while (/*CONSTCOND*/ 0)
+
+#else /* !_KERNEL */
+
__BEGIN_DECLS
void *shmat(int, const void *, int);
int shmctl(int, int, struct shmid_ds *) __RENAME(__shmctl50);
int shmget(key_t, size_t, int);
__END_DECLS
+#endif /* !_KERNEL */
+
+#ifdef __minix
+/* ipcs ctl commands */
+#define SHM_STAT 13
+#define SHM_INFO 14
+#endif
+
+#ifdef __minix
+struct shm_info
+{
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+};
+
+#define SHMMNI 4096
+#define SHMSEG 32 /* 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 */
+
+#endif
+
#endif /* !_SYS_SHM_H_ */