1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/openenvcore/include/sys/msg.dosc Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,588 @@
1.4 +/** @file ../include/sys/msg.h
1.5 +@internalComponent
1.6 +*/
1.7 +
1.8 +/** @fn msgget(key_t key, int msgflg)
1.9 +@param key
1.10 +@param msgflg
1.11 +@return Upon successful completion a positive message queue identifier is returned.
1.12 +Otherwise, -1 is returned and the global variable errno is set to indicate the error.
1.13 +
1.14 + The msgget function
1.15 +returns the message queue identifier associated with key. A message queue identifier is a unique integer greater than zero.
1.16 +
1.17 + A message queue is created if either key is equal to IPC_PRIVATE, or key does not have a message queue identifier associated with it and
1.18 + the IPC_CREAT bit is set in msgflg.
1.19 +
1.20 + If a new message queue is created, the data structure associated with it (the msqid_ds structure, see msgctl is initialized as follows: msg_perm.cuid and msg_perm.uid are set to the effective uid of the calling process.
1.21 +In the current implementation, uid is set to root. msg_perm.gid and msg_perm.cgid are set to the effective gid of the calling process.
1.22 +In the current implementation, gid is set to root. msg_perm.mode is set to the lower 9 bits of msgflg. msg_cbytes, msg_qnum, msg_lspid, msg_lrpid, msg_rtime, and msg_stime are set to 0. msg_qbytes is set to the system wide maximum value for the number of bytes in a queue (Dv MSGMNB). msg_ctime is set to the current time.
1.23 +
1.24 +Examples:
1.25 +
1.26 + Example code to create a message queue using msgget
1.27 +
1.28 +@code
1.29 +#include <sys/types.h>
1.30 +#include <sys/ipc.h>
1.31 +#include <sys/msg.h>
1.32 +#include <stdio.h>
1.33 +#include <string.h>
1.34 +#include <errno.h>
1.35 +
1.36 +#define MESSAGE_Q_KEY 1000
1.37 +
1.38 +int main(void)
1.39 +{
1.40 + int msq_id, len;
1.41 + struct {
1.42 + long mtype;
1.43 + char mtext[128];
1.44 + } msg_buf;
1.45 + /*
1.46 + * Create a message queue with a given key
1.47 + */
1.48 + if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
1.49 + printf("Message Q create failed with errno %d
1.50 +", errno);
1.51 + return -1;
1.52 + }
1.53 + msg_buf.mtype = 1; /* message identifier */
1.54 + strcpy(msg_buf.mtext, "some_data_to_send"); /* data */
1.55 + len = strlen(msg_buf.mtext)+1;
1.56 + /*
1.57 + * Put the message in the queue
1.58 + */
1.59 + if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) {
1.60 + printf("Message Q send failed with errno %d
1.61 +", errno);
1.62 + }
1.63 + return 0;
1.64 +}
1.65 +
1.66 +@endcode
1.67 + Example code to return an existing message queue with msgget
1.68 +@code
1.69 +#include <sys/types.h>
1.70 +#include <sys/ipc.h>
1.71 +#include <sys/msg.h>
1.72 +#include <stdio.h>
1.73 +#include <string.h>
1.74 +#include <errno.h>
1.75 +
1.76 +#define MESSAGE_Q_KEY 1000
1.77 +
1.78 +int main(void)
1.79 +{
1.80 + int msq_id;
1.81 + int msg_len = 128;
1.82 + int msg_type = 0; /* Any type of message */
1.83 + struct {
1.84 + long mtype;
1.85 + char mtext[128];
1.86 + } msg_buf;
1.87 + /*
1.88 + * Get the message queue id for the given key
1.89 + */
1.90 + if ((msq_id = msgget(MESSAGE_Q_KEY, 0)) == -1) {
1.91 + printf("Message Q get id failed with errno %d
1.92 +", errno);
1.93 + return -1;
1.94 + }
1.95 + /*
1.96 + * Get the message from the queue
1.97 + */
1.98 + if (msgrcv(msq_id, (struct msgbuf *)&msg;_buf, msg_len, msg_type, 0) == -1) {
1.99 + printf("Message Q recv failed with errno %d
1.100 +", errno);
1.101 + }
1.102 + /*
1.103 + * Remove the message queue
1.104 + */
1.105 + if (msgctl(msq_id, IPC_RMID, NULL) == -1) {
1.106 + printf("Message Q delete failed with errno %d
1.107 +", errno);
1.108 + return -1;
1.109 + }
1.110 + return 0;
1.111 +}
1.112 +
1.113 +@endcode
1.114 +@see msgctl()
1.115 +@see msgrcv()
1.116 +@see msgsnd()
1.117 +
1.118 +
1.119 +
1.120 +
1.121 +@publishedAll
1.122 +@externallyDefinedApi
1.123 +*/
1.124 +
1.125 +/** @fn msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
1.126 +@param msqid
1.127 +@param msgp
1.128 +@param msgsz
1.129 +@param msgflg
1.130 +
1.131 +@return The msgsnd function returns the value 0 if successful; otherwise the
1.132 +value -1 is returned and errno is set to indicate the error.
1.133 +
1.134 +The msgsnd function sends a message to the message queue specified in msqid. The msgp argument points to a structure containing the message. This structure should consist of the following members:
1.135 +@code
1.136 +long mtype; /* message type */
1.137 +char mtext[1]; /* body of message */
1.138 +@endcode
1.139 +
1.140 +mtype is an integer greater than 0 that can be used for selecting messages (see msgrcv mtext is an array of bytes, with a size up to that of the system limit (Dv MSGMAX).
1.141 +
1.142 +If the number of bytes already on the message queue plus msgsz is bigger than the maximum number of bytes on the message queue (Va msg_qbytes, see msgctl or the number of messages on all queues system-wide is already equal to the system limit, msgflg determines the action of msgsnd. If msgflg has IPC_NOWAIT mask set in it, the call will return immediately. If msgflg does not have IPC_NOWAIT set in it, the call will block until:
1.143 +
1.144 +The condition which caused the call to block does no longer exist. The message will be sent.
1.145 +The message queue is removed, in which case -1 will be returned, and errno is set to EINVAL.
1.146 +After a successful call, the data structure associated with the message queue is updated in the following way:
1.147 +
1.148 +msg_cbytes is incremented by the size of the message.
1.149 +msg_qnum is incremented by 1.
1.150 +msg_lspid is set to the pid of the calling process.
1.151 +msg_stime is set to the current time.
1.152 +
1.153 +
1.154 +Examples:
1.155 +@code
1.156 +#include <sys/types.h>
1.157 +#include <sys/ipc.h>
1.158 +#include <sys/msg.h>
1.159 +#include <stdio.h>
1.160 +#include <string.h>
1.161 +#include <errno.h>
1.162 +
1.163 +#define MESSAGE_Q_KEY 1000
1.164 +
1.165 +int main(void)
1.166 +{
1.167 + int msq_id, len;
1.168 + struct {
1.169 + long mtype;
1.170 + char mtext[128];
1.171 + } msg_buf;
1.172 + /*
1.173 + * Create a message queue with the given key
1.174 + */
1.175 + if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
1.176 + printf("Message Q create failed with errno %d
1.177 +", errno);
1.178 + return -1;
1.179 + }
1.180 + msg_buf.mtype = 1; /* message identifier */
1.181 + strcpy(msg_buf.mtext, "some_data_to_send"); /* data */
1.182 + len = strlen(msg_buf.mtext)+1;
1.183 + /*
1.184 + * Put the message in the queue
1.185 + */
1.186 + if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) {
1.187 + printf("Message Q send failed with errno %d
1.188 +", errno);
1.189 + }
1.190 + return 0;
1.191 +}
1.192 +
1.193 +@endcode
1.194 +
1.195 +
1.196 +@publishedAll
1.197 +@externallyDefinedApi
1.198 +*/
1.199 +
1.200 +/** @fn msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
1.201 +@param msqid
1.202 +@param msgp
1.203 +@param msgsz
1.204 +@param msgtyp
1.205 +@param msgflg
1.206 +@return Upon successful completion, msgrcv returns the number of bytes received into the mtext field of the structure pointed to by msgp. Otherwise, -1 is returned, and errno set to indicate the error.
1.207 +
1.208 + The msgrcv function receives a message from the message queue specified
1.209 +in msqid and places it into the structure pointed to by msgp. This structure should consist of the following members:
1.210 +@code
1.211 +long mtype; /* message type */
1.212 +char mtext[1]; /* body of message */
1.213 +@endcode
1.214 +
1.215 + mtype is an integer greater than 0 that can be used for selecting messages, mtext is an array of bytes with a size up to that of the system limit (Dv MSGMAX).
1.216 +
1.217 + The value of msgtyp has one of the following meanings: The msgtyp argument
1.218 +is greater than 0.
1.219 +The first message of type msgtyp will be received. The msgtyp argument
1.220 +is equal to 0.
1.221 +The first message on the queue (of any message type) will be received. The msgtyp argument
1.222 +is less than 0.
1.223 +The first message of the lowest message type that is
1.224 +less than or equal to the absolute value of msgtyp will be received.
1.225 +
1.226 + The msgsz argument
1.227 +specifies the maximum length of the requested message.
1.228 +If the received
1.229 +message has a length greater than msgsz it will be silently truncated if the MSG_NOERROR flag is set in msgflg, otherwise an error will be returned.
1.230 +
1.231 + If no matching message is present on the message queue specified by msqid, the behavior of msgrcv depends on whether the IPC_NOWAIT flag is set in msgflg or not. If IPC_NOWAIT is set, msgrcv will immediately return a value of -1 and set errno to ENOMSG. If IPC_NOWAIT is not set, the calling process will be blocked until: A message of the requested type becomes available on the message queue. The message queue is removed, in which case -1 will be returned and errno set to EINVAL.
1.232 +
1.233 + If a message is successfully received, the data structure associated with msqid is updated as follows: msg_cbytes is decremented by the size of the message. msg_lrpid is set to the pid of the caller. msg_lrtime is set to the current time. msg_qnum is decremented by 1.
1.234 +
1.235 +Examples:
1.236 +
1.237 + Receive a message from the queue
1.238 +
1.239 +@code
1.240 +#include <sys/types.h>
1.241 +#include <sys/ipc.h>
1.242 +#include <sys/msg.h>
1.243 +#include <stdio.h>
1.244 +#include <string.h>
1.245 +#include <errno.h>
1.246 +
1.247 +#define MESSAGE_Q_KEY 1000
1.248 +
1.249 +int main(void)
1.250 +{
1.251 + int msq_id;
1.252 + int msg_len = 128;
1.253 + int msg_type = 0; /* Any type of message */
1.254 + struct {
1.255 + long mtype;
1.256 + char mtext[128];
1.257 + } msg_buf;
1.258 + int ret_val = -1;
1.259 + /*
1.260 + * Get the message queue id for the given key
1.261 + */
1.262 + if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT)) == -1) {
1.263 + printf("Message Q get id failed with errno %d
1.264 +", errno);
1.265 + return -1;
1.266 + }
1.267 + /*
1.268 + * Get the message from the queue
1.269 + */
1.270 + if ((ret_val = msgrcv(msq_id, (struct msgbuf *)&msg;_buf, msg_len, msg_type, 0)) == -1) {
1.271 + printf("Message Q recv failed with errno %d
1.272 +", errno);
1.273 + }
1.274 + /*
1.275 + * Remove the message queue
1.276 + */
1.277 + if (msgctl(msq_id, IPC_RMID, NULL) == -1) {
1.278 + printf("Message Q delete failed with errno %d
1.279 +", errno);
1.280 + return -1;
1.281 + }
1.282 + return ret_val;
1.283 +}
1.284 +
1.285 +
1.286 + Send a message to the queue
1.287 +
1.288 +#include <sys/types.h>
1.289 +#include <sys/ipc.h>
1.290 +#include <sys/msg.h>
1.291 +#include <stdio.h>
1.292 +#include <string.h>
1.293 +#include <errno.h>
1.294 +
1.295 +#define MESSAGE_Q_KEY 1000
1.296 +
1.297 +int main(void)
1.298 +{
1.299 + int msq_id, len;
1.300 + struct {
1.301 + long mtype;
1.302 + char mtext[128];
1.303 + } msg_buf;
1.304 + /*
1.305 + * Create a message queue with the given key
1.306 + */
1.307 + if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
1.308 + printf("Message Q create failed with errno %d0, errno);
1.309 + return -1;
1.310 + }
1.311 + msg_buf.mtype = 1; /* message identifier */
1.312 + strcpy(msg_buf.mtext, "some_data_to_send"); /* data */
1.313 + len = strlen(msg_buf.mtext)+1;
1.314 + /*
1.315 + * Put the message in the queue
1.316 + */
1.317 + if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) {
1.318 + printf("Message Q send failed with errno %d
1.319 +", errno);
1.320 + }
1.321 + return 0;
1.322 +}
1.323 +
1.324 +@endcode
1.325 +@see msgctl()
1.326 +@see msgget()
1.327 +@see msgsnd()
1.328 +
1.329 +
1.330 +
1.331 +
1.332 +@publishedAll
1.333 +@externallyDefinedApi
1.334 +*/
1.335 +
1.336 +/** @fn msgctl(int msqid, int cmd, struct msqid_ds *buf)
1.337 +@param msqid
1.338 +@param cmd
1.339 +@param buf
1.340 +@return The msgctl function returns the value 0 if successful; otherwise the
1.341 +value -1 is returned and errno is set to indicate the error.
1.342 +
1.343 +The msgctl system call performs some control operations on the message queue specified by msqid.
1.344 +Each message queue has a data structure associated with it, parts of which may be altered by msgctl and parts of which determine the actions of msgctl. The data structure is defined in \<sys/msg.h\> and contains (amongst others) the following members:
1.345 +
1.346 +@code
1.347 +struct msqid_ds {
1.348 + struct ipc_perm msg_perm; /* msg queue permission bits */
1.349 + struct msg *msg_first; /* first message in the queue */
1.350 + struct msg *msg_last; /* last message in the queue */
1.351 + u_long msg_cbytes; /* number of bytes in use on the queue */
1.352 + u_long msg_qnum; /* number of msgs in the queue */
1.353 + u_long msg_qbytes; /* max # of bytes on the queue */
1.354 + pid_t msg_lspid; /* pid of last msgsnd() */
1.355 + pid_t msg_lrpid; /* pid of last msgrcv() */
1.356 + time_t msg_stime; /* time of last msgsnd() */
1.357 + long msg_pad1;
1.358 + time_t msg_rtime; /* time of last msgrcv() */
1.359 + long msg_pad2;
1.360 + time_t msg_ctime; /* time of last msgctl() */
1.361 + long msg_pad3;
1.362 + long msg_pad4[4];
1.363 +};
1.364 +@endcode
1.365 +
1.366 +The ipc_perm structure used inside the shmid_ds structure is defined in \<sys/ipc.h\> and looks like this:
1.367 +@code
1.368 +struct ipc_perm {
1.369 + ushort cuid; /* creator user id */
1.370 + ushort cgid; /* creator group id */
1.371 + ushort uid; /* user id */
1.372 + ushort gid; /* group id */
1.373 + ushort mode; /* r/w permission */
1.374 + ushort seq; /* sequence # (to generate unique msg/sem/shm id) */
1.375 + key_t key; /* user specified msg/sem/shm key */
1.376 +};
1.377 +@endcode
1.378 +
1.379 +
1.380 +
1.381 +The operation to be performed by msgctl is specified in cmd and is one of: IPC_STAT Gather information about the message queue and place it in the structure pointed to by buf.
1.382 +IPC_SET Set the value of the msg_perm.uid, msg_perm.gid, msg_perm.mode and msg_qbytes fields in the structure associated with msqid. The values are taken from the corresponding fields in the structure pointed to by buf. Values for msg_qbytes that exceed the system limit (MSGMNB from \<sys/msg.h\>) are silently truncated to that limit.
1.383 +IPC_RMID Remove the message queue specified by msqid and destroy the data associated with it.
1.384 +
1.385 +
1.386 +
1.387 +The permission to read from or write to a message queue (see msgsnd and msgrcv is determined by the msg_perm.mode field in the same way as is done with files (see chmod)
1.388 +
1.389 +
1.390 +
1.391 +Examples:
1.392 +@code
1.393 +#include <sys/types.h>
1.394 +#include <sys/ipc.h>
1.395 +#include <sys/msg.h>
1.396 +#include <stdio.h>
1.397 +#include <string.h>
1.398 +#include <errno.h>
1.399 +
1.400 +#define MESSAGE_Q_KEY 1000
1.401 +
1.402 +int main(void)
1.403 +{
1.404 + int msq_id, len;
1.405 + struct {
1.406 + long mtype;
1.407 + char mtext[128];
1.408 + } msg_buf;
1.409 + /*
1.410 + * Create a message queue with a given key
1.411 + */
1.412 + if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
1.413 + printf("Message Q create failed with errno %d
1.414 +", errno);
1.415 + return -1;
1.416 + }
1.417 + msg_buf.mtype = 1; /* message identifier */
1.418 + strcpy(msg_buf.mtext, "some_data_to_send"); /* data */
1.419 + len = strlen(msg_buf.mtext)+1;
1.420 + /*
1.421 + * Put the message in the queue
1.422 + */
1.423 + if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) {
1.424 + printf("Message Q send failed with errno %d
1.425 +", errno);
1.426 + }
1.427 + return 0;
1.428 +}
1.429 +
1.430 +@endcode
1.431 +@code
1.432 +#include <sys/types.h>
1.433 +#include <sys/ipc.h>
1.434 +#include <sys/msg.h>
1.435 +#include <stdio.h>
1.436 +#include <string.h>
1.437 +#include <errno.h>
1.438 +
1.439 +#define MESSAGE_Q_KEY 1000
1.440 +
1.441 +int main(void)
1.442 +{
1.443 + int msq_id;
1.444 + int msg_len = 128;
1.445 + int msg_type = 0; /* Any type of message */
1.446 + struct {
1.447 + long mtype;
1.448 + char mtext[128];
1.449 + } msg_buf;
1.450 + /*
1.451 + * Get the message queue id for the given key
1.452 + */
1.453 + if ((msq_id = msgget(MESSAGE_Q_KEY, 0)) == -1) {
1.454 + printf("Message Q get id failed with errno %d
1.455 +", errno);
1.456 + return -1;
1.457 + }
1.458 + /*
1.459 + * Get the message from the queue
1.460 + */
1.461 + if (msgrcv(msq_id, (struct msgbuf *)&msg;_buf, msg_len, msg_type, 0) == -1) {
1.462 + printf("Message Q recv failed with errno %d
1.463 +", errno);
1.464 + }
1.465 + /*
1.466 + * Remove the message queue
1.467 + */
1.468 + if (msgctl(msq_id, IPC_RMID, NULL) == -1) {
1.469 + printf("Message Q delete failed with errno %d
1.470 +", errno);
1.471 + return -1;
1.472 + }
1.473 + return 0;
1.474 +}
1.475 +
1.476 +@endcode
1.477 +
1.478 +Note :The below data members of the structure msqid_ds are internal components.
1.479 +@code
1.480 + struct msg *msg_first
1.481 + struct msg *msg_last;
1.482 + long msg_pad1;
1.483 + long msg_pad2;
1.484 + long msg_pad3;
1.485 + long msg_pad4[4];
1.486 +@endcode
1.487 +and are not filled if msgctl is called with the flag IPC_STAT.
1.488 +
1.489 +@see msgget()
1.490 +@see msgrcv()
1.491 +@see msgsnd()
1.492 +
1.493 +
1.494 +
1.495 +
1.496 +@publishedAll
1.497 +@externallyDefinedApi
1.498 +*/
1.499 +
1.500 +
1.501 +/** @struct msqid_ds
1.502 +
1.503 +The msqid_ds structure defines a message queue associated with a message queue ID. There is one queue per message queue ID.
1.504 +Collectively, the queues are stored as an array, with message queue IDs serving as an index into the array.
1.505 +Contains the following members,
1.506 +
1.507 +@publishedAll
1.508 +@externallyDefinedApi
1.509 +*/
1.510 +
1.511 +/** @var msqid_ds::msg_perm
1.512 +msg queue permission bits
1.513 +*/
1.514 +
1.515 +/** @var msqid_ds::msg_first
1.516 +first message in the queue
1.517 +@internalComponent
1.518 +*/
1.519 +
1.520 +/** @var msqid_ds::msg_last
1.521 +last message in the queue
1.522 +@internalComponent
1.523 +*/
1.524 +
1.525 +/** @var msqid_ds::msg_cbytes
1.526 +number of bytes in use on the queue
1.527 +*/
1.528 +
1.529 +/** @var msqid_ds::msg_qnum
1.530 +number of msgs in the queue
1.531 +*/
1.532 +
1.533 +/** @var msqid_ds::msg_qbytes
1.534 +max n of bytes on the queue
1.535 +*/
1.536 +
1.537 +/** @var msqid_ds::msg_lspid
1.538 +pid of last msgsnd()
1.539 +*/
1.540 +
1.541 +/** @var msqid_ds::msg_lrpid
1.542 +pid of last msgrcv()
1.543 +*/
1.544 +
1.545 +/** @var msqid_ds::msg_stime
1.546 +time of last msgsnd()
1.547 +*/
1.548 +
1.549 +/** @var msqid_ds::msg_pad1
1.550 +time of last msgsnd()
1.551 +@internalComponent
1.552 +*/
1.553 +
1.554 +/** @var msqid_ds::msg_rtime
1.555 +time of last msgrcv()
1.556 +*/
1.557 +
1.558 +/** @var msqid_ds::msg_pad2
1.559 +time of last msgrcv()
1.560 +@internalComponent
1.561 +*/
1.562 +
1.563 +/** @var msqid_ds::msg_ctime
1.564 +time of last msgctl()
1.565 +*/
1.566 +
1.567 +/** @var msqid_ds::msg_pad3
1.568 +time of last msgctl()
1.569 +@internalComponent
1.570 +*/
1.571 +
1.572 +/** @var msqid_ds::msg_pad4
1.573 +time of last msgctl()
1.574 +@internalComponent
1.575 +*/
1.576 +
1.577 +
1.578 +
1.579 +/** @def MSG_NOERROR
1.580 +
1.581 +The MSG_NOERROR identifier value, the msqid_ds struct and the msg struct are as defined by the SV API Intel 386 Processor Supplement.
1.582 +don't complain about too long msgs.
1.583 +
1.584 +@publishedAll
1.585 +@externallyDefinedApi
1.586 +*/
1.587 +
1.588 +
1.589 +
1.590 +
1.591 +