Don't use buffered IO (fread) when not appropriate
fread reads the entire requested size (BUFSIZ), which causes tools to block if only small amounts of data are available at a time. At best, this causes unnecessary copies and inefficiency, at worst, tools like tee and cat are almost unusable in some cases since they only display large chunks of data at a time.
This commit is contained in:
parent
5cb3a1eba1
commit
9a3b12525b
31
cksum.c
31
cksum.c
|
@ -1,7 +1,9 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <fcntl.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -61,19 +63,20 @@ static const unsigned long crctab[] = { 0x00000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cksum(FILE *fp, const char *s)
|
cksum(int fd, const char *s)
|
||||||
{
|
{
|
||||||
size_t len = 0, i, n;
|
ssize_t n;
|
||||||
|
size_t len = 0, i;
|
||||||
uint32_t ck = 0;
|
uint32_t ck = 0;
|
||||||
unsigned char buf[BUFSIZ];
|
unsigned char buf[BUFSIZ];
|
||||||
|
|
||||||
while ((n = fread(buf, 1, sizeof(buf), fp))) {
|
while ((n = read(fd, buf, sizeof(buf))) > 0) {
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
ck = (ck << 8) ^ crctab[(ck >> 24) ^ buf[i]];
|
ck = (ck << 8) ^ crctab[(ck >> 24) ^ buf[i]];
|
||||||
len += n;
|
len += n;
|
||||||
}
|
}
|
||||||
if (ferror(fp)) {
|
if (n < 0) {
|
||||||
weprintf("fread %s:", s ? s : "<stdin>");
|
weprintf("read %s:", s ? s : "<stdin>");
|
||||||
ret = 1;
|
ret = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -92,29 +95,29 @@ cksum(FILE *fp, const char *s)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
FILE *fp;
|
int fd;
|
||||||
|
|
||||||
argv0 = argv[0], argc--, argv++;
|
argv0 = argv[0], argc--, argv++;
|
||||||
|
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
cksum(stdin, NULL);
|
cksum(0, NULL);
|
||||||
} else {
|
} else {
|
||||||
for (; *argv; argc--, argv++) {
|
for (; *argv; argc--, argv++) {
|
||||||
if (!strcmp(*argv, "-")) {
|
if (!strcmp(*argv, "-")) {
|
||||||
*argv = "<stdin>";
|
*argv = "<stdin>";
|
||||||
fp = stdin;
|
fd = 0;
|
||||||
} else if (!(fp = fopen(*argv, "r"))) {
|
} else if ((fd = open(*argv, O_RDONLY)) < 0) {
|
||||||
weprintf("fopen %s:", *argv);
|
weprintf("open %s:", *argv);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cksum(fp, *argv);
|
cksum(fd, *argv);
|
||||||
if (fp != stdin && fshut(fp, *argv))
|
if (fd != 0)
|
||||||
ret = 1;
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
|
ret |= fshut(stdout, "<stdout>");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
2
crypt.h
2
crypt.h
|
@ -8,5 +8,5 @@ struct crypt_ops {
|
||||||
|
|
||||||
int cryptcheck(int, char **, struct crypt_ops *, uint8_t *, size_t);
|
int cryptcheck(int, char **, struct crypt_ops *, uint8_t *, size_t);
|
||||||
int cryptmain(int, char **, struct crypt_ops *, uint8_t *, size_t);
|
int cryptmain(int, char **, struct crypt_ops *, uint8_t *, size_t);
|
||||||
int cryptsum(struct crypt_ops *, FILE *, const char *, uint8_t *);
|
int cryptsum(struct crypt_ops *, int, const char *, uint8_t *);
|
||||||
void mdprint(const uint8_t *, const char *, size_t);
|
void mdprint(const uint8_t *, const char *, size_t);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "../crypt.h"
|
#include "../crypt.h"
|
||||||
#include "../text.h"
|
#include "../text.h"
|
||||||
|
@ -41,7 +43,7 @@ static void
|
||||||
mdchecklist(FILE *listfp, struct crypt_ops *ops, uint8_t *md, size_t sz,
|
mdchecklist(FILE *listfp, struct crypt_ops *ops, uint8_t *md, size_t sz,
|
||||||
int *formatsucks, int *noread, int *nonmatch)
|
int *formatsucks, int *noread, int *nonmatch)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
int fd;
|
||||||
size_t bufsiz = 0;
|
size_t bufsiz = 0;
|
||||||
int r;
|
int r;
|
||||||
char *line = NULL, *file, *p;
|
char *line = NULL, *file, *p;
|
||||||
|
@ -59,12 +61,12 @@ mdchecklist(FILE *listfp, struct crypt_ops *ops, uint8_t *md, size_t sz,
|
||||||
file += 2;
|
file += 2;
|
||||||
for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip newline */
|
for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip newline */
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
if (!(fp = fopen(file, "r"))) {
|
if ((fd = open(file, O_RDONLY)) < 0) {
|
||||||
weprintf("fopen %s:", file);
|
weprintf("open %s:", file);
|
||||||
(*noread)++;
|
(*noread)++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cryptsum(ops, fp, file, md)) {
|
if (cryptsum(ops, fd, file, md)) {
|
||||||
(*noread)++;
|
(*noread)++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +79,7 @@ mdchecklist(FILE *listfp, struct crypt_ops *ops, uint8_t *md, size_t sz,
|
||||||
} else {
|
} else {
|
||||||
(*formatsucks)++;
|
(*formatsucks)++;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
close(fd);
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
@ -124,11 +126,11 @@ cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz
|
||||||
int
|
int
|
||||||
cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
|
cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
int fd;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
if (cryptsum(ops, stdin, "<stdin>", md))
|
if (cryptsum(ops, 0, "<stdin>", md))
|
||||||
ret = 1;
|
ret = 1;
|
||||||
else
|
else
|
||||||
mdprint(md, "<stdin>", sz);
|
mdprint(md, "<stdin>", sz);
|
||||||
|
@ -136,18 +138,18 @@ cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
|
||||||
for (; *argv; argc--, argv++) {
|
for (; *argv; argc--, argv++) {
|
||||||
if ((*argv)[0] == '-' && !(*argv)[1]) {
|
if ((*argv)[0] == '-' && !(*argv)[1]) {
|
||||||
*argv = "<stdin>";
|
*argv = "<stdin>";
|
||||||
fp = stdin;
|
fd = 0;
|
||||||
} else if (!(fp = fopen(*argv, "r"))) {
|
} else if ((fd = open(*argv, O_RDONLY)) < 0) {
|
||||||
weprintf("fopen %s:", *argv);
|
weprintf("open %s:", *argv);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cryptsum(ops, fp, *argv, md))
|
if (cryptsum(ops, fd, *argv, md))
|
||||||
ret = 1;
|
ret = 1;
|
||||||
else
|
else
|
||||||
mdprint(md, *argv, sz);
|
mdprint(md, *argv, sz);
|
||||||
if (fp != stdin && fshut(fp, *argv))
|
if (fd != 0)
|
||||||
ret = 1;
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,16 +157,15 @@ cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cryptsum(struct crypt_ops *ops, FILE *fp, const char *f,
|
cryptsum(struct crypt_ops *ops, int fd, const char *f, uint8_t *md)
|
||||||
uint8_t *md)
|
|
||||||
{
|
{
|
||||||
uint8_t buf[BUFSIZ];
|
uint8_t buf[BUFSIZ];
|
||||||
size_t n;
|
ssize_t n;
|
||||||
|
|
||||||
ops->init(ops->s);
|
ops->init(ops->s);
|
||||||
while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)
|
while ((n = read(fd, buf, sizeof(buf))) > 0)
|
||||||
ops->update(ops->s, buf, n);
|
ops->update(ops->s, buf, n);
|
||||||
if (ferror(fp)) {
|
if (n < 0) {
|
||||||
weprintf("%s: read error:", f);
|
weprintf("%s: read error:", f);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
43
od.c
43
od.c
|
@ -1,8 +1,10 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -124,20 +126,23 @@ once:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
od(FILE *fp, char *fname, int last)
|
od(int fd, char *fname, int last)
|
||||||
{
|
{
|
||||||
static unsigned char *line;
|
static unsigned char *line;
|
||||||
static size_t lineoff;
|
static size_t lineoff;
|
||||||
static off_t addr;
|
static off_t addr;
|
||||||
unsigned char buf[BUFSIZ];
|
unsigned char buf[BUFSIZ];
|
||||||
size_t i, n, size = sizeof(buf);
|
size_t i, size = sizeof(buf);
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
while (skip - addr > 0) {
|
while (skip - addr > 0) {
|
||||||
n = fread(buf, 1, MIN(skip - addr, sizeof(buf)), fp);
|
n = read(fd, buf, MIN(skip - addr, sizeof(buf)));
|
||||||
|
if (n < 0)
|
||||||
|
weprintf("read %s:", fname);
|
||||||
|
if (n <= 0)
|
||||||
|
return n;
|
||||||
addr += n;
|
addr += n;
|
||||||
if (feof(fp) || ferror(fp))
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!line)
|
if (!line)
|
||||||
line = emalloc(linelen);
|
line = emalloc(linelen);
|
||||||
|
@ -145,7 +150,7 @@ od(FILE *fp, char *fname, int last)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (max >= 0)
|
if (max >= 0)
|
||||||
size = MIN(max - (addr - skip), size);
|
size = MIN(max - (addr - skip), size);
|
||||||
if (!(n = fread(buf, 1, size, fp)))
|
if ((n = read(fd, buf, size)) <= 0)
|
||||||
break;
|
break;
|
||||||
for (i = 0; i < n; i++, addr++) {
|
for (i = 0; i < n; i++, addr++) {
|
||||||
line[lineoff++] = buf[i];
|
line[lineoff++] = buf[i];
|
||||||
|
@ -155,10 +160,15 @@ od(FILE *fp, char *fname, int last)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
weprintf("read %s:", fname);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
if (lineoff && last)
|
if (lineoff && last)
|
||||||
printline(line, lineoff, addr - lineoff);
|
printline(line, lineoff, addr - lineoff);
|
||||||
if (last)
|
if (last)
|
||||||
printline((unsigned char *)"", 0, addr);
|
printline((unsigned char *)"", 0, addr);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -196,7 +206,7 @@ usage(void)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
FILE *fp;
|
int fd;
|
||||||
struct type *t;
|
struct type *t;
|
||||||
int ret = 0, len;
|
int ret = 0, len;
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -293,25 +303,26 @@ main(int argc, char *argv[])
|
||||||
linelen *= 2;
|
linelen *= 2;
|
||||||
|
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
od(stdin, "<stdin>", 1);
|
if (od(0, "<stdin>", 1) < 0)
|
||||||
|
ret = 1;
|
||||||
} else {
|
} else {
|
||||||
for (; *argv; argc--, argv++) {
|
for (; *argv; argc--, argv++) {
|
||||||
if (!strcmp(*argv, "-")) {
|
if (!strcmp(*argv, "-")) {
|
||||||
*argv = "<stdin>";
|
*argv = "<stdin>";
|
||||||
fp = stdin;
|
fd = 0;
|
||||||
} else if (!(fp = fopen(*argv, "r"))) {
|
} else if ((fd = open(*argv, O_RDONLY)) < 0) {
|
||||||
weprintf("fopen %s:", *argv);
|
weprintf("open %s:", *argv);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
od(fp, *argv, (!*(argv + 1)));
|
if (od(fd, *argv, (!*(argv + 1))) < 0)
|
||||||
if (fp != stdin && fshut(fp, *argv))
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
if (fd != 0)
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>") |
|
ret |= fshut(stdout, "<stdout>") | fshut(stderr, "<stderr>");
|
||||||
fshut(stderr, "<stderr>");
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
39
tee.c
39
tee.c
|
@ -1,6 +1,7 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -13,14 +14,15 @@ usage(void)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
FILE **fps = NULL;
|
int *fds = NULL;
|
||||||
size_t i, n, nfps;
|
size_t i, nfds;
|
||||||
int ret = 0, aflag = 0, iflag = 0;
|
ssize_t n;
|
||||||
|
int ret = 0, aflag = O_TRUNC, iflag = 0;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'a':
|
case 'a':
|
||||||
aflag = 1;
|
aflag = O_APPEND;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
iflag = 1;
|
iflag = 1;
|
||||||
|
@ -31,31 +33,28 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (iflag && signal(SIGINT, SIG_IGN) == SIG_ERR)
|
if (iflag && signal(SIGINT, SIG_IGN) == SIG_ERR)
|
||||||
eprintf("signal:");
|
eprintf("signal:");
|
||||||
nfps = argc + 1;
|
nfds = argc + 1;
|
||||||
fps = ecalloc(nfps, sizeof(*fps));
|
fds = ecalloc(nfds, sizeof(*fds));
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (!(fps[i] = fopen(argv[i], aflag ? "a" : "w"))) {
|
if ((fds[i] = open(argv[i], O_WRONLY|O_CREAT|aflag, 0666)) < 0) {
|
||||||
weprintf("fopen %s:", argv[i]);
|
weprintf("open %s:", argv[i]);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fps[i] = stdout;
|
fds[i] = 1;
|
||||||
|
|
||||||
while ((n = fread(buf, 1, sizeof(buf), stdin))) {
|
while ((n = read(0, buf, sizeof(buf))) > 0) {
|
||||||
for (i = 0; i < nfps; i++) {
|
for (i = 0; i < nfds; i++) {
|
||||||
if (fps[i] && fwrite(buf, 1, n, fps[i]) != n) {
|
if (fds[i] >= 0 && writeall(fds[i], buf, n) < 0) {
|
||||||
fshut(fps[i], (i != argc) ? argv[i] : "<stdout>");
|
weprintf("write %s:", (i != argc) ? argv[i] : "<stdout>");
|
||||||
fps[i] = NULL;
|
fds[i] = -1;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (n < 0)
|
||||||
ret |= fshut(stdin, "<stdin>");
|
eprintf("read <stdin>:");
|
||||||
for (i = 0; i < nfps; i++)
|
|
||||||
if (fps[i])
|
|
||||||
ret |= fshut(fps[i], (i != argc) ? argv[i] : "<stdout>");
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user