From 944feef43465caf4ffafc8106373bfbd0d9a090f Mon Sep 17 00:00:00 2001 From: DTB Date: Wed, 3 Jul 2024 16:07:02 -0600 Subject: [PATCH] dj(1): Refactor out Io_fdseek entirely --- src/dj.c | 93 +++++++++++++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/src/dj.c b/src/dj.c index 8c9f327..96085e3 100644 --- a/src/dj.c +++ b/src/dj.c @@ -129,52 +129,6 @@ Io_fdopen(struct Io *io, char *fn){ return fd; } -/* Seeks io->seek bytes through *io's file descriptor, subtracting the number - * of sought bytes from io->seek. This procedure leaves garbage in io->buf. - * Read/written bytes here aren't counted in the statistics because successful - * seeking is guaranteed. */ -static void -Io_fdseek(struct Io *io){ - - assert(io != NULL); - assert(io->fd != STDIN_FILENO || io->fl == read_flags); - assert(io->fd != STDOUT_FILENO || io->fl == write_flags); - - if(io->seek == 0 - || (!fdisstd(io->fd) && lseek(io->fd, io->seek, SEEK_SET) != -1)){ - io->seek = 0; - return; - } - - if(io->fl == write_flags) - memset(io->buf, '\0', io->bs); - - 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 - assert(0); /* UNREACHABLE */ - - io->bufuse = 0; - - return; -} - /* Reads io->bs bytes from *io's file descriptor into io->buf, storing the * number of read bytes in io->bufuse and updating io->bytes. If io->bufuse is * 0, errno will probably be set. Returns io. */ @@ -307,24 +261,61 @@ int main(int argc, char *argv[]){ } } + assert(io->fd != STDIN_FILENO || io->fl == read_flags); + assert(io->fd != STDOUT_FILENO || io->fl == write_flags); if(argc > optind){ return usage(program_name); } for(i = 0; i < 2; ++i){ + /* buffer allocation */ if((io[i].buf = malloc(io[i].bs * (sizeof *(io[i].buf)))) == NULL){ fprintf(stderr, "%s: Failed to allocate %d bytes\n", program_name, io[i].bs); return EX_OSERR; - }else if(io[i].seek > 0){ - Io_fdseek(&io[i]); - if(io[i].seek > 0){ - return oserr(io[i].fn); - } } + /* easy seeking */ + if(!fdisstd(io[i].fd) && lseek(io[i].fd, io[i].seek, SEEK_SET) != -1) + io[i].seek = 0; } + /* hard skipping */ + if(io[0].seek > 0){ + do{ + if((io[0].bufuse = read( + io[0].fd, io[0].buf, MIN(io[0].bs, io[0].seek))) + == 0) + /* second chance */ + io->bufuse = read( + io[0].fd, io[0].buf, MIN(io[0].bs, io[0].seek)); + }while((io[0].seek -= io[0].bufuse) > 0 && io[0].bufuse != 0); + io[0].bufuse = 0; + } + + /* hard seeking */ + if(io[1].seek > 0){ + memset(io[1].buf, '\0', io[1].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[1].bufuse = write( + io[1].fd, io[1].buf, MIN(io[1].bs, io[1].seek))) + == 0) + /* second chance */ + io[1].bufuse = write( + io[1].fd, io[1].buf, MIN(io[1].bs, io[1].seek)); + }while((io[1].seek -= io[1].bufuse) > 0 && io[1].bufuse != 0); + io[1].bufuse = 0; + } + + /* Sought bytes aren't counted in the statistics because successful seeking + * is guaranteed here. */ + for(i = 0; i < 2; ++i) + if(io[i].seek > 0) + return oserr(io[i].fn); + do{ /* read */ Io_read(&io[0]); if(!noerror && io[0].bufuse == 0)