From 0547eb36c4e3a1f78b0b42c8349b7d27cd320a82 Mon Sep 17 00:00:00 2001
From: Chris Allegretta <chrisa@asty.org>
Date: Mon, 22 Apr 2002 23:52:34 +0000
Subject: [PATCH] - General: - Change from read() and write() to file streams
 by Jay Carlson. Allows OS to implement read and write ahead rather than
 making us do it.  Hopefully merged properly

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1192 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog |   3 ++
 files.c   | 148 +++++++++++++++++++++++++++++++++++-------------------
 nano.c    |   7 ++-
 proto.h   |   2 +-
 4 files changed, 105 insertions(+), 55 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d3b784e7..29a2dc8e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,9 @@ CVS code -
 	  been wanting it for awhile now and we'll see how bad it messes
 	  everything up.  Changes to files.c:do_writeout(), write_file().
 	  Fixes for O_CREAT & append compatibililty by David Benbennick.
+	- Change from read() and write() to file streams by Jay Carlson.
+	  Allows OS to implement read and write ahead rather than making
+	  us do it.  Hopefully merged properly.
 - configure.ac:
 	- Define NDEBUG to silence asserts (David Benbennick).
 - files.c:
diff --git a/files.c b/files.c
index d3f4614b..7270b32b 100644
--- a/files.c
+++ b/files.c
@@ -100,27 +100,6 @@ void new_file(void)
 
 }
 
-int read_byte(int fd, char *filename, char *input)
-{
-    static char buf[BUFSIZ];
-    static int index = 0;
-    static int size = 0;
-
-    if (index == size) {
-	index = 0;
-	size = read(fd, buf, BUFSIZ);
-	if (size == -1) {
-	    size = index;	/* note index==0 */
-	    nperror(filename);
-	    return -1;
-	}
-	if (!size)
-	    return 0;
-    }
-    *input = buf[index++];
-    return 1;
-}
-
 filestruct *read_line(char *buf, filestruct * prev, int *line1ins)
 {
     filestruct *fileptr;
@@ -169,15 +148,15 @@ filestruct *read_line(char *buf, filestruct * prev, int *line1ins)
     return fileptr;
 }
 
-int read_file(int fd, char *filename, int quiet)
+int read_file(FILE *f, char *filename, int quiet)
 {
-    long size;
     int num_lines = 0;
     char input;		/* current input character */
     char *buf;
     long i = 0, bufx = 128;
     filestruct *fileptr = current, *tmp = NULL;
     int line1ins = 0;
+    int input_int;
 
     buf = charalloc(bufx);
     buf[0] = '\0';
@@ -191,8 +170,8 @@ int read_file(int fd, char *filename, int quiet)
 	line1ins = 1;
     }
     /* Read the entire file into file struct */
-    while ((size = read_byte(fd, filename, &input)) > 0) {
-
+    while ((input_int = getc(f)) != EOF) {
+        input = (char) input_int;
 #ifndef NANO_SMALL
 	if (!ISSET(NO_CONVERT) && input >= 0 && input <= 31
 		&& input != 127 && input != '\t' && input != '\r'
@@ -232,7 +211,13 @@ int read_file(int fd, char *filename, int quiet)
 	    buf[i + 1] = 0;
 	    i++;
 	}
-	totsize += size;
+	totsize++;
+    }
+
+    if (ferror(f)) {
+        /* This conditional duplicates previous read_byte(); behavior;
+           perhaps this could use some better handling. */
+        nperror(filename);
     }
 
     /* Did we not get a newline but still have stuff to do? */
@@ -283,7 +268,7 @@ int read_file(int fd, char *filename, int quiet)
     totlines += num_lines;
 
     free(buf);
-    close(fd);
+    fclose(f);
 
     return 1;
 }
@@ -293,6 +278,7 @@ int read_file(int fd, char *filename, int quiet)
 int open_file(char *filename, int insert, int quiet)
 {
     int fd;
+    FILE *f;
     struct stat fileinfo;
 
     if (!strcmp(filename, "") || stat(filename, &fileinfo) == -1) {
@@ -326,7 +312,12 @@ int open_file(char *filename, int insert, int quiet)
 	}
 	if (!quiet)
 	    statusbar(_("Reading File"));
-	read_file(fd, filename, quiet);
+	f = fdopen(fd, "rb"); /* Binary for our own line-end munging */
+	if (!f) {
+	    nperror("fdopen");
+	    return -1;
+	}
+	read_file(f, filename, quiet);
     }
 
     return 1;
@@ -1187,9 +1178,11 @@ int check_operating_dir(char *currpath, int allow_tabcomp)
 int write_file(char *name, int tmp, int append, int nonamechange)
 {
     long size, lineswritten = 0;
-    char *buf = NULL, prechar;
+    char *buf = NULL;
     filestruct *fileptr;
-    int fd, fd2, mask = 0, realexists, anyexists;
+    FILE *f;
+    int fd;
+    int mask = 0, realexists, anyexists;
     struct stat st, lst;
     char *realname = NULL;
 
@@ -1278,15 +1271,31 @@ int write_file(char *name, int tmp, int append, int nonamechange)
     }
 
     dump_buffer(fileage);
+
+    if (append == 1) {
+        f = fdopen(fd, "ab");
+    } else {
+        f = fdopen(fd, "wb");
+    }
+
+    if (!f) {
+        statusbar(_("Could not open file for writing: %s"),
+                  strerror(errno));
+        return -1;
+    }
+
     while (fileptr != NULL && fileptr->next != NULL) {
+	int data_len;
 	/* Next line is so we discount the "magic line" */
 	if (filebot == fileptr && fileptr->data[0] == '\0')
 	    break;
 
-	size = write(fd, fileptr->data, strlen(fileptr->data));
-	if (size == -1) {
+	data_len = strlen(fileptr->data);
+	size = fwrite(fileptr->data, 1, data_len, f);
+	if (size < data_len) {
 	    statusbar(_("Could not open file for writing: %s"),
 		      strerror(errno));
+            fclose(f);
 	    return -1;
 	} else {
 #ifdef DEBUG
@@ -1295,50 +1304,53 @@ int write_file(char *name, int tmp, int append, int nonamechange)
 	}
 #ifndef NANO_SMALL
 	if (ISSET(DOS_FILE) || ISSET(MAC_FILE))
-	    write(fd, "\r", 1);
+	    putc('\r', f);
 
 	if (!ISSET(MAC_FILE))
 #endif
-	    write(fd, "\n", 1);
+	    putc('\n', f);
 
 	fileptr = fileptr->next;
 	lineswritten++;
     }
 
     if (fileptr != NULL) {
-	size = write(fd, fileptr->data, strlen(fileptr->data));
-	if (size == -1) {
+        int data_len;
+
+        data_len = strlen(fileptr->data);
+	size = fwrite(fileptr->data, 1, data_len, f);
+	if (size < data_len) {
 	    statusbar(_("Could not open file for writing: %s"),
 		      strerror(errno));
 	    return -1;
-	} else if (size > 0) {
+	} else if (data_len > 0) {
 #ifndef NANO_SMALL
 	    if (ISSET(DOS_FILE) || ISSET(MAC_FILE)) {
-		size = write(fd, "\r", 1);
-		lineswritten++;
-		if (size == -1) {
+		if (putc('\r', f) == EOF) {
 		    statusbar(_("Could not open file for writing: %s"),
 			  strerror(errno));
+		    fclose(f);
 		    return -1;
 		}
+		lineswritten++;
 	    }
 
 	    if (!ISSET(MAC_FILE))
 #endif
 	    {
-		size = write(fd, "\n", 1);
-		lineswritten++;
-		if (size == -1) {
+		if (putc('\n', f) == EOF) {
 		    statusbar(_("Could not open file for writing: %s"),
 			  strerror(errno));
+		    fclose(f);
 		    return -1;
 		}
+		lineswritten++;
 	    }
 	}
     }
 
 
-    if (close(fd) == -1) {
+    if (fclose(f)) {
 	statusbar(_("Could not close %s: %s"), realname, strerror(errno));
 	unlink(buf);
 	return -1;
@@ -1346,22 +1358,52 @@ int write_file(char *name, int tmp, int append, int nonamechange)
 
     /* if we're prepending, open the real file, and append it here */
     if (append == 2) {
-	if ((fd = open(buf, O_WRONLY | O_APPEND, (S_IRUSR|S_IWUSR))) == -1) {
+      int fd_source, fd_dest;
+      FILE *f_source, *f_dest;
+      int prechar;
+
+	if ((fd_dest = open(buf, O_WRONLY | O_APPEND, (S_IRUSR|S_IWUSR))) == -1) {
 	    statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
 	    return -1;
 	}
-	if ((fd2 = open(realname, O_RDONLY | O_CREAT)) == -1) {
-	    statusbar(_("Could not open %s for prepend: %s"), realname,
-		strerror(errno));
+	f_dest = fdopen(fd_dest, "wb");
+	if (!f_dest) {
+	    statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
+            close(fd_dest);
+	    return -1;
+	}
+	if ((fd_source = open(realname, O_RDONLY)) == -1) {
+	    statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
+            fclose(f_dest);
+	    return -1;
+	}
+	f_source = fdopen(fd_source, "rb");
+	if (!f_source) {
+	    statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
+	    fclose(f_dest);
+	    close(fd_source);
 	    return -1;
 	}
 
-	while (read(fd2, &prechar, 1) > 0)
-	    write(fd, &prechar, 1);
-
-	close(fd);
-	close(fd2);
+        /* Doing this in blocks is an exercise left to some other reader. */
+	while ((prechar = getc(f_source)) != EOF) {
+	    if (putc(prechar, f_dest) == EOF) {
+		statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
+		fclose(f_source);
+		fclose(f_dest);
+		return -1;
+	    }
+	}
 
+	if (ferror(f_source)) {
+	    statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
+	    fclose(f_source);
+	    fclose(f_dest);
+	    return -1;
+	}
+	    
+	fclose(f_source);
+	fclose(f_dest);
     }
 
 
diff --git a/nano.c b/nano.c
index 6f1aa6d7..4cae80e5 100644
--- a/nano.c
+++ b/nano.c
@@ -1689,6 +1689,7 @@ RETSIGTYPE cancel_fork(int signal) {
 int open_pipe(char *command)
 {
     int fd[2];
+    FILE *f;
     struct sigaction oldaction, newaction;
 			/* original and temporary handlers for SIGINT */
 #ifdef _POSIX_VDISABLE
@@ -1764,7 +1765,11 @@ int open_pipe(char *command)
     }
 #endif   /* _POSIX_VDISABLE */
 
-    read_file(fd[0],"stdin",0);
+    f = fdopen(fd[0], "rb");
+    if (!f)
+      nperror("fdopen");
+    
+    read_file(f, "stdin", 0);
     set_modified();
 
     if (wait(NULL) == -1)
diff --git a/proto.h b/proto.h
index 8fc8b922..b6cff36b 100644
--- a/proto.h
+++ b/proto.h
@@ -125,7 +125,7 @@ int do_insertfile(int loading_file);
 int length_of_list(shortcut *s);
 int num_of_digits(int n);
 int open_pipe(char *command);
-int read_file(int fd, char *filename, int quiet);
+int read_file(FILE *f, char *filename, int quiet);
 
 #ifdef ENABLE_MULTIBUFFER
 int add_open_file(int update);
-- 
GitLab