| 1 | /*	$OpenBSD: msg.h,v 1.24 2024/10/27 22:08:25 jsg Exp $	*/ |
| 2 | /*	$NetBSD: msg.h,v 1.9 1996/02/09 18:25:18 christos Exp $	*/ |
| 3 | |
| 4 | /* |
| 5 | * SVID compatible msg.h file |
| 6 | * |
| 7 | * Author: Daniel Boulet |
| 8 | * |
| 9 | * Copyright 1993 Daniel Boulet and RTMX Inc. |
| 10 | * |
| 11 | * This system call was implemented by Daniel Boulet under contract from RTMX. |
| 12 | * |
| 13 | * Redistribution and use in source forms, with and without modification, |
| 14 | * are permitted provided that this entire comment appears intact. |
| 15 | * |
| 16 | * Redistribution in binary form may occur without any restrictions. |
| 17 | * Obviously, it would be nice if you gave credit where credit is due |
| 18 | * but requiring it would be too onerous. |
| 19 | * |
| 20 | * This software is provided ``AS IS'' without any warranties of any kind. |
| 21 | */ |
| 22 | |
| 23 | #ifndef _SYS_MSG_H_ |
| 24 | #define _SYS_MSG_H_ |
| 25 | |
| 26 | #include <sys/ipc.h> |
| 27 | |
| 28 | /* |
| 29 | * The MSG_NOERROR identifier value, the msqid_ds struct and the msg struct |
| 30 | * are as defined by the SV API Intel 386 Processor Supplement. |
| 31 | */ |
| 32 | |
| 33 | #define MSG_NOERROR	010000		/* don't complain about too long msgs */ |
| 34 | |
| 35 | typedef unsigned long	 msgqnum_t; |
| 36 | typedef unsigned long	 msglen_t; |
| 37 | |
| 38 | struct msqid_ds { |
| 39 | 	struct ipc_perm	msg_perm;	/* msg queue permission bits */ |
| 40 | 	struct msg	*msg_first;	/* first message in the queue */ |
| 41 | 	struct msg	*msg_last;	/* last message in the queue */ |
| 42 | 	msglen_t	msg_cbytes;	/* number of bytes in use on the queue */ |
| 43 | 	msgqnum_t	msg_qnum;	/* number of msgs in the queue */ |
| 44 | 	msglen_t	msg_qbytes;	/* max # of bytes on the queue */ |
| 45 | 	pid_t		msg_lspid;	/* pid of last msgsnd() */ |
| 46 | 	pid_t		msg_lrpid;	/* pid of last msgrcv() */ |
| 47 | 	time_t		msg_stime;	/* time of last msgsnd() */ |
| 48 | 	long		msg_pad1; |
| 49 | 	time_t		msg_rtime;	/* time of last msgrcv() */ |
| 50 | 	long		msg_pad2; |
| 51 | 	time_t		msg_ctime;	/* time of last msgctl() */ |
| 52 | 	long		msg_pad3; |
| 53 | 	long		msg_pad4[4]; |
| 54 | }; |
| 55 | |
| 56 | #ifdef _KERNEL |
| 57 | #include <sys/queue.h> |
| 58 | |
| 59 | struct msg { |
| 60 | 	long		 msg_type; |
| 61 | 	size_t		 msg_len; |
| 62 | 	struct mbuf	*msg_data; |
| 63 | |
| 64 | 	TAILQ_ENTRY(msg)	msg_next; |
| 65 | }; |
| 66 | |
| 67 | struct que { |
| 68 | 	struct msqid_ds	msqid_ds; |
| 69 | 	int		que_ix;		/* pseudo-index */ |
| 70 | 	int		que_flags; |
| 71 | 	int		que_references; |
| 72 | |
| 73 | 	TAILQ_ENTRY(que)	que_next; |
| 74 | 	TAILQ_HEAD(, msg) que_msgs; |
| 75 | }; |
| 76 | |
| 77 | /* for que_flags */ |
| 78 | #define	MSGQ_READERS	0x01 |
| 79 | #define	MSGQ_WRITERS	0x02 |
| 80 | #define	MSGQ_DYING	0x04 |
| 81 | |
| 82 | #define	QREF(q)	(q)->que_references++ |
| 83 | |
| 84 | #define QRELE(q) do {							\ |
| 85 | 	if (--(q)->que_references == 0 && (q)->que_flags & MSGQ_DYING)	\ |
| 86 | 		wakeup_one(&(q)->que_references);			\ |
| 87 | } while (0) |
| 88 | |
| 89 | /* |
| 90 | * Based on the configuration parameters described in an SVR2 (yes, two) |
| 91 | * config(1m) man page. |
| 92 | * |
| 93 | * Each message is broken up and stored in segments that are msgssz bytes |
| 94 | * long. For efficiency reasons, this should be a power of two. Also, |
| 95 | * it doesn't make sense if it is less than 8 or greater than about 256. |
| 96 | * Consequently, msginit in kern/sysv_msg.c checks that msgssz is a power of |
| 97 | * two between 8 and 1024 inclusive (and panic's if it isn't). |
| 98 | */ |
| 99 | struct msginfo { |
| 100 | 	int	msgmax,		/* max chars in a message */ |
| 101 | 		msgmni,		/* max message queue identifiers */ |
| 102 | 		msgmnb,		/* max chars in a queue */ |
| 103 | 		msgtql,		/* max messages in system */ |
| 104 | 		msgssz,		/* size of a message segment (see notes above) */ |
| 105 | 		msgseg;		/* number of message segments */ |
| 106 | }; |
| 107 | #ifdef SYSVMSG |
| 108 | extern struct msginfo	msginfo; |
| 109 | #endif |
| 110 | |
| 111 | int sysctl_sysvmsg(int *, u_int, void *, size_t *); |
| 112 | |
| 113 | struct msg_sysctl_info { |
| 114 | 	struct msginfo msginfo; |
| 115 | 	struct msqid_ds msgids[1]; |
| 116 | }; |
| 117 | |
| 118 | #ifndef MSGSSZ |
| 119 | #define MSGSSZ	8		/* Each segment must be 2^N long */ |
| 120 | #endif |
| 121 | #ifndef MSGSEG |
| 122 | #define MSGSEG	2048		/* must be less than 32767 */ |
| 123 | #endif |
| 124 | #undef MSGMAX			/* ALWAYS compute MSGMAX! */ |
| 125 | #define MSGMAX	(MSGSSZ*MSGSEG) |
| 126 | #ifndef MSGMNB |
| 127 | #define MSGMNB	2048		/* max # of bytes in a queue */ |
| 128 | #endif |
| 129 | #ifndef MSGMNI |
| 130 | #define MSGMNI	40 |
| 131 | #endif |
| 132 | #ifndef MSGTQL |
| 133 | #define MSGTQL	40 |
| 134 | #endif |
| 135 | |
| 136 | void msginit(void); |
| 137 | #else /* !_KERNEL */ |
| 138 | __BEGIN_DECLS |
| 139 | int msgctl(int, int, struct msqid_ds *); |
| 140 | int msgget(key_t, int); |
| 141 | int msgsnd(int, const void *, size_t, int); |
| 142 | int msgrcv(int, void *, size_t, long, int); |
| 143 | __END_DECLS |
| 144 | #endif |
| 145 | |
| 146 | #endif /* !_SYS_MSG_H_ */ |