diff --git a/core/client.c b/core/client.c index 8dcd542..1227cd6 100644 --- a/core/client.c +++ b/core/client.c @@ -105,3 +105,5 @@ void ipc_clients_free (struct ipc_clients *ap) } ap->size = 0; } + + diff --git a/core/client.h b/core/client.h index 51cebf2..08d663c 100644 --- a/core/client.h +++ b/core/client.h @@ -1,5 +1,5 @@ -#ifndef __IPC_PROCESS_H__ -#define __IPC_PROCESS_H__ +#ifndef __IPC_CLIENT_H__ +#define __IPC_CLIENT_H__ struct ipc_client { unsigned int version; diff --git a/core/communication.c b/core/communication.c index ed0cd01..02b158f 100644 --- a/core/communication.c +++ b/core/communication.c @@ -210,3 +210,78 @@ int ipc_server_select (struct ipc_clients *clients, struct ipc_service *srv return 0; } + +/*calculer le max filedescriptor*/ +static int getMaxFdServices(struct ipc_services *services) +{ + int i; + int max = 0; + + for (i = 0; i < services->size; i++ ) { + if (services->services[i]->service_fd > max) { + max = services->services[i]->service_fd; + } + } + + return max; +} + +/* + * ipc_application_select prend en parametre + * * un tableau de server qu'on écoute + * * le service qui attend de nouvelles connexions + * * un tableau de client qui souhaitent parler + * + * 0 = OK + * -1 = error + */ + +int ipc_application_select (struct ipc_services *services, struct ipc_services *active_services) +{ + assert (services != NULL); + assert (active_services != NULL); + + // delete previous read active_services array + ipc_services_free (active_services); + + int i, j; + /* master file descriptor list */ + fd_set master; + fd_set readf; + + /* maximum file descriptor number */ + int fdmax; + + /* clear the master and temp sets */ + FD_ZERO(&master); + FD_ZERO(&readf); + + for (i=0; i < services->size; i++) { + FD_SET(services->services[i]->service_fd, &master); + } + + /* keep track of the biggest file descriptor */ + fdmax = getMaxFdServices(services); + + // 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)) { + for(j = 0; j < services->size; j++) { + // printf ("loop ipc_server_select inner inner loop\n"); + if(i == services->services[j]->service_fd ) { + ipc_service_add (active_services, services->services[j]); + } + } + } + } + + return 0; +} diff --git a/core/communication.h b/core/communication.h index 7fdd90c..bc6e2a7 100644 --- a/core/communication.h +++ b/core/communication.h @@ -45,6 +45,6 @@ int ipc_application_close (struct ipc_service *); int ipc_application_read (struct ipc_service *srv, struct ipc_message *m); int ipc_application_write (struct ipc_service *, const struct ipc_message *m); - +int ipc_application_select (struct ipc_services *services, struct ipc_services *active_services); #endif diff --git a/core/usocket.c b/core/usocket.c index 794e194..2d61714 100644 --- a/core/usocket.c +++ b/core/usocket.c @@ -259,3 +259,107 @@ int usock_remove (const char *path) { return unlink (path); } + + +// TODO: ipc_services functions + +struct ipc_service * ipc_client_server_copy (const struct ipc_service *p) +{ + if (p == NULL) + return NULL; + + struct ipc_service * copy = malloc (sizeof(struct ipc_service)); + memset (copy, 0, sizeof (struct ipc_service)); + memcpy (copy, p, sizeof (struct ipc_service)); + + return copy; +} + +int ipc_client_server_eq (const struct ipc_service *p1, const struct ipc_service *p2) +{ + return (p1->version == p2->version && p1->index == p2->index + && p1->service_fd == p2->service_fd && memcmp(p1->spath, p1->spath, PATH_MAX) == 0 ); +} + +void ipc_client_server_gen (struct ipc_service *p + , unsigned int index, unsigned int version) +{ + p->version = version; + p->index = index; +} + +int ipc_service_add (struct ipc_services *services, struct ipc_service *p) +{ + assert(services != NULL); + assert(p != NULL); + + services->size++; + services->services = realloc(services->services + , sizeof(struct ipc_service) * services->size); + + if (services->services == NULL) { + return -1; + } + + services->services[services->size - 1] = p; + return 0; +} + +int ipc_service_del (struct ipc_services *services, struct ipc_service *p) +{ + assert(services != NULL); + assert(p != NULL); + + if (services->services == NULL) { + return -1; + } + + int i; + for (i = 0; i < services->size; i++) { + if (services->services[i] == p) { + + services->services[i] = services->services[services->size-1]; + services->size--; + if (services->size == 0) { + ipc_services_free (services); + } + else { + services->services = realloc(services->services + , sizeof(struct ipc_service) * services->size); + + if (services->services == NULL) { + return -2; + } + } + + return 0; + } + } + + return -3; +} + +void service_print (struct ipc_service *p) +{ + if (p != NULL) + printf ("client %d : index %d, version %d\n" + , p->service_fd, p->index, p->version); +} + +void ipc_services_print (struct ipc_services *ap) +{ + int i; + for (i = 0; i < ap->size; i++) { + printf("%d : ", i); + service_print(ap->services[i]); + } +} + +void ipc_services_free (struct ipc_services *ap) +{ + if (ap->services != NULL) { + free (ap->services); + ap->services = NULL; + } + ap->size = 0; +} diff --git a/core/usocket.h b/core/usocket.h index 75bf4ee..49fe891 100644 --- a/core/usocket.h +++ b/core/usocket.h @@ -17,6 +17,11 @@ struct ipc_service { int service_fd; }; +struct ipc_services { + struct ipc_service ** services; + int size; +}; + /** * for all functions: 0 ok, < 0 not ok */ @@ -50,4 +55,20 @@ int usock_remove (const char *path); static inline int ipc_service_empty (struct ipc_service *srv) { srv = srv; return 0 ;}; + +// store and remove only pointers on allocated structures +int ipc_service_add (struct ipc_services *, struct ipc_service *); +int ipc_service_del (struct ipc_services *, struct ipc_service *); + +void ipc_services_print (struct ipc_services *); +void ipc_services_free (struct ipc_services *); + +struct ipc_service * ipc_client_server_copy (const struct ipc_service *p); +int ipc_service_eq (const struct ipc_service *p1, const struct ipc_service *p2); +// create the client service structure +void ipc_client_server_gen (struct ipc_service *p + , unsigned int index, unsigned int version); + +void service_print (struct ipc_service *); + #endif