Obsolete
/
libipc-old
Archived
3
0
Fork 0
This repository has been archived on 2024-06-18. You can view files and clone it, but cannot push or open issues/pull-requests.
libipc-old/core/message.c

199 lines
4.2 KiB
C
Raw Normal View History

2018-10-09 13:20:26 +02:00
#include "message.h"
2016-12-21 01:26:47 +01:00
#include "error.h"
#include "usocket.h"
#include <assert.h>
2018-10-03 22:02:37 +02:00
void ipc_message_print (const struct ipc_message *m)
{
assert (m != NULL);
2018-10-10 23:18:15 +02:00
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
2018-10-04 01:54:12 +02:00
printf ("msg: type %d len %d\n", m->type, m->length);
2018-10-10 23:18:15 +02:00
#endif
}
2018-10-08 16:15:35 +02:00
int ipc_message_format_read (struct ipc_message *m, const char *buf, ssize_t msize)
2016-12-21 01:26:47 +01:00
{
assert (m != NULL);
assert (buf != NULL);
assert (msize <= BUFSIZ - 3);
if (m == NULL)
return -1;
m->type = buf[0];
2018-10-04 01:54:12 +02:00
memcpy (&m->length, buf+1, 2);
2016-12-21 01:26:47 +01:00
assert (m->length <= BUFSIZ - 3);
2018-10-10 23:18:15 +02:00
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
printf ("type %d : msize = %ld, length = %d\n", m->type, msize, m->length);
2018-10-10 23:18:15 +02:00
#endif
assert (m->length == msize - 3 || m->length == 0);
2016-12-21 01:26:47 +01:00
2018-10-04 01:54:12 +02:00
if (m->payload != NULL)
free (m->payload), m->payload = NULL;
2016-12-21 01:26:47 +01:00
2018-10-04 01:54:12 +02:00
if (m->payload == NULL && m->length > 0) {
m->payload = malloc (m->length);
memcpy (m->payload, buf+3, m->length);
2016-12-21 01:26:47 +01:00
}
return 0;
}
2018-10-08 16:15:35 +02:00
int ipc_message_format_write (const struct ipc_message *m, char **buf, ssize_t *msize)
2016-12-21 01:26:47 +01:00
{
assert (m != NULL);
assert (buf != NULL);
assert (msize != NULL);
2018-10-04 01:54:12 +02:00
assert (m->length <= BUFSIZ -3);
2016-12-21 01:26:47 +01:00
if (m == NULL)
return -1;
if (buf == NULL)
return -2;
if (msize == NULL)
return -3;
if (*buf == NULL) {
2018-10-04 01:54:12 +02:00
*buf = malloc (3 + m->length);
memset (*buf, 0, 3 + m->length);
}
2016-12-21 01:26:47 +01:00
char *buffer = *buf;
buffer[0] = m->type;
2018-10-04 01:54:12 +02:00
memcpy (buffer + 1, &m->length, 2);
if (m->payload != NULL) {
memcpy (buffer + 3, m->payload, m->length);
}
2018-10-04 01:54:12 +02:00
*msize = 3 + m->length;
2016-12-21 01:26:47 +01:00
2018-10-10 23:18:15 +02:00
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
printf ("sending msg: type %u, size %d, msize %ld\n", m->type, m->length, *msize);
2018-10-10 23:18:15 +02:00
#endif
2016-12-21 01:26:47 +01:00
return 0;
}
2018-10-08 15:18:56 +02:00
// 1 on a recipient socket close
2018-10-03 22:02:37 +02:00
int ipc_message_read (int fd, struct ipc_message *m)
2016-12-21 01:26:47 +01:00
{
assert (m != NULL);
char *buf = NULL;
2018-10-08 16:15:35 +02:00
ssize_t msize = BUFSIZ;
2016-12-21 01:26:47 +01:00
int ret = usock_recv (fd, &buf, &msize);
if (ret < 0) {
2018-10-08 15:18:56 +02:00
// on error, buffer already freed
2016-12-21 01:26:47 +01:00
handle_err ("msg_read", "usock_recv");
2018-10-08 15:18:56 +02:00
return -1;
2016-12-21 01:26:47 +01:00
}
2018-10-08 15:18:56 +02:00
// closed recipient, buffer already freed
if (ret == 1) {
return 1;
}
2016-12-21 01:26:47 +01:00
2018-10-03 21:52:11 +02:00
if (ipc_message_format_read (m, buf, msize) < 0) {
2016-12-21 01:26:47 +01:00
return -1;
}
free (buf);
return 0;
}
2018-10-03 22:02:37 +02:00
int ipc_message_write (int fd, const struct ipc_message *m)
2016-12-21 01:26:47 +01:00
{
assert (m != NULL);
char *buf = NULL;
2018-10-08 15:18:56 +02:00
ssize_t msize = 0;
2018-10-03 21:52:11 +02:00
ipc_message_format_write (m, &buf, &msize);
2016-12-21 01:26:47 +01:00
2018-10-08 15:18:56 +02:00
ssize_t nbytes_sent = 0;
int ret = usock_send (fd, buf, msize, &nbytes_sent);
2016-12-21 01:26:47 +01:00
if (ret < 0) {
2018-10-08 15:18:56 +02:00
if (buf != NULL)
free (buf);
handle_err ("msg_write", "usock_send ret < 0");
return -1;
2016-12-21 01:26:47 +01:00
}
2018-10-08 15:18:56 +02:00
// what was sent != what should have been sent
if (nbytes_sent != msize) {
if (buf != NULL)
free (buf);
handle_err ("msg_write", "usock_send did not send enough data");
return -1;
}
2016-12-21 01:26:47 +01:00
if (buf != NULL)
free (buf);
return 0;
}
// MSG FORMAT
2018-10-08 16:15:35 +02:00
int ipc_message_format (struct ipc_message *m, char type, const char *payload, ssize_t length)
2016-12-21 01:26:47 +01:00
{
assert (m != NULL);
2018-10-04 01:54:12 +02:00
assert (length + 3 <= BUFSIZ);
assert ((length == 0 && payload == NULL) || (length > 0 && payload != NULL));
2016-12-21 01:26:47 +01:00
2018-10-04 01:54:12 +02:00
if (length + 3 > BUFSIZ) {
2016-12-21 01:26:47 +01:00
handle_err ("msg_format_con", "msgsize > BUFSIZ");
return -1;
}
m->type = type;
2018-10-04 01:54:12 +02:00
m->length = (short) length;
if (payload != NULL) {
if (m->payload != NULL) {
free (m->payload);
}
2018-10-08 15:18:56 +02:00
2018-10-04 01:54:12 +02:00
m->payload = malloc (length);
2018-10-08 15:18:56 +02:00
if (m->payload == NULL) {
return IPC_ERROR_NOT_ENOUGH_MEMORY;
}
memset (m->payload, 0, length);
}
if (payload != NULL) {
memcpy (m->payload, payload, length);
}
2016-12-21 01:26:47 +01:00
return 0;
}
2018-10-08 16:15:35 +02:00
int ipc_message_format_data (struct ipc_message *m, const char *payload, ssize_t length)
2016-12-21 01:26:47 +01:00
{
2018-10-04 01:54:12 +02:00
return ipc_message_format (m, MSG_TYPE_DATA, payload, length);
2016-12-21 01:26:47 +01:00
}
int ipc_message_format_server_close (struct ipc_message *m)
{
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, NULL, 0);
}
2018-10-08 15:18:56 +02:00
int ipc_message_empty (struct ipc_message *m)
2016-12-21 01:26:47 +01:00
{
assert (m != NULL);
if (m == NULL)
return -1;
2018-10-04 01:54:12 +02:00
if (m->payload != NULL)
free (m->payload), m->payload = NULL;
2018-10-04 01:54:12 +02:00
m->length = 0;
2016-12-21 01:26:47 +01:00
return 0;
}