vim-patch:8.1.0313: information about a swap file is unavailable

Problem:    Information about a swap file is unavailable.
Solution:   Add swapinfo(). (Enzo Ferber)
00f123a565
This commit is contained in:
Justin M. Keyes
2019-04-29 19:20:22 +02:00
parent a0d723db55
commit 24b7462b3c
5 changed files with 94 additions and 4 deletions

View File

@@ -16423,6 +16423,13 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
/// "swapinfo(swap_filename)" function
static void f_swapinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
get_b0_dict(tv_get_string(argvars), rettv->vval.v_dict);
}
/// "synID(lnum, col, trans)" function
static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{

View File

@@ -301,6 +301,7 @@ return {
strwidth={args=1},
submatch={args={1, 2}},
substitute={args=4},
swapinfo={args={1}},
synID={args=3},
synIDattr={args={2, 3}},
synIDtrans={args=1},

View File

@@ -1457,10 +1457,41 @@ static char *make_percent_swname(const char *dir, char *name)
static bool process_still_running;
#endif
/*
* Give information about an existing swap file.
* Returns timestamp (0 when unknown).
*/
/// Return information found in swapfile "fname" in dictionary "d".
/// This is used by the swapinfo() function.
void get_b0_dict(const char *fname, dict_T *d)
{
int fd;
struct block0 b0;
if ((fd = os_open(fname, O_RDONLY, 0)) >= 0) {
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
if (b0_magic_wrong(&b0)) {
tv_dict_add_str(d, S_LEN("error"), xstrdup("magic number mismatch"));
} else {
// We have swap information.
tv_dict_add_str(d, S_LEN("version"), xstrdup((char *)b0.b0_version));
tv_dict_add_str(d, S_LEN("user"), xstrdup((char *)b0.b0_uname));
tv_dict_add_str(d, S_LEN("host"), xstrdup((char *)b0.b0_hname));
tv_dict_add_str(d, S_LEN("fname"), xstrdup((char *)b0.b0_fname));
tv_dict_add_nr(d, S_LEN("pid"), char_to_long(b0.b0_pid));
tv_dict_add_nr(d, S_LEN("mtime"), char_to_long(b0.b0_mtime));
#ifdef CHECK_INODE
tv_dict_add_nr(d, S_LEN("inode"), char_to_long(b0.b0_ino));
#endif
}
} else {
tv_dict_add_str(d, S_LEN("error"), xstrdup("Cannot read file"));
}
close(fd);
} else {
tv_dict_add_str(d, S_LEN("error"), xstrdup("Cannot open file"));
}
}
/// Give information about an existing swap file.
/// Returns timestamp (0 when unknown).
static time_t swapfile_info(char_u *fname)
{
assert(fname != NULL);

View File

@@ -61,3 +61,37 @@ func Test_missing_dir()
set directory&
call delete('Xswapdir', 'rf')
endfunc
func Test_swapinfo()
new Xswapinfo
call setline(1, ['one', 'two', 'three'])
w
let fname = trim(execute('swapname'))
call assert_match('Xswapinfo', fname)
let info = swapinfo(fname)
call assert_match('8\.', info.version)
call assert_match('\w', info.user)
call assert_equal(hostname(), info.host)
call assert_match('Xswapinfo', info.fname)
call assert_equal(getpid(), info.pid)
call assert_match('^\d*$', info.mtime)
if has_key(info, 'inode')
call assert_match('\d', info.inode)
endif
bwipe!
call delete(fname)
call delete('Xswapinfo')
let info = swapinfo('doesnotexist')
call assert_equal('Cannot open file', info.error)
call writefile(['burp'], 'Xnotaswapfile')
let info = swapinfo('Xnotaswapfile')
call assert_equal('Cannot read file', info.error)
call delete('Xnotaswapfile')
call writefile([repeat('x', 10000)], 'Xnotaswapfile')
let info = swapinfo('Xnotaswapfile')
call assert_equal('magic number mismatch', info.error)
call delete('Xnotaswapfile')
endfunc