@broadblues
Quote:
Which files get the wrong protection bits and how are they created / manipulated by the prgram?
It is swap files created by VIM when you editing main file. Swap files start with "." and ends with .swp.
Vim sources pretty big ones, so i can be wrong, but as far as i can see logic for creating/closing of swap files , they just use open()/close() calls.
At least in the
https://github.com/vim/vim/blob/master/src/memfile.cI can see:
Open swap file:
/*
* Open a swap file for a memfile.
* The "fname" must be in allocated memory, and is consumed (also when an
* error occurs).
*/
static void
mf_do_open(
memfile_T *mfp,
char_u *fname,
int flags) /* flags for open() */
{
#ifdef HAVE_LSTAT
stat_T sb;
#endif
mfp->mf_fname = fname;
/*
* Get the full path name before the open, because this is
* not possible after the open on the Amiga.
* fname cannot be NameBuff, because it must have been allocated.
*/
mf_set_ffname(mfp);
#if defined(MSWIN)
/*
* A ":!cd e:xxx" may change the directory without us knowing, use the
* full pathname always. Careful: This frees fname!
*/
mf_fullname(mfp);
#endif
#ifdef HAVE_LSTAT
/*
* Extra security check: When creating a swap file it really shouldn't
* exist yet. If there is a symbolic link, this is most likely an attack.
*/
if ((flags & O_CREAT) && mch_lstat((char *)mfp->mf_fname, &sb) >= 0)
{
mfp->mf_fd = -1;
emsg(_("E300: Swap file already exists (symlink attack?)"));
}
else
#endif
{
/*
* try to open the file
*/
flags |= O_EXTRA | O_NOFOLLOW;
#ifdef MSWIN
/* Prevent handle inheritance that cause problems with Cscope
* (swap file may not be deleted if cscope connection was open after
* the file) */
flags |= O_NOINHERIT;
#endif
mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags);
}
/*
* If the file cannot be opened, use memory only
*/
if (mfp->mf_fd < 0)
{
VIM_CLEAR(mfp->mf_fname);
VIM_CLEAR(mfp->mf_ffname);
}
else
{
#ifdef HAVE_FD_CLOEXEC
int fdflags = fcntl(mfp->mf_fd, F_GETFD);
if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
(void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
#endif
#if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
mch_copy_sec(fname, mfp->mf_fname);
#endif
mch_hide(mfp->mf_fname); /* try setting the 'hidden' flag */
}
}
There is used mch_open_rw() for actual opening, and this one is defined in macros.h , like this:
#define mch_open_rw(n, f) mch_open((n), (f), 0)
which in turn defined in the vim.h like this:
# define mch_open(n, m, p) open((n), (m), (p))
Close swap file looks like this:
/*
* Close the swap file for a memfile. Used when 'swapfile' is reset.
*/
void
mf_close_file(
buf_T *buf,
int getlines) /* get all lines into memory? */
{
memfile_T *mfp;
linenr_T lnum;
mfp = buf->b_ml.ml_mfp;
if (mfp == NULL || mfp->mf_fd < 0) /* nothing to close */
return;
if (getlines)
{
/* get all blocks in memory by accessing all lines (clumsy!) */
mf_dont_release = TRUE;
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
(void)ml_get_buf(buf, lnum, FALSE);
mf_dont_release = FALSE;
/* TODO: should check if all blocks are really in core */
}
if (close(mfp->mf_fd) < 0) /* close the file */
emsg(_(e_swapclose));
mfp->mf_fd = -1;
if (mfp->mf_fname != NULL)
{
mch_remove(mfp->mf_fname); /* delete the swap file */
VIM_CLEAR(mfp->mf_fname);
VIM_CLEAR(mfp->mf_ffname);
}
}
and then mch_remove() it's just :
#define mch_remove(x) remove((const char *) x)
I do not know when bits exactly gots cleared.. Visually on closing : so i tried to comment out all "close" functions in that memfile.c which i link above and while when exit from VIM bits still cleared, when i operate with tabs , and close tabs (without exit from Vim), then bits start to be _not_ cleared.
Probabaly when VIM exit fully its doing something else, not only those "close" functions from memfile.c, but at least that commenting out those close functison make closing of tab in VIM not clear the bits , mean that its indeed related to close() things too.
Edited by kas1e on 2019/5/8 13:16:28