From 51d8f69fb152ae5a47151c2f132fd4263ec3d144 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sat, 14 Mar 2020 17:52:06 +0100 Subject: lib: Return number of written bytes on flow_write This is more in line with the write() system call and prepares for partial writes. Partial writes are disabled by default (and not yet implemented). Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- CMakeLists.txt | 2 +- doc/man/fccntl.3 | 5 ++++- doc/man/flow_read.3 | 24 +++++++++++++----------- include/ouroboros/fccntl.h | 19 ++++++++++--------- src/ipcpd/broadcast/enroll.c | 6 +++--- src/ipcpd/unicast/enroll.c | 6 +++--- src/lib/dev.c | 5 ++--- src/tools/obc/obc.c | 5 +++-- src/tools/ocbr/ocbr_client.c | 2 +- src/tools/oecho/oecho.c | 6 +++--- src/tools/operf/operf_client.c | 4 ++-- src/tools/oping/oping_client.c | 2 +- src/tools/ovpn/ovpn.c | 2 +- 13 files changed, 47 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f243cf4a..d89b028d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project(ouroboros C) include(GNUInstallDirs) set(PACKAGE_VERSION_MAJOR 0) -set(PACKAGE_VERSION_MINOR 16) +set(PACKAGE_VERSION_MINOR 17) set(PACKAGE_VERSION_PATCH 0) set(PACKAGE_NAME "${CMAKE_PROJECT_NAME}") diff --git a/doc/man/fccntl.3 b/doc/man/fccntl.3 index b0f1b3fb..87e23078 100644 --- a/doc/man/fccntl.3 +++ b/doc/man/fccntl.3 @@ -60,7 +60,10 @@ argument. Supported flags are: \fIFLOWFRNOPART\fR - disable partial reading. -\fIFLOWFDEFAULT\fR - set flow defaults (blocking, read-write). +\fIFLOWFWNOPART\fR - disable partial writing. + +\fIFLOWFDEFAULT\fR - set flow defaults (blocking, read-write, +no partial writes). .RE diff --git a/doc/man/flow_read.3 b/doc/man/flow_read.3 index 655f50b2..1a6c8eaf 100644 --- a/doc/man/flow_read.3 +++ b/doc/man/flow_read.3 @@ -12,9 +12,9 @@ flow_read, flow_write \- read and write from/to a flow .B #include -\fBint flow_read(int \fIfd\fB, void * \fIbuf\fB, size_t \fIcount\fB);\fR +\fBssize_t flow_read(int \fIfd\fB, void * \fIbuf\fB, size_t \fIcount\fB);\fR -\fBint flow_write(int \fIfd\fB, const void * \fIbuf\fB, size_t \fIcount\fB);\fR +\fBssize_t flow_write(int \fIfd\fB, const void * \fIbuf\fB, size_t \fIcount\fB);\fR Compile and link with \fI-louroboros-dev\fR. @@ -30,15 +30,17 @@ from the supplied buffer \fIbuf\fR to the flow specified by \fIfd\fR. .SH RETURN VALUE On success, \fBflow_read\fR() returns the number of bytes read. On -failure, a negative value indicating the error will be returned. If -the number of bytes read equals count, a subsequent call to -\fBflow_read\fR() should be performed to check if there were more -bytes to read. This call to \fBflow_read\fR will return 0 if there was -no more data and mark the end of the datagram. - -On success, \fBflow_write\fR() returns 0. On failure, a negative value -indicating the error will be returned. Passing a NULL pointer for -\fIbuf\fR returns 0 with no other effects. +failure, a negative value indicating the error will be +returned. Partial reads are enabled by default. If the number of bytes +read equals count, a subsequent call to \fBflow_read\fR() should be +performed to check if there were more bytes to read. This call to +\fBflow_read\fR will return 0 if there was no more data and mark the +end of the datagram. + +On success, \fBflow_write\fR() returns the number of bytes written. On +failure, a negative value indicating the error will be returned. +Partial writes needs to be explicitly enabled. Passing a +NULL pointer for \fIbuf\fR returns 0 with no other effects. .SH ERRORS .B -EINVAL diff --git a/include/ouroboros/fccntl.h b/include/ouroboros/fccntl.h index fac90134..965e281d 100644 --- a/include/ouroboros/fccntl.h +++ b/include/ouroboros/fccntl.h @@ -28,19 +28,20 @@ #include /* Flow flags, same values as fcntl.h */ -#define FLOWFRDONLY 00000000 /* Read-only flow */ -#define FLOWFWRONLY 00000001 /* Write-only flow */ -#define FLOWFRDWR 00000002 /* Read-write flow */ -#define FLOWFACCMODE 00000003 /* Access mask */ +#define FLOWFRDONLY 00000000 /* Read-only flow */ +#define FLOWFWRONLY 00000001 /* Write-only flow */ +#define FLOWFRDWR 00000002 /* Read-write flow */ +#define FLOWFACCMODE 00000003 /* Access mask */ -#define FLOWFDOWN 00000004 /* Flow is down */ +#define FLOWFDOWN 00000004 /* Flow is down */ -#define FLOWFRNOBLOCK 00001000 /* Non-blocking read */ -#define FLOWFWNOBLOCK 00002000 /* Non-blocking write */ +#define FLOWFRNOBLOCK 00001000 /* Non-blocking read */ +#define FLOWFWNOBLOCK 00002000 /* Non-blocking write */ #define FLOWFNONBLOCK (FLOWFRNOBLOCK | FLOWFWNOBLOCK) -#define FLOWFRNOPART 00004000 /* Disable partial reads */ +#define FLOWFRNOPART 00010000 /* Disable partial reads */ +#define FLOWFWNOPART 00020000 /* Disable partial writes */ -#define FLOWFDEFAULT FLOWFRDWR +#define FLOWFDEFAULT (FLOWFRDWR | FLOWFWNOPART) #define FLOWFINVALID (FLOWFWRONLY | FLOWFRDWR) diff --git a/src/ipcpd/broadcast/enroll.c b/src/ipcpd/broadcast/enroll.c index 36b82af1..511892b7 100644 --- a/src/ipcpd/broadcast/enroll.c +++ b/src/ipcpd/broadcast/enroll.c @@ -87,7 +87,7 @@ static int send_rcv_enroll_msg(int fd) clock_gettime(CLOCK_REALTIME, &t0); - if (flow_write(fd, buf, len)) { + if (flow_write(fd, buf, len) < 0) { log_dbg("Failed to send request message."); return -1; } @@ -222,7 +222,7 @@ static void * enroll_handle(void * o) log_dbg("Sending enrollment info (%zd bytes).", len); - if (flow_write(conn.flow_info.fd, reply, len)) { + if (flow_write(conn.flow_info.fd, reply, len) < 0) { log_err("Failed respond to enrollment request."); connmgr_dealloc(COMPID_ENROLL, &conn); free(reply); @@ -296,7 +296,7 @@ int enroll_done(struct conn * conn, enroll_msg__pack(&msg, buf); - if (flow_write(conn->flow_info.fd, buf, len)) { + if (flow_write(conn->flow_info.fd, buf, len) < 0) { log_dbg("Failed to send acknowledgment."); return -1; } diff --git a/src/ipcpd/unicast/enroll.c b/src/ipcpd/unicast/enroll.c index 6a612ff3..3b4a5a89 100644 --- a/src/ipcpd/unicast/enroll.c +++ b/src/ipcpd/unicast/enroll.c @@ -87,7 +87,7 @@ static int send_rcv_enroll_msg(int fd) clock_gettime(CLOCK_REALTIME, &t0); - if (flow_write(fd, buf, len)) { + if (flow_write(fd, buf, len) < 0) { log_dbg("Failed to send request message."); return -1; } @@ -238,7 +238,7 @@ static void * enroll_handle(void * o) log_dbg("Sending enrollment info (%zd bytes).", len); - if (flow_write(conn.flow_info.fd, reply, len)) { + if (flow_write(conn.flow_info.fd, reply, len) < 0) { log_err("Failed respond to enrollment request."); connmgr_dealloc(COMPID_ENROLL, &conn); free(reply); @@ -312,7 +312,7 @@ int enroll_done(struct conn * conn, enroll_msg__pack(&msg, buf); - if (flow_write(conn->flow_info.fd, buf, len)) { + if (flow_write(conn->flow_info.fd, buf, len) < 0) { log_dbg("Failed to send acknowledgment."); return -1; } diff --git a/src/lib/dev.c b/src/lib/dev.c index 8647bea9..80d7e9ad 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -1007,6 +1007,7 @@ ssize_t flow_write(int fd, if ((flags & FLOWFACCMODE) == FLOWFRDONLY) return -EPERM; + /* TODO: partial writes. */ if (flags & FLOWFWNOBLOCK) idx = shm_rdrbuff_alloc(ai.rdrb, count, @@ -1056,9 +1057,7 @@ ssize_t flow_write(int fd, pthread_rwlock_unlock(&ai.lock); - assert(ret <= 0); - - return ret; + return ret < 0 ? (ssize_t) ret : (ssize_t) count; } ssize_t flow_read(int fd, diff --git a/src/tools/obc/obc.c b/src/tools/obc/obc.c index eb5a42ce..256cb84e 100644 --- a/src/tools/obc/obc.c +++ b/src/tools/obc/obc.c @@ -88,7 +88,8 @@ static int reader_main(const char * dst) static int writer_main(const char * dst, const char * message) { - int fd = 0; + int fd = 0; + size_t len = strlen(message) + 1; fd = flow_join(dst, NULL, NULL); if (fd < 0) { @@ -96,7 +97,7 @@ static int writer_main(const char * dst, return -1; } - if (flow_write(fd, message, strlen(message) + 1) < 0) { + if (flow_write(fd, message, len) < 0) { printf("Failed to write packet.\n"); flow_dealloc(fd); return -1; diff --git a/src/tools/ocbr/ocbr_client.c b/src/tools/ocbr/ocbr_client.c index 6381a235..6120e1fd 100644 --- a/src/tools/ocbr/ocbr_client.c +++ b/src/tools/ocbr/ocbr_client.c @@ -135,7 +135,7 @@ int client_main(char * server, } else { /* flood */ while (!stop) { clock_gettime(CLOCK_REALTIME, &end); - if (flow_write(fd, buf, (size_t) size) < 0) { + if (flow_write(fd, buf, size) < 0) { stop = true; continue; } diff --git a/src/tools/oecho/oecho.c b/src/tools/oecho/oecho.c index f52f53de..a44b8b76 100644 --- a/src/tools/oecho/oecho.c +++ b/src/tools/oecho/oecho.c @@ -79,7 +79,7 @@ static int server_main(void) printf("Message from client is %.*s.\n", (int) count, buf); - if (flow_write(fd, buf, count) == -1) { + if (flow_write(fd, buf, count) < 0) { printf("Failed to write packet.\n"); flow_dealloc(fd); continue; @@ -93,10 +93,10 @@ static int server_main(void) static int client_main(void) { - int fd = 0; + int fd; char buf[BUF_SIZE]; char * message = "Client says hi!"; - ssize_t count = 0; + ssize_t count; fd = flow_alloc("oecho", NULL, NULL); if (fd < 0) { diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c index 3b0ff2af..004a8965 100644 --- a/src/tools/operf/operf_client.c +++ b/src/tools/operf/operf_client.c @@ -141,7 +141,7 @@ void * writer(void * o) msg->id = client.sent; - if (flow_write(*fdp, buf, client.size) == -1) { + if (flow_write(*fdp, buf, client.size) < 0) { printf("Failed to send packet.\n"); flow_dealloc(*fdp); free(buf); @@ -204,7 +204,7 @@ int client_main(void) else printf("Doing a unidirectional test.\n"); - if (flow_write(fd, &client.conf, sizeof(client.conf))) { + if (flow_write(fd, &client.conf, sizeof(client.conf)) < 0) { printf("Failed to send configuration.\n"); flow_dealloc(fd); return -1; diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index aa92be53..d0255b7c 100644 --- a/src/tools/oping/oping_client.c +++ b/src/tools/oping/oping_client.c @@ -175,7 +175,7 @@ void * writer(void * o) msg->tv_sec = now.tv_sec; msg->tv_nsec = now.tv_nsec; - if (flow_write(*fdp, buf, client.size) == -1) { + if (flow_write(*fdp, buf, client.size) < 0) { printf("Failed to send packet.\n"); flow_dealloc(*fdp); free(buf); diff --git a/src/tools/ovpn/ovpn.c b/src/tools/ovpn/ovpn.c index a3dd2ec6..02501d52 100644 --- a/src/tools/ovpn/ovpn.c +++ b/src/tools/ovpn/ovpn.c @@ -163,7 +163,7 @@ void * t_reader(void * o) if (len <= 0) continue; - if (flow_write(o_fd, buf, len)) + if (flow_write(o_fd, buf, len) < 0) continue; } } -- cgit v1.2.3