summaryrefslogtreecommitdiff
path: root/usr.bin/sort/fsort.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/sort/fsort.c')
-rw-r--r--usr.bin/sort/fsort.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/usr.bin/sort/fsort.c b/usr.bin/sort/fsort.c
index 5f9485c20cf..6502a44a70b 100644
--- a/usr.bin/sort/fsort.c
+++ b/usr.bin/sort/fsort.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fsort.c,v 1.13 2006/10/18 23:30:43 millert Exp $ */
+/* $OpenBSD: fsort.c,v 1.14 2006/10/28 21:14:29 naddy Exp $ */
/*-
* Copyright (c) 1993
@@ -36,7 +36,7 @@
#if 0
static char sccsid[] = "@(#)fsort.c 8.1 (Berkeley) 6/6/93";
#else
-static char rcsid[] = "$OpenBSD: fsort.c,v 1.13 2006/10/18 23:30:43 millert Exp $";
+static char rcsid[] = "$OpenBSD: fsort.c,v 1.14 2006/10/28 21:14:29 naddy Exp $";
#endif
#endif /* not lint */
@@ -53,8 +53,8 @@ static char rcsid[] = "$OpenBSD: fsort.c,v 1.13 2006/10/18 23:30:43 millert Exp
#include <stdlib.h>
#include <string.h>
-u_char *buffer = NULL, *linebuf = NULL;
-size_t bufsize = BUFSIZE, linebuf_size = MAXLLEN;
+u_char **keylist = 0, *buffer = 0, *linebuf = 0;
+size_t bufsize, linebuf_size;
struct tempfile fstack[MAXFCT];
extern char toutpath[];
#define FSORTMAX 4
@@ -64,8 +64,8 @@ void
fsort(int binno, int depth, union f_handle infiles, int nfiles, FILE *outfp,
struct field *ftbl)
{
- u_char *bufend, *weights, **keypos, *tmpbuf;
- static u_char **keylist;
+ u_char *bufend, **keypos, *tmpbuf;
+ u_char *weights;
int ntfiles, mfct = 0, total, i, maxb, lastb, panic = 0;
int c, nelem;
long sizes[NBINS+1];
@@ -85,11 +85,18 @@ fsort(int binno, int depth, union f_handle infiles, int nfiles, FILE *outfp,
tfield[0].weights = ascii;
tfield[0].icol.num = 1;
weights = ftbl[0].weights;
- bufend = buffer + bufsize;
- if (keylist == NULL) {
- if ((keylist = calloc(MAXNUM, sizeof(u_char *))) == NULL)
- err(2, NULL);
+ if (!buffer) {
+ bufsize = BUFSIZE;
+ if ((buffer = malloc(bufsize + 1)) == NULL ||
+ (keylist = calloc(MAXNUM, sizeof(u_char *))) == NULL)
+ errx(2, "cannot allocate memory");
+ if (!SINGL_FLD) {
+ linebuf_size = MAXLLEN;
+ if ((linebuf = malloc(linebuf_size)) == NULL)
+ errx(2, "cannot allocate memory");
+ }
}
+ bufend = buffer + bufsize;
if (binno >= 0) {
tfiles.top = infiles.top + nfiles;
get = getnext;
@@ -133,12 +140,9 @@ fsort(int binno, int depth, union f_handle infiles, int nfiles, FILE *outfp,
*/
if (c == BUFFEND && nelem == 0) {
bufsize *= 2;
- tmpbuf = realloc(buffer, bufsize);
- if (!tmpbuf)
+ buffer = realloc(buffer, bufsize);
+ if (!buffer)
err(2, "failed to realloc buffer");
- crec = (RECHEADER *)
- (tmpbuf + ((u_char *)crec - buffer));
- buffer = tmpbuf;
bufend = buffer + bufsize;
continue;
}
@@ -153,6 +157,27 @@ fsort(int binno, int depth, union f_handle infiles, int nfiles, FILE *outfp,
mfct++;
/* reduce number of open files */
if (mfct == 16 ||(c == EOF && ntfiles)) {
+ /*
+ * Only copy extra incomplete
+ * crec data if there is any.
+ */
+ int nodata = (bufend
+ >= (u_char *)crec
+ && bufend <= crec->data);
+ size_t sz = 0;
+
+ if (!nodata) {
+ sz = bufend
+ - crec->data;
+ tmpbuf = malloc(sz);
+ if (tmpbuf == NULL)
+ errx(2, "cannot"
+ " allocate"
+ " memory");
+ memmove(tmpbuf,
+ crec->data, sz);
+ }
+
fstack[tfiles.top + ntfiles].fp
= ftmp();
fmerge(0, mstart, mfct, geteasy,
@@ -160,6 +185,12 @@ fsort(int binno, int depth, union f_handle infiles, int nfiles, FILE *outfp,
putrec, ftbl);
ntfiles++;
mfct = 0;
+
+ if (!nodata) {
+ memmove(crec->data,
+ tmpbuf, sz);
+ free(tmpbuf);
+ }
}
} else {
fstack[tfiles.top + ntfiles].fp= ftmp();