Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] mapfile without HAVE_MMAP should not trim newlines



When memory mapping is not available, the mapfile module was using
readoutput() to slurp the file contents.  This metafies the contents
(which is necessary for return as a parameter value) but has the
side-effect of dropping trailing newlines.

Src/input.c has another file-slurping function stuff() which has the
side-effect of loading the input buffer.  This patch separates the
guts of stuff() into a separately-callable function and uses that in
mapfile.c to preserve the newlines.
diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c
index dd86fb596..84cdfea18 100644
--- a/Src/Modules/mapfile.c
+++ b/Src/Modules/mapfile.c
@@ -170,6 +170,8 @@ get_contents(char *fname)
 #ifdef USE_MMAP
     caddr_t mmptr;
     struct stat sbuf;
+#else
+    off_t size;
 #endif
     char *val;
     unmetafy(fname = ztrdup(fname), &fd);
@@ -196,12 +198,8 @@ get_contents(char *fname)
     close(fd);
 #else /* don't USE_MMAP */
     val = NULL;
-    if ((fd = open(fname, O_RDONLY | O_NOCTTY)) >= 0) {
-	LinkList ll;
-
-	if ((ll = readoutput(fd, 1, 0)))
-	    val = peekfirst(ll);
-    }
+    if ((size = zstuff(&val, fname)) > 0)
+	val = metafy(val, size, META_HEAPDUP);
 #endif /* USE_MMAP */
     free(fname);
     return val;
diff --git a/Src/input.c b/Src/input.c
index 4ed8f2ff2..8d7f44d7c 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -613,8 +613,8 @@ inungetc(int c)
 /* stuff a whole file into memory and return it */
 
 /**/
-char *
-ztuff(const char *fn)
+off_t
+zstuff(char **out, const char *fn)
 {
     FILE *in;
     char *buf;
@@ -622,20 +622,36 @@ ztuff(const char *fn)
 
     if (!(in = fopen(unmeta(fn), "r"))) {
 	zerr("can't open %s", fn);
-	return NULL;
+	return -1;
     }
+    queue_signals();
     fseek(in, 0, SEEK_END);
     len = ftell(in);
     fseek(in, 0, SEEK_SET);
     buf = (char *)zalloc(len + 1);
-    if (!(fread(buf, len, 1, in))) {
+    if (len && !(fread(buf, len, 1, in))) {
 	zerr("read error on %s", fn);
 	fclose(in);
-	return NULL;
+	unqueue_signals();
+	return -1;
     }
     fclose(in);
     buf[len] = '\0';
-    return buf;
+    *out = buf;
+    unqueue_signals();
+    return len;
+}
+
+/**/
+char *
+ztuff(const char *fn)
+{
+    char *buf;
+    off_t len = zstuff(&buf, fn);
+    if (len > 0)
+	return buf;
+    else
+	return NULL;
 }
 
 /* stuff a whole file into the input queue and print it */
@@ -644,26 +660,12 @@ ztuff(const char *fn)
 int
 stuff(char *fn)
 {
-    FILE *in;
     char *buf;
-    off_t len;
+    off_t len = zstuff(&buf, fn);
 
-    if (!(in = fopen(unmeta(fn), "r"))) {
-	zerr("can't open %s", fn);
+    if (len < 0)
 	return 1;
-    }
-    fseek(in, 0, SEEK_END);
-    len = ftell(in);
-    fseek(in, 0, SEEK_SET);
-    buf = (char *)zalloc(len + 1);
-    if (!(fread(buf, len, 1, in))) {
-	zerr("read error on %s", fn);
-	fclose(in);
-	zfree(buf, len + 1);
-	return 1;
-    }
-    fclose(in);
-    buf[len] = '\0';
+    
     fwrite(buf, len, 1, stderr);
     fflush(stderr);
     inputsetline(metafy(buf, len, META_REALLOC), INP_FREE);


Messages sorted by: Reverse Date, Date, Thread, Author