home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / memfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-04  |  32.3 KB  |  1,304 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. /*
  11.  * memfile.c: Contains the functions for handling blocks of memory which can
  12.  * be stored in a file. This is the implementation of a sort of virtual memory.
  13.  *
  14.  * A memfile consists of a sequence of blocks. The blocks numbered from 0
  15.  * upwards have been assigned a place in the actual file. The block number
  16.  * is equal to the page number in the file. The
  17.  * blocks with negative numbers are currently in memory only. They can be
  18.  * assigned a place in the file when too much memory is being used. At that
  19.  * moment they get a new, positive, number. A list is used for translation of
  20.  * negative to positive numbers.
  21.  *
  22.  * The size of a block is a multiple of a page size, normally the page size of
  23.  * the device the file is on. Most blocks are 1 page long. A Block of multiple
  24.  * pages is used for a line that does not fit in a single page.
  25.  *
  26.  * Each block can be in memory and/or in a file. The block stays in memory
  27.  * as long as it is locked. If it is no longer locked it can be swapped out to
  28.  * the file. It is only written to the file if it has been changed.
  29.  *
  30.  * Under normal operation the file is created when opening the memory file and
  31.  * deleted when closing the memory file. Only with recovery an existing memory
  32.  * file is opened.
  33.  */
  34.  
  35. #if defined MSDOS || defined(WIN32) || defined(_WIN64)
  36. # include <io.h>    /* for lseek(), must be before vim.h */
  37. #endif
  38.  
  39. #include "vim.h"
  40.  
  41. #ifdef HAVE_FCNTL_H
  42. # include <fcntl.h>
  43. #endif
  44.  
  45. /*
  46.  * Some systems have the page size in statfs.f_bsize, some in stat.st_blksize
  47.  */
  48. #ifdef HAVE_ST_BLKSIZE
  49. # define STATFS stat
  50. # define F_BSIZE st_blksize
  51. # define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
  52. #else
  53. # ifdef HAVE_SYS_STATFS_H
  54. #  include <sys/statfs.h>
  55. #  define STATFS statfs
  56. #  define F_BSIZE f_bsize
  57. #  ifdef __MINT__        /* do we still need this? */
  58. #   define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
  59. #  endif
  60. # endif
  61. #endif
  62.  
  63. /*
  64.  * for Amiga Dos 2.0x we use Flush
  65.  */
  66. #ifdef AMIGA
  67. # ifdef FEAT_ARP
  68. extern int dos2;            /* this is in os_amiga.c */
  69. # endif
  70. # ifdef SASC
  71. #  include <proto/dos.h>
  72. #  include <ios1.h>            /* for chkufb() */
  73. # endif
  74. #endif
  75.  
  76. #define MEMFILE_PAGE_SIZE 4096        /* default page size */
  77.  
  78. static long_u    total_mem_used = 0;    /* total memory used for memfiles */
  79. static int    dont_release = FALSE;    /* don't release blocks */
  80.  
  81. static void mf_ins_hash __ARGS((memfile_T *, bhdr_T *));
  82. static void mf_rem_hash __ARGS((memfile_T *, bhdr_T *));
  83. static bhdr_T *mf_find_hash __ARGS((memfile_T *, blocknr_T));
  84. static void mf_ins_used __ARGS((memfile_T *, bhdr_T *));
  85. static void mf_rem_used __ARGS((memfile_T *, bhdr_T *));
  86. static bhdr_T *mf_release __ARGS((memfile_T *, int));
  87. static bhdr_T *mf_alloc_bhdr __ARGS((memfile_T *, int));
  88. static void mf_free_bhdr __ARGS((bhdr_T *));
  89. static void mf_ins_free __ARGS((memfile_T *, bhdr_T *));
  90. static bhdr_T *mf_rem_free __ARGS((memfile_T *));
  91. static int  mf_read __ARGS((memfile_T *, bhdr_T *));
  92. static int  mf_write __ARGS((memfile_T *, bhdr_T *));
  93. static int  mf_trans_add __ARGS((memfile_T *, bhdr_T *));
  94. static void mf_do_open __ARGS((memfile_T *, char_u *, int));
  95.  
  96. /*
  97.  * The functions for using a memfile:
  98.  *
  99.  * mf_open()        open a new or existing memfile
  100.  * mf_open_file()   open a swap file for an existing memfile
  101.  * mf_close()        close (and delete) a memfile
  102.  * mf_new()        create a new block in a memfile and lock it
  103.  * mf_get()        get an existing block and lock it
  104.  * mf_put()        unlock a block, may be marked for writing
  105.  * mf_free()        remove a block
  106.  * mf_sync()        sync changed parts of memfile to disk
  107.  * mf_release_all() release as much memory as possible
  108.  * mf_trans_del()   may translate negative to positive block number
  109.  * mf_fullname()    make file name full path (use before first :cd)
  110.  */
  111.  
  112. /*
  113.  * Open an existing or new memory block file.
  114.  *
  115.  *  fname:    name of file to use (NULL means no file at all)
  116.  *        Note: fname must have been allocated, it is not copied!
  117.  *            If opening the file fails, fname is freed.
  118.  *  flags:    flags for open() call
  119.  *
  120.  *  If fname != NULL and file cannot be opened, fail.
  121.  *
  122.  * return value: identifier for this memory block file.
  123.  */
  124.     memfile_T *
  125. mf_open(fname, flags)
  126.     char_u    *fname;
  127.     int        flags;
  128. {
  129.     memfile_T        *mfp;
  130.     int            i;
  131.     off_t        size;
  132. #if defined(STATFS) && defined(UNIX) && !defined(__QNX__)
  133. # define USE_FSTATFS
  134.     struct STATFS    stf;
  135. #endif
  136.  
  137.     if ((mfp = (memfile_T *)alloc((unsigned)sizeof(memfile_T))) == NULL)
  138.     return NULL;
  139.  
  140.     if (fname == NULL)        /* no file for this memfile, use memory only */
  141.     {
  142.     mfp->mf_fname = NULL;
  143.     mfp->mf_ffname = NULL;
  144.     mfp->mf_fd = -1;
  145.     }
  146.     else
  147.     {
  148.     mf_do_open(mfp, fname, flags);    /* try to open the file */
  149.  
  150.     /* if the file cannot be opened, return here */
  151.     if (mfp->mf_fd < 0)
  152.     {
  153.         vim_free(mfp);
  154.         return NULL;
  155.     }
  156.     }
  157.  
  158.     mfp->mf_free_first = NULL;        /* free list is empty */
  159.     mfp->mf_used_first = NULL;        /* used list is empty */
  160.     mfp->mf_used_last = NULL;
  161.     mfp->mf_dirty = FALSE;
  162.     mfp->mf_used_count = 0;
  163.     for (i = 0; i < MEMHASHSIZE; ++i)
  164.     {
  165.     mfp->mf_hash[i] = NULL;        /* hash lists are empty */
  166.     mfp->mf_trans[i] = NULL;    /* trans lists are empty */
  167.     }
  168.     mfp->mf_page_size = MEMFILE_PAGE_SIZE;
  169.  
  170. #ifdef USE_FSTATFS
  171.     /*
  172.      * Try to set the page size equal to the block size of the device.
  173.      * Speeds up I/O a lot.
  174.      * When recovering, the actual block size will be retrieved from block 0
  175.      * in ml_recover().  The size used here may be wrong, therefore
  176.      * mf_blocknr_max must be rounded up.
  177.      */
  178.     if (mfp->mf_fd >= 0
  179.         && fstatfs(mfp->mf_fd, &stf, sizeof(struct statfs), 0) == 0
  180.         && stf.F_BSIZE >= MIN_SWAP_PAGE_SIZE
  181.         && stf.F_BSIZE <= MAX_SWAP_PAGE_SIZE)
  182.     mfp->mf_page_size = stf.F_BSIZE;
  183. #endif
  184.  
  185.     if (mfp->mf_fd < 0 || (flags & (O_TRUNC|O_EXCL))
  186.               || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
  187.     mfp->mf_blocknr_max = 0;    /* no file or empty file */
  188.     else
  189.     mfp->mf_blocknr_max = (blocknr_T)((size + mfp->mf_page_size - 1)
  190.                              / mfp->mf_page_size);
  191.     mfp->mf_blocknr_min = -1;
  192.     mfp->mf_neg_count = 0;
  193.     mfp->mf_infile_count = mfp->mf_blocknr_max;
  194.     mfp->mf_used_count_max = p_mm * 1024 / mfp->mf_page_size;
  195.  
  196.     return mfp;
  197. }
  198.  
  199. /*
  200.  * Open a file for an existing memfile.  Used when updatecount set from 0 to
  201.  * some value.
  202.  * If the file already exists, this fails.
  203.  * "fname" is the name of file to use (NULL means no file at all)
  204.  * Note: "fname" must have been allocated, it is not copied!  If opening the
  205.  * file fails, "fname" is freed.
  206.  *
  207.  * return value: FAIL if file could not be opened, OK otherwise
  208.  */
  209.     int
  210. mf_open_file(mfp, fname)
  211.     memfile_T    *mfp;
  212.     char_u    *fname;
  213. {
  214.     mf_do_open(mfp, fname, O_RDWR|O_CREAT|O_EXCL); /* try to open the file */
  215.  
  216.     if (mfp->mf_fd < 0)
  217.     return FAIL;
  218.  
  219.     mfp->mf_dirty = TRUE;
  220.     return OK;
  221. }
  222.  
  223. /*
  224.  * close a memory file and delete the associated file if 'del_file' is TRUE
  225.  */
  226.     void
  227. mf_close(mfp, del_file)
  228.     memfile_T    *mfp;
  229.     int        del_file;
  230. {
  231.     bhdr_T    *hp, *nextp;
  232.     NR_TRANS    *tp, *tpnext;
  233.     int        i;
  234.  
  235.     if (mfp == NULL)            /* safety check */
  236.     return;
  237.     if (mfp->mf_fd >= 0)
  238.     {
  239.     if (close(mfp->mf_fd) < 0)
  240.         EMSG(_(e_swapclose));
  241.     }
  242.     if (del_file && mfp->mf_fname != NULL)
  243.     mch_remove(mfp->mf_fname);
  244.                         /* free entries in used list */
  245.     for (hp = mfp->mf_used_first; hp != NULL; hp = nextp)
  246.     {
  247.     total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
  248.     nextp = hp->bh_next;
  249.     mf_free_bhdr(hp);
  250.     }
  251.     while (mfp->mf_free_first != NULL)        /* free entries in free list */
  252.     vim_free(mf_rem_free(mfp));
  253.     for (i = 0; i < MEMHASHSIZE; ++i)        /* free entries in trans lists */
  254.     for (tp = mfp->mf_trans[i]; tp != NULL; tp = tpnext)
  255.     {
  256.         tpnext = tp->nt_next;
  257.         vim_free(tp);
  258.     }
  259.     vim_free(mfp->mf_fname);
  260.     vim_free(mfp->mf_ffname);
  261.     vim_free(mfp);
  262. }
  263.  
  264. /*
  265.  * Close the swap file for a memfile.  Used when 'swapfile' is reset.
  266.  */
  267.     void
  268. mf_close_file(buf, getlines)
  269.     buf_T    *buf;
  270.     int        getlines;    /* get all lines into memory? */
  271. {
  272.     memfile_T    *mfp;
  273.     linenr_T    lnum;
  274.  
  275.     mfp = buf->b_ml.ml_mfp;
  276.     if (mfp == NULL || mfp->mf_fd < 0)        /* nothing to close */
  277.     return;
  278.  
  279.     if (getlines)
  280.     {
  281.     /* get all blocks in memory by accessing all lines (clumsy!) */
  282.     dont_release = TRUE;
  283.     for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
  284.         (void)ml_get_buf(buf, lnum, FALSE);
  285.     dont_release = FALSE;
  286.     /* TODO: should check if all blocks are really in core */
  287.     }
  288.  
  289.     if (close(mfp->mf_fd) < 0)            /* close the file */
  290.     EMSG(_(e_swapclose));
  291.     mfp->mf_fd = -1;
  292.  
  293.     if (mfp->mf_fname != NULL)
  294.     {
  295.     mch_remove(mfp->mf_fname);        /* delete the swap file */
  296.     vim_free(mfp->mf_fname);
  297.     vim_free(mfp->mf_ffname);
  298.     mfp->mf_fname = NULL;
  299.     mfp->mf_ffname = NULL;
  300.     }
  301. }
  302.  
  303. /*
  304.  * Set new size for a memfile.  Used when block 0 of a swapfile has been read
  305.  * and the size it indicates differs from what was guessed.
  306.  */
  307.     void
  308. mf_new_page_size(mfp, new_size)
  309.     memfile_T    *mfp;
  310.     unsigned    new_size;
  311. {
  312.     /* Correct the memory used for block 0 to the new size, because it will be
  313.      * freed with that size later on. */
  314.     total_mem_used += new_size - mfp->mf_page_size;
  315.     mfp->mf_page_size = new_size;
  316. }
  317.  
  318. /*
  319.  * get a new block
  320.  *
  321.  *   negative: TRUE if negative block number desired (data block)
  322.  */
  323.     bhdr_T *
  324. mf_new(mfp, negative, page_count)
  325.     memfile_T    *mfp;
  326.     int        negative;
  327.     int        page_count;
  328. {
  329.     bhdr_T    *hp;        /* new bhdr_T */
  330.     bhdr_T    *freep;        /* first block in free list */
  331.     char_u  *p;
  332.  
  333.     /*
  334.      * If we reached the maximum size for the used memory blocks, release one
  335.      * If a bhdr_T is returned, use it and adjust the page_count if necessary.
  336.      */
  337.     hp = mf_release(mfp, page_count);
  338.  
  339. /*
  340.  * Decide on the number to use:
  341.  * If there is a free block, use its number.
  342.  * Otherwise use mf_block_min for a negative number, mf_block_max for
  343.  * a positive number.
  344.  */
  345.     freep = mfp->mf_free_first;
  346.     if (!negative && freep != NULL && freep->bh_page_count >= page_count)
  347.     {
  348.     /*
  349.      * If the block in the free list has more pages, take only the number
  350.      * of pages needed and allocate a new bhdr_T with data
  351.      *
  352.      * If the number of pages matches and mf_release did not return a bhdr_T,
  353.      * use the bhdr_T from the free list and allocate the data
  354.      *
  355.      * If the number of pages matches and mf_release returned a bhdr_T,
  356.      * just use the number and free the bhdr_T from the free list
  357.      */
  358.     if (freep->bh_page_count > page_count)
  359.     {
  360.         if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
  361.         return NULL;
  362.         hp->bh_bnum = freep->bh_bnum;
  363.         freep->bh_bnum += page_count;
  364.         freep->bh_page_count -= page_count;
  365.     }
  366.     else if (hp == NULL)        /* need to allocate memory for this block */
  367.     {
  368.         if ((p = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL)
  369.         return NULL;
  370.         hp = mf_rem_free(mfp);
  371.         hp->bh_data = p;
  372.     }
  373.     else            /* use the number, remove entry from free list */
  374.     {
  375.         freep = mf_rem_free(mfp);
  376.         hp->bh_bnum = freep->bh_bnum;
  377.         vim_free(freep);
  378.     }
  379.     }
  380.     else    /* get a new number */
  381.     {
  382.     if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
  383.         return NULL;
  384.     if (negative)
  385.     {
  386.         hp->bh_bnum = mfp->mf_blocknr_min--;
  387.         mfp->mf_neg_count++;
  388.     }
  389.     else
  390.     {
  391.         hp->bh_bnum = mfp->mf_blocknr_max;
  392.         mfp->mf_blocknr_max += page_count;
  393.     }
  394.     }
  395.     hp->bh_flags = BH_LOCKED | BH_DIRTY;    /* new block is always dirty */
  396.     mfp->mf_dirty = TRUE;
  397.     hp->bh_page_count = page_count;
  398.     mf_ins_used(mfp, hp);
  399.     mf_ins_hash(mfp, hp);
  400.  
  401.     /*
  402.      * Init the data to all zero, to avoid reading uninitialized data.
  403.      * This also avoids that the passwd file ends up in the swap file!
  404.      */
  405.     (void)vim_memset((char *)(hp->bh_data), 0, (size_t)mfp->mf_page_size);
  406.  
  407.     return hp;
  408. }
  409.  
  410. /*
  411.  * get existing block 'nr' with 'page_count' pages
  412.  *
  413.  * Note: The caller should first check a negative nr with mf_trans_del()
  414.  */
  415.     bhdr_T *
  416. mf_get(mfp, nr, page_count)
  417.     memfile_T    *mfp;
  418.     blocknr_T    nr;
  419.     int        page_count;
  420. {
  421.     bhdr_T    *hp;
  422.                         /* doesn't exist */
  423.     if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
  424.     return NULL;
  425.  
  426.     /*
  427.      * see if it is in the cache
  428.      */
  429.     hp = mf_find_hash(mfp, nr);
  430.     if (hp == NULL)    /* not in the hash list */
  431.     {
  432.     if (nr < 0 || nr >= mfp->mf_infile_count)   /* can't be in the file */
  433.         return NULL;
  434.  
  435.     /* could check here if the block is in the free list */
  436.  
  437.     /*
  438.      * Check if we need to flush an existing block.
  439.      * If so, use that block.
  440.      * If not, allocate a new block.
  441.      */
  442.     hp = mf_release(mfp, page_count);
  443.     if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
  444.         return NULL;
  445.  
  446.     hp->bh_bnum = nr;
  447.     hp->bh_flags = 0;
  448.     hp->bh_page_count = page_count;
  449.     if (mf_read(mfp, hp) == FAIL)        /* cannot read the block! */
  450.     {
  451.         mf_free_bhdr(hp);
  452.         return NULL;
  453.     }
  454.     }
  455.     else
  456.     {
  457.     mf_rem_used(mfp, hp);    /* remove from list, insert in front below */
  458.     mf_rem_hash(mfp, hp);
  459.     }
  460.  
  461.     hp->bh_flags |= BH_LOCKED;
  462.     mf_ins_used(mfp, hp);    /* put in front of used list */
  463.     mf_ins_hash(mfp, hp);    /* put in front of hash list */
  464.  
  465.     return hp;
  466. }
  467.  
  468. /*
  469.  * release the block *hp
  470.  *
  471.  *   dirty: Block must be written to file later
  472.  *   infile: Block should be in file (needed for recovery)
  473.  *
  474.  *  no return value, function cannot fail
  475.  */
  476.     void
  477. mf_put(mfp, hp, dirty, infile)
  478.     memfile_T    *mfp;
  479.     bhdr_T    *hp;
  480.     int        dirty;
  481.     int        infile;
  482. {
  483.     int        flags;
  484.  
  485.     flags = hp->bh_flags;
  486.  
  487.     if ((flags & BH_LOCKED) == 0)
  488.     EMSG(_("E293: block was not locked"));
  489.     flags &= ~BH_LOCKED;
  490.     if (dirty)
  491.     {
  492.     flags |= BH_DIRTY;
  493.     mfp->mf_dirty = TRUE;
  494.     }
  495.     hp->bh_flags = flags;
  496.     if (infile)
  497.     mf_trans_add(mfp, hp);        /* may translate negative in positive nr */
  498. }
  499.  
  500. /*
  501.  * block *hp is no longer in used, may put it in the free list of memfile *mfp
  502.  */
  503.     void
  504. mf_free(mfp, hp)
  505.     memfile_T    *mfp;
  506.     bhdr_T    *hp;
  507. {
  508.     vim_free(hp->bh_data);    /* free the memory */
  509.     mf_rem_hash(mfp, hp);    /* get *hp out of the hash list */
  510.     mf_rem_used(mfp, hp);    /* get *hp out of the used list */
  511.     if (hp->bh_bnum < 0)
  512.     {
  513.     vim_free(hp);        /* don't want negative numbers in free list */
  514.     mfp->mf_neg_count--;
  515.     }
  516.     else
  517.     mf_ins_free(mfp, hp);    /* put *hp in the free list */
  518. }
  519.  
  520. /*
  521.  * Sync the memory file *mfp to disk.
  522.  * Flags:
  523.  *  MFS_ALL    If not given, blocks with negative numbers are not synced,
  524.  *        even when they are dirty!
  525.  *  MFS_STOP    Stop syncing when a character becomes available, but sync at
  526.  *        least one block.
  527.  *  MFS_FLUSH    Make sure buffers are flushed to disk, so they will survive a
  528.  *        system crash.
  529.  *  MFS_ZERO    Only write block 0.
  530.  *
  531.  * Return FAIL for failure, OK otherwise
  532.  */
  533.     int
  534. mf_sync(mfp, flags)
  535.     memfile_T    *mfp;
  536.     int        flags;
  537. {
  538.     int        status;
  539.     bhdr_T    *hp;
  540. #if defined(SYNC_DUP_CLOSE) && !defined(MSDOS)
  541.     int        fd;
  542. #endif
  543.     int        got_int_save = got_int;
  544.  
  545.     if (mfp->mf_fd < 0)        /* there is no file, nothing to do */
  546.     {
  547.     mfp->mf_dirty = FALSE;
  548.     return FAIL;
  549.     }
  550.  
  551.     /* Only a CTRL-C while writing will break us here, not one typed
  552.      * previously. */
  553.     got_int = FALSE;
  554.  
  555.     /*
  556.      * sync from last to first (may reduce the probability of an inconsistent
  557.      * file) If a write fails, it is very likely caused by a full filesystem.
  558.      * Then we only try to write blocks within the existing file. If that also
  559.      * fails then we give up.
  560.      */
  561.     status = OK;
  562.     for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
  563.     if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
  564.         && (hp->bh_flags & BH_DIRTY)
  565.         && (status == OK || (hp->bh_bnum >= 0
  566.             && hp->bh_bnum < mfp->mf_infile_count)))
  567.     {
  568.         if ((flags & MFS_ZERO) && hp->bh_bnum != 0)
  569.         continue;
  570.         if (mf_write(mfp, hp) == FAIL)
  571.         {
  572.         if (status == FAIL)    /* double error: quit syncing */
  573.             break;
  574.         status = FAIL;
  575.         }
  576.         if (flags & MFS_STOP)
  577.         {
  578.         /* Stop when char available now. */
  579.         if (ui_char_avail())
  580.             break;
  581.         }
  582.         else
  583.         ui_breakcheck();
  584.         if (got_int)
  585.         break;
  586.     }
  587.  
  588.     /*
  589.      * If the whole list is flushed, the memfile is not dirty anymore.
  590.      * In case of an error this flag is also set, to avoid trying all the time.
  591.      */
  592.     if (hp == NULL || status == FAIL)
  593.     mfp->mf_dirty = FALSE;
  594.  
  595.     if ((flags & MFS_FLUSH) && *p_sws != NUL)
  596.     {
  597. #if defined(UNIX)
  598. # ifdef HAVE_FSYNC
  599.     /*
  600.      * most Unixes have the very useful fsync() function, just what we need.
  601.      * However, with OS/2 and EMX it is also available, but there are
  602.      * reports of bad problems with it (a bug in HPFS.IFS).
  603.      * So we disable use of it here in case someone tries to be smart
  604.      * and changes os_os2_cfg.h... (even though there is no __EMX__ test
  605.      * in the #if, as __EMX__ does not have sync(); we hope for a timely
  606.      * sync from the system itself).
  607.      */
  608. #  if defined(__EMX__)
  609.    error "Dont use fsync with EMX! Read emxdoc.doc or emxfix01.doc for info."
  610. #  endif
  611.     if (STRCMP(p_sws, "fsync") == 0)
  612.     {
  613.         if (fsync(mfp->mf_fd))
  614.         status = FAIL;
  615.     }
  616.     else
  617. # endif
  618.         /* OpenNT is strictly POSIX (Benzinger) */
  619.         /* Tandem/Himalaya NSK-OSS doesn't have sync() */
  620. # if defined(__OPENNT) || defined(__TANDEM)
  621.         fflush(NULL);
  622. # else
  623.         sync();
  624. # endif
  625. #endif
  626. #ifdef VMS
  627.     if (STRCMP(p_sws, "fsync") == 0)
  628.     {
  629.         if (fsync(mfp->mf_fd))
  630.         status = FAIL;
  631.     }
  632. #endif
  633. #ifdef MSDOS
  634.     if (_dos_commit(mfp->mf_fd))
  635.         status = FAIL;
  636. #else
  637. # ifdef SYNC_DUP_CLOSE
  638.     /*
  639.      * Win32 is a bit more work: Duplicate the file handle and close it.
  640.      * This should flush the file to disk.
  641.      */
  642.     if ((fd = dup(mfp->mf_fd)) >= 0)
  643.         close(fd);
  644. # endif
  645. #endif
  646. #ifdef AMIGA
  647.     /*
  648.      * Flush() only exists for AmigaDos 2.0.
  649.      * For 1.3 it should be done with close() + open(), but then the risk
  650.      * is that the open() may fail and lose the file....
  651.      */
  652. # ifdef FEAT_ARP
  653.     if (dos2)
  654. # endif
  655. # ifdef SASC
  656.     {
  657.         struct UFB *fp = chkufb(mfp->mf_fd);
  658.  
  659.         if (fp != NULL)
  660.         Flush(fp->ufbfh);
  661.     }
  662. # else
  663. #  ifdef _DCC
  664.     {
  665.         BPTR fh = (BPTR)fdtofh(mfp->mf_fd);
  666.  
  667.         if (fh != 0)
  668.         Flush(fh);
  669.         }
  670. #  else /* assume Manx */
  671.         Flush(_devtab[mfp->mf_fd].fd);
  672. #  endif
  673. # endif
  674. #endif /* AMIGA */
  675.     }
  676.  
  677.     got_int |= got_int_save;
  678.  
  679.     return status;
  680. }
  681.  
  682. /*
  683.  * insert block *hp in front of hashlist of memfile *mfp
  684.  */
  685.     static void
  686. mf_ins_hash(mfp, hp)
  687.     memfile_T    *mfp;
  688.     bhdr_T    *hp;
  689. {
  690.     bhdr_T    *hhp;
  691.     int        hash;
  692.  
  693.     hash = MEMHASH(hp->bh_bnum);
  694.     hhp = mfp->mf_hash[hash];
  695.     hp->bh_hash_next = hhp;
  696.     hp->bh_hash_prev = NULL;
  697.     if (hhp != NULL)
  698.     hhp->bh_hash_prev = hp;
  699.     mfp->mf_hash[hash] = hp;
  700. }
  701.  
  702. /*
  703.  * remove block *hp from hashlist of memfile list *mfp
  704.  */
  705.     static void
  706. mf_rem_hash(mfp, hp)
  707.     memfile_T    *mfp;
  708.     bhdr_T    *hp;
  709. {
  710.     if (hp->bh_hash_prev == NULL)
  711.     mfp->mf_hash[MEMHASH(hp->bh_bnum)] = hp->bh_hash_next;
  712.     else
  713.     hp->bh_hash_prev->bh_hash_next = hp->bh_hash_next;
  714.  
  715.     if (hp->bh_hash_next)
  716.     hp->bh_hash_next->bh_hash_prev = hp->bh_hash_prev;
  717. }
  718.  
  719. /*
  720.  * look in hash lists of memfile *mfp for block header with number 'nr'
  721.  */
  722.     static bhdr_T *
  723. mf_find_hash(mfp, nr)
  724.     memfile_T    *mfp;
  725.     blocknr_T    nr;
  726. {
  727.     bhdr_T    *hp;
  728.  
  729.     for (hp = mfp->mf_hash[MEMHASH(nr)]; hp != NULL; hp = hp->bh_hash_next)
  730.     if (hp->bh_bnum == nr)
  731.         break;
  732.     return hp;
  733. }
  734.  
  735. /*
  736.  * insert block *hp in front of used list of memfile *mfp
  737.  */
  738.     static void
  739. mf_ins_used(mfp, hp)
  740.     memfile_T    *mfp;
  741.     bhdr_T    *hp;
  742. {
  743.     hp->bh_next = mfp->mf_used_first;
  744.     mfp->mf_used_first = hp;
  745.     hp->bh_prev = NULL;
  746.     if (hp->bh_next == NULL)        /* list was empty, adjust last pointer */
  747.     mfp->mf_used_last = hp;
  748.     else
  749.     hp->bh_next->bh_prev = hp;
  750.     mfp->mf_used_count += hp->bh_page_count;
  751.     total_mem_used += hp->bh_page_count * mfp->mf_page_size;
  752. }
  753.  
  754. /*
  755.  * remove block *hp from used list of memfile *mfp
  756.  */
  757.     static void
  758. mf_rem_used(mfp, hp)
  759.     memfile_T    *mfp;
  760.     bhdr_T    *hp;
  761. {
  762.     if (hp->bh_next == NULL)        /* last block in used list */
  763.     mfp->mf_used_last = hp->bh_prev;
  764.     else
  765.     hp->bh_next->bh_prev = hp->bh_prev;
  766.     if (hp->bh_prev == NULL)        /* first block in used list */
  767.     mfp->mf_used_first = hp->bh_next;
  768.     else
  769.     hp->bh_prev->bh_next = hp->bh_next;
  770.     mfp->mf_used_count -= hp->bh_page_count;
  771.     total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
  772. }
  773.  
  774. /*
  775.  * Release the least recently used block from the used list if the number
  776.  * of used memory blocks gets to big.
  777.  *
  778.  * Return the block header to the caller, including the memory block, so
  779.  * it can be re-used. Make sure the page_count is right.
  780.  */
  781.     static bhdr_T *
  782. mf_release(mfp, page_count)
  783.     memfile_T    *mfp;
  784.     int        page_count;
  785. {
  786.     bhdr_T    *hp;
  787.     int        need_release;
  788.     buf_T    *buf;
  789.  
  790.     /* don't release while in mf_close_file() */
  791.     if (dont_release)
  792.     return NULL;
  793.  
  794.     /*
  795.      * Need to release a block if the number of blocks for this memfile is
  796.      * higher than the maximum or total memory used is over 'maxmemtot'
  797.      */
  798.     need_release = ((mfp->mf_used_count >= mfp->mf_used_count_max)
  799.                   || (total_mem_used >> 10) >= (long_u)p_mmt);
  800.  
  801.     /*
  802.      * Try to create a swap file if the amount of memory used is getting too
  803.      * high.
  804.      */
  805.     if (mfp->mf_fd < 0 && need_release && p_uc)
  806.     {
  807.     /* find for which buffer this memfile is */
  808.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  809.         if (buf->b_ml.ml_mfp == mfp)
  810.         break;
  811.     if (buf != NULL && buf->b_may_swap)
  812.         ml_open_file(buf);
  813.     }
  814.  
  815.     /*
  816.      * don't release a block if
  817.      *    there is no file for this memfile
  818.      * or
  819.      *    the number of blocks for this memfile is lower than the maximum
  820.      *      and
  821.      *    total memory used is not up to 'maxmemtot'
  822.      */
  823.     if (mfp->mf_fd < 0 || !need_release)
  824.     return NULL;
  825.  
  826.     for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
  827.     if (!(hp->bh_flags & BH_LOCKED))
  828.         break;
  829.     if (hp == NULL)    /* not a single one that can be released */
  830.     return NULL;
  831.  
  832.     /*
  833.      * If the block is dirty, write it.
  834.      * If the write fails we don't free it.
  835.      */
  836.     if ((hp->bh_flags & BH_DIRTY) && mf_write(mfp, hp) == FAIL)
  837.     return NULL;
  838.  
  839.     mf_rem_used(mfp, hp);
  840.     mf_rem_hash(mfp, hp);
  841.  
  842.     /*
  843.      * If a bhdr_T is returned, make sure that the page_count of bh_data is
  844.      * right
  845.      */
  846.     if (hp->bh_page_count != page_count)
  847.     {
  848.     vim_free(hp->bh_data);
  849.     if ((hp->bh_data = alloc(mfp->mf_page_size * page_count)) == NULL)
  850.     {
  851.         vim_free(hp);
  852.         return NULL;
  853.     }
  854.     hp->bh_page_count = page_count;
  855.     }
  856.     return hp;
  857. }
  858.  
  859. /*
  860.  * release as many blocks as possible
  861.  * Used in case of out of memory
  862.  *
  863.  * return TRUE if any memory was released
  864.  */
  865.     int
  866. mf_release_all()
  867. {
  868.     buf_T    *buf;
  869.     memfile_T    *mfp;
  870.     bhdr_T    *hp;
  871.     int        retval = FALSE;
  872.  
  873.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  874.     {
  875.     mfp = buf->b_ml.ml_mfp;
  876.     if (mfp != NULL)
  877.     {
  878.         /* If no swap file yet, may open one */
  879.         if (mfp->mf_fd < 0 && buf->b_may_swap)
  880.         ml_open_file(buf);
  881.  
  882.         /* only if there is a swapfile */
  883.         if (mfp->mf_fd >= 0)
  884.         {
  885.         for (hp = mfp->mf_used_last; hp != NULL; )
  886.         {
  887.             if (!(hp->bh_flags & BH_LOCKED)
  888.                 && (!(hp->bh_flags & BH_DIRTY)
  889.                 || mf_write(mfp, hp) != FAIL))
  890.             {
  891.             mf_rem_used(mfp, hp);
  892.             mf_rem_hash(mfp, hp);
  893.             mf_free_bhdr(hp);
  894.             hp = mfp->mf_used_last;    /* re-start, list was changed */
  895.             retval = TRUE;
  896.             }
  897.             else
  898.             hp = hp->bh_prev;
  899.         }
  900.         }
  901.     }
  902.     }
  903.     return retval;
  904. }
  905.  
  906. /*
  907.  * Allocate a block header and a block of memory for it
  908.  */
  909.     static bhdr_T *
  910. mf_alloc_bhdr(mfp, page_count)
  911.     memfile_T    *mfp;
  912.     int        page_count;
  913. {
  914.     bhdr_T    *hp;
  915.  
  916.     if ((hp = (bhdr_T *)alloc((unsigned)sizeof(bhdr_T))) != NULL)
  917.     {
  918.     if ((hp->bh_data = (char_u *)alloc(mfp->mf_page_size * page_count))
  919.                                       == NULL)
  920.     {
  921.         vim_free(hp);        /* not enough memory */
  922.         return NULL;
  923.     }
  924.     hp->bh_page_count = page_count;
  925.     }
  926.     return hp;
  927. }
  928.  
  929. /*
  930.  * Free a block header and the block of memory for it
  931.  */
  932.     static void
  933. mf_free_bhdr(hp)
  934.     bhdr_T    *hp;
  935. {
  936.     vim_free(hp->bh_data);
  937.     vim_free(hp);
  938. }
  939.  
  940. /*
  941.  * insert entry *hp in the free list
  942.  */
  943.     static void
  944. mf_ins_free(mfp, hp)
  945.     memfile_T    *mfp;
  946.     bhdr_T    *hp;
  947. {
  948.     hp->bh_next = mfp->mf_free_first;
  949.     mfp->mf_free_first = hp;
  950. }
  951.  
  952. /*
  953.  * remove the first entry from the free list and return a pointer to it
  954.  * Note: caller must check that mfp->mf_free_first is not NULL!
  955.  */
  956.     static bhdr_T *
  957. mf_rem_free(mfp)
  958.     memfile_T    *mfp;
  959. {
  960.     bhdr_T    *hp;
  961.  
  962.     hp = mfp->mf_free_first;
  963.     mfp->mf_free_first = hp->bh_next;
  964.     return hp;
  965. }
  966.  
  967. /*
  968.  * read a block from disk
  969.  *
  970.  * Return FAIL for failure, OK otherwise
  971.  */
  972.     static int
  973. mf_read(mfp, hp)
  974.     memfile_T    *mfp;
  975.     bhdr_T    *hp;
  976. {
  977.     off_t    offset;
  978.     unsigned    page_size;
  979.     unsigned    size;
  980.  
  981.     if (mfp->mf_fd < 0)        /* there is no file, can't read */
  982.     return FAIL;
  983.  
  984.     page_size = mfp->mf_page_size;
  985.     offset = (off_t)page_size * hp->bh_bnum;
  986.     size = page_size * hp->bh_page_count;
  987.     if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
  988.     {
  989.     EMSG(_("E294: Seek error in swap file read"));
  990.     return FAIL;
  991.     }
  992.     if ((unsigned)vim_read(mfp->mf_fd, hp->bh_data, size) != size)
  993.     {
  994.     EMSG(_("E295: Read error in swap file"));
  995.     return FAIL;
  996.     }
  997.     return OK;
  998. }
  999.  
  1000. /*
  1001.  * write a block to disk
  1002.  *
  1003.  * Return FAIL for failure, OK otherwise
  1004.  */
  1005.     static int
  1006. mf_write(mfp, hp)
  1007.     memfile_T    *mfp;
  1008.     bhdr_T    *hp;
  1009. {
  1010.     off_t    offset;        /* offset in the file */
  1011.     blocknr_T    nr;        /* block nr which is being written */
  1012.     bhdr_T    *hp2;
  1013.     unsigned    page_size;  /* number of bytes in a page */
  1014.     unsigned    page_count; /* number of pages written */
  1015.     unsigned    size;        /* number of bytes written */
  1016.  
  1017.     if (mfp->mf_fd < 0)        /* there is no file, can't write */
  1018.     return FAIL;
  1019.  
  1020.     if (hp->bh_bnum < 0)    /* must assign file block number */
  1021.     if (mf_trans_add(mfp, hp) == FAIL)
  1022.         return FAIL;
  1023.  
  1024.     page_size = mfp->mf_page_size;
  1025.  
  1026.     /*
  1027.      * We don't want gaps in the file. Write the blocks in front of *hp
  1028.      * to extend the file.
  1029.      * If block 'mf_infile_count' is not in the hash list, it has been
  1030.      * freed. Fill the space in the file with data from the current block.
  1031.      */
  1032.     for (;;)
  1033.     {
  1034.     nr = hp->bh_bnum;
  1035.     if (nr > mfp->mf_infile_count)        /* beyond end of file */
  1036.     {
  1037.         nr = mfp->mf_infile_count;
  1038.         hp2 = mf_find_hash(mfp, nr);    /* NULL catched below */
  1039.     }
  1040.     else
  1041.         hp2 = hp;
  1042.  
  1043.     offset = (off_t)page_size * nr;
  1044.     if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
  1045.     {
  1046.         EMSG(_("E296: Seek error in swap file write"));
  1047.         return FAIL;
  1048.     }
  1049.     if (hp2 == NULL)        /* freed block, fill with dummy data */
  1050.         page_count = 1;
  1051.     else
  1052.         page_count = hp2->bh_page_count;
  1053.     size = page_size * page_count;
  1054.     if ((unsigned)vim_write(mfp->mf_fd,
  1055.          (hp2 == NULL ? hp : hp2)->bh_data, size) != size)
  1056.     {
  1057.         /*
  1058.          * Avoid repeating the error message, this mostly happens when the
  1059.          * disk is full. We give the message again only after a succesful
  1060.          * write or when hitting a key. We keep on trying, in case some
  1061.          * space becomes available.
  1062.          */
  1063.         if (!did_swapwrite_msg)
  1064.         EMSG(_("E297: Write error in swap file"));
  1065.         did_swapwrite_msg = TRUE;
  1066.         return FAIL;
  1067.     }
  1068.     did_swapwrite_msg = FALSE;
  1069.     if (hp2 != NULL)            /* written a non-dummy block */
  1070.         hp2->bh_flags &= ~BH_DIRTY;
  1071.                         /* appended to the file */
  1072.     if (nr + (blocknr_T)page_count > mfp->mf_infile_count)
  1073.         mfp->mf_infile_count = nr + page_count;
  1074.     if (nr == hp->bh_bnum)            /* written the desired block */
  1075.         break;
  1076.     }
  1077.     return OK;
  1078. }
  1079.  
  1080. /*
  1081.  * Make block number for *hp positive and add it to the translation list
  1082.  *
  1083.  * Return FAIL for failure, OK otherwise
  1084.  */
  1085.     static int
  1086. mf_trans_add(mfp, hp)
  1087.     memfile_T    *mfp;
  1088.     bhdr_T    *hp;
  1089. {
  1090.     bhdr_T    *freep;
  1091.     blocknr_T    new_bnum;
  1092.     int        hash;
  1093.     NR_TRANS    *np;
  1094.     int        page_count;
  1095.  
  1096.     if (hp->bh_bnum >= 0)            /* it's already positive */
  1097.     return OK;
  1098.  
  1099.     if ((np = (NR_TRANS *)alloc((unsigned)sizeof(NR_TRANS))) == NULL)
  1100.     return FAIL;
  1101.  
  1102. /*
  1103.  * get a new number for the block.
  1104.  * If the first item in the free list has sufficient pages, use its number
  1105.  * Otherwise use mf_blocknr_max.
  1106.  */
  1107.     freep = mfp->mf_free_first;
  1108.     page_count = hp->bh_page_count;
  1109.     if (freep != NULL && freep->bh_page_count >= page_count)
  1110.     {
  1111.     new_bnum = freep->bh_bnum;
  1112.     /*
  1113.      * If the page count of the free block was larger, recude it.
  1114.      * If the page count matches, remove the block from the free list
  1115.      */
  1116.     if (freep->bh_page_count > page_count)
  1117.     {
  1118.         freep->bh_bnum += page_count;
  1119.         freep->bh_page_count -= page_count;
  1120.     }
  1121.     else
  1122.     {
  1123.         freep = mf_rem_free(mfp);
  1124.         vim_free(freep);
  1125.     }
  1126.     }
  1127.     else
  1128.     {
  1129.     new_bnum = mfp->mf_blocknr_max;
  1130.     mfp->mf_blocknr_max += page_count;
  1131.     }
  1132.  
  1133.     np->nt_old_bnum = hp->bh_bnum;        /* adjust number */
  1134.     np->nt_new_bnum = new_bnum;
  1135.  
  1136.     mf_rem_hash(mfp, hp);            /* remove from old hash list */
  1137.     hp->bh_bnum = new_bnum;
  1138.     mf_ins_hash(mfp, hp);            /* insert in new hash list */
  1139.  
  1140.     hash = MEMHASH(np->nt_old_bnum);        /* insert in trans list */
  1141.     np->nt_next = mfp->mf_trans[hash];
  1142.     mfp->mf_trans[hash] = np;
  1143.     if (np->nt_next != NULL)
  1144.     np->nt_next->nt_prev = np;
  1145.     np->nt_prev = NULL;
  1146.  
  1147.     return OK;
  1148. }
  1149.  
  1150. /*
  1151.  * Lookup a tranlation from the trans lists and delete the entry
  1152.  *
  1153.  * Return the positive new number when found, the old number when not found
  1154.  */
  1155.     blocknr_T
  1156. mf_trans_del(mfp, old_nr)
  1157.     memfile_T    *mfp;
  1158.     blocknr_T    old_nr;
  1159. {
  1160.     int        hash;
  1161.     NR_TRANS    *np;
  1162.     blocknr_T    new_bnum;
  1163.  
  1164.     hash = MEMHASH(old_nr);
  1165.     for (np = mfp->mf_trans[hash]; np != NULL; np = np->nt_next)
  1166.     if (np->nt_old_bnum == old_nr)
  1167.         break;
  1168.     if (np == NULL)        /* not found */
  1169.     return old_nr;
  1170.  
  1171.     mfp->mf_neg_count--;
  1172.     new_bnum = np->nt_new_bnum;
  1173.     if (np->nt_prev != NULL)        /* remove entry from the trans list */
  1174.     np->nt_prev->nt_next = np->nt_next;
  1175.     else
  1176.     mfp->mf_trans[hash] = np->nt_next;
  1177.     if (np->nt_next != NULL)
  1178.     np->nt_next->nt_prev = np->nt_prev;
  1179.     vim_free(np);
  1180.  
  1181.     return new_bnum;
  1182. }
  1183.  
  1184. /*
  1185.  * Set mfp->mf_ffname according to mfp->mf_fname and some other things.
  1186.  * Only called when creating or renaming the swapfile.    Either way it's a new
  1187.  * name so we must work out the full path name.
  1188.  */
  1189.     void
  1190. mf_set_ffname(mfp)
  1191.     memfile_T    *mfp;
  1192. {
  1193.     mfp->mf_ffname = FullName_save(mfp->mf_fname, FALSE);
  1194. }
  1195.  
  1196. /*
  1197.  * Make the name of the file used for the memfile a full path.
  1198.  * Used before doing a :cd
  1199.  */
  1200.     void
  1201. mf_fullname(mfp)
  1202.     memfile_T    *mfp;
  1203. {
  1204.     if (mfp != NULL && mfp->mf_fname != NULL && mfp->mf_ffname != NULL)
  1205.     {
  1206.     vim_free(mfp->mf_fname);
  1207.     mfp->mf_fname = mfp->mf_ffname;
  1208.     mfp->mf_ffname = NULL;
  1209.     }
  1210. }
  1211.  
  1212. /*
  1213.  * return TRUE if there are any translations pending for 'mfp'
  1214.  */
  1215.     int
  1216. mf_need_trans(mfp)
  1217.     memfile_T    *mfp;
  1218. {
  1219.     return (mfp->mf_fname != NULL && mfp->mf_neg_count > 0);
  1220. }
  1221.  
  1222. /*
  1223.  * Open a swap file for a memfile.
  1224.  * The "fname" must be in allocated memory, and is consumed (also when an
  1225.  * error occurs).
  1226.  */
  1227.     static void
  1228. mf_do_open(mfp, fname, flags)
  1229.     memfile_T    *mfp;
  1230.     char_u    *fname;
  1231.     int        flags;        /* flags for open() */
  1232. {
  1233. #ifdef HAVE_LSTAT
  1234.     struct stat sb;
  1235. #endif
  1236.  
  1237.     mfp->mf_fname = fname;
  1238.  
  1239.     /*
  1240.      * Get the full path name before the open, because this is
  1241.      * not possible after the open on the Amiga.
  1242.      * fname cannot be NameBuff, because it must have been allocated.
  1243.      */
  1244.     mf_set_ffname(mfp);
  1245. #if defined(MSDOS) || defined(MSWIN) || defined(RISCOS)
  1246.     /*
  1247.      * A ":!cd e:xxx" may change the directory without us knowning, use the
  1248.      * full pathname always.  Careful: This frees fname!
  1249.      */
  1250.     mf_fullname(mfp);
  1251. #endif
  1252.  
  1253. #ifdef HAVE_LSTAT
  1254.     /*
  1255.      * Extra security check: When creating a swap file it really shouldn't
  1256.      * exist yet.  If there is a symbolic link, this is most likely an attack.
  1257.      */
  1258.     if ((flags & O_CREAT) && mch_lstat((char *)mfp->mf_fname, &sb) >= 0)
  1259.     {
  1260.     mfp->mf_fd = -1;
  1261.     EMSG(_("E300: Swap file already exists (symlink attack?)"));
  1262.     }
  1263.     else
  1264. #endif
  1265.  
  1266.     /*
  1267.      * try to open the file
  1268.      */
  1269.     mfp->mf_fd = open(
  1270. #ifdef VMS
  1271.         vms_fixfilename(mfp->mf_fname),
  1272. #else
  1273.         (char *)mfp->mf_fname,
  1274. #endif
  1275.         flags | O_EXTRA
  1276. #ifdef WIN32
  1277.     /* Prevent handle inheritance that cause problems with Cscope
  1278.      * (swap file may not be deleted if cscope connection was open after
  1279.      * the file)
  1280.      */
  1281.         |O_NOINHERIT
  1282. #endif
  1283. #if defined(UNIX) || defined(RISCOS) || defined(VMS)
  1284.             , (mode_t)0600        /* open in rw------- mode */
  1285. #endif
  1286. #if defined(MSDOS) || defined(MSWIN) || defined(__EMX__)
  1287.             , S_IREAD | S_IWRITE    /* open read/write */
  1288. #endif
  1289.             );
  1290.  
  1291.     /*
  1292.      * If the file cannot be opened, use memory only
  1293.      */
  1294.     if (mfp->mf_fd < 0)
  1295.     {
  1296.     vim_free(mfp->mf_fname);
  1297.     vim_free(mfp->mf_ffname);
  1298.     mfp->mf_fname = NULL;
  1299.     mfp->mf_ffname = NULL;
  1300.     }
  1301.     else
  1302.     mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
  1303. }
  1304.