Archived
3
0

cleaning names, pongd stops itself for greater good

This commit is contained in:
Philippe PITTOLI 2018-10-04 22:51:31 +02:00
parent e48b5f2ce4
commit 1936ef4b6a
16 changed files with 167 additions and 128 deletions

View File

@ -5,8 +5,8 @@
int main()
{
int ret;
struct ipc_client_array clients;
memset(&clients, 0, sizeof(struct ipc_client_array));
struct ipc_clients clients;
memset(&clients, 0, sizeof(struct ipc_clients));
struct ipc_client client_tab[5];
memset(&client_tab, 0, sizeof(struct ipc_client) * 5);

View File

@ -11,6 +11,7 @@ struct ipc_client * ipc_server_client_copy (const struct ipc_client *p)
return NULL;
struct ipc_client * copy = malloc (sizeof(struct ipc_client));
memset (copy, 0, sizeof (struct ipc_client));
memcpy (copy, p, sizeof (struct ipc_client));
return copy;
@ -29,7 +30,7 @@ void ipc_server_client_gen (struct ipc_client *p
p->index = index;
}
int ipc_client_add (struct ipc_client_array *clients, struct ipc_client *p)
int ipc_client_add (struct ipc_clients *clients, struct ipc_client *p)
{
assert(clients != NULL);
assert(p != NULL);
@ -45,7 +46,7 @@ int ipc_client_add (struct ipc_client_array *clients, struct ipc_client *p)
return 0;
}
int ipc_client_del (struct ipc_client_array *clients, struct ipc_client *p)
int ipc_client_del (struct ipc_clients *clients, struct ipc_client *p)
{
assert(clients != NULL);
assert(p != NULL);
@ -86,7 +87,7 @@ void client_print (struct ipc_client *p)
, p->proc_fd, p->index, p->version);
}
void ipc_client_array_print (struct ipc_client_array *ap)
void ipc_client_array_print (struct ipc_clients *ap)
{
int i;
for (i = 0; i < ap->size; i++) {
@ -95,7 +96,7 @@ void ipc_client_array_print (struct ipc_client_array *ap)
}
}
void ipc_client_array_free (struct ipc_client_array *ap)
void ipc_client_array_free (struct ipc_clients *ap)
{
if (ap->clients != NULL) {
free (ap->clients);

View File

@ -7,16 +7,16 @@ struct ipc_client {
int proc_fd;
};
struct ipc_client_array {
struct ipc_clients {
struct ipc_client **clients;
int size;
};
int ipc_client_add (struct ipc_client_array *, struct ipc_client *);
int ipc_client_del (struct ipc_client_array *clients, struct ipc_client *p);
int ipc_client_add (struct ipc_clients *, struct ipc_client *);
int ipc_client_del (struct ipc_clients *clients, struct ipc_client *p);
void ipc_client_array_print (struct ipc_client_array *);
void ipc_client_array_free (struct ipc_client_array *);
void ipc_client_array_print (struct ipc_clients *);
void ipc_client_array_free (struct ipc_clients *);
struct ipc_client * ipc_server_client_copy (const struct ipc_client *p);
int ipc_server_client_eq (const struct ipc_client *p1, const struct ipc_client *p2);

View File

@ -159,15 +159,15 @@ int ipc_application_write (struct ipc_service *srv, const struct ipc_message *m)
/*calculer le max filedescriptor*/
static int getMaxFd(struct ipc_client_array *ap)
static int getMaxFd(struct ipc_clients *clients)
{
int i;
int max = 0;
for (i = 0; i < ap->size; i++ ) {
if (ap->clients[i]->proc_fd > max) {
max = ap->clients[i]->proc_fd;
for (i = 0; i < clients->size; i++ ) {
if (clients->clients[i]->proc_fd > max) {
max = clients->clients[i]->proc_fd;
}
}
@ -180,21 +180,18 @@ static int getMaxFd(struct ipc_client_array *ap)
* * le service qui attend de nouvelles connexions
* * un tableau de client qui souhaitent parler
*
* la fonction trouve le clientus/service actif et renvoie
* un entier correspondant à quel descripteur de fichier il faut lire
* * celui du serveur = nouvelle connexion entrante (CONNECTION)
* * celui d'un ou plusieurs clientus = ils nous parlent (APPLICATION)
* * les deux à la fois (CON_APP)
* 0 = OK
* -1 = error
*/
int ipc_server_select (struct ipc_client_array *ap, struct ipc_service *srv
, struct ipc_client_array *client)
int ipc_server_select (struct ipc_clients *clients, struct ipc_service *srv
, struct ipc_clients *active_clients, int *new_connection)
{
assert (ap != NULL);
assert (client != NULL);
assert (clients != NULL);
assert (active_clients != NULL);
// delete previous read client array
ipc_client_array_free (client);
// delete previous read active_clients array
ipc_client_array_free (active_clients);
int i, j;
/* master file descriptor list */
@ -212,44 +209,36 @@ int ipc_server_select (struct ipc_client_array *ap, struct ipc_service *srv
/* add the listener to the master set */
FD_SET(listener, &master);
for (i=0; i < ap->size; i++) {
FD_SET(ap->clients[i]->proc_fd, &master);
for (i=0; i < clients->size; i++) {
FD_SET(clients->clients[i]->proc_fd, &master);
}
/* keep track of the biggest file descriptor */
fdmax = getMaxFd(ap) > srv->service_fd ? getMaxFd(ap) : srv->service_fd;
fdmax = getMaxFd(clients) > srv->service_fd ? getMaxFd(clients) : srv->service_fd;
int is_listener = 0;
// printf ("loop ipc_server_select main_loop\n");
readf = master;
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
perror("select");
return -1;
}
do {
// printf ("loop ipc_server_select main_loop\n");
readf = master;
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
perror("select");
return -1;
}
/*run through the existing connections looking for data to be read*/
for (i = 0; i <= fdmax; i++) {
// printf ("loop ipc_server_select inner loop\n");
if (FD_ISSET(i, &readf)) {
if (i == listener) {
*new_connection = 1;
} else {
for(j = 0; j < clients->size; j++) {
// printf ("loop ipc_server_select inner inner loop\n");
if(i == clients->clients[j]->proc_fd ) {
ipc_client_add (active_clients, clients->clients[j]);
}
}
}
}
}
/*run through the existing connections looking for data to be read*/
for (i = 0; i <= fdmax; i++) {
// printf ("loop ipc_server_select inner loop\n");
if (FD_ISSET(i, &readf)) {
if (i == listener) {
is_listener = 1;
} else {
for(j = 0; j < ap->size; j++) {
// printf ("loop ipc_server_select inner inner loop\n");
if(i == ap->clients[j]->proc_fd ) {
ipc_client_add (client, ap->clients[j]);
}
}
}
}
}
} while (0);
if (client->size > 0 && is_listener)
return CON_APP;
if (client->size > 0)
return APPLICATION;
return CONNECTION;
return 0;
}

View File

@ -18,9 +18,10 @@
#define PATH_MAX BUFSIZ
#define CONNECTION 0
#define APPLICATION 1
#define CON_APP 2
#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;
@ -43,7 +44,8 @@ int ipc_server_accept (struct ipc_service *srv, struct ipc_client *p);
int ipc_server_read (const struct ipc_client *, struct ipc_message *m);
int ipc_server_write (const struct ipc_client *, const struct ipc_message *m);
int ipc_server_select (struct ipc_client_array *, struct ipc_service *, struct ipc_client_array *);
int ipc_server_select (struct ipc_clients * clients, struct ipc_service *srv
, struct ipc_clients *active_clients, int *new_connection);
// APPLICATION

View File

@ -22,9 +22,9 @@ int ipc_message_format_read (struct ipc_message *m, const char *buf, size_t msiz
m->type = buf[0];
memcpy (&m->length, buf+1, 2);
assert (m->length <= BUFSIZ -3);
// printf ("type %d : msize = %ld, length = %d\n", m->type, msize, m->length);
assert (m->length == msize - 3);
assert (m->length <= BUFSIZ - 3);
printf ("type %d : msize = %ld, length = %d\n", m->type, msize, m->length);
assert (m->length == msize - 3 || m->length == 0);
if (m->payload != NULL)
free (m->payload), m->payload = NULL;
@ -55,16 +55,21 @@ int ipc_message_format_write (const struct ipc_message *m, char **buf, size_t *m
if (*buf == NULL) {
*buf = malloc (3 + m->length);
memset (*buf, 0, 3 + m->length);
}
char *buffer = *buf;
buffer[0] = m->type;
memcpy (buffer + 1, &m->length, 2);
memcpy (buffer + 3, m->payload, m->length);
if (m->payload != NULL) {
memcpy (buffer + 3, m->payload, m->length);
}
*msize = 3 + m->length;
printf ("sending msg: type %u, size %d, msize %ld\n", m->type, m->length, *msize);
return 0;
}
@ -125,10 +130,18 @@ int ipc_message_format (struct ipc_message *m, char type, const char *payload, s
m->type = type;
m->length = (short) length;
if (m->payload == NULL)
if (payload != NULL) {
if (m->payload != NULL) {
free (m->payload);
}
// FIXME: test malloc
m->payload = malloc (length);
memset (m->payload, 0, length);
}
memcpy (m->payload, payload, length);
if (payload != NULL) {
memcpy (m->payload, payload, length);
}
return 0;
}
@ -147,6 +160,11 @@ int ipc_message_format_ack (struct ipc_message *m, const char *payload, size_t l
return ipc_message_format (m, MSG_TYPE_ACK, payload, length);
}
int ipc_message_format_server_close (struct ipc_message *m)
{
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, NULL, 0);
}
int ipc_message_free (struct ipc_message *m)
{
assert (m != NULL);

View File

@ -10,6 +10,7 @@
#define MSG_TYPE_ERR 2
#define MSG_TYPE_ACK 3
#define MSG_TYPE_DATA 4
#define MSG_TYPE_SERVER_CLOSE 5
struct ipc_message {
char type;
@ -30,6 +31,7 @@ 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_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_server_close (struct ipc_message *m);
int ipc_message_free (struct ipc_message *m);
void ipc_message_print (const struct ipc_message *m);

View File

@ -14,7 +14,7 @@ communication.h \- all functions explained
.sp
.BI "int ipc_server_close (struct ipc_service *" srv );
.BI "int ipc_server_close_client (struct ipc_client *" p );
.BI "int ipc_server_select (struct ipc_client_array *" fds ", struct ipc_service *" srv ", struct ipc_client_array *" readfds );
.BI "int ipc_server_select (struct ipc_clients *" fds ", struct ipc_service *" srv ", struct ipc_clients *" readfds );
.BI "int ipc_application_connection (int " argc ", char **" argv ", char **" env ", struct ipc_service *" srv
.BI " , const char *" service_name "

View File

@ -14,13 +14,13 @@ test:
./pongd.bin
$(EXEC): $(OBJECTS) $(CFILES)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $@.c -lcbor -o $@.bin
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $@.c -o $@.bin
.c.o:
$(CC) -c $(CFLAGS) $< -o $@
$(TESTS):
valgrind --show-leak-kinds=all --leak-check=full -v --track-origins=yes ./$(basename $@).bin
valgrind --show-leak-kinds=all --leak-check=full -v --track-origins=yes ./$(basename $@).bin $(PARAMS)
clean:
@-rm $(OBJECTS)

View File

@ -62,6 +62,8 @@ void interactive (int argc, char *argv[], char *env[])
memset (buf, 0, BUFSIZ);
int n;
int ask_server_to_quit = 0;
// index and version should be filled
srv.index = 0;
srv.version = 0;
@ -80,6 +82,11 @@ void interactive (int argc, char *argv[], char *env[])
if (n == 0 || strncmp (buf, "exit", 4) == 0)
break;
if (strncmp(buf, "close server", 12) == 0) {
ask_server_to_quit = 1;
break;
}
ipc_message_format_data (&m, buf, strlen(buf) +1);
memset (buf, 0, BUFSIZ);
@ -100,7 +107,15 @@ void interactive (int argc, char *argv[], char *env[])
ipc_message_free (&m);
}
if (ipc_application_close (&srv) < 0) {
if (ask_server_to_quit) {
ipc_message_format_server_close (&m);
if (ipc_application_write (&srv, &m) < 0) {
handle_err("main", "application_write < 0");
exit (EXIT_FAILURE);
}
ipc_message_free (&m);
} else if (ipc_application_close (&srv) < 0) {
handle_err("main", "application_close < 0");
exit (EXIT_FAILURE);
}

View File

@ -10,7 +10,9 @@
int cpt = 0;
void handle_new_connection (struct ipc_service *srv, struct ipc_client_array *ap)
struct ipc_service *srv = 0;
void handle_new_connection (struct ipc_clients *clients)
{
struct ipc_client *p = malloc(sizeof(struct ipc_client));
memset(p, 0, sizeof(struct ipc_client));
@ -21,7 +23,7 @@ void handle_new_connection (struct ipc_service *srv, struct ipc_client_array *ap
printf("new connection\n");
}
if (ipc_client_add (ap, p) < 0) {
if (ipc_client_add (clients, p) < 0) {
handle_error("ipc_client_add < 0");
}
@ -29,14 +31,14 @@ void handle_new_connection (struct ipc_service *srv, struct ipc_client_array *ap
printf ("%d client(s)\n", cpt);
}
void handle_new_msg (struct ipc_client_array *ap, struct ipc_client_array *proc_to_read)
void handle_new_msg (struct ipc_clients *clients, struct ipc_clients *clients_talking)
{
struct ipc_message m;
memset (&m, 0, sizeof (struct ipc_message));
int i;
for (i = 0; i < proc_to_read->size; i++) {
for (i = 0; i < clients_talking->size; i++) {
// printf ("loop handle_new_msg\n");
if (ipc_server_read (proc_to_read->clients[i], &m) < 0) {
if (ipc_server_read (clients_talking->clients[i], &m) < 0) {
handle_error("server_read < 0");
}
@ -45,18 +47,25 @@ void handle_new_msg (struct ipc_client_array *ap, struct ipc_client_array *proc_
cpt--;
printf ("disconnection => %d client(s) remaining\n", cpt);
if (ipc_server_close_client (proc_to_read->clients[i]) < 0)
if (ipc_server_close_client (clients_talking->clients[i]) < 0)
handle_err( "handle_new_msg", "server_close_client < 0");
if (ipc_client_del (ap, proc_to_read->clients[i]) < 0)
if (ipc_client_del (clients, clients_talking->clients[i]) < 0)
handle_err( "handle_new_msg", "ipc_client_del < 0");
if (ipc_client_del (proc_to_read, proc_to_read->clients[i]) < 0)
if (ipc_client_del (clients_talking, clients_talking->clients[i]) < 0)
handle_err( "handle_new_msg", "ipc_client_del < 0");
i--;
continue;
}
}
if (m.type == MSG_TYPE_SERVER_CLOSE) {
if (ipc_server_close (srv) < 0) {
handle_error("server_close < 0");
}
exit (0);
}
printf ("new message : %s", m.payload);
if (ipc_server_write (proc_to_read->clients[i], &m) < 0) {
if (ipc_server_write (clients_talking->clients[i], &m) < 0) {
handle_err( "handle_new_msg", "server_write < 0");
}
}
@ -70,35 +79,35 @@ void handle_new_msg (struct ipc_client_array *ap, struct ipc_client_array *proc_
* close a connection if MSG_TYPE_CLOSE received
*/
void main_loop (struct ipc_service *srv)
void main_loop ()
{
int i, ret = 0;
struct ipc_client_array ap;
memset(&ap, 0, sizeof(struct ipc_client_array));
struct ipc_clients clients;
memset(&clients, 0, sizeof(struct ipc_clients));
struct ipc_client_array proc_to_read;
memset(&proc_to_read, 0, sizeof(struct ipc_client_array));
struct ipc_clients clients_talking;
memset(&clients_talking, 0, sizeof(struct ipc_clients));
while(1) {
ret = ipc_server_select (&ap, srv, &proc_to_read);
// printf ("on peut lire ces client:\n");
// ipc_client_array_print (&proc_to_read);
// printf ("-- \n\n");
int new_connection = 0;
ret = ipc_server_select (&clients, srv, &clients_talking, &new_connection);
if (ret < 0) {
handle_error("ipc_server_select < 0");
}
if (ret == CONNECTION) {
handle_new_connection (srv, &ap);
} else if (ret == APPLICATION) {
handle_new_msg (&ap, &proc_to_read);
} else { // both new connection and new msg from at least one client
handle_new_connection (srv, &ap);
handle_new_msg (&ap, &proc_to_read);
if (new_connection) {
handle_new_connection (&clients);
}
ipc_client_array_free (&proc_to_read);
if (clients_talking.size > 0) {
handle_new_msg (&clients, &clients_talking);
}
ipc_client_array_free (&clients_talking);
}
for (i = 0; i < ap.size; i++) {
if (ipc_server_close_client (ap.clients[i]) < 0) {
for (i = 0; i < clients.size; i++) {
if (ipc_server_close_client (clients.clients[i]) < 0) {
handle_error( "server_close_client < 0");
}
}
@ -117,26 +126,29 @@ void main_loop (struct ipc_service *srv)
int main(int argc, char * argv[], char **env)
{
struct ipc_service srv;
memset (&srv, 0, sizeof (struct ipc_service));
srv.index = 0;
srv.version = 0;
srv = malloc (sizeof (struct ipc_service));
if (srv == NULL) {
exit (1);
}
memset (srv, 0, sizeof (struct ipc_service));
srv->index = 0;
srv->version = 0;
// unlink("/tmp/ipc/pongd-0-0");
if (ipc_server_init (argc, argv, env, &srv, PONGD_SERVICE_NAME) < 0) {
if (ipc_server_init (argc, argv, env, srv, PONGD_SERVICE_NAME) < 0) {
handle_error("server_init < 0");
return EXIT_FAILURE;
}
printf ("Listening on %s.\n", srv.spath);
printf ("Listening on %s.\n", srv->spath);
printf("MAIN: server created\n" );
// the service will loop until the end of time, a specific message, a signal
main_loop (&srv);
main_loop ();
// the application will shut down, and remove the service named pipe
if (ipc_server_close (&srv) < 0) {
if (ipc_server_close (srv) < 0) {
handle_error("server_close < 0");
}

View File

@ -98,8 +98,8 @@ int pubsubd_channel_new (struct channel *c, const char * name)
memcpy (c->chan, name, nlen);
c->chanlen = nlen;
c->subs = malloc (sizeof (struct ipc_client_array));
memset (c->subs, 0, sizeof (struct ipc_client_array));
c->subs = malloc (sizeof (struct ipc_clients));
memset (c->subs, 0, sizeof (struct ipc_clients));
return 0;
}

View File

@ -12,7 +12,7 @@ LIST_HEAD(channels, channel);
struct channel {
char *chan;
size_t chanlen;
struct ipc_client_array *subs;
struct ipc_clients *subs;
LIST_ENTRY(channel) entries;
};

View File

@ -11,7 +11,7 @@
#include <sys/un.h>
#include <unistd.h>
void pubsubd_send (const struct ipc_client_array *ap, const struct pubsub_msg * m)
void pubsubd_send (const struct ipc_clients *ap, const struct pubsub_msg * m)
{
if (ap == NULL) {
fprintf (stderr, "pubsubd_send: ap == NULL");
@ -59,7 +59,7 @@ void pubsubd_send (const struct ipc_client_array *ap, const struct pubsub_msg *
* new connection, once accepted the client is added to the array_proc
* structure to be checked periodically for new messages
*/
void handle_new_connection (struct ipc_service *srv, struct ipc_client_array *ap)
void handle_new_connection (struct ipc_service *srv, struct ipc_clients *ap)
{
struct ipc_client *p = malloc(sizeof(struct ipc_client));
memset(p, 0, sizeof(struct ipc_client));
@ -76,7 +76,7 @@ void handle_new_connection (struct ipc_service *srv, struct ipc_client_array *ap
}
void handle_new_msg (struct channels *chans
, struct ipc_client_array *ap, struct ipc_client_array *proc_to_read)
, struct ipc_clients *ap, struct ipc_clients *proc_to_read)
{
struct ipc_message m;
memset (&m, 0, sizeof (struct ipc_message));
@ -169,11 +169,11 @@ void pubsubd_main_loop (struct ipc_service *srv, struct channels *chans)
{
int i, ret = 0;
struct ipc_client_array ap;
memset(&ap, 0, sizeof(struct ipc_client_array));
struct ipc_clients ap;
memset(&ap, 0, sizeof(struct ipc_clients));
struct ipc_client_array proc_to_read;
memset(&proc_to_read, 0, sizeof(struct ipc_client_array));
struct ipc_clients proc_to_read;
memset(&proc_to_read, 0, sizeof(struct ipc_clients));
while(1) {
ret = ipc_server_select (&ap, srv, &proc_to_read);

View File

@ -10,6 +10,6 @@
#define PUBSUBD_SERVICE_NAME "pubsubd"
void pubsubd_main_loop (struct ipc_service *srv, struct channels * chans);
void pubsubd_message_send (const struct ipc_client_array *ap, const struct pubsub_msg * m);
void pubsubd_message_send (const struct ipc_clients *ap, const struct pubsub_msg * m);
#endif

View File

@ -15,7 +15,7 @@
* new connection, once accepted the client is added to the array_proc
* structure to be checked periodically for new messages
*/
void handle_new_connection (struct ipc_service *srv, struct ipc_client_array *ap)
void handle_new_connection (struct ipc_service *srv, struct ipc_clients *ap)
{
struct ipc_client *p = malloc(sizeof(struct ipc_client));
memset(p, 0, sizeof(struct ipc_client));
@ -31,7 +31,7 @@ void handle_new_connection (struct ipc_service *srv, struct ipc_client_array *ap
}
}
void handle_new_msg (struct ipc_client_array *ap, struct ipc_client_array *proc_to_read)
void handle_new_msg (struct ipc_clients *ap, struct ipc_clients *proc_to_read)
{
struct ipc_message m;
memset (&m, 0, sizeof (struct ipc_message));
@ -114,11 +114,11 @@ void remoted_main_loop (struct ipc_service *srv, struct remoted_ctx *ctx)
log_debug ("remoted entering main loop");
int i, ret = 0;
struct ipc_client_array ap;
memset(&ap, 0, sizeof(struct ipc_client_array));
struct ipc_clients ap;
memset(&ap, 0, sizeof(struct ipc_clients));
struct ipc_client_array proc_to_read;
memset(&proc_to_read, 0, sizeof(struct ipc_client_array));
struct ipc_clients proc_to_read;
memset(&proc_to_read, 0, sizeof(struct ipc_clients));
while(1) {
/* TODO: authorizations */