From 45a880455d440deb05034f7562cb756eae5287d7 Mon Sep 17 00:00:00 2001 From: DTB Date: Wed, 26 Jun 2024 12:22:33 -0600 Subject: [PATCH] dj(1): refactor to build again and to get rid of globals --- src/dj.c | 81 +++++++++++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 48 deletions(-) diff --git a/src/dj.c b/src/dj.c index d4462e8..e41f350 100644 --- a/src/dj.c +++ b/src/dj.c @@ -25,6 +25,8 @@ #include /* EX_OK, EX_USAGE */ #include /* close(2), getopt(3), lseek(2), read(2), write(2), * optarg, optind, STDIN_FILENO, STDOUT_FILENO */ +#include /* S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, + S_IWUSR */ extern int errno; /* dj uses two structures that respectively correspond to the reading and @@ -41,47 +43,17 @@ struct Io{ int prec; /* partial records processed */ int rec; /* records processed */ long seek; /* bytes to seek/skip (will be 0 after skippage) (-sS) */ -} ep[2]; /* "engineered pipe"; also "extended play", for the deejay */ +}; -/* Additionally, the following global variables are used to store user options. - */ +/* To be assigned to main:fmt_output and used with output(). */ +static char *fmt_asv = "%d\037%d\036%d\037%d\035%d\036%d\034"; +static char *fmt_human = "%d+%d > %d+%d; %d > %d\n"; -/* (-a) */ static int align; /* Only the lower 8b are used but align is - * negative if no alignment is being done. */ - -/* (-c) */ static int count; /* 0 if dj(1) runs until no more reads are - * possible. */ - -/* ASCII field separator delimited statistics */ - static char *fmt_asv = "%d\037%d\036%d\037%d\035%d\036%d\034"; -/* human-readable statistics */ - static char *fmt_human = "%d+%d > %d+%d; %d > %d\n"; -/* pointer to chosen formatting */ -/* (-H) */ static char *fmt_output; /* fmt_asv (default) or fmt_human (-H) */ - -/* (-n) */ static char noerror; /* 0 - exits on partial reads or writes - * (default) - * 1 - retries on partial reads/writes - * (-n) */ - -/* Non-configurable defaults. */ -#define bs_default 1024 /* GNU dd(1) default; twice POSIX but a neat 2^10 */ static char *program_name = ""; static char *stdin_name = ""; static char *stdout_name = ""; -static int read_flags = O_RDONLY; /* These flags are consistent with Busybox */ -static int write_flags = O_WRONLY | O_CREAT; /* dd(1). */ - -/* Macro to set defaults for user-configurable options. */ -#define setdefaults do{ \ - align = -1; \ - count = 0; \ - fmt_output = fmt_asv; \ - noerror = 0; \ - ep[0].fl = read_flags; \ - Io_setdefaults(&ep[0]); \ - ep[1].fl = write_flags; \ - Io_setdefaults(&ep[1]); }while(0) +static int read_flags = O_RDONLY; /* Consistent with Busybox dd(1). */ +static int write_flags = O_WRONLY | O_CREAT; #define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -238,7 +210,7 @@ Io_read(struct Io *io){ static struct Io * Io_setdefaults(struct Io *io){ - io->bs = bs_default; + io->bs = 1024 /* bytes; 1 KiB */; /* GNU dd(1) default; POSIX says 512B */ io->buf = NULL; io->bytes = 0; io->fd = (io->fl == read_flags) ? STDIN_FILENO : STDOUT_FILENO; @@ -275,13 +247,13 @@ oserr(char *s){ } /* Prints statistics regarding the use of dj, particularly partially and - * completely read and written records, accessing ep and fmt_output. */ + * completely read and written records. */ static void -output(void){ +output(struct Io io[2], char *fmt){ - fprintf(stderr, fmt_output, - ep[0].rec, ep[0].prec, ep[1].rec, ep[1].prec, - ep[0].bytes, ep[1].bytes); + fprintf(stderr, fmt, + io[0].rec, io[0].prec, io[1].rec, io[1].prec, + io[0].bytes, io[1].bytes); return; } @@ -312,14 +284,27 @@ usage(void){ } int main(int argc, char *argv[]){ + int align; /* low 8b used, negative if no alignment is being done */ + int count; /* 0 if dj(1) runs until no more reads are possible */ + struct Io ep[2]; /* "engineered pipe"; also "extended play", for the DJ */ + char *fmt_output; /* fmt_asv (default) or fmt_human (-H) */ + char noerror; /* 0=exits (default) 1=retries on partial reads or writes */ int c; int i; - setdefaults; + /* Set defaults. */ + align = -1; + count = 0; + fmt_output = fmt_asv; + noerror = 0; + ep[0].fl = read_flags; + Io_setdefaults(&ep[0]); + ep[1].fl = write_flags; + Io_setdefaults(&ep[1]); if(argc > 0){ program_name = argv[0]; - while((c = getopt(argc, argv, "a:Ab:B:c:di:hHnqs:S:o:")) != -1) + while((c = getopt(argc, argv, "a:Ab:B:c:i:hHns:S:o:")) != -1) switch(c){ case 'i': case 'o': i = (c == 'o'); @@ -369,7 +354,7 @@ int main(int argc, char *argv[]){ }else if(ep[i].seek > 0) switch(Io_fdseek(&ep[i])){ case EX_OK: - output(); + output(ep, fmt_output); terminate(ep); return EX_OK; } @@ -384,7 +369,7 @@ int main(int argc, char *argv[]){ else if(ep[0].bufuse < ep[0].bs){ ++ep[0].prec; fprintf(stderr, "%s: Partial read:\n\t", program_name); - output(); + output(ep, fmt_output); if(!noerror) count = 1; if(align >= 0) @@ -410,7 +395,7 @@ int main(int argc, char *argv[]){ }else if(c > ep[1].bufuse && ep[1].bufuse > 0){ ep[1].prec += 1; fprintf(stderr, "%s: Partial write:\n\t", program_name); - output(); + output(ep, fmt_output); if(!noerror) count = 1; }else if(ep[1].bufuse == 0 && c < ep[1].bs) @@ -420,7 +405,7 @@ int main(int argc, char *argv[]){ }while(ep[0].bufuse > 0); }while(count == 0 || --count > 0); - output(); + output(ep, fmt_output); terminate(ep); return EX_OK;