summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2007-07-14 22:43:10 +0000
committerDenis Vlasenko2007-07-14 22:43:10 +0000
commit59a1f3045073c92c661035f87bdf7e28099358eb (patch)
treed69a4bcc1059e2bf9ed2e6bb59d26d408a16fac1
parentfb79a2e2cfe33002398f1898c26d8e4f341db006 (diff)
downloadbusybox-59a1f3045073c92c661035f87bdf7e28099358eb.zip
busybox-59a1f3045073c92c661035f87bdf7e28099358eb.tar.gz
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@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
-rw-r--r--editors/vi.c99
1 files changed, 40 insertions, 59 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 01d45e5..fda29ac 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -229,7 +229,12 @@ static int mysleep(int); // sleep for 'h' 1/100 seconds
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 @@ static void edit_file(char * fn)
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 @@ static void colon(char * buf)
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 @@ static void colon(char * buf)
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 @@ static void colon(char * buf)
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 @@ static void colon(char * buf)
// 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 char *get_input_line(const char * prompt) // get input line- use "status
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 @@ static int file_insert(char * fn, char * p, int size)
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 @@ static int file_insert(char * fn, char * p, int size)
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;