pending rewrite
This commit is contained in:
parent
23dc0f0aa9
commit
fefd301279
@ -1,5 +1,4 @@
|
|||||||
#include "communication.h"
|
#include "communication.h"
|
||||||
#include "usocket.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ int ipc_server_init (int argc, char **argv, char **env
|
|||||||
, struct ipc_service *srv, const char *sname)
|
, struct ipc_service *srv, const char *sname)
|
||||||
{
|
{
|
||||||
if (srv == NULL)
|
if (srv == NULL)
|
||||||
return ER_PARAMS;
|
return IPC_ERROR_WRONG_PARAMETERS;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// use the argc, argv and env parameters
|
// use the argc, argv and env parameters
|
||||||
@ -34,7 +33,13 @@ int ipc_server_init (int argc, char **argv, char **env
|
|||||||
// gets the service path
|
// gets the service path
|
||||||
service_path (srv->spath, sname, srv->index, srv->version);
|
service_path (srv->spath, sname, srv->index, srv->version);
|
||||||
|
|
||||||
return usock_init (&srv->service_fd, srv->spath);
|
int ret = usock_init (&srv->service_fd, srv->spath);
|
||||||
|
if (ret < 0) {
|
||||||
|
handle_err ("ipc_server_init", "usock_init ret < 0");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipc_server_accept (struct ipc_service *srv, struct ipc_client *p)
|
int ipc_server_accept (struct ipc_service *srv, struct ipc_client *p)
|
||||||
@ -42,8 +47,13 @@ int ipc_server_accept (struct ipc_service *srv, struct ipc_client *p)
|
|||||||
assert (srv != NULL);
|
assert (srv != NULL);
|
||||||
assert (p != NULL);
|
assert (p != NULL);
|
||||||
|
|
||||||
usock_accept (srv->service_fd, &p->proc_fd);
|
int ret = usock_accept (srv->service_fd, &p->proc_fd);
|
||||||
|
if (ret < 0) {
|
||||||
|
handle_err ("ipc_server_accept", "usock_accept < 0");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
struct ipc_message m_con;
|
struct ipc_message m_con;
|
||||||
memset (&m_con, 0, sizeof (struct ipc_message));
|
memset (&m_con, 0, sizeof (struct ipc_message));
|
||||||
ipc_server_read (p, &m_con);
|
ipc_server_read (p, &m_con);
|
||||||
@ -55,6 +65,7 @@ int ipc_server_accept (struct ipc_service *srv, struct ipc_client *p)
|
|||||||
ipc_message_format_ack (&m_ack, NULL, 0);
|
ipc_message_format_ack (&m_ack, NULL, 0);
|
||||||
ipc_server_write (p, &m_ack);
|
ipc_server_write (p, &m_ack);
|
||||||
ipc_message_free (&m_ack);
|
ipc_message_free (&m_ack);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -106,8 +117,13 @@ int ipc_application_connection (int argc, char **argv, char **env
|
|||||||
// gets the service path
|
// gets the service path
|
||||||
service_path (srv->spath, sname, srv->index, srv->version);
|
service_path (srv->spath, sname, srv->index, srv->version);
|
||||||
|
|
||||||
usock_connect (&srv->service_fd, srv->spath);
|
int ret = usock_connect (&srv->service_fd, srv->spath);
|
||||||
|
if (ret < 0) {
|
||||||
|
handle_err ("ipc_application_connection", "usock_connect ret <= 0");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// send connection string and receive acknowledgement
|
// send connection string and receive acknowledgement
|
||||||
struct ipc_message m_con;
|
struct ipc_message m_con;
|
||||||
memset (&m_con, 0, sizeof (struct ipc_message));
|
memset (&m_con, 0, sizeof (struct ipc_message));
|
||||||
@ -130,10 +146,12 @@ int ipc_application_connection (int argc, char **argv, char **env
|
|||||||
assert (m_ack.type == MSG_TYPE_ACK);
|
assert (m_ack.type == MSG_TYPE_ACK);
|
||||||
assert (m_ack.length == 0);
|
assert (m_ack.length == 0);
|
||||||
ipc_message_free (&m_ack);
|
ipc_message_free (&m_ack);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// send a CLOSE message then close the socket
|
// send a CLOSE message then close the socket
|
||||||
int ipc_application_close (struct ipc_service *srv)
|
int ipc_application_close (struct ipc_service *srv)
|
||||||
{
|
{
|
||||||
@ -146,6 +164,7 @@ int ipc_application_close (struct ipc_service *srv)
|
|||||||
|
|
||||||
return usock_close (srv->service_fd);
|
return usock_close (srv->service_fd);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int ipc_application_read (struct ipc_service *srv, struct ipc_message *m)
|
int ipc_application_read (struct ipc_service *srv, struct ipc_message *m)
|
||||||
{
|
{
|
||||||
|
@ -11,26 +11,10 @@
|
|||||||
|
|
||||||
#define COMMUNICATION_VERSION 1
|
#define COMMUNICATION_VERSION 1
|
||||||
|
|
||||||
#define ER_MEM_ALLOC 100
|
#define IPC_WITH_UNIX_SOCKETS
|
||||||
#define ER_PARAMS 101
|
#ifdef IPC_WITH_UNIX_SOCKETS
|
||||||
|
#include "usocket.h"
|
||||||
#define TMPDIR "/run/ipc/"
|
#endif
|
||||||
|
|
||||||
#define PATH_MAX 4096
|
|
||||||
|
|
||||||
#define IPC_MESSAGE_CONNECTION 0
|
|
||||||
#define IPC_MESSAGE_DATA 1
|
|
||||||
#define IPC_MESSAGE_DATA_AND_CONNECTION 2
|
|
||||||
#define IPC_MESSAGE_SERVICE_STOP 3
|
|
||||||
|
|
||||||
struct ipc_service {
|
|
||||||
unsigned int version;
|
|
||||||
unsigned int index;
|
|
||||||
char spath[PATH_MAX];
|
|
||||||
int service_fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// SERVICE
|
// SERVICE
|
||||||
|
|
||||||
// srv->version and srv->index must be already set
|
// srv->version and srv->index must be already set
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
|
#define IPC_ERROR_NOT_ENOUGH_MEMORY 100
|
||||||
|
#define IPC_ERROR_WRONG_PARAMETERS 101
|
||||||
|
|
||||||
#define handle_error(msg) \
|
#define handle_error(msg) \
|
||||||
do { log_error (msg); exit(EXIT_FAILURE); } while (0)
|
do { log_error (msg); exit(EXIT_FAILURE); } while (0)
|
||||||
|
|
||||||
|
47
core/msg.c
47
core/msg.c
@ -73,6 +73,7 @@ int ipc_message_format_write (const struct ipc_message *m, char **buf, size_t *m
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1 on a recipient socket close
|
||||||
int ipc_message_read (int fd, struct ipc_message *m)
|
int ipc_message_read (int fd, struct ipc_message *m)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
@ -82,9 +83,15 @@ int ipc_message_read (int fd, struct ipc_message *m)
|
|||||||
|
|
||||||
int ret = usock_recv (fd, &buf, &msize);
|
int ret = usock_recv (fd, &buf, &msize);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
// on error, buffer already freed
|
||||||
handle_err ("msg_read", "usock_recv");
|
handle_err ("msg_read", "usock_recv");
|
||||||
return ret;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// closed recipient, buffer already freed
|
||||||
|
if (ret == 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ipc_message_format_read (m, buf, msize) < 0) {
|
if (ipc_message_format_read (m, buf, msize) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -99,15 +106,26 @@ int ipc_message_write (int fd, const struct ipc_message *m)
|
|||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t msize = 0;
|
ssize_t msize = 0;
|
||||||
ipc_message_format_write (m, &buf, &msize);
|
ipc_message_format_write (m, &buf, &msize);
|
||||||
|
|
||||||
int ret = usock_send (fd, buf, msize);
|
ssize_t nbytes_sent = 0;
|
||||||
|
int ret = usock_send (fd, buf, msize, &nbytes_sent);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
handle_err ("msg_write", "usock_send");
|
if (buf != NULL)
|
||||||
return ret;
|
free (buf);
|
||||||
|
handle_err ("msg_write", "usock_send ret < 0");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
if (buf != NULL)
|
if (buf != NULL)
|
||||||
free (buf);
|
free (buf);
|
||||||
|
|
||||||
@ -134,8 +152,11 @@ int ipc_message_format (struct ipc_message *m, char type, const char *payload, s
|
|||||||
if (m->payload != NULL) {
|
if (m->payload != NULL) {
|
||||||
free (m->payload);
|
free (m->payload);
|
||||||
}
|
}
|
||||||
// FIXME: test malloc
|
|
||||||
m->payload = malloc (length);
|
m->payload = malloc (length);
|
||||||
|
if (m->payload == NULL) {
|
||||||
|
return IPC_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
memset (m->payload, 0, length);
|
memset (m->payload, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,27 +166,29 @@ int ipc_message_format (struct ipc_message *m, char type, const char *payload, s
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipc_message_format_con (struct ipc_message *m, const char *payload, size_t length)
|
|
||||||
{
|
|
||||||
return ipc_message_format (m, MSG_TYPE_CON, payload, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ipc_message_format_data (struct ipc_message *m, const char *payload, size_t length)
|
int ipc_message_format_data (struct ipc_message *m, const char *payload, size_t length)
|
||||||
{
|
{
|
||||||
return ipc_message_format (m, MSG_TYPE_DATA, payload, length);
|
return ipc_message_format (m, MSG_TYPE_DATA, payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
int ipc_message_format_con (struct ipc_message *m, const char *payload, size_t length)
|
||||||
|
{
|
||||||
|
return ipc_message_format (m, MSG_TYPE_CON, payload, length);
|
||||||
|
}
|
||||||
int ipc_message_format_ack (struct ipc_message *m, const char *payload, size_t length)
|
int ipc_message_format_ack (struct ipc_message *m, const char *payload, size_t length)
|
||||||
{
|
{
|
||||||
return ipc_message_format (m, MSG_TYPE_ACK, payload, length);
|
return ipc_message_format (m, MSG_TYPE_ACK, payload, length);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int ipc_message_format_server_close (struct ipc_message *m)
|
int ipc_message_format_server_close (struct ipc_message *m)
|
||||||
{
|
{
|
||||||
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, NULL, 0);
|
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipc_message_free (struct ipc_message *m)
|
int ipc_message_empty (struct ipc_message *m)
|
||||||
{
|
{
|
||||||
assert (m != NULL);
|
assert (m != NULL);
|
||||||
|
|
||||||
|
20
core/msg.h
20
core/msg.h
@ -5,12 +5,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define MSG_TYPE_CLOSE 0
|
// FIXME, removed messages types: MSG_TYPE_CON, MSG_TYPE_CLOSE, MSG_TYPE_ACK
|
||||||
#define MSG_TYPE_CON 1
|
// this implies an underlying communication that is always correctly handled by the system
|
||||||
#define MSG_TYPE_ERR 2
|
// (currently: unix sockets)
|
||||||
#define MSG_TYPE_ACK 3
|
|
||||||
#define MSG_TYPE_DATA 4
|
#define MSG_TYPE_SERVER_CLOSE 0
|
||||||
#define MSG_TYPE_SERVER_CLOSE 5
|
#define MSG_TYPE_ERR 1
|
||||||
|
#define MSG_TYPE_DATA 2
|
||||||
|
|
||||||
struct ipc_message {
|
struct ipc_message {
|
||||||
char type;
|
char type;
|
||||||
@ -24,16 +25,17 @@ int ipc_message_format_read (struct ipc_message *m, const char *buf, size_t msiz
|
|||||||
int ipc_message_format_write (const struct ipc_message *m, char **buf, size_t *msize);
|
int ipc_message_format_write (const struct ipc_message *m, char **buf, size_t *msize);
|
||||||
|
|
||||||
// read a structure msg from fd
|
// read a structure msg from fd
|
||||||
|
// 1 on a recipient socket close
|
||||||
int ipc_message_read (int fd, struct ipc_message *m);
|
int ipc_message_read (int fd, struct ipc_message *m);
|
||||||
// write a structure msg to fd
|
// write a structure msg to fd
|
||||||
int ipc_message_write (int fd, const struct ipc_message *m);
|
int ipc_message_write (int fd, const struct ipc_message *m);
|
||||||
|
|
||||||
int ipc_message_format_con (struct ipc_message *m, const char *payload, size_t length);
|
// int ipc_message_format_con (struct ipc_message *m, const char *payload, size_t length);
|
||||||
int ipc_message_format_data (struct ipc_message *m, const char *payload, size_t length);
|
int ipc_message_format_data (struct ipc_message *m, const char *payload, size_t length);
|
||||||
int ipc_message_format_ack (struct ipc_message *m, const char *payload, size_t length);
|
// int ipc_message_format_ack (struct ipc_message *m, const char *payload, size_t length);
|
||||||
int ipc_message_format_server_close (struct ipc_message *m);
|
int ipc_message_format_server_close (struct ipc_message *m);
|
||||||
|
|
||||||
int ipc_message_free (struct ipc_message *m);
|
int ipc_message_empty (struct ipc_message *m);
|
||||||
void ipc_message_print (const struct ipc_message *m);
|
void ipc_message_print (const struct ipc_message *m);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
138
core/usocket.c
138
core/usocket.c
@ -8,54 +8,119 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
int usock_send (const int fd, const char *buf, const int msize)
|
int usock_send (const int fd, const char *buf, ssize_t len, ssize_t *sent)
|
||||||
{
|
{
|
||||||
// print_hexa ("msg send", (unsigned char *)buf, msize);
|
|
||||||
// fflush(stdout);
|
|
||||||
|
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
//printf ("%ld bytes to write\n", msize);
|
//printf ("%ld bytes to write\n", len);
|
||||||
ret = send (fd, buf, msize, 0);
|
ret = send (fd, buf, len, 0);
|
||||||
if (ret <= 0)
|
if (ret <= 0) {
|
||||||
handle_err ("usock_send", "send ret <= 0");
|
handle_err ("usock_send", "send ret <= 0");
|
||||||
return (int) ret;
|
return -1;
|
||||||
|
}
|
||||||
|
*sent = ret;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usock_recv (const int fd, char **buf, size_t *msize)
|
int usock_recv (const int fd, char **buf, ssize_t *len)
|
||||||
{
|
{
|
||||||
assert(buf != NULL);
|
assert(buf != NULL);
|
||||||
assert(msize != NULL);
|
assert(len != NULL);
|
||||||
|
|
||||||
|
ssize_t ret = 0;
|
||||||
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
handle_err ("usock_recv", "buf == NULL");
|
handle_err ("usock_recv", "buf == NULL");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msize == NULL) {
|
if (len == NULL) {
|
||||||
handle_err ("usock_recv", "msize == NULL");
|
handle_err ("usock_recv", "len == NULL");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*buf == NULL) {
|
if (*buf == NULL) {
|
||||||
// do not allocate too much memory
|
// do not allocate too much memory
|
||||||
if (*msize > BUFSIZ)
|
if (*len > BUFSIZ)
|
||||||
handle_err ("usock_recv", "msize > BUFSIZ");
|
handle_err ("usock_recv", "len > BUFSIZ");
|
||||||
if (*msize == 0)
|
if (*len == 0)
|
||||||
*msize = BUFSIZ;
|
*len = BUFSIZ;
|
||||||
*buf = malloc ((*msize < BUFSIZ) ? *msize : BUFSIZ);
|
*buf = malloc ((*len < BUFSIZ) ? *len : BUFSIZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = 0;
|
ret = recv (fd, *buf, *len, 0);
|
||||||
ret = recv (fd, *buf, *msize, 0);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
if (*buf != NULL)
|
||||||
|
free (*buf);
|
||||||
|
|
||||||
handle_err ("usock_recv", "recv ret < 0");
|
handle_err ("usock_recv", "recv ret < 0");
|
||||||
*msize = 0;
|
perror("recv");
|
||||||
return ret;
|
*len = 0;
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
|
||||||
|
// The receive buffer pointer(s) point outside the process's address space.
|
||||||
|
case EFAULT:
|
||||||
|
handle_err ("usock_recv", "critical error: use of unallocated memory, quitting...");
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
// Invalid argument passed.
|
||||||
|
case EINVAL:
|
||||||
|
handle_err ("usock_recv", "critical error: invalid arguments to read(2), quitting...");
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
// Could not allocate memory for recvmsg().
|
||||||
|
case ENOMEM:
|
||||||
|
handle_err ("usock_recv", "critical error: cannot allocate memory, quitting...");
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
// The argument sockfd is an invalid descriptor.
|
||||||
|
case EBADF:
|
||||||
|
handle_err ("usock_recv", "critical error: invalid descriptor, quitting...");
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
// The file descriptor sockfd does not refer to a socket.
|
||||||
|
case ENOTSOCK:
|
||||||
|
handle_err ("usock_recv", "critical error: fd is not a socket, quitting...");
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
// The socket is associated with a connection-oriented protocol and has not
|
||||||
|
// been connected (see connect(2) and accept(2)).
|
||||||
|
case ENOTCONN:
|
||||||
|
handle_err ("usock_recv", "critical error: read(2) on a non connected socket, quitting...");
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
// EWOULDBLOCK
|
||||||
|
case EAGAIN:
|
||||||
|
|
||||||
|
// A remote host refused to allow the network connection
|
||||||
|
// (typically because it is not running the requested service).
|
||||||
|
case ECONNREFUSED:
|
||||||
|
|
||||||
|
// The receive was interrupted by delivery of a signal before
|
||||||
|
// any data were available; see signal(7).
|
||||||
|
case EINTR:
|
||||||
|
|
||||||
|
default:
|
||||||
|
handle_err ("usock_recv", "unsupported error");
|
||||||
|
;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
*msize = (size_t) ret;
|
|
||||||
// print_hexa ("msg recv", (unsigned char *)*buf, *msize);
|
*len = ret;
|
||||||
|
|
||||||
|
// 1 on none byte received, indicates a closed recipient
|
||||||
|
if (ret == 0) {
|
||||||
|
if (*buf != NULL) {
|
||||||
|
free (*buf);
|
||||||
|
*buf = NULL;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print_hexa ("msg recv", (unsigned char *)*buf, *len);
|
||||||
// fflush(stdout);
|
// fflush(stdout);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usock_connect (int *fd, const char *path)
|
int usock_connect (int *fd, const char *path)
|
||||||
@ -87,12 +152,12 @@ int usock_connect (int *fd, const char *path)
|
|||||||
memset(&my_addr, 0, sizeof(struct sockaddr_un));
|
memset(&my_addr, 0, sizeof(struct sockaddr_un));
|
||||||
|
|
||||||
my_addr.sun_family = AF_UNIX;
|
my_addr.sun_family = AF_UNIX;
|
||||||
strncpy(my_addr.sun_path, path, strlen (path));
|
strncpy(my_addr.sun_path, path, (strlen (path) < PATH_MAX) ? strlen(path) : PATH_MAX);
|
||||||
|
|
||||||
peer_addr_size = sizeof(struct sockaddr_un);
|
peer_addr_size = sizeof(struct sockaddr_un);
|
||||||
if(connect(sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
if(connect(sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
||||||
handle_err ("usock_connect", "connect == -1");
|
handle_err ("usock_connect", "connect == -1");
|
||||||
perror("connect()");
|
perror("connect");
|
||||||
exit(errno);
|
exit(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,13 +204,13 @@ int usock_init (int *fd, const char *path)
|
|||||||
|
|
||||||
if (bind (sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
if (bind (sfd, (struct sockaddr *) &my_addr, peer_addr_size) == -1) {
|
||||||
handle_err ("usock_init", "bind == -1");
|
handle_err ("usock_init", "bind == -1");
|
||||||
perror("bind()");
|
perror("bind");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen (sfd, LISTEN_BACKLOG) == -1) {
|
if (listen (sfd, LISTEN_BACKLOG) == -1) {
|
||||||
handle_err ("usock_init", "listen == -1");
|
handle_err ("usock_init", "listen == -1");
|
||||||
perror("listen()");
|
perror("listen");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +235,7 @@ int usock_accept (int fd, int *pfd)
|
|||||||
*pfd = accept (fd, (struct sockaddr *) &peer_addr, &peer_addr_size);
|
*pfd = accept (fd, (struct sockaddr *) &peer_addr, &peer_addr_size);
|
||||||
if (*pfd < 0) {
|
if (*pfd < 0) {
|
||||||
handle_err ("usock_accept", "accept < 0");
|
handle_err ("usock_accept", "accept < 0");
|
||||||
perror("listen()");
|
perror("listen");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,13 +244,22 @@ int usock_accept (int fd, int *pfd)
|
|||||||
|
|
||||||
int usock_close (int fd)
|
int usock_close (int fd)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
ret = close (fd);
|
|
||||||
|
ret = fsync (fd);
|
||||||
|
if (ret < 0) {
|
||||||
|
handle_err ("usock_close", "fsync ret < 0");
|
||||||
|
perror ("closing");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = close (fd);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
handle_err ("usock_close", "close ret < 0");
|
handle_err ("usock_close", "close ret < 0");
|
||||||
perror ("closing");
|
perror ("closing");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usock_remove (const char *path)
|
int usock_remove (const char *path)
|
||||||
|
@ -7,28 +7,42 @@
|
|||||||
|
|
||||||
#define LISTEN_BACKLOG 128
|
#define LISTEN_BACKLOG 128
|
||||||
|
|
||||||
// same as recv(2)
|
#define TMPDIR "/run/ipc/"
|
||||||
int usock_send (int fd, const char *buf, const int m_size);
|
#define PATH_MAX 4096
|
||||||
|
|
||||||
// same as send(2)
|
struct ipc_service {
|
||||||
// if msize == NULL => -1
|
unsigned int version;
|
||||||
// if buf == NULL => -1
|
unsigned int index;
|
||||||
// if *buf == NULL => allocation of *msize bytes
|
char spath[PATH_MAX];
|
||||||
int usock_recv (int fd, char **buf, size_t *msize);
|
int service_fd;
|
||||||
|
};
|
||||||
|
|
||||||
// same as close(2)
|
/**
|
||||||
|
* for all functions: 0 ok, < 0 not ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
// input: len = max buf size
|
||||||
|
// output: *sent = nb received bytes
|
||||||
|
int usock_send (const int fd, const char *buf, ssize_t len, ssize_t *sent);
|
||||||
|
|
||||||
|
// -1 on msize == NULL or buf == NULL
|
||||||
|
// -1 on unsupported errors from read(2)
|
||||||
|
// exit on most errors from read(2)
|
||||||
|
//
|
||||||
|
// allocation of *len bytes on *buf == NULL
|
||||||
|
//
|
||||||
|
// output: *len = nb sent bytes
|
||||||
|
int usock_recv (int fd, char **buf, ssize_t *len);
|
||||||
|
|
||||||
|
// -1 on close(2) < 0
|
||||||
int usock_close (int fd);
|
int usock_close (int fd);
|
||||||
|
|
||||||
// same as connect(2)
|
// same as connect(2)
|
||||||
// if fd == NULL => -1
|
// -1 on fd == NULL
|
||||||
int usock_connect (int *fd, const char *path);
|
int usock_connect (int *fd, const char *path);
|
||||||
|
|
||||||
// if not ok => -1
|
|
||||||
// if ok => 0
|
|
||||||
int usock_init (int *fd, const char *path);
|
int usock_init (int *fd, const char *path);
|
||||||
|
|
||||||
// if not ok => -1
|
|
||||||
// if ok => 0
|
|
||||||
int usock_accept (int fd, int *pfd);
|
int usock_accept (int fd, int *pfd);
|
||||||
|
|
||||||
// same as unlink(2)
|
// same as unlink(2)
|
||||||
|
@ -33,17 +33,19 @@ void handle_new_connection (struct ipc_clients *clients)
|
|||||||
|
|
||||||
void handle_new_msg (struct ipc_clients *clients, struct ipc_clients *clients_talking)
|
void handle_new_msg (struct ipc_clients *clients, struct ipc_clients *clients_talking)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
struct ipc_message m;
|
struct ipc_message m;
|
||||||
memset (&m, 0, sizeof (struct ipc_message));
|
memset (&m, 0, sizeof (struct ipc_message));
|
||||||
int i;
|
int i = 0;
|
||||||
for (i = 0; i < clients_talking->size; i++) {
|
for (i = 0; i < clients_talking->size; i++) {
|
||||||
// printf ("loop handle_new_msg\n");
|
// printf ("loop handle_new_msg\n");
|
||||||
if (ipc_server_read (clients_talking->clients[i], &m) < 0) {
|
ret = ipc_server_read (clients_talking->clients[i], &m);
|
||||||
|
if (ret < 0) {
|
||||||
handle_error("server_read < 0");
|
handle_error("server_read < 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
// close the client then delete it from the client array
|
// close the client then delete it from the client array
|
||||||
if (m.type == MSG_TYPE_CLOSE) {
|
if (ret == 1) {
|
||||||
cpt--;
|
cpt--;
|
||||||
printf ("disconnection => %d client(s) remaining\n", cpt);
|
printf ("disconnection => %d client(s) remaining\n", cpt);
|
||||||
|
|
||||||
@ -117,11 +119,12 @@ void main_loop ()
|
|||||||
/*
|
/*
|
||||||
* service ping-pong
|
* service ping-pong
|
||||||
*
|
*
|
||||||
* 1. creates the named pipe /tmp/<service>, then listens
|
* 1. creates the unix socket /run/ipc/<service>.sock, then listens
|
||||||
* 2. opens the named pipes in & out
|
* 2. listen for new clients
|
||||||
* 3. talks with the (test) program
|
* 3. then accept a new client, and send back everything it sends
|
||||||
* 4. closes the test program named pipes
|
* 4. close any client that closes its socket
|
||||||
* 5. removes the named pipe /tmp/<service>
|
*
|
||||||
|
* and finally, stop the program once a client sends a SERVER CLOSE command
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int main(int argc, char * argv[], char **env)
|
int main(int argc, char * argv[], char **env)
|
||||||
|
Reference in New Issue
Block a user