diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.c | 7 | ||||
-rw-r--r-- | src/nvim/eval.lua | 1 | ||||
-rw-r--r-- | src/nvim/memline.c | 39 | ||||
-rw-r--r-- | src/nvim/testdir/test_swap.vim | 34 |
4 files changed, 77 insertions, 4 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 19324acd5c..e9da1f2f2b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -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) { diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 7978044200..02990fb102 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -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}, diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 662eda3c7c..3e18c8559a 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -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); diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index bc7b7c00d3..28f995f6fb 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -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 |