diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-08-21 20:28:54 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-08-21 20:28:54 +0200 |
commit | 00f123a56585363cd13f062fd3bb123efcfaa664 (patch) | |
tree | 7c8fb2556c2b395cb4d6035a1b0299f05073e409 /src | |
parent | 8e82c057ffb86cec3210ad8a22ad3f21d52e0953 (diff) |
patch 8.1.0313: information about a swap file is unavailablev8.1.0313
Problem: Information about a swap file is unavailable.
Solution: Add swapinfo(). (Enzo Ferber)
Diffstat (limited to 'src')
-rw-r--r-- | src/evalfunc.c | 12 | ||||
-rw-r--r-- | src/memline.c | 43 | ||||
-rw-r--r-- | src/proto/memline.pro | 3 | ||||
-rw-r--r-- | src/testdir/test_swap.vim | 34 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 93 insertions, 1 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index 5e7c013979..3c64212061 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -398,6 +398,7 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv); static void f_strwidth(typval_T *argvars, typval_T *rettv); static void f_submatch(typval_T *argvars, typval_T *rettv); static void f_substitute(typval_T *argvars, typval_T *rettv); +static void f_swapinfo(typval_T *argvars, typval_T *rettv); static void f_synID(typval_T *argvars, typval_T *rettv); static void f_synIDattr(typval_T *argvars, typval_T *rettv); static void f_synIDtrans(typval_T *argvars, typval_T *rettv); @@ -859,6 +860,7 @@ static struct fst {"strwidth", 1, 1, f_strwidth}, {"submatch", 1, 2, f_submatch}, {"substitute", 4, 4, f_substitute}, + {"swapinfo", 1, 1, f_swapinfo}, {"synID", 3, 3, f_synID}, {"synIDattr", 2, 3, f_synIDattr}, {"synIDtrans", 1, 1, f_synIDtrans}, @@ -12314,6 +12316,16 @@ f_substitute(typval_T *argvars, typval_T *rettv) } /* + * "swapinfo(swap_filename)" function + */ + static void +f_swapinfo(typval_T *argvars, typval_T *rettv) +{ + if (rettv_dict_alloc(rettv) == OK) + get_b0_dict(get_tv_string(argvars), rettv->vval.v_dict); +} + +/* * "synID(lnum, col, trans)" function */ static void diff --git a/src/memline.c b/src/memline.c index fbdd8a372c..660e89c111 100644 --- a/src/memline.c +++ b/src/memline.c @@ -2042,6 +2042,49 @@ static int process_still_running; #endif /* + * Return information found in swapfile "fname" in dictionary "d". + * This is used by the swapinfo() function. + */ + void +get_b0_dict(char_u *fname, dict_T *d) +{ + int fd; + struct block0 b0; + + if ((fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0) + { + if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) + { + if (b0_magic_wrong(&b0)) + { + dict_add_string(d, "error", + vim_strsave((char_u *)"magic number mismatch")); + } + else + { + /* we have swap information */ + dict_add_string(d, "version", vim_strsave(b0.b0_version)); + dict_add_string(d, "user", vim_strsave(b0.b0_uname)); + dict_add_string(d, "host", vim_strsave(b0.b0_hname)); + dict_add_string(d, "fname", vim_strsave(b0.b0_fname)); + + dict_add_number(d, "pid", char_to_long(b0.b0_pid)); + dict_add_number(d, "mtime", char_to_long(b0.b0_mtime)); +#ifdef CHECK_INODE + dict_add_number(d, "inode", char_to_long(b0.b0_ino)); +#endif + } + } + else + dict_add_string(d, "error", + vim_strsave((char_u *)"Cannot read file")); + close(fd); + } + else + dict_add_string(d, "error", vim_strsave((char_u *)"Cannot open file")); +} + +/* * Give information about an existing swap file. * Returns timestamp (0 when unknown). */ diff --git a/src/proto/memline.pro b/src/proto/memline.pro index 727b24cc30..d18ede37b6 100644 --- a/src/proto/memline.pro +++ b/src/proto/memline.pro @@ -11,6 +11,8 @@ void ml_close_notmod(void); void ml_timestamp(buf_T *buf); void ml_recover(void); int recover_names(char_u *fname, int list, int nr, char_u **fname_out); +char_u *make_percent_swname(char_u *dir, char_u *name); +void get_b0_dict(char_u *fname, dict_T *d); void ml_sync_all(int check_file, int check_char); void ml_preserve(buf_T *buf, int message); char_u *ml_get(linenr_T lnum); @@ -34,5 +36,4 @@ char_u *ml_encrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned siz void ml_decrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size); long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp); void goto_byte(long cnt); -char_u *make_percent_swname (char_u *dir, char_u *name); /* vim: set ft=c : */ diff --git a/src/testdir/test_swap.vim b/src/testdir/test_swap.vim index da5da2dbbd..b0e2ec9aa5 100644 --- a/src/testdir/test_swap.vim +++ b/src/testdir/test_swap.vim @@ -97,3 +97,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 diff --git a/src/version.c b/src/version.c index d752d04ff4..d0052fa331 100644 --- a/src/version.c +++ b/src/version.c @@ -795,6 +795,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 313, +/**/ 312, /**/ 311, |