dj(1): fix option parsing regression

This commit is contained in:
dtb 2024-07-03 13:50:24 -06:00
parent d1eefcb37e
commit 064abb82a6
Signed by: trinity
GPG Key ID: 34C0543BBB6AF81B

View File

@ -19,7 +19,7 @@
#include <errno.h> /* errno */ #include <errno.h> /* errno */
#include <fcntl.h> /* open(2) */ #include <fcntl.h> /* open(2) */
#include <stdio.h> /* fprintf(3), stderr */ #include <stdio.h> /* fprintf(3), stderr */
#include <stdlib.h> /* free(3), malloc(3), strtol(3), size_t */ #include <stdlib.h> /* malloc(3), strtol(3), size_t */
#include <string.h> /* memcpy(3), memmove(3), memset(3) */ #include <string.h> /* memcpy(3), memmove(3), memset(3) */
#include <sysexits.h> /* EX_OK, EX_USAGE */ #include <sysexits.h> /* EX_OK, EX_USAGE */
#include <unistd.h> /* close(2), getopt(3), lseek(2), read(2), write(2), #include <unistd.h> /* close(2), getopt(3), lseek(2), read(2), write(2),
@ -64,15 +64,6 @@ static int write_flags = O_WRONLY | O_CREAT;
|| (fd) == STDOUT_FILENO \ || (fd) == STDOUT_FILENO \
|| (fd) == STDERR_FILENO) || (fd) == STDERR_FILENO)
/* Macro to call the cleanup functions that operate on struct io on the
* particular io[2] used in main. Error conditions are not checked because this
* is only used when the program is about to terminate (hence its name). */
#define terminate(io) do{ \
free((io[0]).buf); \
free((io[1]).buf); \
Io_fdclose(&(io)[0]); \
Io_fdclose(&(io)[1]); }while(0)
/* Allocates *io's buffer. Returns NULL if unsuccessful. */ /* Allocates *io's buffer. Returns NULL if unsuccessful. */
static void * static void *
Io_bufalloc(struct Io *io){ Io_bufalloc(struct Io *io){
@ -121,15 +112,6 @@ Io_bufxfer(struct Io *dest, struct Io *src, int n){
return dest; return dest;
} }
/* Closes io->fn and returns -1 on error, otherwise io->fd. */
static int
Io_fdclose(struct Io *io){
return fdisstd(io->fd)
? 0
: close(io->fd);
}
/* Opens io->fn and saves the file descriptor into io->fd. Returns io->fd, /* Opens io->fn and saves the file descriptor into io->fd. Returns io->fd,
* which will be -1 if an error occured. */ * which will be -1 if an error occured. */
static int static int
@ -140,7 +122,7 @@ Io_fdopen(struct Io *io, char *fn){
/* these are the flags used by touch(1p) */ /* these are the flags used by touch(1p) */
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH))
!= -1 != -1
&& Io_fdclose(io) == 0){ && (fdisstd(io->fd) || close(io->fd) == 0)){
io->fd = fd; io->fd = fd;
io->fn = fn; io->fn = fn;
} }
@ -294,7 +276,6 @@ int main(int argc, char *argv[]){
break; break;
}else if(Io_fdopen(&io[i], optarg) != -1) }else if(Io_fdopen(&io[i], optarg) != -1)
break; break;
terminate(io);
return oserr(optarg); return oserr(optarg);
case 'n': noerror = 1; break; case 'n': noerror = 1; break;
case 'H': fmt_output = fmt_human; break; case 'H': fmt_output = fmt_human; break;
@ -308,19 +289,18 @@ int main(int argc, char *argv[]){
if(c == 'c' && (count = parse(optarg)) >= 0) if(c == 'c' && (count = parse(optarg)) >= 0)
break; break;
i = (c >= 'A' && c <= 'Z'); /* uppercase changes output */ i = (c >= 'A' && c <= 'Z'); /* uppercase changes output */
c &= 0x20 /* 0b 0010 0000 */; /* (ASCII) make lowercase */ c |= 0x20 /* 0b 0010 0000 */; /* (ASCII) make lowercase */
if((c == 'b' && (io[i].bs = parse(optarg)) > 0) if((c == 'b' && (io[i].bs = parse(optarg)) > 0)
|| (c == 's' && (io[i].seek = parse(optarg)) >= 0)) || (c == 's' && (io[i].seek = parse(optarg)) >= 0))
break; break;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
terminate(io);
return usage(program_name); return usage(program_name);
} }
} }
if(argc > optind){ if(argc > optind){
terminate(io);
return usage(program_name); return usage(program_name);
} }
@ -328,12 +308,10 @@ int main(int argc, char *argv[]){
if(Io_bufalloc(&io[i]) == NULL){ if(Io_bufalloc(&io[i]) == NULL){
fprintf(stderr, "%s: Failed to allocate %d bytes\n", fprintf(stderr, "%s: Failed to allocate %d bytes\n",
program_name, io[i].bs); program_name, io[i].bs);
terminate(io);
return EX_OSERR; return EX_OSERR;
}else if(io[i].seek > 0) }else if(io[i].seek > 0)
Io_fdseek(&io[i]); Io_fdseek(&io[i]);
if(io[i].seek > 0){ if(io[i].seek > 0){
terminate(io);
return oserr(io[i].fn); return oserr(io[i].fn);
} }
} }
@ -387,7 +365,6 @@ int main(int argc, char *argv[]){
}while(count == 0 || --count > 0); }while(count == 0 || --count > 0);
output(io, fmt_output); output(io, fmt_output);
terminate(io);
return EX_OK; return EX_OK;
} }