svn commit: trunk/busybox/editors

vda at busybox.net vda at busybox.net
Sat Jul 14 22:43:12 UTC 2007


Author: vda
Date: 2007-07-14 15:43:10 -0700 (Sat, 14 Jul 2007)
New Revision: 19090

Log:
vi: make status line less confusing when we open non-readable files,
require rood to use w! when saving non-writable files.
Patch by Natanael Copa <natanael.copa at gmail.com>

update_ro_status                                       -      73     +73
edit_file                                            819     822      +3
colon                                               3440    3425     -15
.rodata                                           128090  128058     -32
file_insert                                          288     235     -53
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 76/-100)           Total: -24 bytes
   text    data     bss     dec     hex filename
 673344    2740   13968  690052   a8784 busybox_old
 673320    2740   13968  690028   a876c busybox_unstripped


Modified:
   trunk/busybox/editors/vi.c


Changeset:
Modified: trunk/busybox/editors/vi.c
===================================================================
--- trunk/busybox/editors/vi.c	2007-07-14 22:07:14 UTC (rev 19089)
+++ trunk/busybox/editors/vi.c	2007-07-14 22:43:10 UTC (rev 19090)
@@ -229,7 +229,12 @@
 static char readit(void);	// read (maybe cursor) key from stdin
 static char get_one_char(void);	// read 1 char from stdin
 static int file_size(const char *);   // what is the byte size of "fn"
-static int file_insert(char *, char *, int);
+static int file_insert(char *, char *);
+#if ENABLE_FEATURE_VI_READONLY
+static void update_ro_status(const char *);
+#else
+static ALWAYS_INLINE void update_ro_status(const char *name) {}
+#endif
 static int file_write(char *, char *, char *);
 static void place_cursor(int, int, int);
 static void screen_erase(void);
@@ -419,8 +424,9 @@
 	new_text(size);		// get a text[] buffer
 	screenbegin = dot = end = text;
 	if (fn != 0) {
-		ch = file_insert(fn, text, cnt);
-	}
+		ch = file_insert(fn, text);
+		update_ro_status(fn);
+	} 
 	if (ch < 1) {
 		char_insert(text, '\n');	// start empty buf with dummy line
 	}
@@ -654,7 +660,6 @@
 	char *fn, cmd[MAX_LINELEN], args[MAX_LINELEN];
 	int i, l, li, ch, b, e;
 	int useforce = FALSE, forced = FALSE;
-	struct stat st_buf;
 
 	// :3154	// if (-e line 3154) goto it  else stay put
 	// :4,33w! foo	// write a portion of buffer to file "foo"
@@ -758,6 +763,7 @@
 		dot_skip_over_ws();
 	} else if (strncasecmp(cmd, "edit", i) == 0) {	// Edit a file
 		int sr;
+		struct stat st_buf;
 		sr= 0;
 		// don't edit, if the current file has been modified
 		if (file_modified && ! useforce) {
@@ -809,7 +815,8 @@
 		screenbegin = dot = end = text;
 
 		// insert new file
-		ch = file_insert(fn, text, file_size(fn));
+		ch = file_insert(fn, text);
+		update_ro_status(fn);
 
 		if (ch < 1) {
 			// start empty buf with dummy line
@@ -937,25 +944,15 @@
 		// read after current line- unless user said ":0r foo"
 		if (b != 0)
 			q = next_line(q);
-#if ENABLE_FEATURE_VI_READONLY
-		l = readonly;			// remember current files' status
-#endif
-		ch = file_insert(fn, q, file_size(fn));
-#if ENABLE_FEATURE_VI_READONLY
-		readonly = l;
-#endif
+		ch = file_insert(fn, q);
 		if (ch < 0)
 			goto vc1;	// nothing was inserted
 		// how many lines in text[]?
 		li = count_lines(q, q + ch - 1);
 		psb("\"%s\""
-#if ENABLE_FEATURE_VI_READONLY
-			"%s"
-#endif
+			USE_FEATURE_VI_READONLY("%s")
 			" %dL, %dC", fn,
-#if ENABLE_FEATURE_VI_READONLY
-			((vi_readonly || readonly) ? " [Read only]" : ""),
-#endif
+			USE_FEATURE_VI_READONLY(((vi_readonly || readonly) ? " [Read only]" : ""),)
 			li, ch);
 		if (ch > 0) {
 			// if the insert is before "dot" then we need to update
@@ -2399,37 +2396,22 @@
 static int file_size(const char * fn) // what is the byte size of "fn"
 {
 	struct stat st_buf;
-	int cnt, sr;
+	int cnt;
 
-	if (!fn || !fn[0])
-		return -1;
 	cnt = -1;
-	sr = stat(fn, &st_buf);	// see if file exists
-	if (sr >= 0) {
+	if (fn && fn[0] && stat(fn, &st_buf) == 0)	// see if file exists
 		cnt = (int) st_buf.st_size;
-	}
 	return cnt;
 }
 
-static int file_insert(char * fn, char * p, int size)
+static int file_insert(char * fn, char * p) 
 {
-	int fd, cnt;
-
-	cnt = -1;
-#if ENABLE_FEATURE_VI_READONLY
-	readonly = FALSE;
-#endif
-	if (!fn || !fn[0]) {
-		psbs("No filename given");
-		goto fi0;
-	}
-	if (size == 0) {
-		// OK- this is just a no-op
-		cnt = 0;
-		goto fi0;
-	}
+	int cnt = -1;
+	int fd, size;
+	
+	size = file_size(fn);
 	if (size < 0) {
-		psbs("Trying to insert a negative number (%d) of characters", size);
+		psbs("File does not exist");
 		goto fi0;
 	}
 	if (p < text || p > end) {
@@ -2437,25 +2419,11 @@
 		goto fi0;
 	}
 
-	// see if we can open the file
-#if ENABLE_FEATURE_VI_READONLY
-	if (vi_readonly) goto fi1;		// do not try write-mode
-#endif
-	fd = open(fn, O_RDWR);			// assume read & write
+	// read file to buffer
+	fd = open(fn, O_RDONLY);
 	if (fd < 0) {
-		// could not open for writing- maybe file is read only
-#if ENABLE_FEATURE_VI_READONLY
- fi1:
-#endif
-		fd = open(fn, O_RDONLY);	// try read-only
-		if (fd < 0) {
-			psbs("\"%s\" %s", fn, "cannot open file");
-			goto fi0;
-		}
-#if ENABLE_FEATURE_VI_READONLY
-		// got the file- read-only
-		readonly = TRUE;
-#endif
+		psbs("\"%s\" %s", fn, "cannot open file");
+		goto fi0;
 	}
 	p = text_hole_make(p, size);
 	cnt = read(fd, p, size);
@@ -2475,6 +2443,19 @@
 	return cnt;
 }
 
+#if ENABLE_FEATURE_VI_READONLY
+static void update_ro_status(const char *fn)
+{
+	struct stat sb;
+	if (stat(fn, &sb) == 0) {
+		readonly = vi_readonly || (access(fn, W_OK) < 0) ||
+			/* root will always have access()
+			 * so we check fileperms too */
+			!(sb.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH));
+	}
+}
+#endif
+
 static int file_write(char * fn, char * first, char * last)
 {
 	int fd, cnt, charcnt;




More information about the busybox-cvs mailing list