From a5877101eb7aa309ca7352ab17cbbcd873ff2124 Mon Sep 17 00:00:00 2001 From: Karchnu Date: Wed, 1 Jul 2020 09:53:24 +0200 Subject: [PATCH] WIP: no mem leaks on simple use. switch still to test. --- Makefile | 44 +++++++++++++++++++++++----- src/communication.c | 68 +------------------------------------------- src/context.c | 46 ++++++++++++++++++++++++++++++ src/ipc.h | 20 +++++++------ src/message.c | 1 - src/service_path.c | 19 +++++++++++++ tests/func_02_pong.c | 1 + 7 files changed, 116 insertions(+), 83 deletions(-) create mode 100644 src/context.c create mode 100644 src/service_path.c diff --git a/Makefile b/Makefile index 4a29984..9745a5e 100644 --- a/Makefile +++ b/Makefile @@ -45,9 +45,9 @@ man/libipc.7.uninstall: @echo ' RM > $(MANDIR)/man7/libipc.7' $(Q)rm -f '$(DESTDIR)$(MANDIR)/man7/libipc.7' -libipc.so: src/communication.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/usocket.o src/utils.o src/fs.h src/ipc.h src/message.h src/usocket.h src/utils.h +libipc.so: src/communication.o src/context.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/service_path.o src/usocket.o src/utils.o src/fs.h src/ipc.h src/message.h src/usocket.h src/utils.h @echo ' LD > libipc.so' - $(Q)$(CC) -o libipc.so -shared $(LDFLAGS) src/communication.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/usocket.o src/utils.o + $(Q)$(CC) -o libipc.so -shared $(LDFLAGS) src/communication.o src/context.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/service_path.o src/usocket.o src/utils.o libipc.so.install: libipc.so @echo ' IN > $(LIBDIR)/libipc.so.0.6.0' @@ -74,9 +74,9 @@ libipc.so.uninstall: @echo ' RM > $(LIBDIR)/libipc.so' $(Q)rm -f '$(DESTDIR)$(LIBDIR)/libipc.so' -libipc.a: src/communication.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/usocket.o src/utils.o src/fs.h src/ipc.h src/message.h src/usocket.h src/utils.h +libipc.a: src/communication.o src/context.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/service_path.o src/usocket.o src/utils.o src/fs.h src/ipc.h src/message.h src/usocket.h src/utils.h @echo ' LD > libipc.a' - $(Q)$(AR) rc 'libipc.a' src/communication.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/usocket.o src/utils.o + $(Q)$(AR) rc 'libipc.a' src/communication.o src/context.o src/error.o src/fs.o src/message.o src/network.o src/print.o src/service_path.o src/usocket.o src/utils.o libipc.a.install: libipc.a @echo ' IN > $(LIBDIR)/libipc.a' @@ -103,6 +103,18 @@ src/communication.o.clean: src/communication.o.uninstall: +src/context.o: src/context.c src/ipc.h + @echo ' CC > src/context.o' + $(Q)$(CC) $(CFLAGS) -fPIC -std=c11 -c src/context.c -fPIC -std=c11 -o src/context.o + +src/context.o.install: + +src/context.o.clean: + @echo ' RM > src/context.o' + $(Q)rm -f src/context.o + +src/context.o.uninstall: + src/error.o: src/error.c src/ipc.h @echo ' CC > src/error.o' $(Q)$(CC) $(CFLAGS) -fPIC -std=c11 -c src/error.c -fPIC -std=c11 -o src/error.o @@ -163,6 +175,18 @@ src/print.o.clean: src/print.o.uninstall: +src/service_path.o: src/service_path.c src/ipc.h + @echo ' CC > src/service_path.o' + $(Q)$(CC) $(CFLAGS) -fPIC -std=c11 -c src/service_path.c -fPIC -std=c11 -o src/service_path.o + +src/service_path.o.install: + +src/service_path.o.clean: + @echo ' RM > src/service_path.o' + $(Q)rm -f src/service_path.o + +src/service_path.o.uninstall: + src/usocket.o: src/usocket.c src/usocket.h src/utils.h src/fs.h @echo ' CC > src/usocket.o' $(Q)$(CC) $(CFLAGS) -fPIC -std=c11 -c src/usocket.c -fPIC -std=c11 -o src/usocket.o @@ -209,13 +233,13 @@ $(DESTDIR)$(INCLUDEDIR): $(DESTDIR)$(MANDIR): @echo ' DIR > $(MANDIR)' $(Q)mkdir -p $(DESTDIR)$(MANDIR) -install: libipc.install man/libipc.7.install libipc.so.install libipc.a.install src/communication.o.install src/error.o.install src/fs.o.install src/message.o.install src/network.o.install src/print.o.install src/usocket.o.install src/utils.o.install src/communication.o.install src/error.o.install src/fs.o.install src/message.o.install src/network.o.install src/print.o.install src/usocket.o.install src/utils.o.install +install: libipc.install man/libipc.7.install libipc.so.install libipc.a.install src/communication.o.install src/context.o.install src/error.o.install src/fs.o.install src/message.o.install src/network.o.install src/print.o.install src/service_path.o.install src/usocket.o.install src/utils.o.install src/communication.o.install src/context.o.install src/error.o.install src/fs.o.install src/message.o.install src/network.o.install src/print.o.install src/service_path.o.install src/usocket.o.install src/utils.o.install @: -uninstall: libipc.uninstall man/libipc.7.uninstall libipc.so.uninstall libipc.a.uninstall src/communication.o.uninstall src/error.o.uninstall src/fs.o.uninstall src/message.o.uninstall src/network.o.uninstall src/print.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall src/communication.o.uninstall src/error.o.uninstall src/fs.o.uninstall src/message.o.uninstall src/network.o.uninstall src/print.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall +uninstall: libipc.uninstall man/libipc.7.uninstall libipc.so.uninstall libipc.a.uninstall src/communication.o.uninstall src/context.o.uninstall src/error.o.uninstall src/fs.o.uninstall src/message.o.uninstall src/network.o.uninstall src/print.o.uninstall src/service_path.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall src/communication.o.uninstall src/context.o.uninstall src/error.o.uninstall src/fs.o.uninstall src/message.o.uninstall src/network.o.uninstall src/print.o.uninstall src/service_path.o.uninstall src/usocket.o.uninstall src/utils.o.uninstall @: -clean: libipc.clean man/libipc.7.clean libipc.so.clean libipc.a.clean src/communication.o.clean src/error.o.clean src/fs.o.clean src/message.o.clean src/network.o.clean src/print.o.clean src/usocket.o.clean src/utils.o.clean src/communication.o.clean src/error.o.clean src/fs.o.clean src/message.o.clean src/network.o.clean src/print.o.clean src/usocket.o.clean src/utils.o.clean +clean: libipc.clean man/libipc.7.clean libipc.so.clean libipc.a.clean src/communication.o.clean src/context.o.clean src/error.o.clean src/fs.o.clean src/message.o.clean src/network.o.clean src/print.o.clean src/service_path.o.clean src/usocket.o.clean src/utils.o.clean src/communication.o.clean src/context.o.clean src/error.o.clean src/fs.o.clean src/message.o.clean src/network.o.clean src/print.o.clean src/service_path.o.clean src/usocket.o.clean src/utils.o.clean distclean: clean dist: dist-gz dist-xz dist-bz2 $(Q)rm -- $(PACKAGE)-$(VERSION) @@ -235,11 +259,13 @@ $(PACKAGE)-$(VERSION).tar.gz: distdir $(PACKAGE)-$(VERSION)/Makefile \ $(PACKAGE)-$(VERSION)/project.zsh \ $(PACKAGE)-$(VERSION)/src/communication.c \ + $(PACKAGE)-$(VERSION)/src/context.c \ $(PACKAGE)-$(VERSION)/src/error.c \ $(PACKAGE)-$(VERSION)/src/fs.c \ $(PACKAGE)-$(VERSION)/src/message.c \ $(PACKAGE)-$(VERSION)/src/network.c \ $(PACKAGE)-$(VERSION)/src/print.c \ + $(PACKAGE)-$(VERSION)/src/service_path.c \ $(PACKAGE)-$(VERSION)/src/usocket.c \ $(PACKAGE)-$(VERSION)/src/utils.c \ $(PACKAGE)-$(VERSION)/src/ipc.h \ @@ -259,11 +285,13 @@ $(PACKAGE)-$(VERSION).tar.xz: distdir $(PACKAGE)-$(VERSION)/Makefile \ $(PACKAGE)-$(VERSION)/project.zsh \ $(PACKAGE)-$(VERSION)/src/communication.c \ + $(PACKAGE)-$(VERSION)/src/context.c \ $(PACKAGE)-$(VERSION)/src/error.c \ $(PACKAGE)-$(VERSION)/src/fs.c \ $(PACKAGE)-$(VERSION)/src/message.c \ $(PACKAGE)-$(VERSION)/src/network.c \ $(PACKAGE)-$(VERSION)/src/print.c \ + $(PACKAGE)-$(VERSION)/src/service_path.c \ $(PACKAGE)-$(VERSION)/src/usocket.c \ $(PACKAGE)-$(VERSION)/src/utils.c \ $(PACKAGE)-$(VERSION)/src/ipc.h \ @@ -283,11 +311,13 @@ $(PACKAGE)-$(VERSION).tar.bz2: distdir $(PACKAGE)-$(VERSION)/Makefile \ $(PACKAGE)-$(VERSION)/project.zsh \ $(PACKAGE)-$(VERSION)/src/communication.c \ + $(PACKAGE)-$(VERSION)/src/context.c \ $(PACKAGE)-$(VERSION)/src/error.c \ $(PACKAGE)-$(VERSION)/src/fs.c \ $(PACKAGE)-$(VERSION)/src/message.c \ $(PACKAGE)-$(VERSION)/src/network.c \ $(PACKAGE)-$(VERSION)/src/print.c \ + $(PACKAGE)-$(VERSION)/src/service_path.c \ $(PACKAGE)-$(VERSION)/src/usocket.c \ $(PACKAGE)-$(VERSION)/src/utils.c \ $(PACKAGE)-$(VERSION)/src/ipc.h \ diff --git a/src/communication.c b/src/communication.c index 04131a6..b31ab88 100644 --- a/src/communication.c +++ b/src/communication.c @@ -13,53 +13,6 @@ // print structures #include "message.h" -struct ipc_error -service_path (char *path, const char *sname) -{ - T_R ((path == NULL), IPC_ERROR_SERVICE_PATH__NO_PATH); - T_R ((sname == NULL), IPC_ERROR_SERVICE_PATH__NO_SERVICE_NAME); - - memset (path, 0, PATH_MAX); - - char *rundir = getenv ("IPC_RUNDIR"); - if (rundir == NULL) - rundir = RUNDIR; - - snprintf (path, PATH_MAX - 1, "%s/%s", rundir, sname); - - IPC_RETURN_NO_ERROR; -} - -/** - * PERFORMANCE POINT: - * Realloc is performed at each new user. There is plenty of room for improvement, - * for example by managing allocations of thousands of structures at once. - * WARNING: Store and remove only pointers on allocated structures. - */ -struct ipc_error ipc_ctx_new_alloc (struct ipc_ctx *ctx) -{ - ctx->size++; - - // Memory could be not allocated, yet. - if (ctx->size == 1 && ctx->cinfos == NULL && ctx->pollfd == NULL) { - SECURE_BUFFER_HEAP_ALLOCATION_R (ctx->cinfos, sizeof (struct ipc_connection_info),, - IPC_ERROR_ADD__MALLOC); - SECURE_BUFFER_HEAP_ALLOCATION_R (ctx->pollfd, sizeof (struct pollfd),, IPC_ERROR_ADD__MALLOC_POLLFD); - } else { - ctx->cinfos = realloc (ctx->cinfos, sizeof (struct ipc_connection_info) * ctx->size); - ctx->pollfd = realloc (ctx->pollfd, sizeof (struct pollfd ) * ctx->size); - } - - T_R ((ctx->cinfos == NULL), IPC_ERROR_ADD__EMPTY_LIST); - T_R ((ctx->pollfd == NULL), IPC_ERROR_ADD__EMPTY_LIST); - - // Clean the last entry. - memset (&ctx->cinfos[ctx->size -1], 0, sizeof (struct ipc_connection_info)); - memset (&ctx->pollfd[ctx->size -1], 0, sizeof (struct pollfd)); - - IPC_RETURN_NO_ERROR; -} - struct ipc_error ipc_server_init (struct ipc_ctx *ctx, const char *sname) { T_R ((sname == NULL), IPC_ERROR_SERVER_INIT__NO_SERVER_NAME_PARAM); @@ -194,7 +147,6 @@ struct ipc_error ipc_close (struct ipc_ctx *ctx, uint32_t index) struct ipc_error ret = usock_close (ctx->pollfd[index].fd); // TODO: verify that the close was OK?? - if (ctx->cinfos[index].type == IPC_CONNECTION_TYPE_SERVER) { ret = usock_remove (ctx->cinfos[index].spath); if (ctx->cinfos[index].spath != NULL) { @@ -319,7 +271,7 @@ struct ipc_error ipc_del (struct ipc_ctx *ctx, uint32_t index) if (ctx->size == 0) { // free ctx->cinfos and ctx->pollfd - ipc_connections_free (ctx); + ipc_ctx_free (ctx); IPC_RETURN_NO_ERROR; } @@ -338,22 +290,6 @@ struct ipc_error ipc_del (struct ipc_ctx *ctx, uint32_t index) IPC_RETURN_NO_ERROR; } -void ipc_connections_free (struct ipc_ctx *ctx) -{ - if (ctx->cinfos != NULL) { - free (ctx->cinfos); - free (ctx->pollfd); - ctx->cinfos = NULL; - ctx->pollfd = NULL; - } - - if (ctx->switchdb.collection != NULL) { - free (ctx->switchdb.collection); - ctx->switchdb.collection = NULL; - } - ctx->size = 0; -} - // add an arbitrary file descriptor to read struct ipc_error ipc_add_fd (struct ipc_ctx *ctx, int fd) { @@ -385,8 +321,6 @@ struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd) } -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) { int txfd = ctx->pollfd[index].fd; diff --git a/src/context.c b/src/context.c new file mode 100644 index 0000000..5438cf7 --- /dev/null +++ b/src/context.c @@ -0,0 +1,46 @@ +#include "ipc.h" + +/** + * PERFORMANCE POINT: + * Realloc is performed at each new user. There is plenty of room for improvement, + * for example by managing allocations of thousands of structures at once. + * WARNING: Store and remove only pointers on allocated structures. + */ +struct ipc_error ipc_ctx_new_alloc (struct ipc_ctx *ctx) +{ + ctx->size++; + + // Memory could be not allocated, yet. + if (ctx->size == 1 && ctx->cinfos == NULL && ctx->pollfd == NULL) { + SECURE_BUFFER_HEAP_ALLOCATION_R (ctx->cinfos, sizeof (struct ipc_connection_info),, + IPC_ERROR_ADD__MALLOC); + SECURE_BUFFER_HEAP_ALLOCATION_R (ctx->pollfd, sizeof (struct pollfd),, IPC_ERROR_ADD__MALLOC_POLLFD); + } else { + ctx->cinfos = realloc (ctx->cinfos, sizeof (struct ipc_connection_info) * ctx->size); + ctx->pollfd = realloc (ctx->pollfd, sizeof (struct pollfd ) * ctx->size); + } + + T_R ((ctx->cinfos == NULL), IPC_ERROR_ADD__EMPTY_LIST); + T_R ((ctx->pollfd == NULL), IPC_ERROR_ADD__EMPTY_LIST); + + // Clean the last entry. + memset (&ctx->cinfos[ctx->size -1], 0, sizeof (struct ipc_connection_info)); + memset (&ctx->pollfd[ctx->size -1], 0, sizeof (struct pollfd)); + + IPC_RETURN_NO_ERROR; +} + +void ipc_ctx_free (struct ipc_ctx *ctx) +{ + if (ctx->cinfos != NULL) { + free (ctx->cinfos); + ctx->cinfos = NULL; + } + if (ctx->pollfd != NULL) { + free (ctx->pollfd); + ctx->pollfd = NULL; + } + ctx->size = 0; + + ipc_messages_free (&ctx->tx); +} diff --git a/src/ipc.h b/src/ipc.h index 6cd6185..6dd5dc6 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -221,11 +221,11 @@ struct ipc_connection_info { }; struct ipc_message { - char type; - char user_type; - uint32_t length; + char type; // Internal message type. + char user_type; // User-defined message type. + int fd; // File descriptor concerned about this message. + uint32_t length; // Payload length. char *payload; - int fd; // File descriptor concerned about this message. }; struct ipc_messages { @@ -306,6 +306,8 @@ struct ipc_error ipc_connection (struct ipc_ctx *ctx, const char *sname); struct ipc_error ipc_close (struct ipc_ctx *ctx, uint32_t index); struct ipc_error ipc_close_all (struct ipc_ctx *ctx); +void ipc_ctx_free (struct ipc_ctx *ctx); + struct ipc_error ipc_read (const struct ipc_ctx *, uint32_t index, struct ipc_message *m); struct ipc_error ipc_write (struct ipc_ctx *, const struct ipc_message *m); @@ -316,10 +318,8 @@ struct ipc_error ipc_add (struct ipc_ctx *, struct ipc_connection_info *, struct struct ipc_error ipc_del (struct ipc_ctx *, uint32_t index); // add an arbitrary file descriptor to read -struct ipc_error ipc_add_fd (struct ipc_ctx *cinfos, int fd); -struct ipc_error ipc_del_fd (struct ipc_ctx *cinfos, int fd); - -void ipc_connections_free (struct ipc_ctx *); +struct ipc_error ipc_add_fd (struct ipc_ctx *ctx, int fd); +struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd); /*** * message functions @@ -349,6 +349,10 @@ void ipc_messages_free (struct ipc_messages *); **/ struct ipc_error ipc_write_fd (int fd, const struct ipc_message *m); +struct ipc_error ipc_ctx_new_alloc (struct ipc_ctx *ctx); +struct ipc_error service_path (char *path, const char *sname); + +struct ipc_error handle_writing_message (struct ipc_event *event, struct ipc_ctx *ctx, uint32_t index); /** * Used by ipc_server_init and ipc_connection diff --git a/src/message.c b/src/message.c index b29ec07..35a238d 100644 --- a/src/message.c +++ b/src/message.c @@ -200,6 +200,5 @@ void ipc_messages_free (struct ipc_messages *messages) free(messages->messages); messages->messages = 0; } - free(messages); } } diff --git a/src/service_path.c b/src/service_path.c new file mode 100644 index 0000000..7004a05 --- /dev/null +++ b/src/service_path.c @@ -0,0 +1,19 @@ +#include "ipc.h" + +struct ipc_error +service_path (char *path, const char *sname) +{ + T_R ((path == NULL), IPC_ERROR_SERVICE_PATH__NO_PATH); + T_R ((sname == NULL), IPC_ERROR_SERVICE_PATH__NO_SERVICE_NAME); + + memset (path, 0, PATH_MAX); + + char *rundir = getenv ("IPC_RUNDIR"); + if (rundir == NULL) + rundir = RUNDIR; + + snprintf (path, PATH_MAX - 1, "%s/%s", rundir, sname); + + IPC_RETURN_NO_ERROR; +} + diff --git a/tests/func_02_pong.c b/tests/func_02_pong.c index 4859786..11c9b35 100644 --- a/tests/func_02_pong.c +++ b/tests/func_02_pong.c @@ -36,6 +36,7 @@ void non_interactive () ipc_message_empty (&m); TEST_IPC_Q(ipc_close_all (&ctx), EXIT_FAILURE); + ipc_ctx_free (&ctx); } #if 0