Compiles, not tested and no write buffer.
parent
89d8881a40
commit
0cd6f5bebd
|
@ -239,7 +239,7 @@ struct ipc_error ipc_accept_add (struct ipc_event *event, struct ipc_ctx *ctx, u
|
||||||
|
|
||||||
// Set the event structure.
|
// Set the event structure.
|
||||||
uint32_t client_index = ctx->size - 1;
|
uint32_t client_index = ctx->size - 1;
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_CONNECTION, NULL, client_index, *client_fd);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_CONNECTION, client_index, *client_fd, NULL);
|
||||||
|
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -341,15 +341,17 @@ struct ipc_error ipc_del (struct ipc_ctx *ctx, uint32_t index)
|
||||||
|
|
||||||
void ipc_connections_free (struct ipc_ctx *ctx)
|
void ipc_connections_free (struct ipc_ctx *ctx)
|
||||||
{
|
{
|
||||||
// The close and close_all functions perform deep removal of structures.
|
|
||||||
ipc_close_all (ctx);
|
|
||||||
|
|
||||||
if (ctx->cinfos != NULL) {
|
if (ctx->cinfos != NULL) {
|
||||||
free (ctx->cinfos);
|
free (ctx->cinfos);
|
||||||
free (ctx->pollfd);
|
free (ctx->pollfd);
|
||||||
ctx->cinfos = NULL;
|
ctx->cinfos = NULL;
|
||||||
ctx->pollfd = NULL;
|
ctx->pollfd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->switchdb.collection != NULL) {
|
||||||
|
free (ctx->switchdb.collection);
|
||||||
|
ctx->switchdb.collection = NULL;
|
||||||
|
}
|
||||||
ctx->size = 0;
|
ctx->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,39 +385,51 @@ struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd)
|
||||||
IPC_RETURN_ERROR (IPC_ERROR_DEL_FD__CANNOT_FIND_CLIENT);
|
IPC_RETURN_ERROR (IPC_ERROR_DEL_FD__CANNOT_FIND_CLIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
// TODO
|
||||||
|
struct ipc_error handle_writing_message (struct ipc_event *event, struct ipc_ctx *ctx, uint32_t index);
|
||||||
|
struct ipc_error handle_writing_message (struct ipc_event *event, struct ipc_ctx *ctx, uint32_t index)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (size_t i = 0; ctx->tx.size ; i++) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_TX, index, ctx->pollfd[index].fd, NULL);
|
||||||
|
IPC_RETURN_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// new message
|
// new message
|
||||||
struct ipc_error handle_message (
|
struct ipc_error handle_new_message (struct ipc_event *event, struct ipc_ctx *ctx, int index)
|
||||||
struct ipc_event *event
|
|
||||||
, struct ipc_ctx *ctx
|
|
||||||
, struct ipc_connection_info *pc, struct ipc_switchings *switchdb)
|
|
||||||
{
|
{
|
||||||
// if the socket is associated to another one for networkd
|
|
||||||
// read and write automatically and provide a new IPC_EVENT_TYPE indicating the switch
|
// If the socket is associated to another one for networkd:
|
||||||
if (switchdb != NULL) {
|
// read and write automatically and provide a new IPC_EVENT_TYPE indicating the switch.
|
||||||
int talkingfd = pc->pollfd.fd;
|
if (ctx->switchdb.collection != NULL) {
|
||||||
int correspondingfd = ipc_switching_get (switchdb, talkingfd);
|
int talkingfd = ctx->pollfd[index].fd;
|
||||||
|
int correspondingfd = ipc_switching_get (&ctx->switchdb, talkingfd);
|
||||||
if (correspondingfd != -1) {
|
if (correspondingfd != -1) {
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t msize = 0;
|
size_t msize = 0;
|
||||||
|
|
||||||
TEST_IPC_T_P_I_R (
|
{ /** Some macros use "ret" as a variable name, so this is to be sure. */
|
||||||
/* function to test */ usock_recv (talkingfd, &buf, &msize)
|
struct ipc_error ret = usock_recv (talkingfd, &buf, &msize);
|
||||||
, /* error condition */ ret.error_code != IPC_ERROR_NONE
|
if (ret.error_code != IPC_ERROR_NONE && ret.error_code != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
&& ret.error_code != IPC_ERROR_CLOSED_RECIPIENT
|
if (buf != NULL)
|
||||||
, /* to do on error */ if (buf != NULL) free (buf);
|
free (buf);
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_ERROR, NULL, pc)
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_ERROR, index, talkingfd, NULL)
|
||||||
, /* return function */ return (ret)) ;
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** TODO: there is a message, send it to the corresponding fd **/
|
/** There is a message, send it to the corresponding fd **/
|
||||||
if (msize > 0) {
|
if (msize > 0) {
|
||||||
size_t nbytes_sent = 0;
|
size_t nbytes_sent = 0;
|
||||||
TEST_IPC_RETURN_ON_ERROR_FREE (usock_send (correspondingfd, buf, msize, &nbytes_sent), buf);
|
TEST_IPC_RETURN_ON_ERROR_FREE (usock_send (correspondingfd, buf, msize, &nbytes_sent), buf);
|
||||||
|
|
||||||
if (nbytes_sent != msize) {
|
if (nbytes_sent != msize) {
|
||||||
// LOG_ERROR ("wrote not enough data from %d to fd %d", talkingfd, correspondingfd);
|
// LOG_ERROR ("wrote not enough data from %d to fd %d", talkingfd, correspondingfd);
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_ERROR, NULL, pc);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_ERROR, index, ctx->pollfd[index].fd, NULL);
|
||||||
IPC_RETURN_NO_ERROR; // FIXME: return something else, maybe?
|
IPC_RETURN_NO_ERROR; // FIXME: return something else, maybe?
|
||||||
}
|
}
|
||||||
// LOG_DEBUG ("received a message on fd %d => switch to fd %d", talkingfd, correspondingfd);
|
// LOG_DEBUG ("received a message on fd %d => switch to fd %d", talkingfd, correspondingfd);
|
||||||
|
@ -423,13 +437,13 @@ struct ipc_error handle_message (
|
||||||
if (buf != NULL)
|
if (buf != NULL)
|
||||||
free (buf);
|
free (buf);
|
||||||
|
|
||||||
// everything is OK: inform networkd of a successful transfer
|
// Everything is OK: inform networkd of a successful transfer.
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_SWITCH, NULL, pc);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_SWITCH, index, ctx->pollfd[index].fd, NULL);
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
} else if (msize == 0) {
|
} else if (msize == 0) {
|
||||||
int delfd;
|
int delfd;
|
||||||
|
|
||||||
delfd = ipc_switching_del (switchdb, talkingfd);
|
delfd = ipc_switching_del (&ctx->switchdb, talkingfd);
|
||||||
if (delfd >= 0) {
|
if (delfd >= 0) {
|
||||||
close (delfd);
|
close (delfd);
|
||||||
ipc_del_fd (ctx, delfd);
|
ipc_del_fd (ctx, delfd);
|
||||||
|
@ -446,16 +460,18 @@ struct ipc_error handle_message (
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, NULL, pc);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, index, ctx->pollfd[index].fd, NULL);
|
||||||
IPC_RETURN_ERROR (IPC_ERROR_CLOSED_RECIPIENT);
|
IPC_RETURN_ERROR (IPC_ERROR_CLOSED_RECIPIENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no treatment of the socket if external socket
|
// no treatment of the socket if external socket
|
||||||
if (pc->type == IPC_CONNECTION_TYPE_EXTERNAL) {
|
if (ctx->cinfos[index].type == IPC_CONNECTION_TYPE_EXTERNAL) {
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_EXTRA_SOCKET, NULL, pc);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_EXTRA_SOCKET, index, ctx->pollfd[index].fd, NULL);
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// listen to what they have to say (disconnection or message)
|
// listen to what they have to say (disconnection or message)
|
||||||
// then add a client to `event`, the ipc_event structure
|
// then add a client to `event`, the ipc_event structure
|
||||||
SECURE_DECLARATION (struct ipc_error, ret);
|
SECURE_DECLARATION (struct ipc_error, ret);
|
||||||
|
@ -464,220 +480,83 @@ struct ipc_error handle_message (
|
||||||
SECURE_BUFFER_HEAP_ALLOCATION_R (m, sizeof (struct ipc_message),, IPC_ERROR_HANDLE_MESSAGE__NOT_ENOUGH_MEMORY);
|
SECURE_BUFFER_HEAP_ALLOCATION_R (m, sizeof (struct ipc_message),, IPC_ERROR_HANDLE_MESSAGE__NOT_ENOUGH_MEMORY);
|
||||||
|
|
||||||
// current talking client
|
// current talking client
|
||||||
ret = ipc_read (pc, m);
|
ret = ipc_read (ctx, index, m);
|
||||||
if (ret.error_code != IPC_ERROR_NONE && ret.error_code != IPC_ERROR_CLOSED_RECIPIENT) {
|
if (ret.error_code != IPC_ERROR_NONE && ret.error_code != IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
struct ipc_error rvalue = ret; // store the final return value
|
struct ipc_error rvalue = ret; // store the final return value
|
||||||
ipc_message_empty (m);
|
ipc_message_empty (m);
|
||||||
free (m);
|
free (m);
|
||||||
|
|
||||||
// if there is a problem, just remove the client
|
// if there is a problem, just remove the client
|
||||||
TEST_IPC_P (ipc_close (pc), "cannot close a connection in handle_message");
|
TEST_IPC_P (ipc_close (ctx, index), "cannot close a connection in handle_message");
|
||||||
TEST_IPC_P (ipc_del (ctx, pc), "cannot delete a connection in handle_message");
|
TEST_IPC_P (ipc_del (ctx, index), "cannot delete a connection in handle_message");
|
||||||
|
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_ERROR, NULL, pc);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_ERROR, index, ctx->pollfd[index].fd, NULL);
|
||||||
return rvalue;
|
return rvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disconnection: close the client then delete it from ctx
|
// disconnection: close the client then delete it from ctx
|
||||||
if (ret.error_code == IPC_ERROR_CLOSED_RECIPIENT) {
|
if (ret.error_code == IPC_ERROR_CLOSED_RECIPIENT) {
|
||||||
TEST_IPC_P (ipc_close (pc), "cannot close a connection on closed recipient in handle_message");
|
TEST_IPC_P (ipc_close (ctx, index), "cannot close a connection on closed recipient in handle_message");
|
||||||
TEST_IPC_P (ipc_del (ctx, pc), "cannot delete a connection on closed recipient in handle_message");
|
TEST_IPC_P (ipc_del (ctx, index), "cannot delete a connection on closed recipient in handle_message");
|
||||||
|
|
||||||
ipc_message_empty (m);
|
ipc_message_empty (m);
|
||||||
free (m);
|
free (m);
|
||||||
|
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, NULL, pc);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, index, ctx->pollfd[index].fd, NULL);
|
||||||
|
|
||||||
// warning: do not forget to free the ipc_client structure
|
// warning: do not forget to free the ipc_client structure
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_MESSAGE, m, pc);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_MESSAGE, index, ctx->pollfd[index].fd, m);
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
/* timer is in ms */
|
||||||
struct ipc_error
|
struct ipc_error ipc_events_loop (struct ipc_ctx *ctx, struct ipc_event *event, int *timer)
|
||||||
handle_writing_message (struct ipc_event *events, struct ipc_ctx *ctx, uint32_t i);
|
|
||||||
struct ipc_error
|
|
||||||
handle_writing_message (struct ipc_event *events, struct ipc_ctx *ctx, uint32_t i)
|
|
||||||
{
|
|
||||||
IPC_RETURN_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ipc_error
|
|
||||||
ipc_events_loop (
|
|
||||||
struct ipc_ctx *ctx
|
|
||||||
, struct ipc_connection_info *cinfo // NULL for clients
|
|
||||||
, struct ipc_event *event
|
|
||||||
, struct ipc_switchings *switchdb
|
|
||||||
, struct ipc_messages *messages_to_send
|
|
||||||
, int *timer /* in ms */)
|
|
||||||
{
|
{
|
||||||
T_R ((ctx == NULL), IPC_ERROR_WAIT_EVENT__NO_CLIENTS_PARAM);
|
T_R ((ctx == NULL), IPC_ERROR_WAIT_EVENT__NO_CLIENTS_PARAM);
|
||||||
T_R ((event == NULL), IPC_ERROR_WAIT_EVENT__NO_EVENT_PARAM);
|
T_R ((event == NULL), IPC_ERROR_WAIT_EVENT__NO_EVENT_PARAM);
|
||||||
|
|
||||||
IPC_EVENT_CLEAN (event);
|
IPC_EVENT_CLEAN (event);
|
||||||
|
|
||||||
int i, n, listenfd, client_fd, nread;
|
int32_t n;
|
||||||
uid_t uid;
|
|
||||||
|
|
||||||
// Generate the array of pollfd structure once, then use it each time.
|
if ((n = poll(ctx->pollfd, ctx->size, *timer)) < 0) {
|
||||||
// TODO: ça ailleurs: if ( (ctx->pollfd = malloc(sizeof(struct pollfd))) == NULL)
|
printf("select error\n");
|
||||||
// TODO: ça ailleurs: err_sys("malloc error");
|
exit(1); // TODO FIXME
|
||||||
// TODO: ça ailleurs: client_add(listenfd, 0); /* we use [0] for listenfd */
|
|
||||||
// TODO: ça ailleurs: ctx->pollfd[0].fd = listenfd;
|
|
||||||
// TODO: ça ailleurs: ctx->pollfd[0].events = POLLIN;
|
|
||||||
|
|
||||||
if ((n = poll(ctx->pollfd, ctx->size, *timer)) < 0)
|
|
||||||
{
|
|
||||||
log_sys("select error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout.
|
// Timeout.
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
// TODO: timeout
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_TIMER, 0, 0, NULL);
|
||||||
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i <= ctx->size; i++) {
|
for (size_t i = 0; i <= ctx->size; i++) {
|
||||||
// Something to read or connection.
|
// Something to read or connection.
|
||||||
if (ctx->pollfd[i].revents & POLLIN)
|
if (ctx->pollfd[i].revents & POLLIN) {
|
||||||
{
|
|
||||||
// In case there is something to read for the server socket: new client.
|
// In case there is something to read for the server socket: new client.
|
||||||
if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_SERVER) {
|
if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_SERVER) {
|
||||||
return ipc_accept_add (event, ctx, i);
|
return ipc_accept_add (event, ctx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle_message (event, ctx, i, switchdb);
|
return handle_new_message (event, ctx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->pollfd[i].revents & POLLOUT)
|
// Something can be sent.
|
||||||
{
|
if (ctx->pollfd[i].revents & POLLOUT) {
|
||||||
return handle_writing_message (event, ctx, i);
|
return handle_writing_message (event, ctx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: in case there is an error that way??
|
|
||||||
//if (ctx->cinfos[i].fd < 0)
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
// Disconnection.
|
// Disconnection.
|
||||||
if (ctx->pollfd[i].revents & POLLHUP)
|
if (ctx->pollfd[i].revents & POLLHUP) {
|
||||||
goto hungup;
|
/** IPC_EVENT_SET: event, type, index, fd, message */
|
||||||
else if (ctx->pollfd[i].revents & POLLIN) {
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, i, ctx->pollfd[i].fd, NULL);
|
||||||
return handle_disconnection (event, ctx, i, switchdb);
|
return ipc_close (ctx, i);
|
||||||
/* read argument buffer from client */
|
|
||||||
if ( (nread = read(client_fd, buf, MAXLINE)) < 0)
|
|
||||||
log_sys("read error on fd %d", client_fd);
|
|
||||||
else if (nread == 0) {
|
|
||||||
hungup:
|
|
||||||
log_msg("closed: uid %d, fd %d", client[i].uid, client_fd);
|
|
||||||
client_del(client_fd); /* client has closed conn */
|
|
||||||
ctx->pollfd[i].fd = -1;
|
|
||||||
close(client_fd);
|
|
||||||
} else /* process client's rquest */
|
|
||||||
request(buf, nread, client_fd, client[i].uid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /** for loop: end of the message handling */
|
} /** for loop: end of the message handling */
|
||||||
|
|
||||||
// from 0 to ctx->size
|
|
||||||
// if something to read
|
|
||||||
// if this is the server
|
|
||||||
// return handle_connection
|
|
||||||
// else
|
|
||||||
// from 0 to ctx->size
|
|
||||||
// if this is the right index in ctx->cinfos
|
|
||||||
// return handle_message (event, ctx, i, switchdb);
|
|
||||||
|
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipc_error ipc_wait_event_networkd (
|
|
||||||
struct ipc_ctx *ctx
|
|
||||||
, struct ipc_connection_info *cinfo // NULL for clients
|
|
||||||
, struct ipc_event *event
|
|
||||||
, struct ipc_switchings *switchdb
|
|
||||||
, int *timer)
|
|
||||||
{
|
|
||||||
T_R ((ctx == NULL), IPC_ERROR_WAIT_EVENT__NO_CLIENTS_PARAM);
|
|
||||||
T_R ((event == NULL), IPC_ERROR_WAIT_EVENT__NO_EVENT_PARAM);
|
|
||||||
|
|
||||||
IPC_EVENT_CLEAN (event);
|
|
||||||
|
|
||||||
size_t i, j;
|
|
||||||
/* master file descriptor list */
|
|
||||||
fd_set master;
|
|
||||||
fd_set readf;
|
|
||||||
|
|
||||||
/* clear the master and temp sets */
|
|
||||||
FD_ZERO (&master);
|
|
||||||
FD_ZERO (&readf);
|
|
||||||
|
|
||||||
/* maximum file descriptor number */
|
|
||||||
/* keep track of the biggest file descriptor */
|
|
||||||
int32_t fdmax = get_max_fd (ctx);
|
|
||||||
|
|
||||||
/* listening socket descriptor */
|
|
||||||
int32_t listener;
|
|
||||||
if (cinfo != NULL) {
|
|
||||||
listener = cinfo->pollfd.fd;
|
|
||||||
|
|
||||||
/* add the listener to the master set */
|
|
||||||
FD_SET (listener, &master);
|
|
||||||
|
|
||||||
/* if listener is max fd */
|
|
||||||
if (fdmax < listener)
|
|
||||||
fdmax = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ctx->size; i++) {
|
|
||||||
FD_SET (ctx->cinfos[i]->pollfd.fd, &master);
|
|
||||||
}
|
|
||||||
|
|
||||||
readf = master;
|
|
||||||
|
|
||||||
struct timeval *ptimeout = NULL;
|
|
||||||
SECURE_DECLARATION (struct timeval, timeout);
|
|
||||||
|
|
||||||
if (timer != NULL && *timer > 0.0) {
|
|
||||||
timeout.tv_sec = (long) *timer;
|
|
||||||
timeout.tv_usec = (long) ((long)((*timer) * 1000000) % 1000000);
|
|
||||||
ptimeout = &timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
T_PERROR_RIPC ((select (fdmax + 1, &readf, NULL, NULL, ptimeout) == -1), "select", IPC_ERROR_WAIT_EVENT__SELECT);
|
|
||||||
|
|
||||||
if (ptimeout != NULL) {
|
|
||||||
*timer = timeout.tv_sec + (timeout.tv_usec / 1000000.0);
|
|
||||||
if (*timer == 0) {
|
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_TIMER, NULL, NULL);
|
|
||||||
IPC_RETURN_NO_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i <= (size_t) fdmax; i++) {
|
|
||||||
if (FD_ISSET (i, &readf)) {
|
|
||||||
if (cinfo != NULL && i == (size_t) listener) {
|
|
||||||
return handle_connection (event, ctx, cinfo);
|
|
||||||
} else {
|
|
||||||
for (j = 0; j < ctx->size; j++) {
|
|
||||||
if (i == (size_t) ctx->cinfos[j]->pollfd.fd) {
|
|
||||||
return handle_message (event, ctx, ctx->cinfos[j], switchdb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IPC_RETURN_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ipc_error ipc_wait_event (
|
|
||||||
struct ipc_ctx *ctx
|
|
||||||
, struct ipc_connection_info *cinfo // NULL for clients
|
|
||||||
, struct ipc_event *event
|
|
||||||
, int *timer)
|
|
||||||
{
|
|
||||||
return ipc_wait_event_networkd (ctx, cinfo, event, NULL, timer);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
101
src/ipc.h
101
src/ipc.h
|
@ -73,13 +73,14 @@ enum msg_types {
|
||||||
enum ipc_event_type {
|
enum ipc_event_type {
|
||||||
IPC_EVENT_TYPE_NOT_SET = 0
|
IPC_EVENT_TYPE_NOT_SET = 0
|
||||||
, IPC_EVENT_TYPE_ERROR = 1
|
, IPC_EVENT_TYPE_ERROR = 1
|
||||||
, IPC_EVENT_TYPE_EXTRA_SOCKET = 2
|
, IPC_EVENT_TYPE_EXTRA_SOCKET = 2 // Message received from a non IPC socket.
|
||||||
, IPC_EVENT_TYPE_SWITCH = 3
|
, IPC_EVENT_TYPE_SWITCH = 3 // Message to send to a corresponding fd.
|
||||||
, IPC_EVENT_TYPE_CONNECTION = 4
|
, IPC_EVENT_TYPE_CONNECTION = 4 // New user.
|
||||||
, IPC_EVENT_TYPE_DISCONNECTION = 5
|
, IPC_EVENT_TYPE_DISCONNECTION = 5 // User disconnected.
|
||||||
, IPC_EVENT_TYPE_MESSAGE = 6
|
, IPC_EVENT_TYPE_MESSAGE = 6 // New message.
|
||||||
, IPC_EVENT_TYPE_LOOKUP = 7
|
, IPC_EVENT_TYPE_LOOKUP = 7 // Client asking for a service through ipcd.
|
||||||
, IPC_EVENT_TYPE_TIMER = 8
|
, IPC_EVENT_TYPE_TIMER = 8 // Timeout in the poll(2) function.
|
||||||
|
, IPC_EVENT_TYPE_TX = 9 // Message sent.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,19 +171,19 @@ enum ipc_error_code {
|
||||||
, IPC_ERROR_DIR_SETUP__DIRECTORY_NOT_WRITABLE = 84
|
, IPC_ERROR_DIR_SETUP__DIRECTORY_NOT_WRITABLE = 84
|
||||||
, IPC_ERROR_DIRECTORY_SETUP__PATH_PARAM = 85
|
, IPC_ERROR_DIRECTORY_SETUP__PATH_PARAM = 85
|
||||||
|
|
||||||
, IPC_ERROR_SERVER_INIT__NOT_ENOUGH_MEMORY = 86
|
, IPC_ERROR_SERVER_INIT__NOT_ENOUGH_MEMORY = 86
|
||||||
, IPC_ERROR_CONNECTION__NOT_ENOUGH_MEMORY = 87
|
, IPC_ERROR_CONNECTION__NOT_ENOUGH_MEMORY = 87
|
||||||
, IPC_ERROR_CTX_INIT__NO_CONTEXT_PARAM = 88
|
, IPC_ERROR_CTX_INIT__NO_CONTEXT_PARAM = 88
|
||||||
, IPC_ERROR_CTX_INIT__CONTEXT_ALREADY_INIT = 89
|
, IPC_ERROR_CTX_INIT__CONTEXT_ALREADY_INIT = 89
|
||||||
, IPC_ERROR_ADD__MALLOC_POLLFD = 90
|
, IPC_ERROR_ADD__MALLOC_POLLFD = 90
|
||||||
, IPC_ERROR_ADD_MESSAGE_TO_SEND__EMPTY_LIST = 91
|
, IPC_ERROR_ADD_MESSAGE_TO_SEND__EMPTY_LIST = 91
|
||||||
, IPC_ERROR_ADD_MESSAGE_TO_SEND__MALLOC = 92
|
, IPC_ERROR_ADD_MESSAGE_TO_SEND__MALLOC = 92
|
||||||
, IPC_ERROR_ADD_MESSAGE_TO_SEND__NO_PARAM_MESSAGE = 93
|
, IPC_ERROR_ADD_MESSAGE_TO_SEND__NO_PARAM_MESSAGE = 93
|
||||||
, IPC_ERROR_ADD_MESSAGE_TO_SEND__NO_PARAM_MESSAGES = 94
|
, IPC_ERROR_ADD_MESSAGE_TO_SEND__NO_PARAM_MESSAGES = 94
|
||||||
, IPC_ERROR_CONNECTION__NO_CTX = 95
|
, IPC_ERROR_CONNECTION__NO_CTX = 95
|
||||||
, IPC_ERROR_CTX_INIT__MALLOC_CTX = 96
|
, IPC_ERROR_CTX_INIT__MALLOC_CTX = 96
|
||||||
, IPC_ERROR_CTX_INIT__MALLOC_POLLFD = 97
|
, IPC_ERROR_CTX_INIT__MALLOC_POLLFD = 97
|
||||||
, IPC_ERROR_CONTACT_NETWORKD__NO_FD_PARAM = 98
|
, IPC_ERROR_CONTACT_NETWORKD__NO_FD_PARAM = 98
|
||||||
, IPC_ERROR_HANDLE_NEW_CONNECTION__INCONSISTENT_INDEX = 99
|
, IPC_ERROR_HANDLE_NEW_CONNECTION__INCONSISTENT_INDEX = 99
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,6 +192,16 @@ struct ipc_error {
|
||||||
char error_message[BUFSIZ];
|
char error_message[BUFSIZ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ipc_switching {
|
||||||
|
int orig;
|
||||||
|
int dest;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_switchings {
|
||||||
|
struct ipc_switching *collection;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
// get explanation about an error
|
// get explanation about an error
|
||||||
// This only returns the generic error based on its code.
|
// This only returns the generic error based on its code.
|
||||||
// Library's users have a more meaningful insight on the error
|
// Library's users have a more meaningful insight on the error
|
||||||
|
@ -202,6 +213,19 @@ struct ipc_connection_info {
|
||||||
char *spath; // max size: PATH_MAX
|
char *spath; // max size: PATH_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ipc_message {
|
||||||
|
char type;
|
||||||
|
char user_type;
|
||||||
|
uint32_t length;
|
||||||
|
char *payload;
|
||||||
|
int fd; // File descriptor concerned about this message.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_messages {
|
||||||
|
struct ipc_message *messages;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context of the whole networking state.
|
* Context of the whole networking state.
|
||||||
*/
|
*/
|
||||||
|
@ -218,37 +242,32 @@ struct ipc_ctx {
|
||||||
* Size of the connection list.
|
* Size of the connection list.
|
||||||
*/
|
*/
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
/**
|
||||||
|
* List of messages to send, once the fd are available.
|
||||||
struct ipc_messages {
|
*/
|
||||||
struct ipc_message **messages;
|
struct ipc_messages tx;
|
||||||
size_t size;
|
/**
|
||||||
};
|
* Relations between fd.
|
||||||
|
*/
|
||||||
struct ipc_message {
|
struct ipc_switchings switchdb;
|
||||||
char type;
|
|
||||||
char user_type;
|
|
||||||
uint32_t length;
|
|
||||||
char *payload;
|
|
||||||
int fd; // File descriptor concerned about this message.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipc_event {
|
struct ipc_event {
|
||||||
enum ipc_event_type type;
|
enum ipc_event_type type;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
int origin;
|
int origin;
|
||||||
void *m; // message pointer
|
void *m; // message pointer
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* ipc event macros
|
* ipc event macros
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#define IPC_EVENT_SET(pevent,type_,message_,index_, origin_fd_) {\
|
#define IPC_EVENT_SET(pevent,type_,index_, origin_fd_,message_) {\
|
||||||
pevent->type = type_; \
|
pevent->type = type_; \
|
||||||
pevent->m = message_; \
|
|
||||||
pevent->index = index_; \
|
pevent->index = index_; \
|
||||||
pevent->origin = origin_fd_; \
|
pevent->origin = origin_fd_; \
|
||||||
|
pevent->m = message_; \
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ipc_connection_types {
|
enum ipc_connection_types {
|
||||||
|
@ -335,16 +354,6 @@ struct ipc_error service_path (char *path, const char *sname);
|
||||||
* networkd enumerations, structures and functions
|
* networkd enumerations, structures and functions
|
||||||
**/
|
**/
|
||||||
|
|
||||||
struct ipc_switching {
|
|
||||||
int orig;
|
|
||||||
int dest;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc_switchings {
|
|
||||||
struct ipc_switching *collection;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct networkd {
|
struct networkd {
|
||||||
int cpt;
|
int cpt;
|
||||||
struct ipc_connection_info *srv;
|
struct ipc_connection_info *srv;
|
||||||
|
|
|
@ -163,7 +163,8 @@ struct ipc_error ipc_messages_add (struct ipc_messages *messages, struct ipc_me
|
||||||
|
|
||||||
T_R ((messages->messages == NULL), IPC_ERROR_ADD_MESSAGE_TO_SEND__EMPTY_LIST);
|
T_R ((messages->messages == NULL), IPC_ERROR_ADD_MESSAGE_TO_SEND__EMPTY_LIST);
|
||||||
|
|
||||||
messages->messages[messages->size - 1] = message;
|
// NOT A DEEP COPY.
|
||||||
|
messages->messages[messages->size - 1] = *message;
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue