# HG changeset patch # User Christian Brabandt # Date 1457453704 -3600 # Node ID c0b5c2b0a5eed6d9164038e0204579db0319b093 # Parent 198586538c019cb9c78407e70de5ffeda7faa597 commit https://github.com/vim/vim/commit/8049253b96838b3584600e5ad229abad37a95b10 Author: Bram Moolenaar Date: Tue Mar 8 17:08:53 2016 +0100 patch 7.4.1516 Problem: Cannot change file permissions. Solution: Add setfperm(). diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2067,6 +2067,7 @@ serverlist() String get a list of avai setbufvar( {expr}, {varname}, {val}) set {varname} in buffer {expr} to {val} setcharsearch( {dict}) Dict set character search from {dict} setcmdpos( {pos}) Number set cursor position in command-line +setfperm( {fname}, {mode}) Number set {fname} file permissions to {mode} setline( {lnum}, {line}) Number set line {lnum} to {line} setloclist( {nr}, {list}[, {action}]) Number modify location list using {list} @@ -3830,6 +3831,8 @@ getfperm({fname}) *getfperm()* < This will hopefully (from a security point of view) display the string "rw-r--r--" or even "rw-------". + For setting permissins use |setfperm()|. + getftime({fname}) *getftime()* The result is a Number, which is the last modification time of the given file {fname}. The value is measured as seconds @@ -6001,6 +6004,24 @@ setcmdpos({pos}) *setcmdpos()* Returns 0 when successful, 1 when not editing the command line. +setfperm({fname}, {mode}) *setfperm()* *chmod* + Set the file permissions for {fname} to {mode}. + {mode} must be a string with 9 characters. It is of the form + "rwxrwxrwx", where each group of "rwx" flags represent, in + turn, the permissions of the owner of the file, the group the + file belongs to, and other users. A '-' character means the + permission is off, any other character means on. Multi-byte + characters are not supported. + + For example "rw-r-----" means read-write for the user, + readable by the group, not accessible by others. "xx-x-----" + would do the same thing. + + Returns non-zero for success, zero for failure. + + To read permissions see |getfperm()|. + + setline({lnum}, {text}) *setline()* Set line {lnum} of the current buffer to {text}. To insert lines use |append()|. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -735,6 +735,7 @@ static void f_serverlist(typval_T *argva static void f_setbufvar(typval_T *argvars, typval_T *rettv); static void f_setcharsearch(typval_T *argvars, typval_T *rettv); static void f_setcmdpos(typval_T *argvars, typval_T *rettv); +static void f_setfperm(typval_T *argvars, typval_T *rettv); static void f_setline(typval_T *argvars, typval_T *rettv); static void f_setloclist(typval_T *argvars, typval_T *rettv); static void f_setmatches(typval_T *argvars, typval_T *rettv); @@ -8446,6 +8447,7 @@ static struct fst {"setbufvar", 3, 3, f_setbufvar}, {"setcharsearch", 1, 1, f_setcharsearch}, {"setcmdpos", 1, 1, f_setcmdpos}, + {"setfperm", 2, 2, f_setfperm}, {"setline", 2, 2, f_setline}, {"setloclist", 2, 3, f_setloclist}, {"setmatches", 1, 1, f_setmatches}, @@ -18422,6 +18424,42 @@ f_setcmdpos(typval_T *argvars, typval_T } /* + * "setfperm({fname}, {mode})" function + */ + static void +f_setfperm(typval_T *argvars, typval_T *rettv) +{ + char_u *fname; + char_u modebuf[NUMBUFLEN]; + char_u *mode_str; + int i; + int mask; + int mode = 0; + + rettv->vval.v_number = 0; + fname = get_tv_string_chk(&argvars[0]); + if (fname == NULL) + return; + mode_str = get_tv_string_buf_chk(&argvars[1], modebuf); + if (mode_str == NULL) + return; + if (STRLEN(mode_str) != 9) + { + EMSG2(_(e_invarg2), mode_str); + return; + } + + mask = 1; + for (i = 8; i >= 0; --i) + { + if (mode_str[i] != '-') + mode |= mask; + mask = mask << 1; + } + rettv->vval.v_number = mch_setperm(fname, mode) == OK; +} + +/* * "setline()" function */ static void diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim --- a/src/testdir/test_alot.vim +++ b/src/testdir/test_alot.vim @@ -5,6 +5,7 @@ source test_backspace_opt.vim source test_cursor_func.vim source test_delete.vim source test_expand.vim +source test_file_perm.vim source test_glob2regpat.vim source test_join.vim source test_lispwords.vim diff --git a/src/testdir/test_file_perm.vim b/src/testdir/test_file_perm.vim new file mode 100644 --- /dev/null +++ b/src/testdir/test_file_perm.vim @@ -0,0 +1,20 @@ +" Test getting and setting file permissions. + +func Test_file_perm() + call assert_equal('', getfperm('Xtest')) + call assert_equal(0, setfperm('Xtest', 'r--------')) + + call writefile(['one'], 'Xtest') + call assert_true(len(getfperm('Xtest')) == 9) + + call assert_equal(1, setfperm('Xtest', 'rwx------')) + call assert_equal('rwx------', getfperm('Xtest')) + + call assert_equal(1, setfperm('Xtest', 'r--r--r--')) + call assert_equal('r--r--r--', getfperm('Xtest')) + + call assert_fails("setfperm('Xtest', '---')") + + call assert_equal(1, setfperm('Xtest', 'rwx------')) + call delete('Xtest') +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -744,6 +744,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1516, +/**/ 1515, /**/ 1514,