libcfe  0.12.1
some useful C-functions
msgqueue.c
Go to the documentation of this file.
1 #include "config.h"
2 #include "msgqueue.h"
3 
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/ipc.h>
10 #include <sys/msg.h>
11 #include <libintl.h>
12 
13 #include "len.h"
14 #include "output.h"
15 
16 #define MSGMAX 8192
17 
18 typedef struct
19 {
20  long mtype;
21  char mtext[MSGMAX];
22 } mymsgbuf_t;
23 
24 int send_message(int qid, int type, char *msg, int len, short flag)
25 {
26  int res, n = 0;
27  mymsgbuf_t mqbuf;
28  struct msqid_ds mqinfo;
29  short f;
30 
31  mqbuf.mtype = type;
32 
33  if(len == 0)
34  len = str_len(msg);
35 
36  for(n = 0; n < len; n++)
37  mqbuf.mtext[n] = msg[n]; // Copy 'len' characters from 'msg' to message struct
38 
39  while(n < MSGMAX)
40  mqbuf.mtext[n++] = '\0'; // Fill with '\0' 's
41 
42  if((flag & MSG_PRIORITY) == MSG_PRIORITY)
43  f = 100;
44  else
45  f = 90;
46 
47  if((flag & MSG_NOBLOCK) != MSG_NOBLOCK)
48  {
49  /* check if there is enough space in the message queue */
50  while(((res = msgctl(qid, IPC_STAT, &mqinfo)) == 0) && ((mqinfo.__msg_cbytes + len + 1) > (mqinfo.msg_qbytes * f / 100)))
51  sleep(5); // Message queue is full, wait 5 seconds and try again
52  if(res != 0)
53  {
54  error(_("error in message control: %s"), strerror(errno));
55  return -4;
56  }
57  }
58  else
59  {
60  res = msgctl(qid, IPC_STAT, &mqinfo);
61  if(res != 0)
62  {
63  error(_("error in message control: %s"), strerror(errno));
64  return -4;
65  }
66  /* check if there is enough space in the message queue */
67  if((mqinfo.__msg_cbytes + len + 1) > (mqinfo.msg_qbytes * f / 100))
68  {
69  errno = EAGAIN;
70  return -3;
71  }
72  }
73 
74  /* send the message */
75  if((res = msgsnd(qid, &mqbuf, len + 1, ((flag & MSG_NOBLOCK) == MSG_NOBLOCK) ? IPC_NOWAIT : 0)) == -1)
76  {
77  if(errno == EAGAIN)
78  return -3;
79  error(_("cannot put message in queue: %s"), strerror(errno));
80  return -4;
81  }
82 
83  return 0;
84 }
85 
86 int receive_message(int qid, int type, char **msg)
87 {
88  int res = 0, n = 0;
89  char *ptr = NULL;
90  mymsgbuf_t mqbuf;
91 
92  if((res = msgrcv(qid, &mqbuf, MSGMAX, type, 0)) == -1)
93  {
94  error(_("cannot receive message: %s"), strerror(errno));
95  return -1;
96  }
97 
98  ptr = *msg = (char *)malloc(res);
99 
100  while(n < res)
101  *ptr++ = mqbuf.mtext[n++];
102 
103  return res;
104 }
105 
106 int remove_queue(int qid)
107 {
108  if(msgctl(qid, IPC_RMID, 0) == -1)
109  {
110  error(_("error in message control: %s"), strerror(errno));
111  return -1;
112  }
113  return 0;
114 }
115 
116 int create_queue(void)
117 {
118  return msgget(IPC_PRIVATE, 0660);
119 }
int send_message(int qid, int type, char *msg, int len, short flag)
Definition: msgqueue.c:24
#define str_len(s)
Shorthand for counting &#39;\0&#39; terminating strings. See _len for more info.
Definition: len.h:17
#define _(string)
Definition: output.h:43
#define MSGMAX
Definition: msgqueue.c:16
#define error(...)
Definition: output.h:30
#define MSG_NOBLOCK
TODO.
Definition: msgqueue.h:6
long mtype
Definition: msgqueue.c:20
int create_queue(void)
Definition: msgqueue.c:116
#define f
char mtext[MSGMAX]
Definition: msgqueue.c:21
int remove_queue(int qid)
Definition: msgqueue.c:106
#define MSG_PRIORITY
Indicates a message as important.
Definition: msgqueue.h:5
int receive_message(int qid, int type, char **msg)
Definition: msgqueue.c:86