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
This commit is contained in:
Denis Vlasenko 2007-07-14 22:43:10 +00:00
parent fb79a2e2cf
commit 59a1f30450

View File

@ -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;