WIP: no mem leaks on simple use. switch still to test.

pollfd
Karchnu 2020-07-01 09:53:24 +02:00
parent f4ffd7386f
commit a5877101eb
7 changed files with 116 additions and 83 deletions

View File

@ -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 \

View File

@ -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;

46
src/context.c Normal file
View File

@ -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);
}

View File

@ -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

View File

@ -200,6 +200,5 @@ void ipc_messages_free (struct ipc_messages *messages)
free(messages->messages);
messages->messages = 0;
}
free(messages);
}
}

19
src/service_path.c Normal file
View File

@ -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;
}

View File

@ -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