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 / amiga / vim46src.lha / vim-4.6 / src / fileio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  52.6 KB  |  2,186 lines

  1. /* vi:set ts=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.  */
  8.  
  9. /*
  10.  * fileio.c: read from and write to a file
  11.  */
  12.  
  13. #if defined MSDOS  ||  defined WIN32
  14. # include <io.h>        /* for lseek(), must be before vim.h */
  15. #endif
  16.  
  17. #include "vim.h"
  18. #include "globals.h"
  19. #include "proto.h"
  20. #include "option.h"
  21. #ifdef HAVE_FCNTL_H
  22. # include <fcntl.h>
  23. #endif
  24.  
  25. #ifdef LATTICE
  26. # include <proto/dos.h>        /* for Lock() and UnLock() */
  27. #endif
  28.  
  29. #define BUFSIZE        8192            /* size of normal write buffer */
  30. #define SBUFSIZE    256                /* size of emergency write buffer */
  31.  
  32. #ifdef VIMINFO
  33. static void check_marks_read __ARGS((void));
  34. #endif
  35. static void msg_add_fname __ARGS((BUF *, char_u *));
  36. static int msg_add_textmode __ARGS((int));
  37. static void msg_add_lines __ARGS((int, long, long));
  38. static void msg_add_eol __ARGS((void));
  39. static int  write_buf __ARGS((int, char_u *, int));
  40.  
  41. static linenr_t    write_no_eol_lnum = 0;     /* non-zero lnum when last line of
  42.                                            next binary write should not have
  43.                                            an end-of-line */
  44.  
  45.     void
  46. filemess(buf, name, s)
  47.     BUF            *buf;
  48.     char_u        *name;
  49.     char_u        *s;
  50. {
  51.     msg_add_fname(buf, name);        /* put file name in IObuff with quotes */
  52.     STRCAT(IObuff, s);
  53.     /*
  54.      * For the first message may have to start a new line.
  55.      * For further ones overwrite the previous one, reset msg_scroll before
  56.      * calling filemess().
  57.      */
  58.     msg_start();
  59.     msg_outtrans(IObuff);
  60.     stop_highlight();
  61.     msg_clr_eos();
  62.     flushbuf();
  63. }
  64.  
  65. /*
  66.  * Read lines from file 'fname' into the buffer after line 'from'.
  67.  *
  68.  * 1. We allocate blocks with lalloc, as big as possible.
  69.  * 2. Each block is filled with characters from the file with a single read().
  70.  * 3. The lines are inserted in the buffer with ml_append().
  71.  *
  72.  * (caller must check that fname != NULL)
  73.  *
  74.  * lines_to_skip is the number of lines that must be skipped
  75.  * lines_to_read is the number of lines that are appended
  76.  * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
  77.  *
  78.  * return FAIL for failure, OK otherwise
  79.  */
  80.     int
  81. readfile(fname, sfname, from, newfile, lines_to_skip, lines_to_read, filtering)
  82.     char_u           *fname;
  83.     char_u           *sfname;
  84.     linenr_t        from;
  85.     int                newfile;
  86.     linenr_t        lines_to_skip;
  87.     linenr_t        lines_to_read;
  88.     int                filtering;
  89. {
  90.     int                 fd;
  91.     register char_u     c;
  92.     register linenr_t    lnum = from;
  93.     register char_u     *ptr = NULL;            /* pointer into read buffer */
  94.     register char_u        *buffer = NULL;            /* read buffer */
  95.     char_u                *new_buffer = NULL;        /* init to shut up gcc */
  96.     char_u                *line_start = NULL;        /* init to shut up gcc */
  97.     colnr_t                len;
  98.     register long        size;
  99.     register char_u        *p;
  100.     long                filesize = 0;
  101.     int                    split = 0;                /* number of split lines */
  102. #define UNKNOWN        0x0fffffff                    /* file size is unknown */
  103.     linenr_t            linecnt;
  104.     int                 error = FALSE;            /* errors encountered */
  105.     int                    tx_error = FALSE;        /* textmode, but no CR */
  106.     long                linerest = 0;            /* remaining chars in line */
  107.     int                    firstpart = TRUE;        /* reading first part */
  108. #ifdef UNIX
  109.     int                    perm;
  110. #endif
  111.     int                    textmode;                /* accept CR-LF linebreak */
  112.     struct stat            st;
  113.     int                    file_readonly;
  114.     linenr_t            skip_count = lines_to_skip;
  115.     linenr_t            read_count = lines_to_read;
  116.     int                    msg_save = msg_scroll;
  117.     linenr_t            read_no_eol_lnum = 0;     /* non-zero lnum when last
  118.                                                    line of last read was
  119.                                                    missing the eol */
  120.  
  121.  
  122. #ifdef AUTOCMD
  123.     write_no_eol_lnum = 0;        /* in case it was set by the previous read */
  124. #endif
  125.  
  126.     /*
  127.      * If there is no file name yet, use the one for the read file.
  128.      * b_notedited is set to reflect this.
  129.      * Don't do this for a read from a filter.
  130.      * Only do this when 'cpoptions' contains the 'f' flag.
  131.      */
  132.     if (curbuf->b_filename == NULL && !filtering &&
  133.                                         vim_strchr(p_cpo, CPO_FNAMER) != NULL)
  134.     {
  135.         if (setfname(fname, sfname, FALSE) == OK)
  136.             curbuf->b_notedited = TRUE;
  137.     }
  138.  
  139.     if (shortmess(SHM_OVER) || curbuf->b_help)
  140.         msg_scroll = FALSE;        /* overwrite previous file message */
  141.     else
  142.         msg_scroll = TRUE;        /* don't overwrite previous file message */
  143.     if (sfname == NULL)
  144.         sfname = fname;
  145.     /*
  146.      * For Unix: Use the short filename whenever possible.
  147.      * Avoids problems with networks and when directory names are changed.
  148.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  149.      * another directory, which we don't detect.
  150.      */
  151. #if defined(UNIX) || defined(__EMX__)
  152.     if (!did_cd)
  153.         fname = sfname;
  154. #endif
  155.  
  156. #ifdef UNIX
  157.     /*
  158.      * On Unix it is possible to read a directory, so we have to
  159.      * check for it before the open().
  160.      */
  161.     perm = getperm(fname);
  162. # ifdef _POSIX_SOURCE
  163.     if (perm >= 0 && !S_ISREG(perm)                     /* not a regular file ... */
  164. #  ifdef S_ISFIFO
  165.                   && !S_ISFIFO(perm)                /* ... or fifo or socket */
  166. #  endif
  167.                                            )
  168. # else
  169.     if (perm >= 0 && (perm & S_IFMT) != S_IFREG        /* not a regular file ... */
  170. #  ifdef S_IFIFO
  171.                   && (perm & S_IFMT) != S_IFIFO        /* ... or fifo ... */
  172. #  endif
  173. #  ifdef S_IFSOCK
  174.                   && (perm & S_IFMT) != S_IFSOCK    /* ... or socket */
  175. #  endif
  176.                                             )
  177. # endif
  178.     {
  179. # ifdef _POSIX_SOURCE
  180.         if (S_ISDIR(perm))
  181. # else
  182.         if ((perm & S_IFMT) == S_IFDIR)
  183. # endif
  184.             filemess(curbuf, fname, (char_u *)"is a directory");
  185.         else
  186.             filemess(curbuf, fname, (char_u *)"is not a file");
  187.         msg_scroll = msg_save;
  188.         return FAIL;
  189.     }
  190. #endif
  191.  
  192.     /*
  193.      * When opening a new file we take the readonly flag from the file.
  194.      * Default is r/w, can be set to r/o below.
  195.      * Don't reset it when in readonly mode
  196.      */
  197.     if (newfile && !readonlymode)            /* default: set file not readonly */
  198.         curbuf->b_p_ro = FALSE;
  199.  
  200.     if (newfile)
  201.     {
  202.         if (stat((char *)fname, &st) >= 0)    /* remember time of file */
  203.         {
  204.             curbuf->b_mtime = st.st_mtime;
  205.             curbuf->b_mtime_read = st.st_mtime;
  206. #ifdef UNIX
  207.             /*
  208.              * Set the protection bits of the swap file equal to the original
  209.              * file. This makes it possible for others to read the name of the
  210.              * original file from the swapfile.
  211.              */
  212.             if (curbuf->b_ml.ml_mfp->mf_fname != NULL)
  213.                 (void)setperm(curbuf->b_ml.ml_mfp->mf_fname,
  214.                                                   (st.st_mode & 0777) | 0600);
  215. #endif
  216.         }
  217.         else
  218.         {
  219.             curbuf->b_mtime = 0;
  220.             curbuf->b_mtime_read = 0;
  221.         }
  222.     }
  223.  
  224. /*
  225.  * for UNIX: check readonly with perm and access()
  226.  * for MSDOS and Amiga: check readonly by trying to open the file for writing
  227.  */
  228.     file_readonly = FALSE;
  229. #if defined(UNIX) || defined(DJGPP) || defined(__EMX__)
  230.     if (
  231. # ifdef UNIX
  232.         !(perm & 0222) ||
  233. # endif
  234.                             access((char *)fname, W_OK))
  235.         file_readonly = TRUE;
  236.     fd = open((char *)fname, O_RDONLY | O_EXTRA);
  237. #else
  238.     if (!newfile || readonlymode || (fd =
  239.                                    open((char *)fname, O_RDWR | O_EXTRA)) < 0)
  240.     {
  241.         file_readonly = TRUE;
  242.         fd = open((char *)fname, O_RDONLY | O_EXTRA);    /* try to open ro */
  243.     }
  244. #endif
  245.  
  246.     if (fd < 0)                     /* cannot open at all */
  247.     {
  248. #ifndef UNIX
  249.         int        isdir_f;
  250. #endif
  251.         msg_scroll = msg_save;
  252. #ifndef UNIX
  253.     /*
  254.      * On MSDOS and Amiga we can't open a directory, check here.
  255.      */
  256.         isdir_f = (mch_isdir(fname));
  257.         /* replace with short name now, for the messages */
  258.         if (!did_cd)
  259.             fname = sfname;
  260.         if (isdir_f)
  261.             filemess(curbuf, fname, (char_u *)"is a directory");
  262.         else
  263. #endif
  264.             if (newfile)
  265.             {
  266. #ifdef UNIX
  267.                 if (perm < 0)
  268. #endif
  269.                 {
  270.                     filemess(curbuf, fname, (char_u *)"[New File]");
  271. #ifdef AUTOCMD
  272.                     apply_autocmds(EVENT_BUFNEWFILE, fname, fname, FALSE);
  273. #endif
  274.                     return OK;        /* a new file is not an error */
  275.                 }
  276. #ifdef UNIX
  277.                 else
  278.                     filemess(curbuf, fname, (char_u *)"[Permission Denied]");
  279. #endif
  280.             }
  281.  
  282.         return FAIL;
  283.     }
  284.  
  285.     /*
  286.      * Only set the 'ro' flag for readonly files the first time they are
  287.      * loaded.
  288.      * Help files always get readonly mode
  289.      */
  290.     if ((newfile && file_readonly) || curbuf->b_help)
  291.         curbuf->b_p_ro = TRUE;
  292.  
  293.     if (newfile)
  294.         curbuf->b_p_eol = TRUE;
  295.  
  296. #ifndef UNIX
  297.     /* replace with short name now, for the messages */
  298.     if (!did_cd)
  299.         fname = sfname;
  300. #endif
  301.     ++no_wait_return;                            /* don't wait for return yet */
  302.  
  303.     /*
  304.      * Set '[ mark to the line above where the lines go (line 1 if zero).
  305.      */
  306.     curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
  307.     curbuf->b_op_start.col = 0;
  308.  
  309. #ifdef AUTOCMD
  310.     {
  311.         int    m = msg_scroll;
  312.         int n = msg_scrolled;
  313.         BUF    *old_curbuf = curbuf;
  314.  
  315.         /*
  316.          * The file must be closed again, the autocommands may want to change
  317.          * the file before reading it.
  318.          */
  319.         close(fd);            /* ignore errors */
  320.  
  321.         /*
  322.          * The output from the autocommands should not overwrite anything and
  323.          * should not be overwritten: Set msg_scroll, restore its value if no
  324.          * output was done.
  325.          */
  326.         msg_scroll = TRUE;
  327.         if (filtering)
  328.             apply_autocmds(EVENT_FILTERREADPRE, NULL, fname, FALSE);
  329.         else if (newfile)
  330.             apply_autocmds(EVENT_BUFREADPRE, NULL, fname, FALSE);
  331.         else
  332.             apply_autocmds(EVENT_FILEREADPRE, fname, fname, FALSE);
  333.         if (msg_scrolled == n)
  334.             msg_scroll = m;
  335.  
  336.         /*
  337.          * Don't allow the autocommands to change the current buffer.
  338.          * Try to re-open the file.
  339.          */
  340.         if (curbuf != old_curbuf ||
  341.                            (fd = open((char *)fname, O_RDONLY | O_EXTRA)) < 0)
  342.         {
  343.             --no_wait_return;
  344.             msg_scroll = msg_save;
  345.             if (fd < 0)
  346.                 EMSG("*ReadPre autocommands made the file unreadable");
  347.             else
  348.                 EMSG("*ReadPre autocommands must not change current buffer");
  349.             return FAIL;
  350.         }
  351.     }
  352. #endif
  353.  
  354.     if (!recoverymode && !filtering)
  355.         filemess(curbuf, fname, (char_u *)"");    /* show that we are busy */
  356.  
  357.     msg_scroll = FALSE;                            /* overwrite the file message */
  358.  
  359.     /*
  360.      * Set textmode and linecnt now, before the "retry" caused by 'textauto'
  361.      * and after the autocommands, which may change them.
  362.      */
  363.     textmode = curbuf->b_p_tx;
  364.     linecnt = curbuf->b_ml.ml_line_count;
  365.  
  366. retry:
  367.     while (!error && !got_int)
  368.     {
  369.         /*
  370.          * We allocate as much space for the file as we can get, plus
  371.          * space for the old line plus room for one terminating NUL.
  372.          * The amount is limited by the fact that read() only can read
  373.          * upto max_unsigned characters (and other things).
  374.          */
  375. #if SIZEOF_INT <= 2
  376.         if (linerest >= 0x7ff0)
  377.         {
  378.             ++split;
  379.             *ptr = NL;                /* split line by inserting a NL */
  380.             size = 1;
  381.         }
  382.         else
  383. #endif
  384.         {
  385. #if SIZEOF_INT > 2
  386.             size = 0x10000L;                /* use buffer >= 64K */
  387. #else
  388.             size = 0x7ff0L - linerest;        /* limit buffer to 32K */
  389. #endif
  390.  
  391.             for ( ; size >= 10; size >>= 1)
  392.             {
  393.                 if ((new_buffer = lalloc((long_u)(size + linerest + 1), FALSE)) != NULL)
  394.                     break;
  395.             }
  396.             if (new_buffer == NULL)
  397.             {
  398.                 do_outofmem_msg();
  399.                 error = TRUE;
  400.                 break;
  401.             }
  402.             if (linerest)        /* copy characters from the previous buffer */
  403.                 vim_memmove(new_buffer, ptr - linerest, (size_t)linerest);
  404.             vim_free(buffer);
  405.             buffer = new_buffer;
  406.             ptr = buffer + linerest;
  407.             line_start = buffer;
  408.             
  409.             if ((size = read(fd, (char *)ptr, (size_t)size)) <= 0)
  410.             {
  411.                 if (size < 0)                /* read error */
  412.                     error = TRUE;
  413.                 break;
  414.             }
  415.             filesize += size;                /* count the number of characters */
  416.  
  417.             /*
  418.              * when reading the first part of a file: guess EOL type
  419.              */
  420.             if (firstpart && p_ta)
  421.             {
  422.                 for (p = ptr; p < ptr + size; ++p)
  423.                     if (*p == NL)
  424.                     {
  425.                         if (p > ptr && p[-1] == CR)    /* found CR-NL */
  426.                             textmode = TRUE;
  427.                         else                        /* found a single NL */
  428.                             textmode = FALSE;
  429.                             /* if editing a new file: may set p_tx */
  430.                         if (newfile)
  431.                             curbuf->b_p_tx = textmode;
  432.                         break;
  433.                     }
  434.             }
  435.         }
  436.  
  437.         firstpart = FALSE;
  438.  
  439.         /*
  440.          * This loop is executed once for every character read.
  441.          * Keep it fast!
  442.          */
  443.         --ptr;
  444.         while (++ptr, --size >= 0)
  445.         {
  446.             if ((c = *ptr) != NUL && c != NL)    /* catch most common case */
  447.                 continue;
  448.             if (c == NUL)
  449.                 *ptr = NL;        /* NULs are replaced by newlines! */
  450.             else
  451.             {
  452.                 if (skip_count == 0)
  453.                 {
  454.                     *ptr = NUL;        /* end of line */
  455.                     len = ptr - line_start + 1;
  456.                     if (textmode)
  457.                     {
  458.                         if (ptr[-1] == CR)    /* remove CR */
  459.                         {
  460.                             ptr[-1] = NUL;
  461.                             --len;
  462.                         }
  463.                         /*
  464.                          * Reading in textmode, but no CR-LF found!
  465.                          * When 'textauto' set, delete all the lines read so
  466.                          * far and start all over again.
  467.                          * Otherwise give an error message later.
  468.                          */
  469.                         else if (!tx_error)
  470.                         {
  471.                             if (p_ta && lseek(fd, 0L, SEEK_SET) == 0)
  472.                             {
  473.                                 while (lnum > from)
  474.                                     ml_delete(lnum--, FALSE);
  475.                                 textmode = FALSE;
  476.                                 if (newfile)
  477.                                     curbuf->b_p_tx = FALSE;
  478.                                 linerest = 0;
  479.                                 filesize = 0;
  480.                                 skip_count = lines_to_skip;
  481.                                 read_count = lines_to_read;
  482.                                 goto retry;
  483.                             }
  484.                             else
  485.                                 tx_error = TRUE;
  486.                         }
  487.                     }
  488.                     if (ml_append(lnum, line_start, len, newfile) == FAIL)
  489.                     {
  490.                         error = TRUE;
  491.                         break;
  492.                     }
  493.                     ++lnum;
  494.                     if (--read_count == 0)
  495.                     {
  496.                         error = TRUE;        /* break loop */
  497.                         line_start = ptr;    /* nothing left to write */
  498.                         break;
  499.                     }
  500.                 }
  501.                 else
  502.                     --skip_count;
  503.                 line_start = ptr + 1;
  504.             }
  505.         }
  506.         linerest = ptr - line_start;
  507.         mch_breakcheck();
  508.     }
  509.  
  510.     /* not an error, max. number of lines reached */
  511.     if (error && read_count == 0)
  512.         error = FALSE;
  513.  
  514.     /*
  515.      * If we get EOF in the middle of a line, note the fact and
  516.      * complete the line ourselves.
  517.      * In textmode ignore a trailing CTRL-Z, unless 'binary' set.
  518.      */
  519.     if (!error && !got_int && linerest != 0 &&
  520.             !(!curbuf->b_p_bin && textmode &&
  521.                     *line_start == Ctrl('Z') && ptr == line_start + 1))
  522.     {
  523.         if (newfile)                /* remember for when writing */
  524.             curbuf->b_p_eol = FALSE;
  525.         *ptr = NUL;
  526.         if (ml_append(lnum, line_start,
  527.                         (colnr_t)(ptr - line_start + 1), newfile) == FAIL)
  528.             error = TRUE;
  529.         else
  530.             read_no_eol_lnum = ++lnum;
  531.     }
  532.     if (lnum != from && !newfile)    /* added at least one line */
  533.         CHANGED;
  534.  
  535.     close(fd);                        /* errors are ignored */
  536.     vim_free(buffer);
  537.  
  538.     --no_wait_return;                /* may wait for return now */
  539.  
  540.     /* in recovery mode everything but autocommands are skipped */
  541.     if (!recoverymode)
  542.     {
  543.  
  544.         /* need to delete the last line, which comes from the empty buffer */
  545.         if (newfile && !(curbuf->b_ml.ml_flags & ML_EMPTY))
  546.         {
  547.             ml_delete(curbuf->b_ml.ml_line_count, FALSE);
  548.             --linecnt;
  549.         }
  550.         linecnt = curbuf->b_ml.ml_line_count - linecnt;
  551.         if (filesize == 0)
  552.             linecnt = 0;
  553.         if (!newfile)
  554.             mark_adjust(from + 1, MAXLNUM, (long)linecnt, 0L);
  555.  
  556.         if (got_int)
  557.         {
  558.             filemess(curbuf, fname, e_interr);
  559.             msg_scroll = msg_save;
  560. #ifdef VIMINFO
  561.             check_marks_read();
  562. #endif /* VIMINFO */
  563.             return OK;            /* an interrupt isn't really an error */
  564.         }
  565.  
  566.         if (!filtering)
  567.         {
  568.             msg_add_fname(curbuf, fname);    /* fname in IObuff with quotes */
  569.             c = FALSE;
  570.  
  571. #ifdef UNIX
  572. # ifdef S_ISFIFO
  573.             if (S_ISFIFO(perm))                        /* fifo or socket */
  574.             {
  575.                 STRCAT(IObuff, "[fifo/socket]");
  576.                 c = TRUE;
  577.             }
  578. # else
  579. #  ifdef S_IFIFO
  580.             if ((perm & S_IFMT) == S_IFIFO)            /* fifo */
  581.             {
  582.                 STRCAT(IObuff, "[fifo]");
  583.                 c = TRUE;
  584.             }
  585. #  endif
  586. #  ifdef S_IFSOCK
  587.             if ((perm & S_IFMT) == S_IFSOCK)        /* or socket */
  588.             {
  589.                 STRCAT(IObuff, "[socket]");
  590.                 c = TRUE;
  591.             }
  592. #  endif
  593. # endif
  594. #endif
  595.             if (curbuf->b_p_ro)
  596.             {
  597.                 STRCAT(IObuff, shortmess(SHM_RO) ? "[RO]" : "[readonly]");
  598.                 c = TRUE;
  599.             }
  600.             if (read_no_eol_lnum)
  601.             {
  602.                 msg_add_eol();
  603.                 c = TRUE;
  604.             }
  605.             if (tx_error)
  606.             {
  607.                 STRCAT(IObuff, "[CR missing]");
  608.                 c = TRUE;
  609.             }
  610.             if (split)
  611.             {
  612.                 STRCAT(IObuff, "[long lines split]");
  613.                 c = TRUE;
  614.             }
  615.             if (error)
  616.             {
  617.                 STRCAT(IObuff, "[READ ERRORS]");
  618.                 c = TRUE;
  619.             }
  620.             if (msg_add_textmode(textmode))
  621.                 c = TRUE;
  622.             msg_add_lines(c, (long)linecnt, filesize);
  623.             msg_trunc(IObuff);
  624.         }
  625.  
  626.         if (error && newfile)    /* with errors we should not write the file */
  627.             curbuf->b_p_ro = TRUE;
  628.  
  629.         u_clearline();        /* cannot use "U" command after adding lines */
  630.  
  631.         if (from < curbuf->b_ml.ml_line_count)
  632.         {
  633.             curwin->w_cursor.lnum = from + 1;    /* cursor at first new line */
  634.             beginline(TRUE);                    /* on first non-blank */
  635.         }
  636.  
  637.         /*
  638.          * Set '[ and '] marks to the newly read lines.
  639.          */
  640.         curbuf->b_op_start.lnum = from + 1;
  641.         curbuf->b_op_start.col = 0;
  642.         curbuf->b_op_end.lnum = from + linecnt;
  643.         curbuf->b_op_end.col = 0;
  644.     }
  645.     msg_scroll = msg_save;
  646.  
  647. #ifdef VIMINFO
  648.     /*
  649.      * Get the marks before executing autocommands, so they can be used there.
  650.      */
  651.     check_marks_read();
  652. #endif /* VIMINFO */
  653.  
  654. #ifdef AUTOCMD
  655.     {
  656.         int    m = msg_scroll;
  657.         int n = msg_scrolled;
  658.  
  659.         /*
  660.          * Trick: We remember if the last line of the read didn't have
  661.          * an eol for when writing it again.  This is required for
  662.          * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
  663.          */
  664.         write_no_eol_lnum = read_no_eol_lnum;
  665.  
  666.         /*
  667.          * The output from the autocommands should not overwrite anything and
  668.          * should not be overwritten: Set msg_scroll, restore its value if no
  669.          * output was done.
  670.          */
  671.         msg_scroll = TRUE;
  672.         if (filtering)
  673.             apply_autocmds(EVENT_FILTERREADPOST, NULL, fname, FALSE);
  674.         else if (newfile)
  675.             apply_autocmds(EVENT_BUFREADPOST, NULL, fname, FALSE);
  676.         else
  677.             apply_autocmds(EVENT_FILEREADPOST, fname, fname, FALSE);
  678.         if (msg_scrolled == n)
  679.             msg_scroll = m;
  680.     }
  681. #endif
  682.  
  683.     if (recoverymode && error)
  684.         return FAIL;
  685.     return OK;
  686. }
  687.  
  688. #ifdef VIMINFO
  689.     static void
  690. check_marks_read()
  691. {
  692.     if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0)
  693.     {
  694.         read_viminfo(NULL, FALSE, TRUE, FALSE);
  695.         curbuf->b_marks_read = TRUE;
  696.     }
  697. }
  698. #endif /* VIMINFO */
  699.  
  700. /*
  701.  * buf_write() - write to file 'fname' lines 'start' through 'end'
  702.  *
  703.  * We do our own buffering here because fwrite() is so slow.
  704.  *
  705.  * If forceit is true, we don't care for errors when attempting backups (jw).
  706.  * In case of an error everything possible is done to restore the original file.
  707.  * But when forceit is TRUE, we risk loosing it.
  708.  * When reset_changed is TRUE and start == 1 and end ==
  709.  * curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
  710.  *
  711.  * This function must NOT use NameBuff (because it's called by autowrite()).
  712.  *
  713.  * return FAIL for failure, OK otherwise
  714.  */
  715.     int
  716. buf_write(buf, fname, sfname, start, end, append, forceit,
  717.                                                       reset_changed, filtering)
  718.     BUF                *buf;
  719.     char_u            *fname;
  720.     char_u            *sfname;
  721.     linenr_t        start, end;
  722.     int                append;
  723.     int                forceit;
  724.     int                reset_changed;
  725.     int                filtering;
  726. {
  727.     int                 fd;
  728.     char_u               *backup = NULL;
  729.     char_u               *ffname;
  730. #ifdef AUTOCMD
  731.     BUF                   *save_buf;
  732. #endif
  733.     register char_u       *s;
  734.     register char_u       *ptr;
  735.     register char_u        c;
  736.     register int        len;
  737.     register linenr_t    lnum;
  738.     long                nchars;
  739.     char_u                *errmsg = NULL;
  740.     char_u                *buffer;
  741.     char_u                smallbuf[SBUFSIZE];
  742.     char_u                *backup_ext;
  743.     int                    bufsize;
  744.     long                 perm = -1;            /* file permissions */
  745.     int                    retval = OK;
  746.     int                    newfile = FALSE;    /* TRUE if file doesn't exist yet */
  747.     int                    msg_save = msg_scroll;
  748.     int                    overwriting;        /* TRUE if writing over original */
  749.     int                    no_eol = FALSE;        /* no end-of-line written */
  750. #if defined(UNIX) || defined(__EMX__XX) /*XXX fix me sometime? */
  751.     struct stat            st_old;
  752.     int                    made_writable = FALSE;    /* 'w' bit has been set */
  753. #endif
  754. #ifdef AMIGA
  755.     BPTR                flock;
  756. #endif
  757.                                             /* writing everything */
  758.     int                    whole = (start == 1 && end == buf->b_ml.ml_line_count);
  759. #ifdef AUTOCMD
  760.     linenr_t            old_line_count = buf->b_ml.ml_line_count;
  761. #endif
  762.  
  763.     if (fname == NULL || *fname == NUL)        /* safety check */
  764.         return FAIL;
  765.  
  766.     /*
  767.      * If there is no file name yet, use the one for the written file.
  768.      * b_notedited is set to reflect this (in case the write fails).
  769.      * Don't do this when the write is for a filter command.
  770.      * Only do this when 'cpoptions' contains the 'f' flag.
  771.      */
  772.     if (reset_changed && whole && buf == curbuf &&
  773.                                    curbuf->b_filename == NULL && !filtering &&
  774.                                         vim_strchr(p_cpo, CPO_FNAMEW) != NULL)
  775.     {
  776.         if (setfname(fname, sfname, FALSE) == OK)
  777.             curbuf->b_notedited = TRUE;
  778.     }
  779.  
  780.     if (sfname == NULL)
  781.         sfname = fname;
  782.     /*
  783.      * For Unix: Use the short filename whenever possible.
  784.      * Avoids problems with networks and when directory names are changed.
  785.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  786.      * another directory, which we don't detect
  787.      */
  788.     ffname = fname;                            /* remember full fname */
  789. #ifdef UNIX
  790.     if (!did_cd)
  791.         fname = sfname;
  792. #endif
  793.  
  794.         /* make sure we have a valid backup extension to use */
  795.     if (*p_bex == NUL)
  796.         backup_ext = (char_u *)".bak";
  797.     else
  798.         backup_ext = p_bex;
  799.  
  800.     if (buf->b_filename != NULL && fnamecmp(ffname, buf->b_filename) == 0)
  801.         overwriting = TRUE;
  802.     else
  803.         overwriting = FALSE;
  804.  
  805.     /*
  806.      * Disallow writing from .exrc and .vimrc in current directory for
  807.      * security reasons.
  808.      */
  809.     if (secure)
  810.     {
  811.         secure = 2;
  812.         emsg(e_curdir);
  813.         return FAIL;
  814.     }
  815.  
  816.     if (exiting)
  817.         settmode(0);                /* when exiting allow typahead now */
  818.  
  819.     ++no_wait_return;                /* don't wait for return yet */
  820.  
  821.     /*
  822.      * Set '[ and '] marks to the lines to be written.
  823.      */
  824.     buf->b_op_start.lnum = start;
  825.     buf->b_op_start.col = 0;
  826.     buf->b_op_end.lnum = end;
  827.     buf->b_op_end.col = 0;
  828.  
  829. #ifdef AUTOCMD
  830.     /*
  831.      * Apply PRE aucocommands.
  832.      * Set curbuf to the buffer to be written.
  833.      * Careful: The autocommands may call buf_write() recursively!
  834.      */
  835.     save_buf = curbuf;
  836.     curbuf = buf;
  837.     curwin->w_buffer = buf;
  838.     if (append)
  839.         apply_autocmds(EVENT_FILEAPPENDPRE, fname, fname, FALSE);
  840.     else if (filtering)
  841.         apply_autocmds(EVENT_FILTERWRITEPRE, NULL, fname, FALSE);
  842.     else if (reset_changed && whole)
  843.         apply_autocmds(EVENT_BUFWRITEPRE, fname, fname, FALSE);
  844.     else
  845.         apply_autocmds(EVENT_FILEWRITEPRE, fname, fname, FALSE);
  846.     /*
  847.      * If the autocommands deleted or unloaded the buffer, give an error
  848.      * message.
  849.      */
  850.     if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL)
  851.     {
  852.         --no_wait_return;
  853.         msg_scroll = msg_save;
  854.         EMSG("Autocommands deleted or unloaded buffer to be written");
  855.         return FAIL;
  856.     }
  857.     /*
  858.      * If the autocommands didn't change the current buffer, go back to the
  859.      * original current buffer, if it still exists.
  860.      */
  861.     if (curbuf == buf && buf_valid(save_buf))
  862.     {
  863.         curbuf = save_buf;
  864.         curwin->w_buffer = save_buf;
  865.     }
  866.     
  867.     /*
  868.      * The autocommands may have changed the number of lines in the file.
  869.      * When writing the whole file, adjust the end.
  870.      * When writing part of the file, assume that the autocommands only
  871.      * changed the number of lines that are to be written (tricky!).
  872.      */
  873.     if (buf->b_ml.ml_line_count != old_line_count)
  874.     {
  875.         if (whole)                                            /* writing all */
  876.             end = buf->b_ml.ml_line_count;
  877.         else if (buf->b_ml.ml_line_count > old_line_count)    /* more lines */
  878.             end += buf->b_ml.ml_line_count - old_line_count;
  879.         else                                                /* less lines */
  880.         {
  881.             end -= old_line_count - buf->b_ml.ml_line_count;
  882.             if (end < start)
  883.             {
  884.                 --no_wait_return;
  885.                 msg_scroll = msg_save;
  886.                 EMSG("Autocommand changed number of lines in unexpected way");
  887.                 return FAIL;
  888.             }
  889.         }
  890.     }
  891. #endif
  892.  
  893.     if (shortmess(SHM_OVER))
  894.         msg_scroll = FALSE;            /* overwrite previous file message */
  895.     else
  896.         msg_scroll = TRUE;            /* don't overwrite previous file message */
  897.     if (!filtering)
  898.         filemess(buf,
  899. #ifndef UNIX
  900.                 did_cd ? fname : sfname,
  901. #else
  902.                 fname,
  903. #endif
  904.                     (char_u *)"");    /* show that we are busy */
  905.     msg_scroll = FALSE;                /* always overwrite the file message now */
  906.  
  907.     buffer = alloc(BUFSIZE);
  908.     if (buffer == NULL)                /* can't allocate big buffer, use small
  909.                                      * one (to be able to write when out of
  910.                                      * memory) */
  911.     {
  912.         buffer = smallbuf;
  913.         bufsize = SBUFSIZE;
  914.     }
  915.     else
  916.         bufsize = BUFSIZE;
  917.  
  918. #if defined(UNIX) && !defined(ARCHIE)
  919.         /* get information about original file (if there is one) */
  920.     st_old.st_dev = st_old.st_ino = 0;
  921.     if (stat((char *)fname, &st_old))
  922.         newfile = TRUE;
  923.     else
  924.     {
  925. #ifdef _POSIX_SOURCE
  926.         if (!S_ISREG(st_old.st_mode))              /* not a file */
  927. #else
  928.         if ((st_old.st_mode & S_IFMT) != S_IFREG)    /* not a file */
  929. #endif
  930.         {
  931. #ifdef _POSIX_SOURCE
  932.             if (S_ISDIR(st_old.st_mode))
  933. #else
  934.             if ((st_old.st_mode & S_IFMT) == S_IFDIR)
  935. #endif
  936.                 errmsg = (char_u *)"is a directory";
  937.             else
  938.                 errmsg = (char_u *)"is not a file";
  939.             goto fail;
  940.         }
  941.         if (buf->b_mtime_read != 0 &&
  942.                           buf->b_mtime_read != st_old.st_mtime && overwriting)
  943.         {
  944.             msg_scroll = TRUE;        /* don't overwrite messages here */
  945.             (void)set_highlight('e');    /* set highlight for error messages */
  946.             msg_highlight = TRUE;
  947.             /* don't use emsg() here, don't want to flush the buffers */
  948.             MSG("WARNING: The file has been changed since reading it!!!");
  949.             if (ask_yesno((char_u *)"Do you really want to write to it",
  950.                                                                  TRUE) == 'n')
  951.             {
  952.                 retval = FAIL;
  953.                 goto fail;
  954.             }
  955.             msg_scroll = FALSE;        /* always overwrite the file message now */
  956.         }
  957.         perm = st_old.st_mode;
  958.     }
  959. /*
  960.  * If we are not appending, the file exists, and the 'writebackup', 'backup'
  961.  * or 'patchmode' option is set, try to make a backup copy of the file.
  962.  */
  963.     if (!append && perm >= 0 && (p_wb || p_bk || *p_pm != NUL) &&
  964.                           (fd = open((char *)fname, O_RDONLY | O_EXTRA)) >= 0)
  965.     {
  966.         int                bfd, buflen;
  967.         char_u            copybuf[BUFSIZE + 1], *wp;
  968.         int                some_error = FALSE;
  969.         struct stat        st_new;
  970.         char_u            *dirp;
  971.         char_u            *rootname;
  972. #ifndef SHORT_FNAME
  973.         int                did_set_shortname;
  974. #endif
  975.  
  976.         /*
  977.          * Try to make the backup in each directory in the 'bdir' option.
  978.          *
  979.          * Unix semantics has it, that we may have a writable file, 
  980.          * that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
  981.          *  - the directory is not writable, 
  982.          *  - the file may be a symbolic link, 
  983.          *  - the file may belong to another user/group, etc.
  984.          *
  985.          * For these reasons, the existing writable file must be truncated
  986.          * and reused. Creation of a backup COPY will be attempted.
  987.          */
  988.         dirp = p_bdir;
  989.         while (*dirp)
  990.         {
  991.             st_new.st_dev = st_new.st_ino = 0;
  992.             st_new.st_gid = 0;
  993.  
  994.             /*
  995.              * Isolate one directory name, using an entry in 'bdir'.
  996.              */
  997.             (void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
  998.             rootname = get_file_in_dir(fname, copybuf);
  999.             if (rootname == NULL)
  1000.             {
  1001.                 some_error = TRUE;            /* out of memory */
  1002.                 goto nobackup;
  1003.             }
  1004.  
  1005.  
  1006. #ifndef SHORT_FNAME
  1007.             did_set_shortname = FALSE;
  1008. #endif
  1009.  
  1010.             /*
  1011.              * May try twice if 'shortname' not set.
  1012.              */
  1013.             for (;;)
  1014.             {
  1015.                 /*
  1016.                  * Make backup file name.
  1017.                  */
  1018.                 backup = buf_modname(
  1019. #ifdef SHORT_FNAME
  1020.                                         TRUE,
  1021. #else
  1022.                                         (buf->b_p_sn || buf->b_shortname),
  1023. #endif
  1024.                                                         rootname, backup_ext);
  1025.                 if (backup == NULL)
  1026.                 {
  1027.                     some_error = TRUE;            /* out of memory */
  1028.                     vim_free(rootname);
  1029.                     goto nobackup;
  1030.                 }
  1031.  
  1032.                 /*
  1033.                  * Check if backup file already exists.
  1034.                  */
  1035.                 if (!stat((char *)backup, &st_new))
  1036.                 {
  1037.                     /*
  1038.                      * Check if backup file is same as original file.
  1039.                      * May happen when modname gave the same file back.
  1040.                      * E.g. silly link, or filename-length reached.
  1041.                      * If we don't check here, we either ruin the file when
  1042.                      * copying or erase it after writing. jw.
  1043.                      */
  1044.                     if (st_new.st_dev == st_old.st_dev &&
  1045.                                            st_new.st_ino == st_old.st_ino)
  1046.                     {
  1047.                         vim_free(backup);
  1048.                         backup = NULL;    /* there is no backup file to delete */
  1049. #ifndef SHORT_FNAME
  1050.                         /*
  1051.                          * may try again with 'shortname' set
  1052.                          */
  1053.                         if (!(buf->b_shortname || buf->b_p_sn))
  1054.                         {
  1055.                             buf->b_shortname = TRUE;
  1056.                             did_set_shortname = TRUE;
  1057.                             continue;
  1058.                         }
  1059.                             /* setting shortname didn't help */
  1060.                         if (did_set_shortname)
  1061.                             buf->b_shortname = FALSE;
  1062. #endif
  1063.                         break;
  1064.                     }
  1065.  
  1066.                     /*
  1067.                      * If we are not going to keep the backup file, don't
  1068.                      * delete an existing one, try to use another name.
  1069.                      * Change one character, just before the extension.
  1070.                      */
  1071.                     if (!p_bk)
  1072.                     {
  1073.                         wp = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
  1074.                         if (wp < backup)        /* empty file name ??? */
  1075.                             wp = backup;
  1076.                         *wp = 'z';
  1077.                         while (*wp > 'a' && !stat((char *)backup, &st_new))
  1078.                             --*wp;
  1079.                         /* They all exist??? Must be something wrong. */
  1080.                         if (*wp == 'a')
  1081.                         {
  1082.                             vim_free(backup);
  1083.                             backup = NULL;
  1084.                         }
  1085.                     }
  1086.                 }
  1087.                 break;
  1088.             }
  1089.             vim_free(rootname);
  1090.  
  1091.             /*
  1092.              * Try to create the backup file
  1093.              */
  1094.             if (backup != NULL)
  1095.             {
  1096.                 /* remove old backup, if present */
  1097.                 vim_remove(backup);
  1098.                 bfd = open((char *)backup, O_WRONLY | O_CREAT | O_EXTRA, 0666);
  1099.                 if (bfd < 0)
  1100.                 {
  1101.                     vim_free(backup);
  1102.                     backup = NULL;
  1103.                 }
  1104.                 else
  1105.                 {
  1106.                     /* set file protection same as original file, but strip
  1107.                      * s-bit */
  1108.                     (void)setperm(backup, perm & 0777);
  1109.  
  1110.                     /*
  1111.                      * Try to set the group of the backup same as the original
  1112.                      * file. If this fails, set the protection bits for the
  1113.                      * group same as the protection bits for others.
  1114.                      */
  1115.                     if (st_new.st_gid != st_old.st_gid &&
  1116. #ifdef HAVE_FCHOWN    /* sequent-ptx lacks fchown() */
  1117.                                           fchown(bfd, -1, st_old.st_gid) != 0)
  1118. #else
  1119.                                 chown((char *)backup, -1, st_old.st_gid) != 0)
  1120. #endif
  1121.                         setperm(backup, (perm & 0707) | ((perm & 07) << 3));
  1122.  
  1123.                     /* copy the file. */
  1124.                     while ((buflen = read(fd, (char *)copybuf, BUFSIZE)) > 0)
  1125.                     {
  1126.                         if (write_buf(bfd, copybuf, buflen) == FAIL)
  1127.                         {
  1128.                             errmsg = (char_u *)"Can't write to backup file (use ! to override)";
  1129.                             break;
  1130.                         }
  1131.                     }
  1132.                     if (close(bfd) < 0 && errmsg == NULL)
  1133.                         errmsg = (char_u *)"Close error for backup file (use ! to override)";
  1134.                     if (buflen < 0)
  1135.                         errmsg = (char_u *)"Can't read file for backup (use ! to override)";
  1136.                     break;
  1137.                 }
  1138.             }
  1139.         }
  1140. nobackup:
  1141.         close(fd);                /* ignore errors for closing read file */
  1142.  
  1143.         if (backup == NULL && errmsg == NULL)
  1144.             errmsg = (char_u *)"Cannot create backup file (use ! to override)";
  1145.         /* ignore errors when forceit is TRUE */
  1146.         if ((some_error || errmsg) && !forceit)
  1147.         {
  1148.             retval = FAIL;
  1149.             goto fail;
  1150.         }
  1151.         errmsg = NULL;
  1152.     }
  1153.     /* When using ":w!" and the file was read-only: make it writable */
  1154.     if (forceit && (st_old.st_uid == getuid()) && perm >= 0 && !(perm & 0200))
  1155.      {
  1156.         perm |= 0200;    
  1157.         (void)setperm(fname, perm);
  1158.         made_writable = TRUE;
  1159.     }
  1160.  
  1161. #else /* end of UNIX, start of the rest */
  1162.  
  1163. /*
  1164.  * If we are not appending, the file exists, and the 'writebackup' or
  1165.  * 'backup' option is set, make a backup.
  1166.  * Do not make any backup, if "writebackup" and "backup" are 
  1167.  * both switched off. This helps when editing large files on
  1168.  * almost-full disks. (jw)
  1169.  */
  1170.     perm = getperm(fname);
  1171.     if (perm < 0)
  1172.         newfile = TRUE;
  1173.     else if (mch_isdir(fname))
  1174.     {
  1175.         errmsg = (char_u *)"is a directory";
  1176.         goto fail;
  1177.     }
  1178.     if (!append && perm >= 0 && (p_wb || p_bk || *p_pm != NUL))
  1179.     {
  1180.         char_u            *dirp;
  1181.         char_u            *p;
  1182.         char_u            *rootname;
  1183.  
  1184.         /*
  1185.          * Form the backup file name - change path/fo.o.h to path/fo.o.h.bak
  1186.          * Try all directories in 'backupdir', first one that works is used.
  1187.          */
  1188.         dirp = p_bdir;
  1189.         while (*dirp)
  1190.         {
  1191.             /*
  1192.              * Isolate one directory name and make the backup file name.
  1193.              */
  1194.             (void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
  1195.             rootname = get_file_in_dir(fname, IObuff);
  1196.             if (rootname == NULL)
  1197.                 backup = NULL;
  1198.             else
  1199.             {
  1200.                 backup = buf_modname(
  1201. #ifdef SHORT_FNAME
  1202.                                         TRUE,
  1203. #else
  1204.                                         (buf->b_p_sn || buf->b_shortname),
  1205. #endif
  1206.                                                         rootname, backup_ext);
  1207.                 vim_free(rootname);
  1208.             }
  1209.  
  1210.             if (backup != NULL)
  1211.             {
  1212.                 /*
  1213.                  * If we are not going to keep the backup file, don't
  1214.                  * delete an existing one, try to use another name.
  1215.                  * Change one character, just before the extension.
  1216.                  */
  1217.                 if (!p_bk && getperm(backup) >= 0)
  1218.                 {
  1219.                     p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
  1220.                     if (p < backup)        /* empty file name ??? */
  1221.                         p = backup;
  1222.                     *p = 'z';
  1223.                     while (*p > 'a' && getperm(backup) >= 0)
  1224.                         --*p;
  1225.                     /* They all exist??? Must be something wrong! */
  1226.                     if (*p == 'a')
  1227.                     {
  1228.                         vim_free(backup);
  1229.                         backup = NULL;
  1230.                     }
  1231.                 }
  1232.             }
  1233.             if (backup != NULL)
  1234.             {
  1235.  
  1236.                 /*
  1237.                  * Delete any existing backup and move the current version to
  1238.                  * the backup.  For safety, we don't remove the backup until
  1239.                  * the write has finished successfully. And if the 'backup'
  1240.                  * option is set, leave it around.
  1241.                  */
  1242. #ifdef AMIGA
  1243.                 /*
  1244.                  * With MSDOS-compatible filesystems (crossdos, messydos) it is
  1245.                  * possible that the name of the backup file is the same as the
  1246.                  * original file. To avoid the chance of accidently deleting the
  1247.                  * original file (horror!) we lock it during the remove.
  1248.                  * This should not happen with ":w", because startscript()
  1249.                  * should detect this problem and set buf->b_shortname,
  1250.                  * causing modname to return a correct ".bak" filename. This
  1251.                  * problem does exist with ":w filename", but then the
  1252.                  * original file will be somewhere else so the backup isn't
  1253.                  * really important. If autoscripting is off the rename may
  1254.                  * fail.
  1255.                  */
  1256.                 flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
  1257. #endif
  1258.                 vim_remove(backup);
  1259. #ifdef AMIGA
  1260.                 if (flock)
  1261.                     UnLock(flock);
  1262. #endif
  1263.                 /*
  1264.                  * If the renaming of the original file to the backup file
  1265.                  * works, quit here.
  1266.                  */
  1267.                 if (vim_rename(fname, backup) == 0)
  1268.                     break;
  1269.  
  1270.                 vim_free(backup);    /* don't do the rename below */
  1271.                 backup = NULL;
  1272.             }
  1273.         }
  1274.         if (backup == NULL && !forceit)
  1275.         {
  1276.             errmsg = (char_u *)"Can't make backup file (use ! to override)";
  1277.             goto fail;
  1278.         }
  1279.     }
  1280. #endif /* UNIX */
  1281.  
  1282.     /* When using ":w!" and writing to the current file, readonly makes no
  1283.      * sense, reset it */
  1284.     if (forceit && overwriting)
  1285.         buf->b_p_ro = FALSE;
  1286.  
  1287.     /*
  1288.      * If the original file is being overwritten, there is a small chance that
  1289.      * we crash in the middle of writing. Therefore the file is preserved now.
  1290.      * This makes all block numbers positive so that recovery does not need
  1291.      * the original file.
  1292.      * Don't do this if there is a backup file and we are exiting.
  1293.      */
  1294.     if (reset_changed && !newfile && !otherfile(ffname) &&
  1295.                                             !(exiting && backup != NULL))
  1296.         ml_preserve(buf, FALSE);
  1297.  
  1298.     /* 
  1299.      * We may try to open the file twice: If we can't write to the
  1300.      * file and forceit is TRUE we delete the existing file and try to create
  1301.      * a new one. If this still fails we may have lost the original file!
  1302.      * (this may happen when the user reached his quotum for number of files).
  1303.      * Appending will fail if the file does not exist and forceit is FALSE.
  1304.      */
  1305.     while ((fd = open((char *)fname, O_WRONLY | O_EXTRA | (append ?
  1306.                     (forceit ? (O_APPEND | O_CREAT) : O_APPEND) :
  1307.                     (O_CREAT | O_TRUNC)), 0666)) < 0)
  1308.      {
  1309.         /*
  1310.          * A forced write will try to create a new file if the old one is
  1311.          * still readonly. This may also happen when the directory is
  1312.          * read-only. In that case the vim_remove() will fail.
  1313.          */
  1314.         if (!errmsg)
  1315.         {
  1316.             errmsg = (char_u *)"Can't open file for writing";
  1317.             if (forceit)
  1318.             {
  1319. #ifdef UNIX
  1320.                 /* we write to the file, thus it should be marked
  1321.                                                     writable after all */
  1322.                 perm |= 0200;        
  1323.                 made_writable = TRUE;
  1324.                 if (st_old.st_uid != getuid() || st_old.st_gid != getgid())
  1325.                     perm &= 0777;
  1326. #endif /* UNIX */
  1327.                 if (!append)        /* don't remove when appending */
  1328.                     vim_remove(fname);
  1329.                 continue;
  1330.             }
  1331.         }
  1332. /*
  1333.  * If we failed to open the file, we don't need a backup. Throw it away.
  1334.  * If we moved or removed the original file try to put the backup in its place.
  1335.  */
  1336.          if (backup != NULL)
  1337.         {
  1338. #ifdef UNIX
  1339.             struct stat st;
  1340.  
  1341.             /*
  1342.              * There is a small chance that we removed the original, try
  1343.              * to move the copy in its place.
  1344.              * This may not work if the vim_rename() fails.
  1345.              * In that case we leave the copy around.
  1346.              */
  1347.                                          /* file does not exist */
  1348.             if (stat((char *)fname, &st) < 0)
  1349.                                         /* put the copy in its place */
  1350.                 vim_rename(backup, fname);
  1351.                                         /* original file does exist */
  1352.             if (stat((char *)fname, &st) >= 0)
  1353.                 vim_remove(backup);    /* throw away the copy */
  1354. #else
  1355.                                         /* try to put the original file back */
  1356.              vim_rename(backup, fname);
  1357. #endif
  1358.         }
  1359.          goto fail;
  1360.      }
  1361.     errmsg = NULL;
  1362.  
  1363.     if (end > buf->b_ml.ml_line_count)
  1364.         end = buf->b_ml.ml_line_count;
  1365.     len = 0;
  1366.     s = buffer;
  1367.     nchars = 0;
  1368.     if (buf->b_ml.ml_flags & ML_EMPTY)
  1369.         start = end + 1;
  1370.     for (lnum = start; lnum <= end; ++lnum)
  1371.     {
  1372.         /*
  1373.          * The next while loop is done once for each character written.
  1374.          * Keep it fast!
  1375.          */
  1376.         ptr = ml_get_buf(buf, lnum, FALSE) - 1;
  1377.         while ((c = *++ptr) != NUL)
  1378.         {
  1379.             if (c == NL)
  1380.                 *s = NUL;        /* replace newlines with NULs */
  1381.             else
  1382.                 *s = c;
  1383.             ++s;
  1384.             if (++len != bufsize)
  1385.                 continue;
  1386.             if (write_buf(fd, buffer, bufsize) == FAIL)
  1387.             {
  1388.                 end = 0;                /* write error: break loop */
  1389.                 break;
  1390.             }
  1391.             nchars += bufsize;
  1392.             s = buffer;
  1393.             len = 0;
  1394.         }
  1395.             /* write failed or last line has no EOL: stop here */
  1396.         if (end == 0 || (lnum == end && buf->b_p_bin &&
  1397.                                                 (lnum == write_no_eol_lnum ||
  1398.                          (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol))))
  1399.         {
  1400.             ++lnum;                /* written the line, count it */
  1401.             no_eol = TRUE;
  1402.             break;
  1403.         }
  1404.         if (buf->b_p_tx)        /* write CR-NL */
  1405.         {
  1406.             *s = CR;
  1407.             ++s;
  1408.             if (++len == bufsize)
  1409.             {
  1410.                 if (write_buf(fd, buffer, bufsize) == FAIL)
  1411.                 {
  1412.                     end = 0;                /* write error: break loop */
  1413.                     break;
  1414.                 }
  1415.                 nchars += bufsize;
  1416.                 s = buffer;
  1417.                 len = 0;
  1418.             }
  1419.         }
  1420.         *s = NL;
  1421.         ++s;
  1422.         if (++len == bufsize && end)
  1423.         {
  1424.             if (write_buf(fd, buffer, bufsize) == FAIL)
  1425.             {
  1426.                 end = 0;                /* write error: break loop */
  1427.                 break;
  1428.             }
  1429.             nchars += bufsize;
  1430.             s = buffer;
  1431.             len = 0;
  1432.         }
  1433.     }
  1434.     if (len && end)
  1435.     {
  1436.         if (write_buf(fd, buffer, len) == FAIL)
  1437.             end = 0;                /* write error */
  1438.         nchars += len;
  1439.     }
  1440.  
  1441.     if (close(fd) != 0)
  1442.     {
  1443.         errmsg = (char_u *)"Close failed";
  1444.         goto fail;
  1445.     }
  1446. #ifdef UNIX
  1447.     if (made_writable)
  1448.         perm &= ~0200;            /* reset 'w' bit for security reasons */
  1449. #endif
  1450.     if (perm >= 0)
  1451.         (void)setperm(fname, perm);    /* set permissions of new file same as old file */
  1452.  
  1453.     if (end == 0)
  1454.     {
  1455.         errmsg = (char_u *)"write error (file system full?)";
  1456.         /*
  1457.          * If we have a backup file, try to put it in place of the new file,
  1458.          * because it is probably corrupt. This avoids loosing the original
  1459.          * file when trying to make a backup when writing the file a second
  1460.          * time.
  1461.          * For unix this means copying the backup over the new file.
  1462.          * For others this means renaming the backup file.
  1463.          * If this is OK, don't give the extra warning message.
  1464.          */
  1465.         if (backup != NULL)
  1466.         {
  1467. #ifdef UNIX
  1468.             char_u        copybuf[BUFSIZE + 1];
  1469.             int            bfd, buflen;
  1470.  
  1471.             if ((bfd = open((char *)backup, O_RDONLY | O_EXTRA)) >= 0)
  1472.             {
  1473.                 if ((fd = open((char *)fname,
  1474.                           O_WRONLY | O_CREAT | O_TRUNC | O_EXTRA, 0666)) >= 0)
  1475.                 {
  1476.                     /* copy the file. */
  1477.                     while ((buflen = read(bfd, (char *)copybuf, BUFSIZE)) > 0)
  1478.                         if (write_buf(fd, copybuf, buflen) == FAIL)
  1479.                             break;
  1480.                     if (close(fd) >= 0 && buflen == 0)    /* success */
  1481.                         end = 1;
  1482.                 }
  1483.                 close(bfd);        /* ignore errors for closing read file */
  1484.             }
  1485. #else
  1486.             if (vim_rename(backup, fname) == 0)
  1487.                 end = 1;
  1488. #endif
  1489.         }
  1490.         goto fail;
  1491.     }
  1492.  
  1493.     lnum -= start;            /* compute number of written lines */
  1494.     --no_wait_return;        /* may wait for return now */
  1495.  
  1496. #ifndef UNIX
  1497.     /* use shortname now, for the messages */
  1498.     if (!did_cd)
  1499.         fname = sfname;
  1500. #endif
  1501.     if (!filtering)
  1502.     {
  1503.         msg_add_fname(buf, fname);        /* put fname in IObuff with quotes */
  1504.         c = FALSE;
  1505.         if (newfile)
  1506.         {
  1507.             STRCAT(IObuff, shortmess(SHM_NEW) ? "[New]" : "[New File]");
  1508.             c = TRUE;
  1509.         }
  1510.         if (no_eol)
  1511.         {
  1512.             msg_add_eol();
  1513.             c = TRUE;
  1514.         }
  1515.         if (msg_add_textmode(buf->b_p_tx))        /* may add [textmode] */
  1516.             c = TRUE;
  1517.         msg_add_lines(c, (long)lnum, nchars);    /* add line/char count */
  1518.         if (!shortmess(SHM_WRITE))
  1519.             STRCAT(IObuff, shortmess(SHM_WRI) ? " [w]" : " written");
  1520.  
  1521.         msg_trunc(IObuff);
  1522.     }
  1523.  
  1524.     if (reset_changed && whole)            /* when written everything */
  1525.     {
  1526.         UNCHANGED(buf);
  1527.         u_unchanged(buf);
  1528.     }
  1529.  
  1530.     /*
  1531.      * If written to the current file, update the timestamp of the swap file
  1532.      * and reset the 'notedited' flag. Also sets buf->b_mtime.
  1533.      */
  1534.     if (!exiting && overwriting)
  1535.     {
  1536.         ml_timestamp(buf);
  1537.         buf->b_notedited = FALSE;
  1538.     }
  1539.  
  1540.     /*
  1541.      * If we kept a backup until now, and we are in patch mode, then we make
  1542.      * the backup file our 'original' file.
  1543.      */
  1544.     if (*p_pm)
  1545.     {
  1546.         char *org = (char *)buf_modname(
  1547. #ifdef SHORT_FNAME
  1548.                                         TRUE,
  1549. #else
  1550.                                         (buf->b_p_sn || buf->b_shortname),
  1551. #endif
  1552.                                                                  fname, p_pm);
  1553.  
  1554.         if (backup != NULL)
  1555.         {
  1556.             struct stat st;
  1557.  
  1558.             /*
  1559.              * If the original file does not exist yet
  1560.              * the current backup file becomes the original file
  1561.              */
  1562.             if (org == NULL)
  1563.                 EMSG("patchmode: can't save original file");
  1564.             else if (stat(org, &st) < 0)
  1565.             {
  1566.                 vim_rename(backup, (char_u *)org);
  1567.                 vim_free(backup);            /* don't delete the file */
  1568.                 backup = NULL;
  1569.             }
  1570.         }
  1571.         /*
  1572.          * If there is no backup file, remember that a (new) file was
  1573.          * created.
  1574.          */
  1575.         else
  1576.         {
  1577.             int empty_fd;
  1578.  
  1579.             if (org == NULL || (empty_fd =
  1580.                                       open(org, O_CREAT | O_EXTRA, 0666)) < 0)
  1581.               EMSG("patchmode: can't touch empty original file");
  1582.             else
  1583.               close(empty_fd);
  1584.         }
  1585.         if (org != NULL)
  1586.         {
  1587.             setperm((char_u *)org, getperm(fname) & 0777);
  1588.             vim_free(org);
  1589.         }
  1590.     }
  1591.  
  1592.     /*
  1593.      * Remove the backup unless 'backup' option is set
  1594.      */
  1595.     if (!p_bk && backup != NULL && vim_remove(backup) != 0)
  1596.         EMSG("Can't delete backup file");
  1597.     
  1598.     goto nofail;
  1599.  
  1600. fail:
  1601.     --no_wait_return;        /* may wait for return now */
  1602. nofail:
  1603.  
  1604.     vim_free(backup);
  1605.     if (buffer != smallbuf)
  1606.         vim_free(buffer);
  1607.  
  1608.     if (errmsg != NULL)
  1609.     {
  1610.         /* can't use emsg() here, do something alike */
  1611.         if (p_eb)
  1612.             beep_flush();            /* also includes flush_buffers() */
  1613.         else
  1614.             flush_buffers(FALSE);    /* flush internal buffers */
  1615.         (void)set_highlight('e');    /* set highlight mode for error messages */
  1616.         start_highlight();
  1617.         filemess(buf,
  1618. #ifndef UNIX
  1619.                         did_cd ? fname : sfname,
  1620. #else
  1621.                         fname,
  1622. #endif
  1623.                                                     errmsg);
  1624.         retval = FAIL;
  1625.         if (end == 0)
  1626.         {
  1627.             MSG_OUTSTR("\nWARNING: Original file may be lost or damaged\n");
  1628.             MSG_OUTSTR("don't quit the editor until the file is successfully written!");
  1629.         }
  1630.     }
  1631.     msg_scroll = msg_save;
  1632.  
  1633. #ifdef AUTOCMD
  1634.     write_no_eol_lnum = 0;        /* in case it was set by the previous read */
  1635.  
  1636.     /*
  1637.      * Apply POST autocommands.
  1638.      * Careful: The autocommands may call buf_write() recursively!
  1639.      */
  1640.     save_buf = curbuf;
  1641.     curbuf = buf;
  1642.     curwin->w_buffer = buf;
  1643.     if (append)
  1644.         apply_autocmds(EVENT_FILEAPPENDPOST, fname, fname, FALSE);
  1645.     else if (filtering)
  1646.         apply_autocmds(EVENT_FILTERWRITEPOST, NULL, fname, FALSE);
  1647.     else if (reset_changed && whole)
  1648.         apply_autocmds(EVENT_BUFWRITEPOST, fname, fname, FALSE);
  1649.     else
  1650.         apply_autocmds(EVENT_FILEWRITEPOST, fname, fname, FALSE);
  1651.     /*
  1652.      * If the autocommands didn't change the current buffer, go back to the
  1653.      * original current buffer, if it still exists.
  1654.      */
  1655.     if (curbuf == buf && buf_valid(save_buf))
  1656.     {
  1657.         curbuf = save_buf;
  1658.         curwin->w_buffer = save_buf;
  1659.     }
  1660. #endif
  1661.  
  1662.     return retval;
  1663. }
  1664.  
  1665. /*
  1666.  * Put file name into IObuff with quotes.
  1667.  */
  1668.     static void
  1669. msg_add_fname(buf, fname)
  1670.     BUF        *buf;
  1671.     char_u    *fname;
  1672. {
  1673.         /* careful: home_replace calls vim_getenv(), which also uses IObuff! */
  1674.     home_replace(buf, fname, IObuff + 1, IOSIZE - 1);
  1675.     IObuff[0] = '"';
  1676.     STRCAT(IObuff, "\" ");
  1677. }
  1678.  
  1679. /*
  1680.  * Append message for text mode to IObuff.
  1681.  * Return TRUE if something appended.
  1682.  */
  1683.     static int
  1684. msg_add_textmode(textmode)
  1685.     int        textmode;
  1686. {
  1687. #ifdef USE_CRNL
  1688.     if (!textmode)
  1689.     {
  1690.         STRCAT(IObuff, shortmess(SHM_TEXT) ? "[notx]" : "[notextmode]");
  1691.         return TRUE;
  1692.     }
  1693. #else
  1694.     if (textmode)
  1695.     {
  1696.         STRCAT(IObuff, shortmess(SHM_TEXT) ? "[tx]" : "[textmode]");
  1697.         return TRUE;
  1698.     }
  1699. #endif
  1700.     return FALSE;
  1701. }
  1702.  
  1703. /*
  1704.  * Append line and character count to IObuff.
  1705.  */
  1706.     static void
  1707. msg_add_lines(insert_space, lnum, nchars)
  1708.     int        insert_space;
  1709.     long    lnum;
  1710.     long    nchars;
  1711. {
  1712.     char_u    *p;
  1713.  
  1714.     p = IObuff + STRLEN(IObuff);
  1715.  
  1716.     if (insert_space)
  1717.         *p++ = ' ';
  1718.     if (shortmess(SHM_LINES))
  1719.         sprintf((char *)p, "%ldL, %ldC", lnum, nchars);
  1720.     else
  1721.         sprintf((char *)p, "%ld line%s, %ld character%s",
  1722.             lnum, plural(lnum),
  1723.             nchars, plural(nchars));
  1724. }
  1725.  
  1726. /*
  1727.  * Append message for missing line separator to IObuff.
  1728.  */
  1729.     static void
  1730. msg_add_eol()
  1731. {
  1732.     STRCAT(IObuff, shortmess(SHM_LAST) ? "[noeol]" : "[Incomplete last line]");
  1733. }
  1734.  
  1735. /*
  1736.  * write_buf: call write() to write a buffer
  1737.  *
  1738.  * return FAIL for failure, OK otherwise
  1739.  */
  1740.     static int
  1741. write_buf(fd, buf, len)
  1742.     int        fd;
  1743.     char_u    *buf;
  1744.     int        len;
  1745. {
  1746.     int        wlen;
  1747.  
  1748.     while (len)
  1749.     {
  1750.         wlen = write(fd, (char *)buf, (size_t)len);
  1751.         if (wlen <= 0)                /* error! */
  1752.             return FAIL;
  1753.         len -= wlen;
  1754.         buf += wlen;
  1755.     }
  1756.     return OK;
  1757. }
  1758.  
  1759. /*
  1760.  * add extention to filename - change path/fo.o.h to path/fo.o.h.ext or
  1761.  * fo_o_h.ext for MSDOS or when shortname option set.
  1762.  *
  1763.  * Assumed that fname is a valid name found in the filesystem we assure that
  1764.  * the return value is a different name and ends in 'ext'.
  1765.  * "ext" MUST be at most 4 characters long if it starts with a dot, 3
  1766.  * characters otherwise.
  1767.  * Space for the returned name is allocated, must be freed later.
  1768.  */
  1769.  
  1770.     char_u *
  1771. modname(fname, ext)
  1772.     char_u *fname, *ext;
  1773. {
  1774.     return buf_modname(
  1775. #ifdef SHORT_FNAME
  1776.                         TRUE,
  1777. #else
  1778.                         (curbuf->b_p_sn || curbuf->b_shortname),
  1779. #endif
  1780.                                                                   fname, ext);
  1781. }
  1782.  
  1783.     char_u *
  1784. buf_modname(shortname, fname, ext)
  1785.     int        shortname;                /* use 8.3 filename */
  1786.     char_u    *fname, *ext;
  1787. {
  1788.     char_u                *retval;
  1789.     register char_u     *s;
  1790.     register char_u        *e;
  1791.     register char_u        *ptr;
  1792.     register int        fnamelen, extlen;
  1793.  
  1794.     extlen = STRLEN(ext);
  1795.  
  1796.     /*
  1797.      * if there is no filename we must get the name of the current directory
  1798.      * (we need the full path in case :cd is used)
  1799.      */
  1800.     if (fname == NULL || *fname == NUL)
  1801.     {
  1802.         retval = alloc((unsigned)(MAXPATHL + extlen + 3));
  1803.         if (retval == NULL)
  1804.             return NULL;
  1805.         if (mch_dirname(retval, MAXPATHL) == FAIL ||
  1806.                                              (fnamelen = STRLEN(retval)) == 0)
  1807.         {
  1808.             vim_free(retval);
  1809.             return NULL;
  1810.         }
  1811.         if (!ispathsep(retval[fnamelen - 1]))
  1812.         {
  1813.             retval[fnamelen++] = PATHSEP;
  1814.             retval[fnamelen] = NUL;
  1815.         }
  1816.     }
  1817.     else
  1818.     {
  1819.         fnamelen = STRLEN(fname);
  1820.         retval = alloc((unsigned)(fnamelen + extlen + 2));
  1821.         if (retval == NULL)
  1822.             return NULL;
  1823.         STRCPY(retval, fname);
  1824.     }
  1825.  
  1826.     /*
  1827.      * search backwards until we hit a '/', '\' or ':' replacing all '.'
  1828.      * by '_' for MSDOS or when shortname option set and ext starts with a dot.
  1829.      * Then truncate what is after the '/', '\' or ':' to 8 characters for
  1830.      * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
  1831.      */
  1832.     for (ptr = retval + fnamelen; ptr >= retval; ptr--)
  1833.     {
  1834.         if (*ext == '.'
  1835. #ifdef USE_LONG_FNAME
  1836.                     && (!USE_LONG_FNAME || shortname)
  1837. #else
  1838. # ifndef SHORT_FNAME
  1839.                     && shortname
  1840. # endif
  1841. #endif
  1842.                                                                 )
  1843.             if (*ptr == '.')    /* replace '.' by '_' */
  1844.                 *ptr = '_';
  1845.         if (ispathsep(*ptr))
  1846.             break;
  1847.     }
  1848.     ptr++;
  1849.  
  1850.     /* the filename has at most BASENAMELEN characters. */
  1851. #ifndef SHORT_FNAME
  1852.     if (STRLEN(ptr) > (unsigned)BASENAMELEN)
  1853.         ptr[BASENAMELEN] = '\0';
  1854. #endif
  1855.  
  1856.     s = ptr + STRLEN(ptr);
  1857.  
  1858.     /*
  1859.      * For 8.3 filenames we may have to reduce the length.
  1860.      */
  1861. #ifdef USE_LONG_FNAME
  1862.     if (!USE_LONG_FNAME || shortname)
  1863. #else
  1864. # ifndef SHORT_FNAME
  1865.     if (shortname)
  1866. # endif
  1867. #endif
  1868.     {
  1869.         /*
  1870.          * If there is no file name, and the extension starts with '.', put a
  1871.          * '_' before the dot, because just ".ext" is invalid.
  1872.          */
  1873.         if (fname == NULL || *fname == NUL)
  1874.         {
  1875.             if (*ext == '.')
  1876.                 *s++ = '_';
  1877.         }
  1878.         /*
  1879.          * If the extension starts with '.', truncate the base name at 8
  1880.          * characters
  1881.          */
  1882.         else if (*ext == '.')
  1883.         {
  1884.             if (s - ptr > (size_t)8)
  1885.             {
  1886.                 s = ptr + 8;
  1887.                 *s = '\0';
  1888.             }
  1889.         }
  1890.         /*
  1891.          * If the extension doesn't start with '.', and the file name
  1892.          * doesn't have an extension yet, append a '.'
  1893.          */
  1894.         else if ((e = vim_strchr(ptr, '.')) == NULL)
  1895.             *s++ = '.';
  1896.         /*
  1897.          * If If the extension doesn't start with '.', and there already is an
  1898.          * extension, it may need to be tructated
  1899.          */
  1900.         else if ((int)STRLEN(e) + extlen > 4)
  1901.             s = e + 4 - extlen;
  1902.     }
  1903. #ifdef OS2
  1904.     /*
  1905.      * If there is no file name, and the extension starts with '.', put a
  1906.      * '_' before the dot, because just ".ext" may be invalid if it's on a
  1907.      * FAT partition, and on HPFS it doesn't matter.
  1908.      */
  1909.     else if ((fname == NULL || *fname == NUL) && *ext == '.')
  1910.         *s++ = '_';
  1911. #endif
  1912.  
  1913.     /*
  1914.      * Append the extention.
  1915.      * ext can start with '.' and cannot exceed 3 more characters.
  1916.      */
  1917.     STRCPY(s, ext);
  1918.  
  1919.     /*
  1920.      * Check that, after appending the extension, the file name is really
  1921.      * different.
  1922.      */
  1923.     if (fname != NULL && STRCMP(fname, retval) == 0)
  1924.     {
  1925.         /* we search for a character that can be replaced by '_' */
  1926.         while (--s >= ptr)
  1927.         {
  1928.             if (*s != '_')
  1929.             {
  1930.                 *s = '_';
  1931.                 break;
  1932.             }
  1933.         }
  1934.         if (s < ptr)    /* fname was "________.<ext>" how tricky! */
  1935.             *ptr = 'v';
  1936.     }
  1937.     return retval;
  1938. }
  1939.  
  1940. /* vim_fgets();
  1941.  *
  1942.  * Like fgets(), but if the file line is too long, it is truncated and the
  1943.  * rest of the line is thrown away.  Returns TRUE for end-of-file.
  1944.  * Note: do not pass IObuff as the buffer since this is used to read and
  1945.  * discard the extra part of any long lines.
  1946.  */
  1947.     int
  1948. vim_fgets(buf, size, fp)
  1949.     char_u        *buf;
  1950.     int            size;
  1951.     FILE        *fp;
  1952. {
  1953.     char *eof;
  1954.  
  1955.     buf[size - 2] = NUL;
  1956.     eof = fgets((char *)buf, size, fp);
  1957.     if (buf[size - 2] != NUL && buf[size - 2] != '\n')
  1958.     {
  1959.         buf[size - 1] = NUL;        /* Truncate the line */
  1960.  
  1961.         /* Now throw away the rest of the line: */
  1962.         do
  1963.         {
  1964.             IObuff[IOSIZE - 2] = NUL;
  1965.             fgets((char *)IObuff, IOSIZE, fp);
  1966.         } while (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != '\n');
  1967.     }
  1968.     return (eof == NULL);
  1969. }
  1970.  
  1971. /*
  1972.  * rename() only works if both files are on the same file system, this
  1973.  * function will (attempts to?) copy the file across if rename fails -- webb
  1974.  * Return -1 for failure, 0 for success.
  1975.  */
  1976.     int
  1977. vim_rename(from, to)
  1978.     char_u *from;
  1979.     char_u *to;
  1980. {
  1981.     int        fd_in;
  1982.     int        fd_out;
  1983.     int        n;
  1984.     char     *errmsg = NULL;
  1985.  
  1986.     /*
  1987.      * First delete the "to" file, this is required on some systems to make
  1988.      * the rename() work, on other systems it makes sure that we don't have
  1989.      * two files when the rename() fails.
  1990.      */
  1991.     vim_remove(to);
  1992.  
  1993.     /*
  1994.      * First try a normal rename, return if it works.
  1995.      */
  1996.     if (rename((char *)from, (char *)to) == 0)
  1997.         return 0;
  1998.  
  1999.     /*
  2000.      * Rename() failed, try copying the file.
  2001.      */
  2002.     fd_in = open((char *)from, O_RDONLY | O_EXTRA);
  2003.     if (fd_in == -1)
  2004.         return -1;
  2005.     fd_out = open((char *)to, O_CREAT | O_TRUNC | O_WRONLY | O_EXTRA, 0666);
  2006.     if (fd_out == -1)
  2007.     {
  2008.         close(fd_in);
  2009.         return -1;
  2010.     }
  2011.     while ((n = read(fd_in, (char *)IObuff, (size_t)IOSIZE)) > 0)
  2012.         if (write(fd_out, (char *)IObuff, (size_t)n) != n)
  2013.         {
  2014.             errmsg = "writing to";
  2015.             break;
  2016.         }
  2017.     close(fd_in);
  2018.     if (close(fd_out) < 0)
  2019.         errmsg = "closing";
  2020.     if (n < 0)
  2021.     {
  2022.         errmsg = "reading";
  2023.         to = from;
  2024.     }
  2025.     if (errmsg != NULL)
  2026.     {
  2027.         sprintf((char *)IObuff, "Error %s '%s'", errmsg, to);
  2028.         emsg(IObuff);
  2029.         return -1;
  2030.     }
  2031.     vim_remove(from);
  2032.     return 0;
  2033. }
  2034.  
  2035. /*
  2036.  * Check if any not hidden buffer has been changed.
  2037.  * Postpone the check if there are characters in the stuff buffer, a global
  2038.  * command is being executed, a mapping is being executed or an autocommand is
  2039.  * busy.
  2040.  */
  2041.     void
  2042. check_timestamps()
  2043. {
  2044.     BUF        *buf;
  2045.  
  2046.     if (!stuff_empty() || global_busy || !typebuf_typed()
  2047. #ifdef AUTOCMD
  2048.                         || autocmd_busy
  2049. #endif
  2050.                                         )
  2051.         need_check_timestamps = TRUE;            /* check later */
  2052.     else
  2053.     {
  2054.         ++no_wait_return;
  2055.         for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  2056.             buf_check_timestamp(buf);
  2057.         --no_wait_return;
  2058.         need_check_timestamps = FALSE;
  2059.     }
  2060. }
  2061.  
  2062. /*
  2063.  * Check if buffer "buf" has been changed.
  2064.  */
  2065.     void
  2066. buf_check_timestamp(buf)
  2067.     BUF        *buf;
  2068. {
  2069.     struct stat        st;
  2070.     char_u            *path;
  2071.  
  2072.     if (    buf->b_filename != NULL &&
  2073.             buf->b_ml.ml_mfp != NULL &&
  2074.             !buf->b_notedited &&
  2075.             buf->b_mtime != 0 &&
  2076.             stat((char *)buf->b_filename, &st) >= 0 &&
  2077.             buf->b_mtime != st.st_mtime)
  2078.     {
  2079.         path = home_replace_save(buf, buf->b_xfilename);
  2080.         if (path != NULL)
  2081.         {
  2082.             EMSG2("Warning: File \"%s\" has changed since editing started",
  2083.                                                                 path);
  2084.             buf->b_mtime = st.st_mtime;
  2085.             vim_free(path);
  2086.         }
  2087.     }
  2088. }
  2089.  
  2090. /*
  2091.  * Adjust the line with missing eol, used for the next write.
  2092.  * Used for do_filter(), when the input lines for the filter are deleted.
  2093.  */
  2094.     void
  2095. write_lnum_adjust(offset)
  2096.     linenr_t    offset;
  2097. {
  2098.     if (write_no_eol_lnum)                /* only if there is a missing eol */
  2099.         write_no_eol_lnum += offset;
  2100. }
  2101.  
  2102. #ifdef USE_TMPNAM
  2103. extern char        *tmpnam __ARGS((char *));
  2104. #else
  2105. extern char        *mktemp __ARGS((char *));
  2106. #endif
  2107.  
  2108. /*
  2109.  * vim_tempname(): Return a unique name that can be used for a temp file.
  2110.  *
  2111.  * The temp file is NOT created.
  2112.  *
  2113.  * The returned pointer is to allocated memory.
  2114.  * The returned pointer is NULL if no valid name was found.
  2115.  */
  2116.     char_u    *
  2117. vim_tempname(extra_char)
  2118.     int        extra_char;        /* character to use in the name instead of '?' */
  2119. {
  2120. #ifdef USE_TMPNAM
  2121.     char_u            itmp[L_tmpnam];        /* use tmpnam() */
  2122. #else
  2123.     char_u            itmp[TEMPNAMELEN];
  2124. #endif
  2125. #if defined(TEMPDIRNAMES) || !defined(USE_TMPNAM)
  2126.     char_u            *p;
  2127. #endif
  2128.  
  2129. #if defined(TEMPDIRNAMES)
  2130.     static char        *(tempdirs[]) = {TEMPDIRNAMES};
  2131.     static int        first_dir = 0;
  2132.     int                first_try = TRUE;
  2133.     int                i;
  2134.  
  2135.     /*
  2136.      * Try a few places to put the temp file.
  2137.      * To avoid waisting time with non-existing environment variables and
  2138.      * directories, they are skipped next time.
  2139.      */
  2140.     for (i = first_dir; i < sizeof(tempdirs) / sizeof(char *); ++i)
  2141.     {
  2142.         /* expand $TMP, leave room for '/', "v?XXXXXX" and NUL */
  2143.         expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 10);
  2144.         if (mch_isdir(itmp))            /* directory exists */
  2145.         {
  2146.             if (first_try)
  2147.                 first_dir = i;            /* start here next time */
  2148.             first_try = FALSE;
  2149. #ifdef __EMX__
  2150.             /*
  2151.              * if $TMP contains a forward slash (perhaps because we're using
  2152.              * bash or tcsh, right Stefan?), don't add a backslash to the
  2153.              * directory before tacking on the filename; use a forward slash!
  2154.              * I first tried adding 2 backslashes, but somehow that didn't
  2155.              * work (something in the EMX system() ate them, I think).
  2156.              */
  2157.             if (vim_strchr(itmp, '/'))
  2158.                 STRCAT(itmp, "/");
  2159.             else
  2160. #endif
  2161.                 STRCAT(itmp, PATHSEPSTR);
  2162.             STRCAT(itmp, TEMPNAME);
  2163.             if ((p = vim_strchr(itmp, '?')) != NULL)
  2164.                 *p = extra_char;
  2165.             if (*mktemp((char *)itmp) == NUL)
  2166.                 continue;
  2167.             return strsave(itmp);
  2168.         }
  2169.     }
  2170.     return NULL;
  2171. #else
  2172.  
  2173. # ifdef USE_TMPNAM
  2174.     /* tmpnam() will make its own name */
  2175.     if (*tmpnam((char *)itmp) == NUL)
  2176. # else
  2177.     STRCPY(itmp, TEMPNAME);
  2178.     if ((p = vim_strchr(itmp, '?')) != NULL)
  2179.         *p = extra_char;
  2180.     if (*mktemp((char *)itmp) == NUL)
  2181. # endif
  2182.         return NULL;
  2183.     return strsave(itmp);
  2184. #endif
  2185. }
  2186.