From 58245c9484ca74ad2d71d0dbe63b861820c65db9 Mon Sep 17 00:00:00 2001 From: DTB Date: Thu, 22 Feb 2024 19:27:14 -0700 Subject: [PATCH] dj(1): remove function pointer hijinks (fixes #66) --- src/dj.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/dj.c b/src/dj.c index d5bd59c..8a6732c 100644 --- a/src/dj.c +++ b/src/dj.c @@ -203,28 +203,28 @@ Io_fdseek(struct Io *io){ if(!fdisstd(io->fd) && lseek(io->fd, io->seek, SEEK_SET) != -1) return -1; - else if(io->fl == write_flags){ - memset(io->buf, '\0', io->bs); - /* This is a dirty trick; rather than testing conditions and operating - * likewise, because the parameters to read or write are going to be - * the same either way, just use a function pointer to keep track of - * the intended operation. */ - op = (int (*)(int, void *, size_t))&write; - /* Function pointer casts are risky; this works because the difference - * is in the second parameter and only that write(2) makes the buffer - * const whereas read(2) does not. To avoid even the slightest - * undefined behavior comment out the cast, just be ready for a - * -Wincompatible-function-pointer-types if your compiler notices it. - */ - }else - op = &read; - /* We're going to cheat and use bufuse as the retval for write(2), which is - * fine because it'll be zeroed as this function returns anyway. */ - do{ if( (io->bufuse = (*op)(io->fd, io->buf, MIN(io->bs, io->seek))) == 0) - /* second chance */ - io->bufuse = (*op)(io->fd, io->buf, MIN(io->bs, io->seek)); - }while((io->seek -= io->bufuse) > 0 && io->bufuse != 0); + /* repeated code to get the condition out of the loop */ + if(io->fl == write_flags){ + memset(io->buf, '\0', io->bs); + /* We're going to cheat and use bufuse as the retval for write(2), + * which is fine because it'll be zeroed as this function returns + * anyway. */ + do{ + if((io->bufuse = write(io->fd, io->buf, MIN(io->bs, io->seek))) + == 0) + /* second chance */ + io->bufuse = write(io->fd, io->buf, MIN(io->bs, io->seek)); + }while((io->seek -= io->bufuse) > 0 && io->bufuse != 0); + }else if(io->fl == read_flags){ + do{ + if((io->bufuse = read(io->fd, io->buf, MIN(io->bs, io->seek))) + == 0) + /* second chance */ + io->bufuse = read(io->fd, io->buf, MIN(io->bs, io->seek)); + }while((io->seek -= io->bufuse) > 0 && io->bufuse != 0); + }else + return EX_SOFTWARE; io->bufuse = 0;