xref: /vim-8.2.3635/src/fileio.c (revision def69dff)
1 /* vi:set ts=8 sts=4 sw=4 noet:
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  * fileio.c: read from and write to a file
12  */
13 
14 #include "vim.h"
15 
16 #if defined(__TANDEM)
17 # include <limits.h>		// for SSIZE_MAX
18 #endif
19 #if (defined(UNIX) || defined(VMS)) && defined(FEAT_EVAL)
20 # include <pwd.h>
21 # include <grp.h>
22 #endif
23 #if defined(VMS) && defined(HAVE_XOS_R_H)
24 # include <x11/xos_r.h>
25 #endif
26 
27 // Is there any system that doesn't have access()?
28 #define USE_MCH_ACCESS
29 
30 #if defined(__hpux) && !defined(HAVE_DIRFD)
31 # define dirfd(x) ((x)->__dd_fd)
32 # define HAVE_DIRFD
33 #endif
34 
35 static char_u *next_fenc(char_u **pp, int *alloced);
36 #ifdef FEAT_EVAL
37 static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp);
38 #endif
39 #ifdef FEAT_CRYPT
40 static char_u *check_for_cryptkey(char_u *cryptkey, char_u *ptr, long *sizep, off_T *filesizep, int newfile, char_u *fname, int *did_ask);
41 #endif
42 static linenr_T readfile_linenr(linenr_T linecnt, char_u *p, char_u *endp);
43 static char_u *check_for_bom(char_u *p, long size, int *lenp, int flags);
44 static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name");
45 
46 #ifdef FEAT_EVAL
47 static int readdirex_sort;
48 #endif
49 
50     void
filemess(buf_T * buf,char_u * name,char_u * s,int attr)51 filemess(
52     buf_T	*buf,
53     char_u	*name,
54     char_u	*s,
55     int		attr)
56 {
57     int		msg_scroll_save;
58     int		prev_msg_col = msg_col;
59 
60     if (msg_silent != 0)
61 	return;
62     msg_add_fname(buf, name);	    // put file name in IObuff with quotes
63 
64     // If it's extremely long, truncate it.
65     if (STRLEN(IObuff) > IOSIZE - 100)
66 	IObuff[IOSIZE - 100] = NUL;
67 
68     // Avoid an over-long translation to cause trouble.
69     STRNCAT(IObuff, s, 99);
70 
71     /*
72      * For the first message may have to start a new line.
73      * For further ones overwrite the previous one, reset msg_scroll before
74      * calling filemess().
75      */
76     msg_scroll_save = msg_scroll;
77     if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
78 	msg_scroll = FALSE;
79     if (!msg_scroll)	// wait a bit when overwriting an error msg
80 	check_for_delay(FALSE);
81     msg_start();
82     if (prev_msg_col != 0 && msg_col == 0)
83 	msg_putchar('\r');  // overwrite any previous message.
84     msg_scroll = msg_scroll_save;
85     msg_scrolled_ign = TRUE;
86     // may truncate the message to avoid a hit-return prompt
87     msg_outtrans_attr(msg_may_trunc(FALSE, IObuff), attr);
88     msg_clr_eos();
89     out_flush();
90     msg_scrolled_ign = FALSE;
91 }
92 
93 /*
94  * Read lines from file "fname" into the buffer after line "from".
95  *
96  * 1. We allocate blocks with lalloc, as big as possible.
97  * 2. Each block is filled with characters from the file with a single read().
98  * 3. The lines are inserted in the buffer with ml_append().
99  *
100  * (caller must check that fname != NULL, unless READ_STDIN is used)
101  *
102  * "lines_to_skip" is the number of lines that must be skipped
103  * "lines_to_read" is the number of lines that are appended
104  * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
105  *
106  * flags:
107  * READ_NEW	starting to edit a new buffer
108  * READ_FILTER	reading filter output
109  * READ_STDIN	read from stdin instead of a file
110  * READ_BUFFER	read from curbuf instead of a file (converting after reading
111  *		stdin)
112  * READ_DUMMY	read into a dummy buffer (to check if file contents changed)
113  * READ_KEEP_UNDO  don't clear undo info or read it from a file
114  * READ_FIFO	read from fifo/socket instead of a file
115  *
116  * return FAIL for failure, NOTDONE for directory (failure), or OK
117  */
118     int
readfile(char_u * fname,char_u * sfname,linenr_T from,linenr_T lines_to_skip,linenr_T lines_to_read,exarg_T * eap,int flags)119 readfile(
120     char_u	*fname,
121     char_u	*sfname,
122     linenr_T	from,
123     linenr_T	lines_to_skip,
124     linenr_T	lines_to_read,
125     exarg_T	*eap,			// can be NULL!
126     int		flags)
127 {
128     int		fd = 0;
129     int		newfile = (flags & READ_NEW);
130     int		check_readonly;
131     int		filtering = (flags & READ_FILTER);
132     int		read_stdin = (flags & READ_STDIN);
133     int		read_buffer = (flags & READ_BUFFER);
134     int		read_fifo = (flags & READ_FIFO);
135     int		set_options = newfile || read_buffer
136 					   || (eap != NULL && eap->read_edit);
137     linenr_T	read_buf_lnum = 1;	// next line to read from curbuf
138     colnr_T	read_buf_col = 0;	// next char to read from this line
139     char_u	c;
140     linenr_T	lnum = from;
141     char_u	*ptr = NULL;		// pointer into read buffer
142     char_u	*buffer = NULL;		// read buffer
143     char_u	*new_buffer = NULL;	// init to shut up gcc
144     char_u	*line_start = NULL;	// init to shut up gcc
145     int		wasempty;		// buffer was empty before reading
146     colnr_T	len;
147     long	size = 0;
148     char_u	*p;
149     off_T	filesize = 0;
150     int		skip_read = FALSE;
151     off_T       filesize_disk = 0;      // file size read from disk
152     off_T       filesize_count = 0;     // counter
153 #ifdef FEAT_CRYPT
154     char_u	*cryptkey = NULL;
155     int		did_ask_for_key = FALSE;
156 #endif
157 #ifdef FEAT_PERSISTENT_UNDO
158     context_sha256_T sha_ctx;
159     int		read_undo_file = FALSE;
160 #endif
161     int		split = 0;		// number of split lines
162 #define UNKNOWN	 0x0fffffff		// file size is unknown
163     linenr_T	linecnt;
164     int		error = FALSE;		// errors encountered
165     int		ff_error = EOL_UNKNOWN; // file format with errors
166     long	linerest = 0;		// remaining chars in line
167 #ifdef UNIX
168     int		perm = 0;
169     int		swap_mode = -1;		// protection bits for swap file
170 #else
171     int		perm;
172 #endif
173     int		fileformat = 0;		// end-of-line format
174     int		keep_fileformat = FALSE;
175     stat_T	st;
176     int		file_readonly;
177     linenr_T	skip_count = 0;
178     linenr_T	read_count = 0;
179     int		msg_save = msg_scroll;
180     linenr_T	read_no_eol_lnum = 0;   // non-zero lnum when last line of
181 					// last read was missing the eol
182     int		try_mac;
183     int		try_dos;
184     int		try_unix;
185     int		file_rewind = FALSE;
186     int		can_retry;
187     linenr_T	conv_error = 0;		// line nr with conversion error
188     linenr_T	illegal_byte = 0;	// line nr with illegal byte
189     int		keep_dest_enc = FALSE;	// don't retry when char doesn't fit
190 					// in destination encoding
191     int		bad_char_behavior = BAD_REPLACE;
192 					// BAD_KEEP, BAD_DROP or character to
193 					// replace with
194     char_u	*tmpname = NULL;	// name of 'charconvert' output file
195     int		fio_flags = 0;
196     char_u	*fenc;			// fileencoding to use
197     int		fenc_alloced;		// fenc_next is in allocated memory
198     char_u	*fenc_next = NULL;	// next item in 'fencs' or NULL
199     int		advance_fenc = FALSE;
200     long	real_size = 0;
201 #ifdef USE_ICONV
202     iconv_t	iconv_fd = (iconv_t)-1;	// descriptor for iconv() or -1
203 # ifdef FEAT_EVAL
204     int		did_iconv = FALSE;	// TRUE when iconv() failed and trying
205 					// 'charconvert' next
206 # endif
207 #endif
208     int		converted = FALSE;	// TRUE if conversion done
209     int		notconverted = FALSE;	// TRUE if conversion wanted but it
210 					// wasn't possible
211     char_u	conv_rest[CONV_RESTLEN];
212     int		conv_restlen = 0;	// nr of bytes in conv_rest[]
213     pos_T	orig_start;
214     buf_T	*old_curbuf;
215     char_u	*old_b_ffname;
216     char_u	*old_b_fname;
217     int		using_b_ffname;
218     int		using_b_fname;
219     static char *msg_is_a_directory = N_("is a directory");
220     int         eof;
221 
222     au_did_filetype = FALSE; // reset before triggering any autocommands
223 
224     curbuf->b_no_eol_lnum = 0;	// in case it was set by the previous read
225 
226     /*
227      * If there is no file name yet, use the one for the read file.
228      * BF_NOTEDITED is set to reflect this.
229      * Don't do this for a read from a filter.
230      * Only do this when 'cpoptions' contains the 'f' flag.
231      */
232     if (curbuf->b_ffname == NULL
233 	    && !filtering
234 	    && fname != NULL
235 	    && vim_strchr(p_cpo, CPO_FNAMER) != NULL
236 	    && !(flags & READ_DUMMY))
237     {
238 	if (set_rw_fname(fname, sfname) == FAIL)
239 	    return FAIL;
240     }
241 
242     // Remember the initial values of curbuf, curbuf->b_ffname and
243     // curbuf->b_fname to detect whether they are altered as a result of
244     // executing nasty autocommands.  Also check if "fname" and "sfname"
245     // point to one of these values.
246     old_curbuf = curbuf;
247     old_b_ffname = curbuf->b_ffname;
248     old_b_fname = curbuf->b_fname;
249     using_b_ffname = (fname == curbuf->b_ffname)
250 					      || (sfname == curbuf->b_ffname);
251     using_b_fname = (fname == curbuf->b_fname) || (sfname == curbuf->b_fname);
252 
253     // After reading a file the cursor line changes but we don't want to
254     // display the line.
255     ex_no_reprint = TRUE;
256 
257     // don't display the file info for another buffer now
258     need_fileinfo = FALSE;
259 
260     /*
261      * For Unix: Use the short file name whenever possible.
262      * Avoids problems with networks and when directory names are changed.
263      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
264      * another directory, which we don't detect.
265      */
266     if (sfname == NULL)
267 	sfname = fname;
268 #if defined(UNIX)
269     fname = sfname;
270 #endif
271 
272     /*
273      * The BufReadCmd and FileReadCmd events intercept the reading process by
274      * executing the associated commands instead.
275      */
276     if (!filtering && !read_stdin && !read_buffer)
277     {
278 	orig_start = curbuf->b_op_start;
279 
280 	// Set '[ mark to the line above where the lines go (line 1 if zero).
281 	curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
282 	curbuf->b_op_start.col = 0;
283 
284 	if (newfile)
285 	{
286 	    if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname,
287 							  FALSE, curbuf, eap))
288 	    {
289 		int status = OK;
290 #ifdef FEAT_EVAL
291 		if (aborting())
292 		    status = FAIL;
293 #endif
294 		// The BufReadCmd code usually uses ":read" to get the text and
295 		// perhaps ":file" to change the buffer name. But we should
296 		// consider this to work like ":edit", thus reset the
297 		// BF_NOTEDITED flag.  Then ":write" will work to overwrite the
298 		// same file.
299 		if (status == OK)
300 		    curbuf->b_flags &= ~BF_NOTEDITED;
301 		return status;
302 	    }
303 	}
304 	else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname,
305 							    FALSE, NULL, eap))
306 #ifdef FEAT_EVAL
307 	    return aborting() ? FAIL : OK;
308 #else
309 	    return OK;
310 #endif
311 
312 	curbuf->b_op_start = orig_start;
313     }
314 
315     if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0)
316 	msg_scroll = FALSE;	// overwrite previous file message
317     else
318 	msg_scroll = TRUE;	// don't overwrite previous file message
319 
320     if (fname != NULL && *fname != NUL)
321     {
322 	size_t namelen = STRLEN(fname);
323 
324 	// If the name is too long we might crash further on, quit here.
325 	if (namelen >= MAXPATHL)
326 	{
327 	    filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0);
328 	    msg_end();
329 	    msg_scroll = msg_save;
330 	    return FAIL;
331 	}
332 
333 	// If the name ends in a path separator, we can't open it.  Check here,
334 	// because reading the file may actually work, but then creating the
335 	// swap file may destroy it!  Reported on MS-DOS and Win 95.
336 	if (after_pathsep(fname, fname + namelen))
337 	{
338 	    filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0);
339 	    msg_end();
340 	    msg_scroll = msg_save;
341 	    return NOTDONE;
342 	}
343     }
344 
345     if (!read_stdin && !read_buffer && !read_fifo)
346     {
347 #if defined(UNIX) || defined(VMS)
348 	/*
349 	 * On Unix it is possible to read a directory, so we have to
350 	 * check for it before the mch_open().
351 	 */
352 	perm = mch_getperm(fname);
353 	if (perm >= 0 && !S_ISREG(perm)		    // not a regular file ...
354 		      && !S_ISFIFO(perm)	    // ... or fifo
355 		      && !S_ISSOCK(perm)	    // ... or socket
356 # ifdef OPEN_CHR_FILES
357 		      && !(S_ISCHR(perm) && is_dev_fd_file(fname))
358 			// ... or a character special file named /dev/fd/<n>
359 # endif
360 						)
361 	{
362 	    int retval = FAIL;
363 
364 	    if (S_ISDIR(perm))
365 	    {
366 		filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0);
367 		retval = NOTDONE;
368 	    }
369 	    else
370 		filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
371 	    msg_end();
372 	    msg_scroll = msg_save;
373 	    return retval;
374 	}
375 #endif
376 #if defined(MSWIN)
377 	/*
378 	 * MS-Windows allows opening a device, but we will probably get stuck
379 	 * trying to read it.
380 	 */
381 	if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
382 	{
383 	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0);
384 	    msg_end();
385 	    msg_scroll = msg_save;
386 	    return FAIL;
387 	}
388 #endif
389     }
390 
391     // Set default or forced 'fileformat' and 'binary'.
392     set_file_options(set_options, eap);
393 
394     /*
395      * When opening a new file we take the readonly flag from the file.
396      * Default is r/w, can be set to r/o below.
397      * Don't reset it when in readonly mode
398      * Only set/reset b_p_ro when BF_CHECK_RO is set.
399      */
400     check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
401     if (check_readonly && !readonlymode)
402 	curbuf->b_p_ro = FALSE;
403 
404     if (newfile && !read_stdin && !read_buffer && !read_fifo)
405     {
406 	// Remember time of file.
407 	if (mch_stat((char *)fname, &st) >= 0)
408 	{
409 	    buf_store_time(curbuf, &st, fname);
410 	    curbuf->b_mtime_read = curbuf->b_mtime;
411 	    curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
412 	    filesize_disk = st.st_size;
413 #ifdef UNIX
414 	    /*
415 	     * Use the protection bits of the original file for the swap file.
416 	     * This makes it possible for others to read the name of the
417 	     * edited file from the swapfile, but only if they can read the
418 	     * edited file.
419 	     * Remove the "write" and "execute" bits for group and others
420 	     * (they must not write the swapfile).
421 	     * Add the "read" and "write" bits for the user, otherwise we may
422 	     * not be able to write to the file ourselves.
423 	     * Setting the bits is done below, after creating the swap file.
424 	     */
425 	    swap_mode = (st.st_mode & 0644) | 0600;
426 #endif
427 #ifdef VMS
428 	    curbuf->b_fab_rfm = st.st_fab_rfm;
429 	    curbuf->b_fab_rat = st.st_fab_rat;
430 	    curbuf->b_fab_mrs = st.st_fab_mrs;
431 #endif
432 	}
433 	else
434 	{
435 	    curbuf->b_mtime = 0;
436 	    curbuf->b_mtime_ns = 0;
437 	    curbuf->b_mtime_read = 0;
438 	    curbuf->b_mtime_read_ns = 0;
439 	    curbuf->b_orig_size = 0;
440 	    curbuf->b_orig_mode = 0;
441 	}
442 
443 	// Reset the "new file" flag.  It will be set again below when the
444 	// file doesn't exist.
445 	curbuf->b_flags &= ~(BF_NEW | BF_NEW_W);
446     }
447 
448 /*
449  * for UNIX: check readonly with perm and mch_access()
450  * for Amiga: check readonly by trying to open the file for writing
451  */
452     file_readonly = FALSE;
453     if (read_stdin)
454     {
455 #if defined(MSWIN)
456 	// Force binary I/O on stdin to avoid CR-LF -> LF conversion.
457 	setmode(0, O_BINARY);
458 #endif
459     }
460     else if (!read_buffer)
461     {
462 #ifdef USE_MCH_ACCESS
463 	if (
464 # ifdef UNIX
465 	    !(perm & 0222) ||
466 # endif
467 				mch_access((char *)fname, W_OK))
468 	    file_readonly = TRUE;
469 	fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
470 #else
471 	if (!newfile
472 		|| readonlymode
473 		|| (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0)
474 	{
475 	    file_readonly = TRUE;
476 	    // try to open ro
477 	    fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
478 	}
479 #endif
480     }
481 
482     if (fd < 0)			    // cannot open at all
483     {
484 #ifndef UNIX
485 	int	isdir_f;
486 #endif
487 	msg_scroll = msg_save;
488 #ifndef UNIX
489 	/*
490 	 * On Amiga we can't open a directory, check here.
491 	 */
492 	isdir_f = (mch_isdir(fname));
493 	perm = mch_getperm(fname);  // check if the file exists
494 	if (isdir_f)
495 	{
496 	    filemess(curbuf, sfname, (char_u *)_(msg_is_a_directory), 0);
497 	    curbuf->b_p_ro = TRUE;	// must use "w!" now
498 	}
499 	else
500 #endif
501 	    if (newfile)
502 	    {
503 		if (perm < 0
504 #ifdef ENOENT
505 			&& errno == ENOENT
506 #endif
507 		   )
508 		{
509 		    /*
510 		     * Set the 'new-file' flag, so that when the file has
511 		     * been created by someone else, a ":w" will complain.
512 		     */
513 		    curbuf->b_flags |= BF_NEW;
514 
515 		    // Create a swap file now, so that other Vims are warned
516 		    // that we are editing this file.  Don't do this for a
517 		    // "nofile" or "nowrite" buffer type.
518 #ifdef FEAT_QUICKFIX
519 		    if (!bt_dontwrite(curbuf))
520 #endif
521 		    {
522 			check_need_swap(newfile);
523 			// SwapExists autocommand may mess things up
524 			if (curbuf != old_curbuf
525 				|| (using_b_ffname
526 					&& (old_b_ffname != curbuf->b_ffname))
527 				|| (using_b_fname
528 					 && (old_b_fname != curbuf->b_fname)))
529 			{
530 			    emsg(_(e_auchangedbuf));
531 			    return FAIL;
532 			}
533 		    }
534 		    if (dir_of_file_exists(fname))
535 			filemess(curbuf, sfname,
536 					      (char_u *)new_file_message(), 0);
537 		    else
538 			filemess(curbuf, sfname,
539 					   (char_u *)_("[New DIRECTORY]"), 0);
540 #ifdef FEAT_VIMINFO
541 		    // Even though this is a new file, it might have been
542 		    // edited before and deleted.  Get the old marks.
543 		    check_marks_read();
544 #endif
545 		    // Set forced 'fileencoding'.
546 		    if (eap != NULL)
547 			set_forced_fenc(eap);
548 		    apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname,
549 							  FALSE, curbuf, eap);
550 		    // remember the current fileformat
551 		    save_file_ff(curbuf);
552 
553 #if defined(FEAT_EVAL)
554 		    if (aborting())   // autocmds may abort script processing
555 			return FAIL;
556 #endif
557 		    return OK;	    // a new file is not an error
558 		}
559 		else
560 		{
561 		    filemess(curbuf, sfname, (char_u *)(
562 # ifdef EFBIG
563 			    (errno == EFBIG) ? _("[File too big]") :
564 # endif
565 # ifdef EOVERFLOW
566 			    (errno == EOVERFLOW) ? _("[File too big]") :
567 # endif
568 						_("[Permission Denied]")), 0);
569 		    curbuf->b_p_ro = TRUE;	// must use "w!" now
570 		}
571 	    }
572 
573 	return FAIL;
574     }
575 
576     /*
577      * Only set the 'ro' flag for readonly files the first time they are
578      * loaded.	Help files always get readonly mode
579      */
580     if ((check_readonly && file_readonly) || curbuf->b_help)
581 	curbuf->b_p_ro = TRUE;
582 
583     if (set_options)
584     {
585 	// Don't change 'eol' if reading from buffer as it will already be
586 	// correctly set when reading stdin.
587 	if (!read_buffer)
588 	{
589 	    curbuf->b_p_eol = TRUE;
590 	    curbuf->b_start_eol = TRUE;
591 	}
592 	curbuf->b_p_bomb = FALSE;
593 	curbuf->b_start_bomb = FALSE;
594     }
595 
596     // Create a swap file now, so that other Vims are warned that we are
597     // editing this file.
598     // Don't do this for a "nofile" or "nowrite" buffer type.
599 #ifdef FEAT_QUICKFIX
600     if (!bt_dontwrite(curbuf))
601 #endif
602     {
603 	check_need_swap(newfile);
604 	if (!read_stdin && (curbuf != old_curbuf
605 		|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
606 		|| (using_b_fname && (old_b_fname != curbuf->b_fname))))
607 	{
608 	    emsg(_(e_auchangedbuf));
609 	    if (!read_buffer)
610 		close(fd);
611 	    return FAIL;
612 	}
613 #ifdef UNIX
614 	// Set swap file protection bits after creating it.
615 	if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL
616 			  && curbuf->b_ml.ml_mfp->mf_fname != NULL)
617 	{
618 	    char_u *swap_fname = curbuf->b_ml.ml_mfp->mf_fname;
619 
620 	    /*
621 	     * If the group-read bit is set but not the world-read bit, then
622 	     * the group must be equal to the group of the original file.  If
623 	     * we can't make that happen then reset the group-read bit.  This
624 	     * avoids making the swap file readable to more users when the
625 	     * primary group of the user is too permissive.
626 	     */
627 	    if ((swap_mode & 044) == 040)
628 	    {
629 		stat_T	swap_st;
630 
631 		if (mch_stat((char *)swap_fname, &swap_st) >= 0
632 			&& st.st_gid != swap_st.st_gid
633 # ifdef HAVE_FCHOWN
634 			&& fchown(curbuf->b_ml.ml_mfp->mf_fd, -1, st.st_gid)
635 									  == -1
636 # endif
637 		   )
638 		    swap_mode &= 0600;
639 	    }
640 
641 	    (void)mch_setperm(swap_fname, (long)swap_mode);
642 	}
643 #endif
644     }
645 
646     // If "Quit" selected at ATTENTION dialog, don't load the file
647     if (swap_exists_action == SEA_QUIT)
648     {
649 	if (!read_buffer && !read_stdin)
650 	    close(fd);
651 	return FAIL;
652     }
653 
654     ++no_wait_return;	    // don't wait for return yet
655 
656     /*
657      * Set '[ mark to the line above where the lines go (line 1 if zero).
658      */
659     orig_start = curbuf->b_op_start;
660     curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
661     curbuf->b_op_start.col = 0;
662 
663     try_mac = (vim_strchr(p_ffs, 'm') != NULL);
664     try_dos = (vim_strchr(p_ffs, 'd') != NULL);
665     try_unix = (vim_strchr(p_ffs, 'x') != NULL);
666 
667     if (!read_buffer)
668     {
669 	int	m = msg_scroll;
670 	int	n = msg_scrolled;
671 
672 	/*
673 	 * The file must be closed again, the autocommands may want to change
674 	 * the file before reading it.
675 	 */
676 	if (!read_stdin)
677 	    close(fd);		// ignore errors
678 
679 	/*
680 	 * The output from the autocommands should not overwrite anything and
681 	 * should not be overwritten: Set msg_scroll, restore its value if no
682 	 * output was done.
683 	 */
684 	msg_scroll = TRUE;
685 	if (filtering)
686 	    apply_autocmds_exarg(EVENT_FILTERREADPRE, NULL, sfname,
687 							  FALSE, curbuf, eap);
688 	else if (read_stdin)
689 	    apply_autocmds_exarg(EVENT_STDINREADPRE, NULL, sfname,
690 							  FALSE, curbuf, eap);
691 	else if (newfile)
692 	    apply_autocmds_exarg(EVENT_BUFREADPRE, NULL, sfname,
693 							  FALSE, curbuf, eap);
694 	else
695 	    apply_autocmds_exarg(EVENT_FILEREADPRE, sfname, sfname,
696 							    FALSE, NULL, eap);
697 	// autocommands may have changed it
698 	try_mac = (vim_strchr(p_ffs, 'm') != NULL);
699 	try_dos = (vim_strchr(p_ffs, 'd') != NULL);
700 	try_unix = (vim_strchr(p_ffs, 'x') != NULL);
701 	curbuf->b_op_start = orig_start;
702 
703 	if (msg_scrolled == n)
704 	    msg_scroll = m;
705 
706 #ifdef FEAT_EVAL
707 	if (aborting())	    // autocmds may abort script processing
708 	{
709 	    --no_wait_return;
710 	    msg_scroll = msg_save;
711 	    curbuf->b_p_ro = TRUE;	// must use "w!" now
712 	    return FAIL;
713 	}
714 #endif
715 	/*
716 	 * Don't allow the autocommands to change the current buffer.
717 	 * Try to re-open the file.
718 	 *
719 	 * Don't allow the autocommands to change the buffer name either
720 	 * (cd for example) if it invalidates fname or sfname.
721 	 */
722 	if (!read_stdin && (curbuf != old_curbuf
723 		|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
724 		|| (using_b_fname && (old_b_fname != curbuf->b_fname))
725 		|| (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
726 	{
727 	    --no_wait_return;
728 	    msg_scroll = msg_save;
729 	    if (fd < 0)
730 		emsg(_("E200: *ReadPre autocommands made the file unreadable"));
731 	    else
732 		emsg(_("E201: *ReadPre autocommands must not change current buffer"));
733 	    curbuf->b_p_ro = TRUE;	// must use "w!" now
734 	    return FAIL;
735 	}
736     }
737 
738     // Autocommands may add lines to the file, need to check if it is empty
739     wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY);
740 
741     if (!recoverymode && !filtering && !(flags & READ_DUMMY))
742     {
743 	/*
744 	 * Show the user that we are busy reading the input.  Sometimes this
745 	 * may take a while.  When reading from stdin another program may
746 	 * still be running, don't move the cursor to the last line, unless
747 	 * always using the GUI.
748 	 */
749 	if (read_stdin)
750 	{
751 	    if (!is_not_a_term())
752 	    {
753 #ifndef ALWAYS_USE_GUI
754 # ifdef VIMDLL
755 		if (!gui.in_use)
756 # endif
757 		    mch_msg(_("Vim: Reading from stdin...\n"));
758 #endif
759 #ifdef FEAT_GUI
760 		// Also write a message in the GUI window, if there is one.
761 		if (gui.in_use && !gui.dying && !gui.starting)
762 		{
763 		    p = (char_u *)_("Reading from stdin...");
764 		    gui_write(p, (int)STRLEN(p));
765 		}
766 #endif
767 	    }
768 	}
769 	else if (!read_buffer)
770 	    filemess(curbuf, sfname, (char_u *)"", 0);
771     }
772 
773     msg_scroll = FALSE;			// overwrite the file message
774 
775     /*
776      * Set linecnt now, before the "retry" caused by a wrong guess for
777      * fileformat, and after the autocommands, which may change them.
778      */
779     linecnt = curbuf->b_ml.ml_line_count;
780 
781     // "++bad=" argument.
782     if (eap != NULL && eap->bad_char != 0)
783     {
784 	bad_char_behavior = eap->bad_char;
785 	if (set_options)
786 	    curbuf->b_bad_char = eap->bad_char;
787     }
788     else
789 	curbuf->b_bad_char = 0;
790 
791     /*
792      * Decide which 'encoding' to use or use first.
793      */
794     if (eap != NULL && eap->force_enc != 0)
795     {
796 	fenc = enc_canonize(eap->cmd + eap->force_enc);
797 	fenc_alloced = TRUE;
798 	keep_dest_enc = TRUE;
799     }
800     else if (curbuf->b_p_bin)
801     {
802 	fenc = (char_u *)"";		// binary: don't convert
803 	fenc_alloced = FALSE;
804     }
805     else if (curbuf->b_help)
806     {
807 	char_u	    firstline[80];
808 	int	    fc;
809 
810 	// Help files are either utf-8 or latin1.  Try utf-8 first, if this
811 	// fails it must be latin1.
812 	// Always do this when 'encoding' is "utf-8".  Otherwise only do
813 	// this when needed to avoid [converted] remarks all the time.
814 	// It is needed when the first line contains non-ASCII characters.
815 	// That is only in *.??x files.
816 	fenc = (char_u *)"latin1";
817 	c = enc_utf8;
818 	if (!c && !read_stdin)
819 	{
820 	    fc = fname[STRLEN(fname) - 1];
821 	    if (TOLOWER_ASC(fc) == 'x')
822 	    {
823 		// Read the first line (and a bit more).  Immediately rewind to
824 		// the start of the file.  If the read() fails "len" is -1.
825 		len = read_eintr(fd, firstline, 80);
826 		vim_lseek(fd, (off_T)0L, SEEK_SET);
827 		for (p = firstline; p < firstline + len; ++p)
828 		    if (*p >= 0x80)
829 		    {
830 			c = TRUE;
831 			break;
832 		    }
833 	    }
834 	}
835 
836 	if (c)
837 	{
838 	    fenc_next = fenc;
839 	    fenc = (char_u *)"utf-8";
840 
841 	    // When the file is utf-8 but a character doesn't fit in
842 	    // 'encoding' don't retry.  In help text editing utf-8 bytes
843 	    // doesn't make sense.
844 	    if (!enc_utf8)
845 		keep_dest_enc = TRUE;
846 	}
847 	fenc_alloced = FALSE;
848     }
849     else if (*p_fencs == NUL)
850     {
851 	fenc = curbuf->b_p_fenc;	// use format from buffer
852 	fenc_alloced = FALSE;
853     }
854     else
855     {
856 	fenc_next = p_fencs;		// try items in 'fileencodings'
857 	fenc = next_fenc(&fenc_next, &fenc_alloced);
858     }
859 
860     /*
861      * Jump back here to retry reading the file in different ways.
862      * Reasons to retry:
863      * - encoding conversion failed: try another one from "fenc_next"
864      * - BOM detected and fenc was set, need to setup conversion
865      * - "fileformat" check failed: try another
866      *
867      * Variables set for special retry actions:
868      * "file_rewind"	Rewind the file to start reading it again.
869      * "advance_fenc"	Advance "fenc" using "fenc_next".
870      * "skip_read"	Re-use already read bytes (BOM detected).
871      * "did_iconv"	iconv() conversion failed, try 'charconvert'.
872      * "keep_fileformat" Don't reset "fileformat".
873      *
874      * Other status indicators:
875      * "tmpname"	When != NULL did conversion with 'charconvert'.
876      *			Output file has to be deleted afterwards.
877      * "iconv_fd"	When != -1 did conversion with iconv().
878      */
879 retry:
880 
881     if (file_rewind)
882     {
883 	if (read_buffer)
884 	{
885 	    read_buf_lnum = 1;
886 	    read_buf_col = 0;
887 	}
888 	else if (read_stdin || vim_lseek(fd, (off_T)0L, SEEK_SET) != 0)
889 	{
890 	    // Can't rewind the file, give up.
891 	    error = TRUE;
892 	    goto failed;
893 	}
894 	// Delete the previously read lines.
895 	while (lnum > from)
896 	    ml_delete(lnum--);
897 	file_rewind = FALSE;
898 	if (set_options)
899 	{
900 	    curbuf->b_p_bomb = FALSE;
901 	    curbuf->b_start_bomb = FALSE;
902 	}
903 	conv_error = 0;
904     }
905 
906     /*
907      * When retrying with another "fenc" and the first time "fileformat"
908      * will be reset.
909      */
910     if (keep_fileformat)
911 	keep_fileformat = FALSE;
912     else
913     {
914 	if (eap != NULL && eap->force_ff != 0)
915 	{
916 	    fileformat = get_fileformat_force(curbuf, eap);
917 	    try_unix = try_dos = try_mac = FALSE;
918 	}
919 	else if (curbuf->b_p_bin)
920 	    fileformat = EOL_UNIX;		// binary: use Unix format
921 	else if (*p_ffs == NUL)
922 	    fileformat = get_fileformat(curbuf);// use format from buffer
923 	else
924 	    fileformat = EOL_UNKNOWN;		// detect from file
925     }
926 
927 #ifdef USE_ICONV
928     if (iconv_fd != (iconv_t)-1)
929     {
930 	// aborted conversion with iconv(), close the descriptor
931 	iconv_close(iconv_fd);
932 	iconv_fd = (iconv_t)-1;
933     }
934 #endif
935 
936     if (advance_fenc)
937     {
938 	/*
939 	 * Try the next entry in 'fileencodings'.
940 	 */
941 	advance_fenc = FALSE;
942 
943 	if (eap != NULL && eap->force_enc != 0)
944 	{
945 	    // Conversion given with "++cc=" wasn't possible, read
946 	    // without conversion.
947 	    notconverted = TRUE;
948 	    conv_error = 0;
949 	    if (fenc_alloced)
950 		vim_free(fenc);
951 	    fenc = (char_u *)"";
952 	    fenc_alloced = FALSE;
953 	}
954 	else
955 	{
956 	    if (fenc_alloced)
957 		vim_free(fenc);
958 	    if (fenc_next != NULL)
959 	    {
960 		fenc = next_fenc(&fenc_next, &fenc_alloced);
961 	    }
962 	    else
963 	    {
964 		fenc = (char_u *)"";
965 		fenc_alloced = FALSE;
966 	    }
967 	}
968 	if (tmpname != NULL)
969 	{
970 	    mch_remove(tmpname);		// delete converted file
971 	    VIM_CLEAR(tmpname);
972 	}
973     }
974 
975     /*
976      * Conversion may be required when the encoding of the file is different
977      * from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4.
978      */
979     fio_flags = 0;
980     converted = need_conversion(fenc);
981     if (converted)
982     {
983 
984 	// "ucs-bom" means we need to check the first bytes of the file
985 	// for a BOM.
986 	if (STRCMP(fenc, ENC_UCSBOM) == 0)
987 	    fio_flags = FIO_UCSBOM;
988 
989 	/*
990 	 * Check if UCS-2/4 or Latin1 to UTF-8 conversion needs to be
991 	 * done.  This is handled below after read().  Prepare the
992 	 * fio_flags to avoid having to parse the string each time.
993 	 * Also check for Unicode to Latin1 conversion, because iconv()
994 	 * appears not to handle this correctly.  This works just like
995 	 * conversion to UTF-8 except how the resulting character is put in
996 	 * the buffer.
997 	 */
998 	else if (enc_utf8 || STRCMP(p_enc, "latin1") == 0)
999 	    fio_flags = get_fio_flags(fenc);
1000 
1001 #ifdef MSWIN
1002 	/*
1003 	 * Conversion from an MS-Windows codepage to UTF-8 or another codepage
1004 	 * is handled with MultiByteToWideChar().
1005 	 */
1006 	if (fio_flags == 0)
1007 	    fio_flags = get_win_fio_flags(fenc);
1008 #endif
1009 
1010 #ifdef MACOS_CONVERT
1011 	// Conversion from Apple MacRoman to latin1 or UTF-8
1012 	if (fio_flags == 0)
1013 	    fio_flags = get_mac_fio_flags(fenc);
1014 #endif
1015 
1016 #ifdef USE_ICONV
1017 	/*
1018 	 * Try using iconv() if we can't convert internally.
1019 	 */
1020 	if (fio_flags == 0
1021 # ifdef FEAT_EVAL
1022 		&& !did_iconv
1023 # endif
1024 		)
1025 	    iconv_fd = (iconv_t)my_iconv_open(
1026 				  enc_utf8 ? (char_u *)"utf-8" : p_enc, fenc);
1027 #endif
1028 
1029 #ifdef FEAT_EVAL
1030 	/*
1031 	 * Use the 'charconvert' expression when conversion is required
1032 	 * and we can't do it internally or with iconv().
1033 	 */
1034 	if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
1035 						    && !read_fifo
1036 # ifdef USE_ICONV
1037 						    && iconv_fd == (iconv_t)-1
1038 # endif
1039 		)
1040 	{
1041 # ifdef USE_ICONV
1042 	    did_iconv = FALSE;
1043 # endif
1044 	    // Skip conversion when it's already done (retry for wrong
1045 	    // "fileformat").
1046 	    if (tmpname == NULL)
1047 	    {
1048 		tmpname = readfile_charconvert(fname, fenc, &fd);
1049 		if (tmpname == NULL)
1050 		{
1051 		    // Conversion failed.  Try another one.
1052 		    advance_fenc = TRUE;
1053 		    if (fd < 0)
1054 		    {
1055 			// Re-opening the original file failed!
1056 			emsg(_("E202: Conversion made file unreadable!"));
1057 			error = TRUE;
1058 			goto failed;
1059 		    }
1060 		    goto retry;
1061 		}
1062 	    }
1063 	}
1064 	else
1065 #endif
1066 	{
1067 	    if (fio_flags == 0
1068 #ifdef USE_ICONV
1069 		    && iconv_fd == (iconv_t)-1
1070 #endif
1071 	       )
1072 	    {
1073 		// Conversion wanted but we can't.
1074 		// Try the next conversion in 'fileencodings'
1075 		advance_fenc = TRUE;
1076 		goto retry;
1077 	    }
1078 	}
1079     }
1080 
1081     // Set "can_retry" when it's possible to rewind the file and try with
1082     // another "fenc" value.  It's FALSE when no other "fenc" to try, reading
1083     // stdin or fixed at a specific encoding.
1084     can_retry = (*fenc != NUL && !read_stdin && !read_fifo && !keep_dest_enc);
1085 
1086     if (!skip_read)
1087     {
1088 	linerest = 0;
1089 	filesize = 0;
1090 	filesize_count = 0;
1091 	skip_count = lines_to_skip;
1092 	read_count = lines_to_read;
1093 	conv_restlen = 0;
1094 #ifdef FEAT_PERSISTENT_UNDO
1095 	read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0
1096 				  && curbuf->b_ffname != NULL
1097 				  && curbuf->b_p_udf
1098 				  && !filtering
1099 				  && !read_fifo
1100 				  && !read_stdin
1101 				  && !read_buffer);
1102 	if (read_undo_file)
1103 	    sha256_start(&sha_ctx);
1104 #endif
1105 #ifdef FEAT_CRYPT
1106 	if (curbuf->b_cryptstate != NULL)
1107 	{
1108 	    // Need to free the state, but keep the key, don't want to ask for
1109 	    // it again.
1110 	    crypt_free_state(curbuf->b_cryptstate);
1111 	    curbuf->b_cryptstate = NULL;
1112 	}
1113 #endif
1114     }
1115 
1116     while (!error && !got_int)
1117     {
1118 	/*
1119 	 * We allocate as much space for the file as we can get, plus
1120 	 * space for the old line plus room for one terminating NUL.
1121 	 * The amount is limited by the fact that read() only can read
1122 	 * up to max_unsigned characters (and other things).
1123 	 */
1124 	if (!skip_read)
1125 	{
1126 #if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L)
1127 		size = SSIZE_MAX;		    // use max I/O size, 52K
1128 #else
1129 		// Use buffer >= 64K.  Add linerest to double the size if the
1130 		// line gets very long, to avoid a lot of copying. But don't
1131 		// read more than 1 Mbyte at a time, so we can be interrupted.
1132 		size = 0x10000L + linerest;
1133 		if (size > 0x100000L)
1134 		    size = 0x100000L;
1135 #endif
1136 	}
1137 
1138 	// Protect against the argument of lalloc() going negative.
1139 	if (size < 0 || size + linerest + 1 < 0 || linerest >= MAXCOL)
1140 	{
1141 	    ++split;
1142 	    *ptr = NL;		    // split line by inserting a NL
1143 	    size = 1;
1144 	}
1145 	else
1146 	{
1147 	    if (!skip_read)
1148 	    {
1149 		for ( ; size >= 10; size = (long)((long_u)size >> 1))
1150 		{
1151 		    if ((new_buffer = lalloc(size + linerest + 1,
1152 							      FALSE)) != NULL)
1153 			break;
1154 		}
1155 		if (new_buffer == NULL)
1156 		{
1157 		    do_outofmem_msg((long_u)(size * 2 + linerest + 1));
1158 		    error = TRUE;
1159 		    break;
1160 		}
1161 		if (linerest)	// copy characters from the previous buffer
1162 		    mch_memmove(new_buffer, ptr - linerest, (size_t)linerest);
1163 		vim_free(buffer);
1164 		buffer = new_buffer;
1165 		ptr = buffer + linerest;
1166 		line_start = buffer;
1167 
1168 		// May need room to translate into.
1169 		// For iconv() we don't really know the required space, use a
1170 		// factor ICONV_MULT.
1171 		// latin1 to utf-8: 1 byte becomes up to 2 bytes
1172 		// utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
1173 		// become up to 4 bytes, size must be multiple of 2
1174 		// ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
1175 		// multiple of 2
1176 		// ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
1177 		// multiple of 4
1178 		real_size = (int)size;
1179 #ifdef USE_ICONV
1180 		if (iconv_fd != (iconv_t)-1)
1181 		    size = size / ICONV_MULT;
1182 		else
1183 #endif
1184 		    if (fio_flags & FIO_LATIN1)
1185 		    size = size / 2;
1186 		else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
1187 		    size = (size * 2 / 3) & ~1;
1188 		else if (fio_flags & FIO_UCS4)
1189 		    size = (size * 2 / 3) & ~3;
1190 		else if (fio_flags == FIO_UCSBOM)
1191 		    size = size / ICONV_MULT;	// worst case
1192 #ifdef MSWIN
1193 		else if (fio_flags & FIO_CODEPAGE)
1194 		    size = size / ICONV_MULT;	// also worst case
1195 #endif
1196 #ifdef MACOS_CONVERT
1197 		else if (fio_flags & FIO_MACROMAN)
1198 		    size = size / ICONV_MULT;	// also worst case
1199 #endif
1200 
1201 		if (conv_restlen > 0)
1202 		{
1203 		    // Insert unconverted bytes from previous line.
1204 		    mch_memmove(ptr, conv_rest, conv_restlen);
1205 		    ptr += conv_restlen;
1206 		    size -= conv_restlen;
1207 		}
1208 
1209 		if (read_buffer)
1210 		{
1211 		    /*
1212 		     * Read bytes from curbuf.  Used for converting text read
1213 		     * from stdin.
1214 		     */
1215 		    eof = FALSE;
1216 		    if (read_buf_lnum > from)
1217 			size = 0;
1218 		    else
1219 		    {
1220 			int	n, ni;
1221 			long	tlen;
1222 
1223 			tlen = 0;
1224 			for (;;)
1225 			{
1226 			    p = ml_get(read_buf_lnum) + read_buf_col;
1227 			    n = (int)STRLEN(p);
1228 			    if ((int)tlen + n + 1 > size)
1229 			    {
1230 				// Filled up to "size", append partial line.
1231 				// Change NL to NUL to reverse the effect done
1232 				// below.
1233 				n = (int)(size - tlen);
1234 				for (ni = 0; ni < n; ++ni)
1235 				{
1236 				    if (p[ni] == NL)
1237 					ptr[tlen++] = NUL;
1238 				    else
1239 					ptr[tlen++] = p[ni];
1240 				}
1241 				read_buf_col += n;
1242 				break;
1243 			    }
1244 			    else
1245 			    {
1246 				// Append whole line and new-line.  Change NL
1247 				// to NUL to reverse the effect done below.
1248 				for (ni = 0; ni < n; ++ni)
1249 				{
1250 				    if (p[ni] == NL)
1251 					ptr[tlen++] = NUL;
1252 				    else
1253 					ptr[tlen++] = p[ni];
1254 				}
1255 				ptr[tlen++] = NL;
1256 				read_buf_col = 0;
1257 				if (++read_buf_lnum > from)
1258 				{
1259 				    // When the last line didn't have an
1260 				    // end-of-line don't add it now either.
1261 				    if (!curbuf->b_p_eol)
1262 					--tlen;
1263 				    size = tlen;
1264 				    eof = TRUE;
1265 				    break;
1266 				}
1267 			    }
1268 			}
1269 		    }
1270 		}
1271 		else
1272 		{
1273 		    /*
1274 		     * Read bytes from the file.
1275 		     */
1276 # ifdef FEAT_SODIUM
1277 		    // Let the crypt layer work with a buffer size of 8192
1278 		    if (filesize == 0)
1279 			// set size to 8K + Sodium Crypt Metadata
1280 			size = WRITEBUFSIZE + crypt_get_max_header_len()
1281 		     + crypto_secretstream_xchacha20poly1305_HEADERBYTES
1282 		     + crypto_secretstream_xchacha20poly1305_ABYTES;
1283 
1284 		    else if (filesize > 0 && (curbuf->b_cryptstate != NULL &&
1285 			 curbuf->b_cryptstate->method_nr == CRYPT_M_SOD))
1286 			size = WRITEBUFSIZE + crypto_secretstream_xchacha20poly1305_ABYTES;
1287 # endif
1288 		    eof = size;
1289 		    size = read_eintr(fd, ptr, size);
1290 		    filesize_count += size;
1291 		    // hit end of file
1292 		    eof = (size < eof || filesize_count == filesize_disk);
1293 		}
1294 
1295 #ifdef FEAT_CRYPT
1296 		/*
1297 		 * At start of file: Check for magic number of encryption.
1298 		 */
1299 		if (filesize == 0 && size > 0)
1300 		{
1301 		    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
1302 						  &filesize, newfile, sfname,
1303 						  &did_ask_for_key);
1304 # ifdef CRYPT_NOT_INPLACE
1305 		    if (curbuf->b_cryptstate != NULL
1306 				 && !crypt_works_inplace(curbuf->b_cryptstate))
1307 			// reading undo file requires crypt_decode_inplace()
1308 			read_undo_file = FALSE;
1309 # endif
1310 		}
1311 		/*
1312 		 * Decrypt the read bytes.  This is done before checking for
1313 		 * EOF because the crypt layer may be buffering.
1314 		 */
1315 		if (cryptkey != NULL && curbuf->b_cryptstate != NULL
1316 								   && size > 0)
1317 		{
1318 # ifdef CRYPT_NOT_INPLACE
1319 		    if (crypt_works_inplace(curbuf->b_cryptstate))
1320 		    {
1321 # endif
1322 			crypt_decode_inplace(curbuf->b_cryptstate, ptr,
1323 								    size, eof);
1324 # ifdef CRYPT_NOT_INPLACE
1325 		    }
1326 		    else
1327 		    {
1328 			char_u	*newptr = NULL;
1329 			int	decrypted_size;
1330 
1331 			decrypted_size = crypt_decode_alloc(
1332 				    curbuf->b_cryptstate, ptr, size,
1333 								 &newptr, eof);
1334 
1335 			if (decrypted_size < 0)
1336 			{
1337 			    // error message already given
1338 			    error = TRUE;
1339 			    vim_free(newptr);
1340 			    break;
1341 			}
1342 			// If the crypt layer is buffering, not producing
1343 			// anything yet, need to read more.
1344 			if (decrypted_size == 0)
1345 			    continue;
1346 
1347 			if (linerest == 0)
1348 			{
1349 			    // Simple case: reuse returned buffer (may be
1350 			    // NULL, checked later).
1351 			    new_buffer = newptr;
1352 			}
1353 			else
1354 			{
1355 			    long_u	new_size;
1356 
1357 			    // Need new buffer to add bytes carried over.
1358 			    new_size = (long_u)(decrypted_size + linerest + 1);
1359 			    new_buffer = lalloc(new_size, FALSE);
1360 			    if (new_buffer == NULL)
1361 			    {
1362 				do_outofmem_msg(new_size);
1363 				error = TRUE;
1364 				break;
1365 			    }
1366 
1367 			    mch_memmove(new_buffer, buffer, linerest);
1368 			    if (newptr != NULL)
1369 				mch_memmove(new_buffer + linerest, newptr,
1370 							      decrypted_size);
1371 			    vim_free(newptr);
1372 			}
1373 
1374 			if (new_buffer != NULL)
1375 			{
1376 			    vim_free(buffer);
1377 			    buffer = new_buffer;
1378 			    new_buffer = NULL;
1379 			    line_start = buffer;
1380 			    ptr = buffer + linerest;
1381 			    real_size = size;
1382 			}
1383 			size = decrypted_size;
1384 		    }
1385 # endif
1386 		}
1387 #endif
1388 
1389 		if (size <= 0)
1390 		{
1391 		    if (size < 0)		    // read error
1392 			error = TRUE;
1393 		    else if (conv_restlen > 0)
1394 		    {
1395 			/*
1396 			 * Reached end-of-file but some trailing bytes could
1397 			 * not be converted.  Truncated file?
1398 			 */
1399 
1400 			// When we did a conversion report an error.
1401 			if (fio_flags != 0
1402 #ifdef USE_ICONV
1403 				|| iconv_fd != (iconv_t)-1
1404 #endif
1405 			   )
1406 			{
1407 			    if (can_retry)
1408 				goto rewind_retry;
1409 			    if (conv_error == 0)
1410 				conv_error = curbuf->b_ml.ml_line_count
1411 								- linecnt + 1;
1412 			}
1413 			// Remember the first linenr with an illegal byte
1414 			else if (illegal_byte == 0)
1415 			    illegal_byte = curbuf->b_ml.ml_line_count
1416 								- linecnt + 1;
1417 			if (bad_char_behavior == BAD_DROP)
1418 			{
1419 			    *(ptr - conv_restlen) = NUL;
1420 			    conv_restlen = 0;
1421 			}
1422 			else
1423 			{
1424 			    // Replace the trailing bytes with the replacement
1425 			    // character if we were converting; if we weren't,
1426 			    // leave the UTF8 checking code to do it, as it
1427 			    // works slightly differently.
1428 			    if (bad_char_behavior != BAD_KEEP && (fio_flags != 0
1429 #ifdef USE_ICONV
1430 				    || iconv_fd != (iconv_t)-1
1431 #endif
1432 			       ))
1433 			    {
1434 				while (conv_restlen > 0)
1435 				{
1436 				    *(--ptr) = bad_char_behavior;
1437 				    --conv_restlen;
1438 				}
1439 			    }
1440 			    fio_flags = 0;	// don't convert this
1441 #ifdef USE_ICONV
1442 			    if (iconv_fd != (iconv_t)-1)
1443 			    {
1444 				iconv_close(iconv_fd);
1445 				iconv_fd = (iconv_t)-1;
1446 			    }
1447 #endif
1448 			}
1449 		    }
1450 		}
1451 	    }
1452 	    skip_read = FALSE;
1453 
1454 	    /*
1455 	     * At start of file (or after crypt magic number): Check for BOM.
1456 	     * Also check for a BOM for other Unicode encodings, but not after
1457 	     * converting with 'charconvert' or when a BOM has already been
1458 	     * found.
1459 	     */
1460 	    if ((filesize == 0
1461 #ifdef FEAT_CRYPT
1462 		   || (cryptkey != NULL
1463 			&& filesize == crypt_get_header_len(
1464 						 crypt_get_method_nr(curbuf)))
1465 #endif
1466 		       )
1467 		    && (fio_flags == FIO_UCSBOM
1468 			|| (!curbuf->b_p_bomb
1469 			    && tmpname == NULL
1470 			    && (*fenc == 'u' || (*fenc == NUL && enc_utf8)))))
1471 	    {
1472 		char_u	*ccname;
1473 		int	blen;
1474 
1475 		// no BOM detection in a short file or in binary mode
1476 		if (size < 2 || curbuf->b_p_bin)
1477 		    ccname = NULL;
1478 		else
1479 		    ccname = check_for_bom(ptr, size, &blen,
1480 		      fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc));
1481 		if (ccname != NULL)
1482 		{
1483 		    // Remove BOM from the text
1484 		    filesize += blen;
1485 		    size -= blen;
1486 		    mch_memmove(ptr, ptr + blen, (size_t)size);
1487 		    if (set_options)
1488 		    {
1489 			curbuf->b_p_bomb = TRUE;
1490 			curbuf->b_start_bomb = TRUE;
1491 		    }
1492 		}
1493 
1494 		if (fio_flags == FIO_UCSBOM)
1495 		{
1496 		    if (ccname == NULL)
1497 		    {
1498 			// No BOM detected: retry with next encoding.
1499 			advance_fenc = TRUE;
1500 		    }
1501 		    else
1502 		    {
1503 			// BOM detected: set "fenc" and jump back
1504 			if (fenc_alloced)
1505 			    vim_free(fenc);
1506 			fenc = ccname;
1507 			fenc_alloced = FALSE;
1508 		    }
1509 		    // retry reading without getting new bytes or rewinding
1510 		    skip_read = TRUE;
1511 		    goto retry;
1512 		}
1513 	    }
1514 
1515 	    // Include not converted bytes.
1516 	    ptr -= conv_restlen;
1517 	    size += conv_restlen;
1518 	    conv_restlen = 0;
1519 	    /*
1520 	     * Break here for a read error or end-of-file.
1521 	     */
1522 	    if (size <= 0)
1523 		break;
1524 
1525 
1526 #ifdef USE_ICONV
1527 	    if (iconv_fd != (iconv_t)-1)
1528 	    {
1529 		/*
1530 		 * Attempt conversion of the read bytes to 'encoding' using
1531 		 * iconv().
1532 		 */
1533 		const char	*fromp;
1534 		char		*top;
1535 		size_t		from_size;
1536 		size_t		to_size;
1537 
1538 		fromp = (char *)ptr;
1539 		from_size = size;
1540 		ptr += size;
1541 		top = (char *)ptr;
1542 		to_size = real_size - size;
1543 
1544 		/*
1545 		 * If there is conversion error or not enough room try using
1546 		 * another conversion.  Except for when there is no
1547 		 * alternative (help files).
1548 		 */
1549 		while ((iconv(iconv_fd, (void *)&fromp, &from_size,
1550 							       &top, &to_size)
1551 			    == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
1552 						  || from_size > CONV_RESTLEN)
1553 		{
1554 		    if (can_retry)
1555 			goto rewind_retry;
1556 		    if (conv_error == 0)
1557 			conv_error = readfile_linenr(linecnt,
1558 							  ptr, (char_u *)top);
1559 
1560 		    // Deal with a bad byte and continue with the next.
1561 		    ++fromp;
1562 		    --from_size;
1563 		    if (bad_char_behavior == BAD_KEEP)
1564 		    {
1565 			*top++ = *(fromp - 1);
1566 			--to_size;
1567 		    }
1568 		    else if (bad_char_behavior != BAD_DROP)
1569 		    {
1570 			*top++ = bad_char_behavior;
1571 			--to_size;
1572 		    }
1573 		}
1574 
1575 		if (from_size > 0)
1576 		{
1577 		    // Some remaining characters, keep them for the next
1578 		    // round.
1579 		    mch_memmove(conv_rest, (char_u *)fromp, from_size);
1580 		    conv_restlen = (int)from_size;
1581 		}
1582 
1583 		// move the linerest to before the converted characters
1584 		line_start = ptr - linerest;
1585 		mch_memmove(line_start, buffer, (size_t)linerest);
1586 		size = (long)((char_u *)top - ptr);
1587 	    }
1588 #endif
1589 
1590 #ifdef MSWIN
1591 	    if (fio_flags & FIO_CODEPAGE)
1592 	    {
1593 		char_u	*src, *dst;
1594 		WCHAR	ucs2buf[3];
1595 		int	ucs2len;
1596 		int	codepage = FIO_GET_CP(fio_flags);
1597 		int	bytelen;
1598 		int	found_bad;
1599 		char	replstr[2];
1600 
1601 		/*
1602 		 * Conversion from an MS-Windows codepage or UTF-8 to UTF-8 or
1603 		 * a codepage, using standard MS-Windows functions.  This
1604 		 * requires two steps:
1605 		 * 1. convert from 'fileencoding' to ucs-2
1606 		 * 2. convert from ucs-2 to 'encoding'
1607 		 *
1608 		 * Because there may be illegal bytes AND an incomplete byte
1609 		 * sequence at the end, we may have to do the conversion one
1610 		 * character at a time to get it right.
1611 		 */
1612 
1613 		// Replacement string for WideCharToMultiByte().
1614 		if (bad_char_behavior > 0)
1615 		    replstr[0] = bad_char_behavior;
1616 		else
1617 		    replstr[0] = '?';
1618 		replstr[1] = NUL;
1619 
1620 		/*
1621 		 * Move the bytes to the end of the buffer, so that we have
1622 		 * room to put the result at the start.
1623 		 */
1624 		src = ptr + real_size - size;
1625 		mch_memmove(src, ptr, size);
1626 
1627 		/*
1628 		 * Do the conversion.
1629 		 */
1630 		dst = ptr;
1631 		size = size;
1632 		while (size > 0)
1633 		{
1634 		    found_bad = FALSE;
1635 
1636 #  ifdef CP_UTF8	// VC 4.1 doesn't define CP_UTF8
1637 		    if (codepage == CP_UTF8)
1638 		    {
1639 			// Handle CP_UTF8 input ourselves to be able to handle
1640 			// trailing bytes properly.
1641 			// Get one UTF-8 character from src.
1642 			bytelen = (int)utf_ptr2len_len(src, size);
1643 			if (bytelen > size)
1644 			{
1645 			    // Only got some bytes of a character.  Normally
1646 			    // it's put in "conv_rest", but if it's too long
1647 			    // deal with it as if they were illegal bytes.
1648 			    if (bytelen <= CONV_RESTLEN)
1649 				break;
1650 
1651 			    // weird overlong byte sequence
1652 			    bytelen = size;
1653 			    found_bad = TRUE;
1654 			}
1655 			else
1656 			{
1657 			    int	    u8c = utf_ptr2char(src);
1658 
1659 			    if (u8c > 0xffff || (*src >= 0x80 && bytelen == 1))
1660 				found_bad = TRUE;
1661 			    ucs2buf[0] = u8c;
1662 			    ucs2len = 1;
1663 			}
1664 		    }
1665 		    else
1666 #  endif
1667 		    {
1668 			// We don't know how long the byte sequence is, try
1669 			// from one to three bytes.
1670 			for (bytelen = 1; bytelen <= size && bytelen <= 3;
1671 								    ++bytelen)
1672 			{
1673 			    ucs2len = MultiByteToWideChar(codepage,
1674 							 MB_ERR_INVALID_CHARS,
1675 							 (LPCSTR)src, bytelen,
1676 								   ucs2buf, 3);
1677 			    if (ucs2len > 0)
1678 				break;
1679 			}
1680 			if (ucs2len == 0)
1681 			{
1682 			    // If we have only one byte then it's probably an
1683 			    // incomplete byte sequence.  Otherwise discard
1684 			    // one byte as a bad character.
1685 			    if (size == 1)
1686 				break;
1687 			    found_bad = TRUE;
1688 			    bytelen = 1;
1689 			}
1690 		    }
1691 
1692 		    if (!found_bad)
1693 		    {
1694 			int	i;
1695 
1696 			// Convert "ucs2buf[ucs2len]" to 'enc' in "dst".
1697 			if (enc_utf8)
1698 			{
1699 			    // From UCS-2 to UTF-8.  Cannot fail.
1700 			    for (i = 0; i < ucs2len; ++i)
1701 				dst += utf_char2bytes(ucs2buf[i], dst);
1702 			}
1703 			else
1704 			{
1705 			    BOOL	bad = FALSE;
1706 			    int		dstlen;
1707 
1708 			    // From UCS-2 to "enc_codepage".  If the
1709 			    // conversion uses the default character "?",
1710 			    // the data doesn't fit in this encoding.
1711 			    dstlen = WideCharToMultiByte(enc_codepage, 0,
1712 				    (LPCWSTR)ucs2buf, ucs2len,
1713 				    (LPSTR)dst, (int)(src - dst),
1714 				    replstr, &bad);
1715 			    if (bad)
1716 				found_bad = TRUE;
1717 			    else
1718 				dst += dstlen;
1719 			}
1720 		    }
1721 
1722 		    if (found_bad)
1723 		    {
1724 			// Deal with bytes we can't convert.
1725 			if (can_retry)
1726 			    goto rewind_retry;
1727 			if (conv_error == 0)
1728 			    conv_error = readfile_linenr(linecnt, ptr, dst);
1729 			if (bad_char_behavior != BAD_DROP)
1730 			{
1731 			    if (bad_char_behavior == BAD_KEEP)
1732 			    {
1733 				mch_memmove(dst, src, bytelen);
1734 				dst += bytelen;
1735 			    }
1736 			    else
1737 				*dst++ = bad_char_behavior;
1738 			}
1739 		    }
1740 
1741 		    src += bytelen;
1742 		    size -= bytelen;
1743 		}
1744 
1745 		if (size > 0)
1746 		{
1747 		    // An incomplete byte sequence remaining.
1748 		    mch_memmove(conv_rest, src, size);
1749 		    conv_restlen = size;
1750 		}
1751 
1752 		// The new size is equal to how much "dst" was advanced.
1753 		size = (long)(dst - ptr);
1754 	    }
1755 	    else
1756 #endif
1757 #ifdef MACOS_CONVERT
1758 	    if (fio_flags & FIO_MACROMAN)
1759 	    {
1760 		/*
1761 		 * Conversion from Apple MacRoman char encoding to UTF-8 or
1762 		 * latin1.  This is in os_mac_conv.c.
1763 		 */
1764 		if (macroman2enc(ptr, &size, real_size) == FAIL)
1765 		    goto rewind_retry;
1766 	    }
1767 	    else
1768 #endif
1769 	    if (fio_flags != 0)
1770 	    {
1771 		int	u8c;
1772 		char_u	*dest;
1773 		char_u	*tail = NULL;
1774 
1775 		/*
1776 		 * "enc_utf8" set: Convert Unicode or Latin1 to UTF-8.
1777 		 * "enc_utf8" not set: Convert Unicode to Latin1.
1778 		 * Go from end to start through the buffer, because the number
1779 		 * of bytes may increase.
1780 		 * "dest" points to after where the UTF-8 bytes go, "p" points
1781 		 * to after the next character to convert.
1782 		 */
1783 		dest = ptr + real_size;
1784 		if (fio_flags == FIO_LATIN1 || fio_flags == FIO_UTF8)
1785 		{
1786 		    p = ptr + size;
1787 		    if (fio_flags == FIO_UTF8)
1788 		    {
1789 			// Check for a trailing incomplete UTF-8 sequence
1790 			tail = ptr + size - 1;
1791 			while (tail > ptr && (*tail & 0xc0) == 0x80)
1792 			    --tail;
1793 			if (tail + utf_byte2len(*tail) <= ptr + size)
1794 			    tail = NULL;
1795 			else
1796 			    p = tail;
1797 		    }
1798 		}
1799 		else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
1800 		{
1801 		    // Check for a trailing byte
1802 		    p = ptr + (size & ~1);
1803 		    if (size & 1)
1804 			tail = p;
1805 		    if ((fio_flags & FIO_UTF16) && p > ptr)
1806 		    {
1807 			// Check for a trailing leading word
1808 			if (fio_flags & FIO_ENDIAN_L)
1809 			{
1810 			    u8c = (*--p << 8);
1811 			    u8c += *--p;
1812 			}
1813 			else
1814 			{
1815 			    u8c = *--p;
1816 			    u8c += (*--p << 8);
1817 			}
1818 			if (u8c >= 0xd800 && u8c <= 0xdbff)
1819 			    tail = p;
1820 			else
1821 			    p += 2;
1822 		    }
1823 		}
1824 		else //  FIO_UCS4
1825 		{
1826 		    // Check for trailing 1, 2 or 3 bytes
1827 		    p = ptr + (size & ~3);
1828 		    if (size & 3)
1829 			tail = p;
1830 		}
1831 
1832 		// If there is a trailing incomplete sequence move it to
1833 		// conv_rest[].
1834 		if (tail != NULL)
1835 		{
1836 		    conv_restlen = (int)((ptr + size) - tail);
1837 		    mch_memmove(conv_rest, (char_u *)tail, conv_restlen);
1838 		    size -= conv_restlen;
1839 		}
1840 
1841 
1842 		while (p > ptr)
1843 		{
1844 		    if (fio_flags & FIO_LATIN1)
1845 			u8c = *--p;
1846 		    else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
1847 		    {
1848 			if (fio_flags & FIO_ENDIAN_L)
1849 			{
1850 			    u8c = (*--p << 8);
1851 			    u8c += *--p;
1852 			}
1853 			else
1854 			{
1855 			    u8c = *--p;
1856 			    u8c += (*--p << 8);
1857 			}
1858 			if ((fio_flags & FIO_UTF16)
1859 					    && u8c >= 0xdc00 && u8c <= 0xdfff)
1860 			{
1861 			    int u16c;
1862 
1863 			    if (p == ptr)
1864 			    {
1865 				// Missing leading word.
1866 				if (can_retry)
1867 				    goto rewind_retry;
1868 				if (conv_error == 0)
1869 				    conv_error = readfile_linenr(linecnt,
1870 								      ptr, p);
1871 				if (bad_char_behavior == BAD_DROP)
1872 				    continue;
1873 				if (bad_char_behavior != BAD_KEEP)
1874 				    u8c = bad_char_behavior;
1875 			    }
1876 
1877 			    // found second word of double-word, get the first
1878 			    // word and compute the resulting character
1879 			    if (fio_flags & FIO_ENDIAN_L)
1880 			    {
1881 				u16c = (*--p << 8);
1882 				u16c += *--p;
1883 			    }
1884 			    else
1885 			    {
1886 				u16c = *--p;
1887 				u16c += (*--p << 8);
1888 			    }
1889 			    u8c = 0x10000 + ((u16c & 0x3ff) << 10)
1890 							      + (u8c & 0x3ff);
1891 
1892 			    // Check if the word is indeed a leading word.
1893 			    if (u16c < 0xd800 || u16c > 0xdbff)
1894 			    {
1895 				if (can_retry)
1896 				    goto rewind_retry;
1897 				if (conv_error == 0)
1898 				    conv_error = readfile_linenr(linecnt,
1899 								      ptr, p);
1900 				if (bad_char_behavior == BAD_DROP)
1901 				    continue;
1902 				if (bad_char_behavior != BAD_KEEP)
1903 				    u8c = bad_char_behavior;
1904 			    }
1905 			}
1906 		    }
1907 		    else if (fio_flags & FIO_UCS4)
1908 		    {
1909 			if (fio_flags & FIO_ENDIAN_L)
1910 			{
1911 			    u8c = (unsigned)*--p << 24;
1912 			    u8c += (unsigned)*--p << 16;
1913 			    u8c += (unsigned)*--p << 8;
1914 			    u8c += *--p;
1915 			}
1916 			else	// big endian
1917 			{
1918 			    u8c = *--p;
1919 			    u8c += (unsigned)*--p << 8;
1920 			    u8c += (unsigned)*--p << 16;
1921 			    u8c += (unsigned)*--p << 24;
1922 			}
1923 		    }
1924 		    else    // UTF-8
1925 		    {
1926 			if (*--p < 0x80)
1927 			    u8c = *p;
1928 			else
1929 			{
1930 			    len = utf_head_off(ptr, p);
1931 			    p -= len;
1932 			    u8c = utf_ptr2char(p);
1933 			    if (len == 0)
1934 			    {
1935 				// Not a valid UTF-8 character, retry with
1936 				// another fenc when possible, otherwise just
1937 				// report the error.
1938 				if (can_retry)
1939 				    goto rewind_retry;
1940 				if (conv_error == 0)
1941 				    conv_error = readfile_linenr(linecnt,
1942 								      ptr, p);
1943 				if (bad_char_behavior == BAD_DROP)
1944 				    continue;
1945 				if (bad_char_behavior != BAD_KEEP)
1946 				    u8c = bad_char_behavior;
1947 			    }
1948 			}
1949 		    }
1950 		    if (enc_utf8)	// produce UTF-8
1951 		    {
1952 			dest -= utf_char2len(u8c);
1953 			(void)utf_char2bytes(u8c, dest);
1954 		    }
1955 		    else		// produce Latin1
1956 		    {
1957 			--dest;
1958 			if (u8c >= 0x100)
1959 			{
1960 			    // character doesn't fit in latin1, retry with
1961 			    // another fenc when possible, otherwise just
1962 			    // report the error.
1963 			    if (can_retry)
1964 				goto rewind_retry;
1965 			    if (conv_error == 0)
1966 				conv_error = readfile_linenr(linecnt, ptr, p);
1967 			    if (bad_char_behavior == BAD_DROP)
1968 				++dest;
1969 			    else if (bad_char_behavior == BAD_KEEP)
1970 				*dest = u8c;
1971 			    else if (eap != NULL && eap->bad_char != 0)
1972 				*dest = bad_char_behavior;
1973 			    else
1974 				*dest = 0xBF;
1975 			}
1976 			else
1977 			    *dest = u8c;
1978 		    }
1979 		}
1980 
1981 		// move the linerest to before the converted characters
1982 		line_start = dest - linerest;
1983 		mch_memmove(line_start, buffer, (size_t)linerest);
1984 		size = (long)((ptr + real_size) - dest);
1985 		ptr = dest;
1986 	    }
1987 	    else if (enc_utf8 && !curbuf->b_p_bin)
1988 	    {
1989 		int  incomplete_tail = FALSE;
1990 
1991 		// Reading UTF-8: Check if the bytes are valid UTF-8.
1992 		for (p = ptr; ; ++p)
1993 		{
1994 		    int	 todo = (int)((ptr + size) - p);
1995 		    int	 l;
1996 
1997 		    if (todo <= 0)
1998 			break;
1999 		    if (*p >= 0x80)
2000 		    {
2001 			// A length of 1 means it's an illegal byte.  Accept
2002 			// an incomplete character at the end though, the next
2003 			// read() will get the next bytes, we'll check it
2004 			// then.
2005 			l = utf_ptr2len_len(p, todo);
2006 			if (l > todo && !incomplete_tail)
2007 			{
2008 			    // Avoid retrying with a different encoding when
2009 			    // a truncated file is more likely, or attempting
2010 			    // to read the rest of an incomplete sequence when
2011 			    // we have already done so.
2012 			    if (p > ptr || filesize > 0)
2013 				incomplete_tail = TRUE;
2014 			    // Incomplete byte sequence, move it to conv_rest[]
2015 			    // and try to read the rest of it, unless we've
2016 			    // already done so.
2017 			    if (p > ptr)
2018 			    {
2019 				conv_restlen = todo;
2020 				mch_memmove(conv_rest, p, conv_restlen);
2021 				size -= conv_restlen;
2022 				break;
2023 			    }
2024 			}
2025 			if (l == 1 || l > todo)
2026 			{
2027 			    // Illegal byte.  If we can try another encoding
2028 			    // do that, unless at EOF where a truncated
2029 			    // file is more likely than a conversion error.
2030 			    if (can_retry && !incomplete_tail)
2031 				break;
2032 #ifdef USE_ICONV
2033 			    // When we did a conversion report an error.
2034 			    if (iconv_fd != (iconv_t)-1 && conv_error == 0)
2035 				conv_error = readfile_linenr(linecnt, ptr, p);
2036 #endif
2037 			    // Remember the first linenr with an illegal byte
2038 			    if (conv_error == 0 && illegal_byte == 0)
2039 				illegal_byte = readfile_linenr(linecnt, ptr, p);
2040 
2041 			    // Drop, keep or replace the bad byte.
2042 			    if (bad_char_behavior == BAD_DROP)
2043 			    {
2044 				mch_memmove(p, p + 1, todo - 1);
2045 				--p;
2046 				--size;
2047 			    }
2048 			    else if (bad_char_behavior != BAD_KEEP)
2049 				*p = bad_char_behavior;
2050 			}
2051 			else
2052 			    p += l - 1;
2053 		    }
2054 		}
2055 		if (p < ptr + size && !incomplete_tail)
2056 		{
2057 		    // Detected a UTF-8 error.
2058 rewind_retry:
2059 		    // Retry reading with another conversion.
2060 #if defined(FEAT_EVAL) && defined(USE_ICONV)
2061 		    if (*p_ccv != NUL && iconv_fd != (iconv_t)-1)
2062 			// iconv() failed, try 'charconvert'
2063 			did_iconv = TRUE;
2064 		    else
2065 #endif
2066 			// use next item from 'fileencodings'
2067 			advance_fenc = TRUE;
2068 		    file_rewind = TRUE;
2069 		    goto retry;
2070 		}
2071 	    }
2072 
2073 	    // count the number of characters (after conversion!)
2074 	    filesize += size;
2075 
2076 	    /*
2077 	     * when reading the first part of a file: guess EOL type
2078 	     */
2079 	    if (fileformat == EOL_UNKNOWN)
2080 	    {
2081 		// First try finding a NL, for Dos and Unix
2082 		if (try_dos || try_unix)
2083 		{
2084 		    // Reset the carriage return counter.
2085 		    if (try_mac)
2086 			try_mac = 1;
2087 
2088 		    for (p = ptr; p < ptr + size; ++p)
2089 		    {
2090 			if (*p == NL)
2091 			{
2092 			    if (!try_unix
2093 				    || (try_dos && p > ptr && p[-1] == CAR))
2094 				fileformat = EOL_DOS;
2095 			    else
2096 				fileformat = EOL_UNIX;
2097 			    break;
2098 			}
2099 			else if (*p == CAR && try_mac)
2100 			    try_mac++;
2101 		    }
2102 
2103 		    // Don't give in to EOL_UNIX if EOL_MAC is more likely
2104 		    if (fileformat == EOL_UNIX && try_mac)
2105 		    {
2106 			// Need to reset the counters when retrying fenc.
2107 			try_mac = 1;
2108 			try_unix = 1;
2109 			for (; p >= ptr && *p != CAR; p--)
2110 			    ;
2111 			if (p >= ptr)
2112 			{
2113 			    for (p = ptr; p < ptr + size; ++p)
2114 			    {
2115 				if (*p == NL)
2116 				    try_unix++;
2117 				else if (*p == CAR)
2118 				    try_mac++;
2119 			    }
2120 			    if (try_mac > try_unix)
2121 				fileformat = EOL_MAC;
2122 			}
2123 		    }
2124 		    else if (fileformat == EOL_UNKNOWN && try_mac == 1)
2125 			// Looking for CR but found no end-of-line markers at
2126 			// all: use the default format.
2127 			fileformat = default_fileformat();
2128 		}
2129 
2130 		// No NL found: may use Mac format
2131 		if (fileformat == EOL_UNKNOWN && try_mac)
2132 		    fileformat = EOL_MAC;
2133 
2134 		// Still nothing found?  Use first format in 'ffs'
2135 		if (fileformat == EOL_UNKNOWN)
2136 		    fileformat = default_fileformat();
2137 
2138 		// if editing a new file: may set p_tx and p_ff
2139 		if (set_options)
2140 		    set_fileformat(fileformat, OPT_LOCAL);
2141 	    }
2142 	}
2143 
2144 	/*
2145 	 * This loop is executed once for every character read.
2146 	 * Keep it fast!
2147 	 */
2148 	if (fileformat == EOL_MAC)
2149 	{
2150 	    --ptr;
2151 	    while (++ptr, --size >= 0)
2152 	    {
2153 		// catch most common case first
2154 		if ((c = *ptr) != NUL && c != CAR && c != NL)
2155 		    continue;
2156 		if (c == NUL)
2157 		    *ptr = NL;	// NULs are replaced by newlines!
2158 		else if (c == NL)
2159 		    *ptr = CAR;	// NLs are replaced by CRs!
2160 		else
2161 		{
2162 		    if (skip_count == 0)
2163 		    {
2164 			*ptr = NUL;	    // end of line
2165 			len = (colnr_T) (ptr - line_start + 1);
2166 			if (ml_append(lnum, line_start, len, newfile) == FAIL)
2167 			{
2168 			    error = TRUE;
2169 			    break;
2170 			}
2171 #ifdef FEAT_PERSISTENT_UNDO
2172 			if (read_undo_file)
2173 			    sha256_update(&sha_ctx, line_start, len);
2174 #endif
2175 			++lnum;
2176 			if (--read_count == 0)
2177 			{
2178 			    error = TRUE;	// break loop
2179 			    line_start = ptr;	// nothing left to write
2180 			    break;
2181 			}
2182 		    }
2183 		    else
2184 			--skip_count;
2185 		    line_start = ptr + 1;
2186 		}
2187 	    }
2188 	}
2189 	else
2190 	{
2191 	    --ptr;
2192 	    while (++ptr, --size >= 0)
2193 	    {
2194 		if ((c = *ptr) != NUL && c != NL)  // catch most common case
2195 		    continue;
2196 		if (c == NUL)
2197 		    *ptr = NL;	// NULs are replaced by newlines!
2198 		else
2199 		{
2200 		    if (skip_count == 0)
2201 		    {
2202 			*ptr = NUL;		// end of line
2203 			len = (colnr_T)(ptr - line_start + 1);
2204 			if (fileformat == EOL_DOS)
2205 			{
2206 			    if (ptr > line_start && ptr[-1] == CAR)
2207 			    {
2208 				// remove CR before NL
2209 				ptr[-1] = NUL;
2210 				--len;
2211 			    }
2212 			    /*
2213 			     * Reading in Dos format, but no CR-LF found!
2214 			     * When 'fileformats' includes "unix", delete all
2215 			     * the lines read so far and start all over again.
2216 			     * Otherwise give an error message later.
2217 			     */
2218 			    else if (ff_error != EOL_DOS)
2219 			    {
2220 				if (   try_unix
2221 				    && !read_stdin
2222 				    && (read_buffer
2223 					|| vim_lseek(fd, (off_T)0L, SEEK_SET)
2224 									  == 0))
2225 				{
2226 				    fileformat = EOL_UNIX;
2227 				    if (set_options)
2228 					set_fileformat(EOL_UNIX, OPT_LOCAL);
2229 				    file_rewind = TRUE;
2230 				    keep_fileformat = TRUE;
2231 				    goto retry;
2232 				}
2233 				ff_error = EOL_DOS;
2234 			    }
2235 			}
2236 			if (ml_append(lnum, line_start, len, newfile) == FAIL)
2237 			{
2238 			    error = TRUE;
2239 			    break;
2240 			}
2241 #ifdef FEAT_PERSISTENT_UNDO
2242 			if (read_undo_file)
2243 			    sha256_update(&sha_ctx, line_start, len);
2244 #endif
2245 			++lnum;
2246 			if (--read_count == 0)
2247 			{
2248 			    error = TRUE;	    // break loop
2249 			    line_start = ptr;	// nothing left to write
2250 			    break;
2251 			}
2252 		    }
2253 		    else
2254 			--skip_count;
2255 		    line_start = ptr + 1;
2256 		}
2257 	    }
2258 	}
2259 	linerest = (long)(ptr - line_start);
2260 	ui_breakcheck();
2261     }
2262 
2263 failed:
2264     // not an error, max. number of lines reached
2265     if (error && read_count == 0)
2266 	error = FALSE;
2267 
2268     /*
2269      * If we get EOF in the middle of a line, note the fact and
2270      * complete the line ourselves.
2271      * In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
2272      */
2273     if (!error
2274 	    && !got_int
2275 	    && linerest != 0
2276 	    && !(!curbuf->b_p_bin
2277 		&& fileformat == EOL_DOS
2278 		&& *line_start == Ctrl_Z
2279 		&& ptr == line_start + 1))
2280     {
2281 	// remember for when writing
2282 	if (set_options)
2283 	    curbuf->b_p_eol = FALSE;
2284 	*ptr = NUL;
2285 	len = (colnr_T)(ptr - line_start + 1);
2286 	if (ml_append(lnum, line_start, len, newfile) == FAIL)
2287 	    error = TRUE;
2288 	else
2289 	{
2290 #ifdef FEAT_PERSISTENT_UNDO
2291 	    if (read_undo_file)
2292 		sha256_update(&sha_ctx, line_start, len);
2293 #endif
2294 	    read_no_eol_lnum = ++lnum;
2295 	}
2296     }
2297 
2298     if (set_options)
2299 	save_file_ff(curbuf);		// remember the current file format
2300 
2301 #ifdef FEAT_CRYPT
2302     if (curbuf->b_cryptstate != NULL)
2303     {
2304 	crypt_free_state(curbuf->b_cryptstate);
2305 	curbuf->b_cryptstate = NULL;
2306     }
2307     if (cryptkey != NULL && cryptkey != curbuf->b_p_key)
2308 	crypt_free_key(cryptkey);
2309     // Don't set cryptkey to NULL, it's used below as a flag that
2310     // encryption was used.
2311 #endif
2312 
2313     // If editing a new file: set 'fenc' for the current buffer.
2314     // Also for ":read ++edit file".
2315     if (set_options)
2316 	set_string_option_direct((char_u *)"fenc", -1, fenc,
2317 						       OPT_FREE|OPT_LOCAL, 0);
2318     if (fenc_alloced)
2319 	vim_free(fenc);
2320 #ifdef USE_ICONV
2321     if (iconv_fd != (iconv_t)-1)
2322 	iconv_close(iconv_fd);
2323 #endif
2324 
2325     if (!read_buffer && !read_stdin)
2326 	close(fd);				// errors are ignored
2327 #ifdef HAVE_FD_CLOEXEC
2328     else
2329     {
2330 	int fdflags = fcntl(fd, F_GETFD);
2331 
2332 	if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
2333 	    (void)fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);
2334     }
2335 #endif
2336     vim_free(buffer);
2337 
2338 #ifdef HAVE_DUP
2339     if (read_stdin)
2340     {
2341 	// Use stderr for stdin, makes shell commands work.
2342 	close(0);
2343 	vim_ignored = dup(2);
2344     }
2345 #endif
2346 
2347     if (tmpname != NULL)
2348     {
2349 	mch_remove(tmpname);		// delete converted file
2350 	vim_free(tmpname);
2351     }
2352     --no_wait_return;			// may wait for return now
2353 
2354     /*
2355      * In recovery mode everything but autocommands is skipped.
2356      */
2357     if (!recoverymode)
2358     {
2359 	// need to delete the last line, which comes from the empty buffer
2360 	if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY))
2361 	{
2362 #ifdef FEAT_NETBEANS_INTG
2363 	    netbeansFireChanges = 0;
2364 #endif
2365 	    ml_delete(curbuf->b_ml.ml_line_count);
2366 #ifdef FEAT_NETBEANS_INTG
2367 	    netbeansFireChanges = 1;
2368 #endif
2369 	    --linecnt;
2370 	}
2371 	linecnt = curbuf->b_ml.ml_line_count - linecnt;
2372 	if (filesize == 0)
2373 	    linecnt = 0;
2374 	if (newfile || read_buffer)
2375 	{
2376 	    redraw_curbuf_later(NOT_VALID);
2377 #ifdef FEAT_DIFF
2378 	    // After reading the text into the buffer the diff info needs to
2379 	    // be updated.
2380 	    diff_invalidate(curbuf);
2381 #endif
2382 #ifdef FEAT_FOLDING
2383 	    // All folds in the window are invalid now.  Mark them for update
2384 	    // before triggering autocommands.
2385 	    foldUpdateAll(curwin);
2386 #endif
2387 	}
2388 	else if (linecnt)		// appended at least one line
2389 	    appended_lines_mark(from, linecnt);
2390 
2391 #ifndef ALWAYS_USE_GUI
2392 	/*
2393 	 * If we were reading from the same terminal as where messages go,
2394 	 * the screen will have been messed up.
2395 	 * Switch on raw mode now and clear the screen.
2396 	 */
2397 	if (read_stdin)
2398 	{
2399 	    settmode(TMODE_RAW);	// set to raw mode
2400 	    starttermcap();
2401 	    screenclear();
2402 	}
2403 #endif
2404 
2405 	if (got_int)
2406 	{
2407 	    if (!(flags & READ_DUMMY))
2408 	    {
2409 		filemess(curbuf, sfname, (char_u *)_(e_interr), 0);
2410 		if (newfile)
2411 		    curbuf->b_p_ro = TRUE;	// must use "w!" now
2412 	    }
2413 	    msg_scroll = msg_save;
2414 #ifdef FEAT_VIMINFO
2415 	    check_marks_read();
2416 #endif
2417 	    return OK;		// an interrupt isn't really an error
2418 	}
2419 
2420 	if (!filtering && !(flags & READ_DUMMY))
2421 	{
2422 	    msg_add_fname(curbuf, sfname);   // fname in IObuff with quotes
2423 	    c = FALSE;
2424 
2425 #ifdef UNIX
2426 	    if (S_ISFIFO(perm))			    // fifo
2427 	    {
2428 		STRCAT(IObuff, _("[fifo]"));
2429 		c = TRUE;
2430 	    }
2431 	    if (S_ISSOCK(perm))			    // or socket
2432 	    {
2433 		STRCAT(IObuff, _("[socket]"));
2434 		c = TRUE;
2435 	    }
2436 # ifdef OPEN_CHR_FILES
2437 	    if (S_ISCHR(perm))			    // or character special
2438 	    {
2439 		STRCAT(IObuff, _("[character special]"));
2440 		c = TRUE;
2441 	    }
2442 # endif
2443 #endif
2444 	    if (curbuf->b_p_ro)
2445 	    {
2446 		STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"));
2447 		c = TRUE;
2448 	    }
2449 	    if (read_no_eol_lnum)
2450 	    {
2451 		msg_add_eol();
2452 		c = TRUE;
2453 	    }
2454 	    if (ff_error == EOL_DOS)
2455 	    {
2456 		STRCAT(IObuff, _("[CR missing]"));
2457 		c = TRUE;
2458 	    }
2459 	    if (split)
2460 	    {
2461 		STRCAT(IObuff, _("[long lines split]"));
2462 		c = TRUE;
2463 	    }
2464 	    if (notconverted)
2465 	    {
2466 		STRCAT(IObuff, _("[NOT converted]"));
2467 		c = TRUE;
2468 	    }
2469 	    else if (converted)
2470 	    {
2471 		STRCAT(IObuff, _("[converted]"));
2472 		c = TRUE;
2473 	    }
2474 #ifdef FEAT_CRYPT
2475 	    if (cryptkey != NULL)
2476 	    {
2477 		crypt_append_msg(curbuf);
2478 		c = TRUE;
2479 	    }
2480 #endif
2481 	    if (conv_error != 0)
2482 	    {
2483 		sprintf((char *)IObuff + STRLEN(IObuff),
2484 		       _("[CONVERSION ERROR in line %ld]"), (long)conv_error);
2485 		c = TRUE;
2486 	    }
2487 	    else if (illegal_byte > 0)
2488 	    {
2489 		sprintf((char *)IObuff + STRLEN(IObuff),
2490 			 _("[ILLEGAL BYTE in line %ld]"), (long)illegal_byte);
2491 		c = TRUE;
2492 	    }
2493 	    else if (error)
2494 	    {
2495 		STRCAT(IObuff, _("[READ ERRORS]"));
2496 		c = TRUE;
2497 	    }
2498 	    if (msg_add_fileformat(fileformat))
2499 		c = TRUE;
2500 #ifdef FEAT_CRYPT
2501 	    if (cryptkey != NULL)
2502 		msg_add_lines(c, (long)linecnt, filesize
2503 			 - crypt_get_header_len(crypt_get_method_nr(curbuf)));
2504 	    else
2505 #endif
2506 		msg_add_lines(c, (long)linecnt, filesize);
2507 
2508 	    VIM_CLEAR(keep_msg);
2509 	    msg_scrolled_ign = TRUE;
2510 #ifdef ALWAYS_USE_GUI
2511 	    // Don't show the message when reading stdin, it would end up in a
2512 	    // message box (which might be shown when exiting!)
2513 	    if (read_stdin || read_buffer)
2514 		p = msg_may_trunc(FALSE, IObuff);
2515 	    else
2516 #endif
2517 	    {
2518 		if (msg_col > 0)
2519 		    msg_putchar('\r');  // overwrite previous message
2520 		p = (char_u *)msg_trunc_attr((char *)IObuff, FALSE, 0);
2521 	    }
2522 	    if (read_stdin || read_buffer || restart_edit != 0
2523 		    || (msg_scrolled != 0 && !need_wait_return))
2524 		// Need to repeat the message after redrawing when:
2525 		// - When reading from stdin (the screen will be cleared next).
2526 		// - When restart_edit is set (otherwise there will be a delay
2527 		//   before redrawing).
2528 		// - When the screen was scrolled but there is no wait-return
2529 		//   prompt.
2530 		set_keep_msg(p, 0);
2531 	    msg_scrolled_ign = FALSE;
2532 	}
2533 
2534 	// with errors writing the file requires ":w!"
2535 	if (newfile && (error
2536 		    || conv_error != 0
2537 		    || (illegal_byte > 0 && bad_char_behavior != BAD_KEEP)))
2538 	    curbuf->b_p_ro = TRUE;
2539 
2540 	u_clearline();	    // cannot use "U" command after adding lines
2541 
2542 	/*
2543 	 * In Ex mode: cursor at last new line.
2544 	 * Otherwise: cursor at first new line.
2545 	 */
2546 	if (exmode_active)
2547 	    curwin->w_cursor.lnum = from + linecnt;
2548 	else
2549 	    curwin->w_cursor.lnum = from + 1;
2550 	check_cursor_lnum();
2551 	beginline(BL_WHITE | BL_FIX);	    // on first non-blank
2552 
2553 	if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0)
2554 	{
2555 	    // Set '[ and '] marks to the newly read lines.
2556 	    curbuf->b_op_start.lnum = from + 1;
2557 	    curbuf->b_op_start.col = 0;
2558 	    curbuf->b_op_end.lnum = from + linecnt;
2559 	    curbuf->b_op_end.col = 0;
2560 	}
2561 
2562 #ifdef MSWIN
2563 	/*
2564 	 * Work around a weird problem: When a file has two links (only
2565 	 * possible on NTFS) and we write through one link, then stat() it
2566 	 * through the other link, the timestamp information may be wrong.
2567 	 * It's correct again after reading the file, thus reset the timestamp
2568 	 * here.
2569 	 */
2570 	if (newfile && !read_stdin && !read_buffer
2571 					 && mch_stat((char *)fname, &st) >= 0)
2572 	{
2573 	    buf_store_time(curbuf, &st, fname);
2574 	    curbuf->b_mtime_read = curbuf->b_mtime;
2575 	    curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
2576 	}
2577 #endif
2578     }
2579     msg_scroll = msg_save;
2580 
2581 #ifdef FEAT_VIMINFO
2582     /*
2583      * Get the marks before executing autocommands, so they can be used there.
2584      */
2585     check_marks_read();
2586 #endif
2587 
2588     /*
2589      * We remember if the last line of the read didn't have
2590      * an eol even when 'binary' is off, to support turning 'fixeol' off,
2591      * or writing the read again with 'binary' on.  The latter is required
2592      * for ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
2593      */
2594     curbuf->b_no_eol_lnum = read_no_eol_lnum;
2595 
2596     // When reloading a buffer put the cursor at the first line that is
2597     // different.
2598     if (flags & READ_KEEP_UNDO)
2599 	u_find_first_changed();
2600 
2601 #ifdef FEAT_PERSISTENT_UNDO
2602     /*
2603      * When opening a new file locate undo info and read it.
2604      */
2605     if (read_undo_file)
2606     {
2607 	char_u	hash[UNDO_HASH_SIZE];
2608 
2609 	sha256_finish(&sha_ctx, hash);
2610 	u_read_undo(NULL, hash, fname);
2611     }
2612 #endif
2613 
2614     if (!read_stdin && !read_fifo && (!read_buffer || sfname != NULL))
2615     {
2616 	int m = msg_scroll;
2617 	int n = msg_scrolled;
2618 
2619 	// Save the fileformat now, otherwise the buffer will be considered
2620 	// modified if the format/encoding was automatically detected.
2621 	if (set_options)
2622 	    save_file_ff(curbuf);
2623 
2624 	/*
2625 	 * The output from the autocommands should not overwrite anything and
2626 	 * should not be overwritten: Set msg_scroll, restore its value if no
2627 	 * output was done.
2628 	 */
2629 	msg_scroll = TRUE;
2630 	if (filtering)
2631 	    apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
2632 							  FALSE, curbuf, eap);
2633 	else if (newfile || (read_buffer && sfname != NULL))
2634 	{
2635 	    apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
2636 							  FALSE, curbuf, eap);
2637 	    if (!au_did_filetype && *curbuf->b_p_ft != NUL)
2638 		/*
2639 		 * EVENT_FILETYPE was not triggered but the buffer already has a
2640 		 * filetype. Trigger EVENT_FILETYPE using the existing filetype.
2641 		 */
2642 		apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname,
2643 			TRUE, curbuf);
2644 	}
2645 	else
2646 	    apply_autocmds_exarg(EVENT_FILEREADPOST, sfname, sfname,
2647 							    FALSE, NULL, eap);
2648 	if (msg_scrolled == n)
2649 	    msg_scroll = m;
2650 # ifdef FEAT_EVAL
2651 	if (aborting())	    // autocmds may abort script processing
2652 	    return FAIL;
2653 # endif
2654     }
2655 
2656     if (recoverymode && error)
2657 	return FAIL;
2658     return OK;
2659 }
2660 
2661 #if defined(OPEN_CHR_FILES) || defined(PROTO)
2662 /*
2663  * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+",
2664  * which is the name of files used for process substitution output by
2665  * some shells on some operating systems, e.g., bash on SunOS.
2666  * Do not accept "/dev/fd/[012]", opening these may hang Vim.
2667  */
2668     int
is_dev_fd_file(char_u * fname)2669 is_dev_fd_file(char_u *fname)
2670 {
2671     return (STRNCMP(fname, "/dev/fd/", 8) == 0
2672 	    && VIM_ISDIGIT(fname[8])
2673 	    && *skipdigits(fname + 9) == NUL
2674 	    && (fname[9] != NUL
2675 		|| (fname[8] != '0' && fname[8] != '1' && fname[8] != '2')));
2676 }
2677 #endif
2678 
2679 /*
2680  * From the current line count and characters read after that, estimate the
2681  * line number where we are now.
2682  * Used for error messages that include a line number.
2683  */
2684     static linenr_T
readfile_linenr(linenr_T linecnt,char_u * p,char_u * endp)2685 readfile_linenr(
2686     linenr_T	linecnt,	// line count before reading more bytes
2687     char_u	*p,		// start of more bytes read
2688     char_u	*endp)		// end of more bytes read
2689 {
2690     char_u	*s;
2691     linenr_T	lnum;
2692 
2693     lnum = curbuf->b_ml.ml_line_count - linecnt + 1;
2694     for (s = p; s < endp; ++s)
2695 	if (*s == '\n')
2696 	    ++lnum;
2697     return lnum;
2698 }
2699 
2700 /*
2701  * Fill "*eap" to force the 'fileencoding', 'fileformat' and 'binary to be
2702  * equal to the buffer "buf".  Used for calling readfile().
2703  * Returns OK or FAIL.
2704  */
2705     int
prep_exarg(exarg_T * eap,buf_T * buf)2706 prep_exarg(exarg_T *eap, buf_T *buf)
2707 {
2708     eap->cmd = alloc(15 + (unsigned)STRLEN(buf->b_p_fenc));
2709     if (eap->cmd == NULL)
2710 	return FAIL;
2711 
2712     sprintf((char *)eap->cmd, "e ++enc=%s", buf->b_p_fenc);
2713     eap->force_enc = 8;
2714     eap->bad_char = buf->b_bad_char;
2715     eap->force_ff = *buf->b_p_ff;
2716 
2717     eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
2718     eap->read_edit = FALSE;
2719     eap->forceit = FALSE;
2720     return OK;
2721 }
2722 
2723 /*
2724  * Set default or forced 'fileformat' and 'binary'.
2725  */
2726     void
set_file_options(int set_options,exarg_T * eap)2727 set_file_options(int set_options, exarg_T *eap)
2728 {
2729     // set default 'fileformat'
2730     if (set_options)
2731     {
2732 	if (eap != NULL && eap->force_ff != 0)
2733 	    set_fileformat(get_fileformat_force(curbuf, eap), OPT_LOCAL);
2734 	else if (*p_ffs != NUL)
2735 	    set_fileformat(default_fileformat(), OPT_LOCAL);
2736     }
2737 
2738     // set or reset 'binary'
2739     if (eap != NULL && eap->force_bin != 0)
2740     {
2741 	int	oldval = curbuf->b_p_bin;
2742 
2743 	curbuf->b_p_bin = (eap->force_bin == FORCE_BIN);
2744 	set_options_bin(oldval, curbuf->b_p_bin, OPT_LOCAL);
2745     }
2746 }
2747 
2748 /*
2749  * Set forced 'fileencoding'.
2750  */
2751     void
set_forced_fenc(exarg_T * eap)2752 set_forced_fenc(exarg_T *eap)
2753 {
2754     if (eap->force_enc != 0)
2755     {
2756 	char_u *fenc = enc_canonize(eap->cmd + eap->force_enc);
2757 
2758 	if (fenc != NULL)
2759 	    set_string_option_direct((char_u *)"fenc", -1,
2760 				 fenc, OPT_FREE|OPT_LOCAL, 0);
2761 	vim_free(fenc);
2762     }
2763 }
2764 
2765 /*
2766  * Find next fileencoding to use from 'fileencodings'.
2767  * "pp" points to fenc_next.  It's advanced to the next item.
2768  * When there are no more items, an empty string is returned and *pp is set to
2769  * NULL.
2770  * When *pp is not set to NULL, the result is in allocated memory and "alloced"
2771  * is set to TRUE.
2772  */
2773     static char_u *
next_fenc(char_u ** pp,int * alloced)2774 next_fenc(char_u **pp, int *alloced)
2775 {
2776     char_u	*p;
2777     char_u	*r;
2778 
2779     *alloced = FALSE;
2780     if (**pp == NUL)
2781     {
2782 	*pp = NULL;
2783 	return (char_u *)"";
2784     }
2785     p = vim_strchr(*pp, ',');
2786     if (p == NULL)
2787     {
2788 	r = enc_canonize(*pp);
2789 	*pp += STRLEN(*pp);
2790     }
2791     else
2792     {
2793 	r = vim_strnsave(*pp, p - *pp);
2794 	*pp = p + 1;
2795 	if (r != NULL)
2796 	{
2797 	    p = enc_canonize(r);
2798 	    vim_free(r);
2799 	    r = p;
2800 	}
2801     }
2802     if (r != NULL)
2803 	*alloced = TRUE;
2804     else
2805     {
2806 	// out of memory
2807 	r = (char_u *)"";
2808 	*pp = NULL;
2809     }
2810     return r;
2811 }
2812 
2813 #ifdef FEAT_EVAL
2814 /*
2815  * Convert a file with the 'charconvert' expression.
2816  * This closes the file which is to be read, converts it and opens the
2817  * resulting file for reading.
2818  * Returns name of the resulting converted file (the caller should delete it
2819  * after reading it).
2820  * Returns NULL if the conversion failed ("*fdp" is not set) .
2821  */
2822     static char_u *
readfile_charconvert(char_u * fname,char_u * fenc,int * fdp)2823 readfile_charconvert(
2824     char_u	*fname,		// name of input file
2825     char_u	*fenc,		// converted from
2826     int		*fdp)		// in/out: file descriptor of file
2827 {
2828     char_u	*tmpname;
2829     char	*errmsg = NULL;
2830 
2831     tmpname = vim_tempname('r', FALSE);
2832     if (tmpname == NULL)
2833 	errmsg = _("Can't find temp file for conversion");
2834     else
2835     {
2836 	close(*fdp);		// close the input file, ignore errors
2837 	*fdp = -1;
2838 	if (eval_charconvert(fenc, enc_utf8 ? (char_u *)"utf-8" : p_enc,
2839 						      fname, tmpname) == FAIL)
2840 	    errmsg = _("Conversion with 'charconvert' failed");
2841 	if (errmsg == NULL && (*fdp = mch_open((char *)tmpname,
2842 						  O_RDONLY | O_EXTRA, 0)) < 0)
2843 	    errmsg = _("can't read output of 'charconvert'");
2844     }
2845 
2846     if (errmsg != NULL)
2847     {
2848 	// Don't use emsg(), it breaks mappings, the retry with
2849 	// another type of conversion might still work.
2850 	msg(errmsg);
2851 	if (tmpname != NULL)
2852 	{
2853 	    mch_remove(tmpname);	// delete converted file
2854 	    VIM_CLEAR(tmpname);
2855 	}
2856     }
2857 
2858     // If the input file is closed, open it (caller should check for error).
2859     if (*fdp < 0)
2860 	*fdp = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
2861 
2862     return tmpname;
2863 }
2864 #endif
2865 
2866 #if defined(FEAT_CRYPT) || defined(PROTO)
2867 /*
2868  * Check for magic number used for encryption.  Applies to the current buffer.
2869  * If found, the magic number is removed from ptr[*sizep] and *sizep and
2870  * *filesizep are updated.
2871  * Return the (new) encryption key, NULL for no encryption.
2872  */
2873     static char_u *
check_for_cryptkey(char_u * cryptkey,char_u * ptr,long * sizep,off_T * filesizep,int newfile,char_u * fname,int * did_ask)2874 check_for_cryptkey(
2875     char_u	*cryptkey,	// previous encryption key or NULL
2876     char_u	*ptr,		// pointer to read bytes
2877     long	*sizep,		// length of read bytes
2878     off_T	*filesizep,	// nr of bytes used from file
2879     int		newfile,	// editing a new buffer
2880     char_u	*fname,		// file name to display
2881     int		*did_ask)	// flag: whether already asked for key
2882 {
2883     int method = crypt_method_nr_from_magic((char *)ptr, *sizep);
2884     int b_p_ro = curbuf->b_p_ro;
2885 
2886     if (method >= 0)
2887     {
2888 	// Mark the buffer as read-only until the decryption has taken place.
2889 	// Avoids accidentally overwriting the file with garbage.
2890 	curbuf->b_p_ro = TRUE;
2891 
2892 	// Set the cryptmethod local to the buffer.
2893 	crypt_set_cm_option(curbuf, method);
2894 	if (cryptkey == NULL && !*did_ask)
2895 	{
2896 	    if (*curbuf->b_p_key)
2897 		cryptkey = curbuf->b_p_key;
2898 	    else
2899 	    {
2900 		// When newfile is TRUE, store the typed key in the 'key'
2901 		// option and don't free it.  bf needs hash of the key saved.
2902 		// Don't ask for the key again when first time Enter was hit.
2903 		// Happens when retrying to detect encoding.
2904 		smsg(_(need_key_msg), fname);
2905 		msg_scroll = TRUE;
2906 		crypt_check_method(method);
2907 		cryptkey = crypt_get_key(newfile, FALSE);
2908 		*did_ask = TRUE;
2909 
2910 		// check if empty key entered
2911 		if (cryptkey != NULL && *cryptkey == NUL)
2912 		{
2913 		    if (cryptkey != curbuf->b_p_key)
2914 			vim_free(cryptkey);
2915 		    cryptkey = NULL;
2916 		}
2917 	    }
2918 	}
2919 
2920 	if (cryptkey != NULL)
2921 	{
2922 	    int header_len;
2923 
2924 	    header_len = crypt_get_header_len(method);
2925 	    if (*sizep <= header_len)
2926 		// invalid header, buffer can't be encrypted
2927 		return NULL;
2928 
2929 	    curbuf->b_cryptstate = crypt_create_from_header(
2930 							method, cryptkey, ptr);
2931 	    crypt_set_cm_option(curbuf, method);
2932 
2933 	    // Remove cryptmethod specific header from the text.
2934 	    *filesizep += header_len;
2935 	    *sizep -= header_len;
2936 	    mch_memmove(ptr, ptr + header_len, (size_t)*sizep);
2937 
2938 	    // Restore the read-only flag.
2939 	    curbuf->b_p_ro = b_p_ro;
2940 	}
2941     }
2942     // When starting to edit a new file which does not have encryption, clear
2943     // the 'key' option, except when starting up (called with -x argument)
2944     else if (newfile && *curbuf->b_p_key != NUL && !starting)
2945 	set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
2946 
2947     return cryptkey;
2948 }
2949 #endif  // FEAT_CRYPT
2950 
2951 /*
2952  * Return TRUE if a file appears to be read-only from the file permissions.
2953  */
2954     int
check_file_readonly(char_u * fname,int perm UNUSED)2955 check_file_readonly(
2956     char_u	*fname,		// full path to file
2957     int		perm UNUSED)	// known permissions on file
2958 {
2959 #ifndef USE_MCH_ACCESS
2960     int	    fd = 0;
2961 #endif
2962 
2963     return (
2964 #ifdef USE_MCH_ACCESS
2965 # ifdef UNIX
2966 	(perm & 0222) == 0 ||
2967 # endif
2968 	mch_access((char *)fname, W_OK)
2969 #else
2970 	(fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
2971 					? TRUE : (close(fd), FALSE)
2972 #endif
2973 	);
2974 }
2975 
2976 #if defined(HAVE_FSYNC) || defined(PROTO)
2977 /*
2978  * Call fsync() with Mac-specific exception.
2979  * Return fsync() result: zero for success.
2980  */
2981     int
vim_fsync(int fd)2982 vim_fsync(int fd)
2983 {
2984     int r;
2985 
2986 # ifdef MACOS_X
2987     r = fcntl(fd, F_FULLFSYNC);
2988     if (r != 0)  // F_FULLFSYNC not working or not supported
2989 # endif
2990 	r = fsync(fd);
2991     return r;
2992 }
2993 #endif
2994 
2995 /*
2996  * Set the name of the current buffer.  Use when the buffer doesn't have a
2997  * name and a ":r" or ":w" command with a file name is used.
2998  */
2999     int
set_rw_fname(char_u * fname,char_u * sfname)3000 set_rw_fname(char_u *fname, char_u *sfname)
3001 {
3002     buf_T	*buf = curbuf;
3003 
3004     // It's like the unnamed buffer is deleted....
3005     if (curbuf->b_p_bl)
3006 	apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
3007     apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
3008 #ifdef FEAT_EVAL
3009     if (aborting())	    // autocmds may abort script processing
3010 	return FAIL;
3011 #endif
3012     if (curbuf != buf)
3013     {
3014 	// We are in another buffer now, don't do the renaming.
3015 	emsg(_(e_auchangedbuf));
3016 	return FAIL;
3017     }
3018 
3019     if (setfname(curbuf, fname, sfname, FALSE) == OK)
3020 	curbuf->b_flags |= BF_NOTEDITED;
3021 
3022     // ....and a new named one is created
3023     apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf);
3024     if (curbuf->b_p_bl)
3025 	apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf);
3026 #ifdef FEAT_EVAL
3027     if (aborting())	    // autocmds may abort script processing
3028 	return FAIL;
3029 #endif
3030 
3031     // Do filetype detection now if 'filetype' is empty.
3032     if (*curbuf->b_p_ft == NUL)
3033     {
3034 	if (au_has_group((char_u *)"filetypedetect"))
3035 	    (void)do_doautocmd((char_u *)"filetypedetect BufRead", FALSE, NULL);
3036 	do_modelines(0);
3037     }
3038 
3039     return OK;
3040 }
3041 
3042 /*
3043  * Put file name into IObuff with quotes.
3044  */
3045     void
msg_add_fname(buf_T * buf,char_u * fname)3046 msg_add_fname(buf_T *buf, char_u *fname)
3047 {
3048     if (fname == NULL)
3049 	fname = (char_u *)"-stdin-";
3050     home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE);
3051     IObuff[0] = '"';
3052     STRCAT(IObuff, "\" ");
3053 }
3054 
3055 /*
3056  * Append message for text mode to IObuff.
3057  * Return TRUE if something appended.
3058  */
3059     int
msg_add_fileformat(int eol_type)3060 msg_add_fileformat(int eol_type)
3061 {
3062 #ifndef USE_CRNL
3063     if (eol_type == EOL_DOS)
3064     {
3065 	STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]"));
3066 	return TRUE;
3067     }
3068 #endif
3069     if (eol_type == EOL_MAC)
3070     {
3071 	STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]"));
3072 	return TRUE;
3073     }
3074 #ifdef USE_CRNL
3075     if (eol_type == EOL_UNIX)
3076     {
3077 	STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]"));
3078 	return TRUE;
3079     }
3080 #endif
3081     return FALSE;
3082 }
3083 
3084 /*
3085  * Append line and character count to IObuff.
3086  */
3087     void
msg_add_lines(int insert_space,long lnum,off_T nchars)3088 msg_add_lines(
3089     int	    insert_space,
3090     long    lnum,
3091     off_T   nchars)
3092 {
3093     char_u  *p;
3094 
3095     p = IObuff + STRLEN(IObuff);
3096 
3097     if (insert_space)
3098 	*p++ = ' ';
3099     if (shortmess(SHM_LINES))
3100 	vim_snprintf((char *)p, IOSIZE - (p - IObuff),
3101 		"%ldL, %lldB", lnum, (varnumber_T)nchars);
3102     else
3103     {
3104 	sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
3105 	p += STRLEN(p);
3106 	vim_snprintf((char *)p, IOSIZE - (p - IObuff),
3107 		NGETTEXT("%lld byte", "%lld bytes", nchars),
3108 		(varnumber_T)nchars);
3109     }
3110 }
3111 
3112 /*
3113  * Append message for missing line separator to IObuff.
3114  */
3115     void
msg_add_eol(void)3116 msg_add_eol(void)
3117 {
3118     STRCAT(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
3119 }
3120 
3121     int
time_differs(stat_T * st,long mtime,long mtime_ns UNUSED)3122 time_differs(stat_T *st, long mtime, long mtime_ns UNUSED)
3123 {
3124     return
3125 #ifdef ST_MTIM_NSEC
3126 	(long)st->ST_MTIM_NSEC != mtime_ns ||
3127 #endif
3128 #if defined(__linux__) || defined(MSWIN)
3129 	// On a FAT filesystem, esp. under Linux, there are only 5 bits to store
3130 	// the seconds.  Since the roundoff is done when flushing the inode, the
3131 	// time may change unexpectedly by one second!!!
3132 	(long)st->st_mtime - mtime > 1 || mtime - (long)st->st_mtime > 1
3133 #else
3134 	(long)st->st_mtime != mtime
3135 #endif
3136 	;
3137 }
3138 
3139 /*
3140  * Return TRUE if file encoding "fenc" requires conversion from or to
3141  * 'encoding'.
3142  */
3143     int
need_conversion(char_u * fenc)3144 need_conversion(char_u *fenc)
3145 {
3146     int		same_encoding;
3147     int		enc_flags;
3148     int		fenc_flags;
3149 
3150     if (*fenc == NUL || STRCMP(p_enc, fenc) == 0)
3151     {
3152 	same_encoding = TRUE;
3153 	fenc_flags = 0;
3154     }
3155     else
3156     {
3157 	// Ignore difference between "ansi" and "latin1", "ucs-4" and
3158 	// "ucs-4be", etc.
3159 	enc_flags = get_fio_flags(p_enc);
3160 	fenc_flags = get_fio_flags(fenc);
3161 	same_encoding = (enc_flags != 0 && fenc_flags == enc_flags);
3162     }
3163     if (same_encoding)
3164     {
3165 	// Specified encoding matches with 'encoding'.  This requires
3166 	// conversion when 'encoding' is Unicode but not UTF-8.
3167 	return enc_unicode != 0;
3168     }
3169 
3170     // Encodings differ.  However, conversion is not needed when 'enc' is any
3171     // Unicode encoding and the file is UTF-8.
3172     return !(enc_utf8 && fenc_flags == FIO_UTF8);
3173 }
3174 
3175 /*
3176  * Check "ptr" for a unicode encoding and return the FIO_ flags needed for the
3177  * internal conversion.
3178  * if "ptr" is an empty string, use 'encoding'.
3179  */
3180     int
get_fio_flags(char_u * ptr)3181 get_fio_flags(char_u *ptr)
3182 {
3183     int		prop;
3184 
3185     if (*ptr == NUL)
3186 	ptr = p_enc;
3187 
3188     prop = enc_canon_props(ptr);
3189     if (prop & ENC_UNICODE)
3190     {
3191 	if (prop & ENC_2BYTE)
3192 	{
3193 	    if (prop & ENC_ENDIAN_L)
3194 		return FIO_UCS2 | FIO_ENDIAN_L;
3195 	    return FIO_UCS2;
3196 	}
3197 	if (prop & ENC_4BYTE)
3198 	{
3199 	    if (prop & ENC_ENDIAN_L)
3200 		return FIO_UCS4 | FIO_ENDIAN_L;
3201 	    return FIO_UCS4;
3202 	}
3203 	if (prop & ENC_2WORD)
3204 	{
3205 	    if (prop & ENC_ENDIAN_L)
3206 		return FIO_UTF16 | FIO_ENDIAN_L;
3207 	    return FIO_UTF16;
3208 	}
3209 	return FIO_UTF8;
3210     }
3211     if (prop & ENC_LATIN1)
3212 	return FIO_LATIN1;
3213     // must be ENC_DBCS, requires iconv()
3214     return 0;
3215 }
3216 
3217 #if defined(MSWIN) || defined(PROTO)
3218 /*
3219  * Check "ptr" for a MS-Windows codepage name and return the FIO_ flags needed
3220  * for the conversion MS-Windows can do for us.  Also accept "utf-8".
3221  * Used for conversion between 'encoding' and 'fileencoding'.
3222  */
3223     int
get_win_fio_flags(char_u * ptr)3224 get_win_fio_flags(char_u *ptr)
3225 {
3226     int		cp;
3227 
3228     // Cannot do this when 'encoding' is not utf-8 and not a codepage.
3229     if (!enc_utf8 && enc_codepage <= 0)
3230 	return 0;
3231 
3232     cp = encname2codepage(ptr);
3233     if (cp == 0)
3234     {
3235 #  ifdef CP_UTF8	// VC 4.1 doesn't define CP_UTF8
3236 	if (STRCMP(ptr, "utf-8") == 0)
3237 	    cp = CP_UTF8;
3238 	else
3239 #  endif
3240 	    return 0;
3241     }
3242     return FIO_PUT_CP(cp) | FIO_CODEPAGE;
3243 }
3244 #endif
3245 
3246 #if defined(MACOS_CONVERT) || defined(PROTO)
3247 /*
3248  * Check "ptr" for a Carbon supported encoding and return the FIO_ flags
3249  * needed for the internal conversion to/from utf-8 or latin1.
3250  */
3251     int
get_mac_fio_flags(char_u * ptr)3252 get_mac_fio_flags(char_u *ptr)
3253 {
3254     if ((enc_utf8 || STRCMP(p_enc, "latin1") == 0)
3255 				     && (enc_canon_props(ptr) & ENC_MACROMAN))
3256 	return FIO_MACROMAN;
3257     return 0;
3258 }
3259 #endif
3260 
3261 /*
3262  * Check for a Unicode BOM (Byte Order Mark) at the start of p[size].
3263  * "size" must be at least 2.
3264  * Return the name of the encoding and set "*lenp" to the length.
3265  * Returns NULL when no BOM found.
3266  */
3267     static char_u *
check_for_bom(char_u * p,long size,int * lenp,int flags)3268 check_for_bom(
3269     char_u	*p,
3270     long	size,
3271     int		*lenp,
3272     int		flags)
3273 {
3274     char	*name = NULL;
3275     int		len = 2;
3276 
3277     if (p[0] == 0xef && p[1] == 0xbb && size >= 3 && p[2] == 0xbf
3278 	    && (flags == FIO_ALL || flags == FIO_UTF8 || flags == 0))
3279     {
3280 	name = "utf-8";		// EF BB BF
3281 	len = 3;
3282     }
3283     else if (p[0] == 0xff && p[1] == 0xfe)
3284     {
3285 	if (size >= 4 && p[2] == 0 && p[3] == 0
3286 	    && (flags == FIO_ALL || flags == (FIO_UCS4 | FIO_ENDIAN_L)))
3287 	{
3288 	    name = "ucs-4le";	// FF FE 00 00
3289 	    len = 4;
3290 	}
3291 	else if (flags == (FIO_UCS2 | FIO_ENDIAN_L))
3292 	    name = "ucs-2le";	// FF FE
3293 	else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L))
3294 	    // utf-16le is preferred, it also works for ucs-2le text
3295 	    name = "utf-16le";	// FF FE
3296     }
3297     else if (p[0] == 0xfe && p[1] == 0xff
3298 	    && (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16))
3299     {
3300 	// Default to utf-16, it works also for ucs-2 text.
3301 	if (flags == FIO_UCS2)
3302 	    name = "ucs-2";	// FE FF
3303 	else
3304 	    name = "utf-16";	// FE FF
3305     }
3306     else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
3307 	    && p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4))
3308     {
3309 	name = "ucs-4";		// 00 00 FE FF
3310 	len = 4;
3311     }
3312 
3313     *lenp = len;
3314     return (char_u *)name;
3315 }
3316 
3317 /*
3318  * Try to find a shortname by comparing the fullname with the current
3319  * directory.
3320  * Returns "full_path" or pointer into "full_path" if shortened.
3321  */
3322     char_u *
shorten_fname1(char_u * full_path)3323 shorten_fname1(char_u *full_path)
3324 {
3325     char_u	*dirname;
3326     char_u	*p = full_path;
3327 
3328     dirname = alloc(MAXPATHL);
3329     if (dirname == NULL)
3330 	return full_path;
3331     if (mch_dirname(dirname, MAXPATHL) == OK)
3332     {
3333 	p = shorten_fname(full_path, dirname);
3334 	if (p == NULL || *p == NUL)
3335 	    p = full_path;
3336     }
3337     vim_free(dirname);
3338     return p;
3339 }
3340 
3341 /*
3342  * Try to find a shortname by comparing the fullname with the current
3343  * directory.
3344  * Returns NULL if not shorter name possible, pointer into "full_path"
3345  * otherwise.
3346  */
3347     char_u *
shorten_fname(char_u * full_path,char_u * dir_name)3348 shorten_fname(char_u *full_path, char_u *dir_name)
3349 {
3350     int		len;
3351     char_u	*p;
3352 
3353     if (full_path == NULL)
3354 	return NULL;
3355     len = (int)STRLEN(dir_name);
3356     if (fnamencmp(dir_name, full_path, len) == 0)
3357     {
3358 	p = full_path + len;
3359 #if defined(MSWIN)
3360 	/*
3361 	 * MS-Windows: when a file is in the root directory, dir_name will end
3362 	 * in a slash, since C: by itself does not define a specific dir. In
3363 	 * this case p may already be correct. <negri>
3364 	 */
3365 	if (!((len > 2) && (*(p - 2) == ':')))
3366 #endif
3367 	{
3368 	    if (vim_ispathsep(*p))
3369 		++p;
3370 #ifndef VMS   // the path separator is always part of the path
3371 	    else
3372 		p = NULL;
3373 #endif
3374 	}
3375     }
3376 #if defined(MSWIN)
3377     /*
3378      * When using a file in the current drive, remove the drive name:
3379      * "A:\dir\file" -> "\dir\file".  This helps when moving a session file on
3380      * a floppy from "A:\dir" to "B:\dir".
3381      */
3382     else if (len > 3
3383 	    && TOUPPER_LOC(full_path[0]) == TOUPPER_LOC(dir_name[0])
3384 	    && full_path[1] == ':'
3385 	    && vim_ispathsep(full_path[2]))
3386 	p = full_path + 2;
3387 #endif
3388     else
3389 	p = NULL;
3390     return p;
3391 }
3392 
3393 /*
3394  * Shorten filename of a buffer.
3395  * When "force" is TRUE: Use full path from now on for files currently being
3396  * edited, both for file name and swap file name.  Try to shorten the file
3397  * names a bit, if safe to do so.
3398  * When "force" is FALSE: Only try to shorten absolute file names.
3399  * For buffers that have buftype "nofile" or "scratch": never change the file
3400  * name.
3401  */
3402     void
shorten_buf_fname(buf_T * buf,char_u * dirname,int force)3403 shorten_buf_fname(buf_T *buf, char_u *dirname, int force)
3404 {
3405     char_u	*p;
3406 
3407     if (buf->b_fname != NULL
3408 #ifdef FEAT_QUICKFIX
3409 	    && !bt_nofilename(buf)
3410 #endif
3411 	    && !path_with_url(buf->b_fname)
3412 	    && (force
3413 		|| buf->b_sfname == NULL
3414 		|| mch_isFullName(buf->b_sfname)))
3415     {
3416 	if (buf->b_sfname != buf->b_ffname)
3417 	    VIM_CLEAR(buf->b_sfname);
3418 	p = shorten_fname(buf->b_ffname, dirname);
3419 	if (p != NULL)
3420 	{
3421 	    buf->b_sfname = vim_strsave(p);
3422 	    buf->b_fname = buf->b_sfname;
3423 	}
3424 	if (p == NULL || buf->b_fname == NULL)
3425 	    buf->b_fname = buf->b_ffname;
3426     }
3427 }
3428 
3429 /*
3430  * Shorten filenames for all buffers.
3431  */
3432     void
shorten_fnames(int force)3433 shorten_fnames(int force)
3434 {
3435     char_u	dirname[MAXPATHL];
3436     buf_T	*buf;
3437 
3438     mch_dirname(dirname, MAXPATHL);
3439     FOR_ALL_BUFFERS(buf)
3440     {
3441 	shorten_buf_fname(buf, dirname, force);
3442 
3443 	// Always make the swap file name a full path, a "nofile" buffer may
3444 	// also have a swap file.
3445 	mf_fullname(buf->b_ml.ml_mfp);
3446     }
3447     status_redraw_all();
3448     redraw_tabline = TRUE;
3449 #if defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX)
3450     popup_update_preview_title();
3451 #endif
3452 }
3453 
3454 #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
3455 	|| defined(FEAT_GUI_MSWIN) \
3456 	|| defined(FEAT_GUI_HAIKU) \
3457 	|| defined(PROTO)
3458 /*
3459  * Shorten all filenames in "fnames[count]" by current directory.
3460  */
3461     void
shorten_filenames(char_u ** fnames,int count)3462 shorten_filenames(char_u **fnames, int count)
3463 {
3464     int		i;
3465     char_u	dirname[MAXPATHL];
3466     char_u	*p;
3467 
3468     if (fnames == NULL || count < 1)
3469 	return;
3470     mch_dirname(dirname, sizeof(dirname));
3471     for (i = 0; i < count; ++i)
3472     {
3473 	if ((p = shorten_fname(fnames[i], dirname)) != NULL)
3474 	{
3475 	    // shorten_fname() returns pointer in given "fnames[i]".  If free
3476 	    // "fnames[i]" first, "p" becomes invalid.  So we need to copy
3477 	    // "p" first then free fnames[i].
3478 	    p = vim_strsave(p);
3479 	    vim_free(fnames[i]);
3480 	    fnames[i] = p;
3481 	}
3482     }
3483 }
3484 #endif
3485 
3486 /*
3487  * Add extension to file name - change path/fo.o.h to path/fo.o.h.ext or
3488  * fo_o_h.ext for MSDOS or when shortname option set.
3489  *
3490  * Assumed that fname is a valid name found in the filesystem we assure that
3491  * the return value is a different name and ends in 'ext'.
3492  * "ext" MUST be at most 4 characters long if it starts with a dot, 3
3493  * characters otherwise.
3494  * Space for the returned name is allocated, must be freed later.
3495  * Returns NULL when out of memory.
3496  */
3497     char_u *
modname(char_u * fname,char_u * ext,int prepend_dot)3498 modname(
3499     char_u *fname,
3500     char_u *ext,
3501     int	    prepend_dot)	// may prepend a '.' to file name
3502 {
3503     return buf_modname((curbuf->b_p_sn || curbuf->b_shortname),
3504 						     fname, ext, prepend_dot);
3505 }
3506 
3507     char_u *
buf_modname(int shortname,char_u * fname,char_u * ext,int prepend_dot)3508 buf_modname(
3509     int	    shortname,		// use 8.3 file name
3510     char_u  *fname,
3511     char_u  *ext,
3512     int	    prepend_dot)	// may prepend a '.' to file name
3513 {
3514     char_u	*retval;
3515     char_u	*s;
3516     char_u	*e;
3517     char_u	*ptr;
3518     int		fnamelen, extlen;
3519 
3520     extlen = (int)STRLEN(ext);
3521 
3522     /*
3523      * If there is no file name we must get the name of the current directory
3524      * (we need the full path in case :cd is used).
3525      */
3526     if (fname == NULL || *fname == NUL)
3527     {
3528 	retval = alloc(MAXPATHL + extlen + 3);
3529 	if (retval == NULL)
3530 	    return NULL;
3531 	if (mch_dirname(retval, MAXPATHL) == FAIL ||
3532 				     (fnamelen = (int)STRLEN(retval)) == 0)
3533 	{
3534 	    vim_free(retval);
3535 	    return NULL;
3536 	}
3537 	if (!after_pathsep(retval, retval + fnamelen))
3538 	{
3539 	    retval[fnamelen++] = PATHSEP;
3540 	    retval[fnamelen] = NUL;
3541 	}
3542 	prepend_dot = FALSE;	    // nothing to prepend a dot to
3543     }
3544     else
3545     {
3546 	fnamelen = (int)STRLEN(fname);
3547 	retval = alloc(fnamelen + extlen + 3);
3548 	if (retval == NULL)
3549 	    return NULL;
3550 	STRCPY(retval, fname);
3551 #ifdef VMS
3552 	vms_remove_version(retval); // we do not need versions here
3553 #endif
3554     }
3555 
3556     /*
3557      * search backwards until we hit a '/', '\' or ':' replacing all '.'
3558      * by '_' for MSDOS or when shortname option set and ext starts with a dot.
3559      * Then truncate what is after the '/', '\' or ':' to 8 characters for
3560      * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
3561      */
3562     for (ptr = retval + fnamelen; ptr > retval; MB_PTR_BACK(retval, ptr))
3563     {
3564 	if (*ext == '.' && shortname)
3565 	    if (*ptr == '.')	// replace '.' by '_'
3566 		*ptr = '_';
3567 	if (vim_ispathsep(*ptr))
3568 	{
3569 	    ++ptr;
3570 	    break;
3571 	}
3572     }
3573 
3574     // the file name has at most BASENAMELEN characters.
3575     if (STRLEN(ptr) > (unsigned)BASENAMELEN)
3576 	ptr[BASENAMELEN] = '\0';
3577 
3578     s = ptr + STRLEN(ptr);
3579 
3580     /*
3581      * For 8.3 file names we may have to reduce the length.
3582      */
3583     if (shortname)
3584     {
3585 	/*
3586 	 * If there is no file name, or the file name ends in '/', and the
3587 	 * extension starts with '.', put a '_' before the dot, because just
3588 	 * ".ext" is invalid.
3589 	 */
3590 	if (fname == NULL || *fname == NUL
3591 				   || vim_ispathsep(fname[STRLEN(fname) - 1]))
3592 	{
3593 	    if (*ext == '.')
3594 		*s++ = '_';
3595 	}
3596 	/*
3597 	 * If the extension starts with '.', truncate the base name at 8
3598 	 * characters
3599 	 */
3600 	else if (*ext == '.')
3601 	{
3602 	    if ((size_t)(s - ptr) > (size_t)8)
3603 	    {
3604 		s = ptr + 8;
3605 		*s = '\0';
3606 	    }
3607 	}
3608 	/*
3609 	 * If the extension doesn't start with '.', and the file name
3610 	 * doesn't have an extension yet, append a '.'
3611 	 */
3612 	else if ((e = vim_strchr(ptr, '.')) == NULL)
3613 	    *s++ = '.';
3614 	/*
3615 	 * If the extension doesn't start with '.', and there already is an
3616 	 * extension, it may need to be truncated
3617 	 */
3618 	else if ((int)STRLEN(e) + extlen > 4)
3619 	    s = e + 4 - extlen;
3620     }
3621 #ifdef MSWIN
3622     /*
3623      * If there is no file name, and the extension starts with '.', put a
3624      * '_' before the dot, because just ".ext" may be invalid if it's on a
3625      * FAT partition, and on HPFS it doesn't matter.
3626      */
3627     else if ((fname == NULL || *fname == NUL) && *ext == '.')
3628 	*s++ = '_';
3629 #endif
3630 
3631     /*
3632      * Append the extension.
3633      * ext can start with '.' and cannot exceed 3 more characters.
3634      */
3635     STRCPY(s, ext);
3636 
3637     /*
3638      * Prepend the dot.
3639      */
3640     if (prepend_dot && !shortname && *(e = gettail(retval)) != '.')
3641     {
3642 	STRMOVE(e + 1, e);
3643 	*e = '.';
3644     }
3645 
3646     /*
3647      * Check that, after appending the extension, the file name is really
3648      * different.
3649      */
3650     if (fname != NULL && STRCMP(fname, retval) == 0)
3651     {
3652 	// we search for a character that can be replaced by '_'
3653 	while (--s >= ptr)
3654 	{
3655 	    if (*s != '_')
3656 	    {
3657 		*s = '_';
3658 		break;
3659 	    }
3660 	}
3661 	if (s < ptr)	// fname was "________.<ext>", how tricky!
3662 	    *ptr = 'v';
3663     }
3664     return retval;
3665 }
3666 
3667 /*
3668  * Like fgets(), but if the file line is too long, it is truncated and the
3669  * rest of the line is thrown away.  Returns TRUE for end-of-file.
3670  * If the line is truncated then buf[size - 2] will not be NUL.
3671  */
3672     int
vim_fgets(char_u * buf,int size,FILE * fp)3673 vim_fgets(char_u *buf, int size, FILE *fp)
3674 {
3675     char	*eof;
3676 #define FGETS_SIZE 200
3677     char	tbuf[FGETS_SIZE];
3678 
3679     buf[size - 2] = NUL;
3680     eof = fgets((char *)buf, size, fp);
3681     if (buf[size - 2] != NUL && buf[size - 2] != '\n')
3682     {
3683 	buf[size - 1] = NUL;	    // Truncate the line
3684 
3685 	// Now throw away the rest of the line:
3686 	do
3687 	{
3688 	    tbuf[FGETS_SIZE - 2] = NUL;
3689 	    vim_ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp);
3690 	} while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n');
3691     }
3692     return (eof == NULL);
3693 }
3694 
3695 /*
3696  * rename() only works if both files are on the same file system, this
3697  * function will (attempts to?) copy the file across if rename fails -- webb
3698  * Return -1 for failure, 0 for success.
3699  */
3700     int
vim_rename(char_u * from,char_u * to)3701 vim_rename(char_u *from, char_u *to)
3702 {
3703     int		fd_in;
3704     int		fd_out;
3705     int		n;
3706     char	*errmsg = NULL;
3707     char	*buffer;
3708 #ifdef AMIGA
3709     BPTR	flock;
3710 #endif
3711     stat_T	st;
3712     long	perm;
3713 #ifdef HAVE_ACL
3714     vim_acl_T	acl;		// ACL from original file
3715 #endif
3716     int		use_tmp_file = FALSE;
3717 
3718     /*
3719      * When the names are identical, there is nothing to do.  When they refer
3720      * to the same file (ignoring case and slash/backslash differences) but
3721      * the file name differs we need to go through a temp file.
3722      */
3723     if (fnamecmp(from, to) == 0)
3724     {
3725 	if (p_fic && STRCMP(gettail(from), gettail(to)) != 0)
3726 	    use_tmp_file = TRUE;
3727 	else
3728 	    return 0;
3729     }
3730 
3731     /*
3732      * Fail if the "from" file doesn't exist.  Avoids that "to" is deleted.
3733      */
3734     if (mch_stat((char *)from, &st) < 0)
3735 	return -1;
3736 
3737 #ifdef UNIX
3738     {
3739 	stat_T	st_to;
3740 
3741 	// It's possible for the source and destination to be the same file.
3742 	// This happens when "from" and "to" differ in case and are on a FAT32
3743 	// filesystem.  In that case go through a temp file name.
3744 	if (mch_stat((char *)to, &st_to) >= 0
3745 		&& st.st_dev == st_to.st_dev
3746 		&& st.st_ino == st_to.st_ino)
3747 	    use_tmp_file = TRUE;
3748     }
3749 #endif
3750 #ifdef MSWIN
3751     {
3752 	BY_HANDLE_FILE_INFORMATION info1, info2;
3753 
3754 	// It's possible for the source and destination to be the same file.
3755 	// In that case go through a temp file name.  This makes rename("foo",
3756 	// "./foo") a no-op (in a complicated way).
3757 	if (win32_fileinfo(from, &info1) == FILEINFO_OK
3758 		&& win32_fileinfo(to, &info2) == FILEINFO_OK
3759 		&& info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
3760 		&& info1.nFileIndexHigh == info2.nFileIndexHigh
3761 		&& info1.nFileIndexLow == info2.nFileIndexLow)
3762 	    use_tmp_file = TRUE;
3763     }
3764 #endif
3765 
3766     if (use_tmp_file)
3767     {
3768 	char	tempname[MAXPATHL + 1];
3769 
3770 	/*
3771 	 * Find a name that doesn't exist and is in the same directory.
3772 	 * Rename "from" to "tempname" and then rename "tempname" to "to".
3773 	 */
3774 	if (STRLEN(from) >= MAXPATHL - 5)
3775 	    return -1;
3776 	STRCPY(tempname, from);
3777 	for (n = 123; n < 99999; ++n)
3778 	{
3779 	    sprintf((char *)gettail((char_u *)tempname), "%d", n);
3780 	    if (mch_stat(tempname, &st) < 0)
3781 	    {
3782 		if (mch_rename((char *)from, tempname) == 0)
3783 		{
3784 		    if (mch_rename(tempname, (char *)to) == 0)
3785 			return 0;
3786 		    // Strange, the second step failed.  Try moving the
3787 		    // file back and return failure.
3788 		    (void)mch_rename(tempname, (char *)from);
3789 		    return -1;
3790 		}
3791 		// If it fails for one temp name it will most likely fail
3792 		// for any temp name, give up.
3793 		return -1;
3794 	    }
3795 	}
3796 	return -1;
3797     }
3798 
3799     /*
3800      * Delete the "to" file, this is required on some systems to make the
3801      * mch_rename() work, on other systems it makes sure that we don't have
3802      * two files when the mch_rename() fails.
3803      */
3804 
3805 #ifdef AMIGA
3806     /*
3807      * With MSDOS-compatible filesystems (crossdos, messydos) it is possible
3808      * that the name of the "to" file is the same as the "from" file, even
3809      * though the names are different. To avoid the chance of accidentally
3810      * deleting the "from" file (horror!) we lock it during the remove.
3811      *
3812      * When used for making a backup before writing the file: This should not
3813      * happen with ":w", because startscript() should detect this problem and
3814      * set buf->b_shortname, causing modname() to return a correct ".bak" file
3815      * name.  This problem does exist with ":w filename", but then the
3816      * original file will be somewhere else so the backup isn't really
3817      * important. If autoscripting is off the rename may fail.
3818      */
3819     flock = Lock((UBYTE *)from, (long)ACCESS_READ);
3820 #endif
3821     mch_remove(to);
3822 #ifdef AMIGA
3823     if (flock)
3824 	UnLock(flock);
3825 #endif
3826 
3827     /*
3828      * First try a normal rename, return if it works.
3829      */
3830     if (mch_rename((char *)from, (char *)to) == 0)
3831 	return 0;
3832 
3833     /*
3834      * Rename() failed, try copying the file.
3835      */
3836     perm = mch_getperm(from);
3837 #ifdef HAVE_ACL
3838     // For systems that support ACL: get the ACL from the original file.
3839     acl = mch_get_acl(from);
3840 #endif
3841     fd_in = mch_open((char *)from, O_RDONLY|O_EXTRA, 0);
3842     if (fd_in == -1)
3843     {
3844 #ifdef HAVE_ACL
3845 	mch_free_acl(acl);
3846 #endif
3847 	return -1;
3848     }
3849 
3850     // Create the new file with same permissions as the original.
3851     fd_out = mch_open((char *)to,
3852 		       O_CREAT|O_EXCL|O_WRONLY|O_EXTRA|O_NOFOLLOW, (int)perm);
3853     if (fd_out == -1)
3854     {
3855 	close(fd_in);
3856 #ifdef HAVE_ACL
3857 	mch_free_acl(acl);
3858 #endif
3859 	return -1;
3860     }
3861 
3862     buffer = alloc(WRITEBUFSIZE);
3863     if (buffer == NULL)
3864     {
3865 	close(fd_out);
3866 	close(fd_in);
3867 #ifdef HAVE_ACL
3868 	mch_free_acl(acl);
3869 #endif
3870 	return -1;
3871     }
3872 
3873     while ((n = read_eintr(fd_in, buffer, WRITEBUFSIZE)) > 0)
3874 	if (write_eintr(fd_out, buffer, n) != n)
3875 	{
3876 	    errmsg = _("E208: Error writing to \"%s\"");
3877 	    break;
3878 	}
3879 
3880     vim_free(buffer);
3881     close(fd_in);
3882     if (close(fd_out) < 0)
3883 	errmsg = _("E209: Error closing \"%s\"");
3884     if (n < 0)
3885     {
3886 	errmsg = _("E210: Error reading \"%s\"");
3887 	to = from;
3888     }
3889 #ifndef UNIX	    // for Unix mch_open() already set the permission
3890     mch_setperm(to, perm);
3891 #endif
3892 #ifdef HAVE_ACL
3893     mch_set_acl(to, acl);
3894     mch_free_acl(acl);
3895 #endif
3896 #if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
3897     mch_copy_sec(from, to);
3898 #endif
3899     if (errmsg != NULL)
3900     {
3901 	semsg(errmsg, to);
3902 	return -1;
3903     }
3904     mch_remove(from);
3905     return 0;
3906 }
3907 
3908 static int already_warned = FALSE;
3909 
3910 /*
3911  * Check if any not hidden buffer has been changed.
3912  * Postpone the check if there are characters in the stuff buffer, a global
3913  * command is being executed, a mapping is being executed or an autocommand is
3914  * busy.
3915  * Returns TRUE if some message was written (screen should be redrawn and
3916  * cursor positioned).
3917  */
3918     int
check_timestamps(int focus)3919 check_timestamps(
3920     int		focus)		// called for GUI focus event
3921 {
3922     buf_T	*buf;
3923     int		didit = 0;
3924     int		n;
3925 
3926     // Don't check timestamps while system() or another low-level function may
3927     // cause us to lose and gain focus.
3928     if (no_check_timestamps > 0)
3929 	return FALSE;
3930 
3931     // Avoid doing a check twice.  The OK/Reload dialog can cause a focus
3932     // event and we would keep on checking if the file is steadily growing.
3933     // Do check again after typing something.
3934     if (focus && did_check_timestamps)
3935     {
3936 	need_check_timestamps = TRUE;
3937 	return FALSE;
3938     }
3939 
3940     if (!stuff_empty() || global_busy || !typebuf_typed()
3941 			|| autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0)
3942 	need_check_timestamps = TRUE;		// check later
3943     else
3944     {
3945 	++no_wait_return;
3946 	did_check_timestamps = TRUE;
3947 	already_warned = FALSE;
3948 	FOR_ALL_BUFFERS(buf)
3949 	{
3950 	    // Only check buffers in a window.
3951 	    if (buf->b_nwindows > 0)
3952 	    {
3953 		bufref_T bufref;
3954 
3955 		set_bufref(&bufref, buf);
3956 		n = buf_check_timestamp(buf, focus);
3957 		if (didit < n)
3958 		    didit = n;
3959 		if (n > 0 && !bufref_valid(&bufref))
3960 		{
3961 		    // Autocommands have removed the buffer, start at the
3962 		    // first one again.
3963 		    buf = firstbuf;
3964 		    continue;
3965 		}
3966 	    }
3967 	}
3968 	--no_wait_return;
3969 	need_check_timestamps = FALSE;
3970 	if (need_wait_return && didit == 2)
3971 	{
3972 	    // make sure msg isn't overwritten
3973 	    msg_puts("\n");
3974 	    out_flush();
3975 	}
3976     }
3977     return didit;
3978 }
3979 
3980 /*
3981  * Move all the lines from buffer "frombuf" to buffer "tobuf".
3982  * Return OK or FAIL.  When FAIL "tobuf" is incomplete and/or "frombuf" is not
3983  * empty.
3984  */
3985     static int
move_lines(buf_T * frombuf,buf_T * tobuf)3986 move_lines(buf_T *frombuf, buf_T *tobuf)
3987 {
3988     buf_T	*tbuf = curbuf;
3989     int		retval = OK;
3990     linenr_T	lnum;
3991     char_u	*p;
3992 
3993     // Copy the lines in "frombuf" to "tobuf".
3994     curbuf = tobuf;
3995     for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum)
3996     {
3997 	p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE));
3998 	if (p == NULL || ml_append(lnum - 1, p, 0, FALSE) == FAIL)
3999 	{
4000 	    vim_free(p);
4001 	    retval = FAIL;
4002 	    break;
4003 	}
4004 	vim_free(p);
4005     }
4006 
4007     // Delete all the lines in "frombuf".
4008     if (retval != FAIL)
4009     {
4010 	curbuf = frombuf;
4011 	for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; --lnum)
4012 	    if (ml_delete(lnum) == FAIL)
4013 	    {
4014 		// Oops!  We could try putting back the saved lines, but that
4015 		// might fail again...
4016 		retval = FAIL;
4017 		break;
4018 	    }
4019     }
4020 
4021     curbuf = tbuf;
4022     return retval;
4023 }
4024 
4025 /*
4026  * Check if buffer "buf" has been changed.
4027  * Also check if the file for a new buffer unexpectedly appeared.
4028  * return 1 if a changed buffer was found.
4029  * return 2 if a message has been displayed.
4030  * return 0 otherwise.
4031  */
4032     int
buf_check_timestamp(buf_T * buf,int focus UNUSED)4033 buf_check_timestamp(
4034     buf_T	*buf,
4035     int		focus UNUSED)	// called for GUI focus event
4036 {
4037     stat_T	st;
4038     int		stat_res;
4039     int		retval = 0;
4040     char_u	*path;
4041     char	*tbuf;
4042     char	*mesg = NULL;
4043     char	*mesg2 = "";
4044     int		helpmesg = FALSE;
4045     int		reload = FALSE;
4046     char	*reason;
4047 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
4048     int		can_reload = FALSE;
4049 #endif
4050     off_T	orig_size = buf->b_orig_size;
4051     int		orig_mode = buf->b_orig_mode;
4052 #ifdef FEAT_GUI
4053     int		save_mouse_correct = need_mouse_correct;
4054 #endif
4055     static int	busy = FALSE;
4056     int		n;
4057 #ifdef FEAT_EVAL
4058     char_u	*s;
4059 #endif
4060     bufref_T	bufref;
4061 
4062     set_bufref(&bufref, buf);
4063 
4064     // If there is no file name, the buffer is not loaded, 'buftype' is
4065     // set, we are in the middle of a save or being called recursively: ignore
4066     // this buffer.
4067     if (buf->b_ffname == NULL
4068 	    || buf->b_ml.ml_mfp == NULL
4069 	    || !bt_normal(buf)
4070 	    || buf->b_saving
4071 	    || busy
4072 #ifdef FEAT_NETBEANS_INTG
4073 	    || isNetbeansBuffer(buf)
4074 #endif
4075 #ifdef FEAT_TERMINAL
4076 	    || buf->b_term != NULL
4077 #endif
4078 	    )
4079 	return 0;
4080 
4081     if (       !(buf->b_flags & BF_NOTEDITED)
4082 	    && buf->b_mtime != 0
4083 	    && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
4084 		|| time_differs(&st, buf->b_mtime, buf->b_mtime_ns)
4085 		|| st.st_size != buf->b_orig_size
4086 #ifdef HAVE_ST_MODE
4087 		|| (int)st.st_mode != buf->b_orig_mode
4088 #else
4089 		|| mch_getperm(buf->b_ffname) != buf->b_orig_mode
4090 #endif
4091 		))
4092     {
4093 	long prev_b_mtime = buf->b_mtime;
4094 
4095 	retval = 1;
4096 
4097 	// set b_mtime to stop further warnings (e.g., when executing
4098 	// FileChangedShell autocmd)
4099 	if (stat_res < 0)
4100 	{
4101 	    // Check the file again later to see if it re-appears.
4102 	    buf->b_mtime = -1;
4103 	    buf->b_orig_size = 0;
4104 	    buf->b_orig_mode = 0;
4105 	}
4106 	else
4107 	    buf_store_time(buf, &st, buf->b_ffname);
4108 
4109 	// Don't do anything for a directory.  Might contain the file
4110 	// explorer.
4111 	if (mch_isdir(buf->b_fname))
4112 	    ;
4113 
4114 	/*
4115 	 * If 'autoread' is set, the buffer has no changes and the file still
4116 	 * exists, reload the buffer.  Use the buffer-local option value if it
4117 	 * was set, the global option value otherwise.
4118 	 */
4119 	else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar)
4120 				       && !bufIsChanged(buf) && stat_res >= 0)
4121 	    reload = TRUE;
4122 	else
4123 	{
4124 	    if (stat_res < 0)
4125 		reason = "deleted";
4126 	    else if (bufIsChanged(buf))
4127 		reason = "conflict";
4128 	    /*
4129 	     * Check if the file contents really changed to avoid giving a
4130 	     * warning when only the timestamp was set (e.g., checked out of
4131 	     * CVS).  Always warn when the buffer was changed.
4132 	     */
4133 	    else if (orig_size != buf->b_orig_size || buf_contents_changed(buf))
4134 		reason = "changed";
4135 	    else if (orig_mode != buf->b_orig_mode)
4136 		reason = "mode";
4137 	    else
4138 		reason = "time";
4139 
4140 	    /*
4141 	     * Only give the warning if there are no FileChangedShell
4142 	     * autocommands.
4143 	     * Avoid being called recursively by setting "busy".
4144 	     */
4145 	    busy = TRUE;
4146 #ifdef FEAT_EVAL
4147 	    set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
4148 	    set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
4149 #endif
4150 	    ++allbuf_lock;
4151 	    n = apply_autocmds(EVENT_FILECHANGEDSHELL,
4152 				      buf->b_fname, buf->b_fname, FALSE, buf);
4153 	    --allbuf_lock;
4154 	    busy = FALSE;
4155 	    if (n)
4156 	    {
4157 		if (!bufref_valid(&bufref))
4158 		    emsg(_("E246: FileChangedShell autocommand deleted buffer"));
4159 #ifdef FEAT_EVAL
4160 		s = get_vim_var_str(VV_FCS_CHOICE);
4161 		if (STRCMP(s, "reload") == 0 && *reason != 'd')
4162 		    reload = TRUE;
4163 		else if (STRCMP(s, "ask") == 0)
4164 		    n = FALSE;
4165 		else
4166 #endif
4167 		    return 2;
4168 	    }
4169 	    if (!n)
4170 	    {
4171 		if (*reason == 'd')
4172 		{
4173 		    // Only give the message once.
4174 		    if (prev_b_mtime != -1)
4175 			mesg = _("E211: File \"%s\" no longer available");
4176 		}
4177 		else
4178 		{
4179 		    helpmesg = TRUE;
4180 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
4181 		    can_reload = TRUE;
4182 #endif
4183 		    if (reason[2] == 'n')
4184 		    {
4185 			mesg = _("W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well");
4186 			mesg2 = _("See \":help W12\" for more info.");
4187 		    }
4188 		    else if (reason[1] == 'h')
4189 		    {
4190 			mesg = _("W11: Warning: File \"%s\" has changed since editing started");
4191 			mesg2 = _("See \":help W11\" for more info.");
4192 		    }
4193 		    else if (*reason == 'm')
4194 		    {
4195 			mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
4196 			mesg2 = _("See \":help W16\" for more info.");
4197 		    }
4198 		    else
4199 		    {
4200 			// Only timestamp changed, store it to avoid a warning
4201 			// in check_mtime() later.
4202 			buf->b_mtime_read = buf->b_mtime;
4203 			buf->b_mtime_read_ns = buf->b_mtime_ns;
4204 		    }
4205 		}
4206 	    }
4207 	}
4208 
4209     }
4210     else if ((buf->b_flags & BF_NEW) && !(buf->b_flags & BF_NEW_W)
4211 						&& vim_fexists(buf->b_ffname))
4212     {
4213 	retval = 1;
4214 	mesg = _("W13: Warning: File \"%s\" has been created after editing started");
4215 	buf->b_flags |= BF_NEW_W;
4216 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
4217 	can_reload = TRUE;
4218 #endif
4219     }
4220 
4221     if (mesg != NULL)
4222     {
4223 	path = home_replace_save(buf, buf->b_fname);
4224 	if (path != NULL)
4225 	{
4226 	    if (!helpmesg)
4227 		mesg2 = "";
4228 	    tbuf = alloc(STRLEN(path) + STRLEN(mesg) + STRLEN(mesg2) + 2);
4229 	    sprintf(tbuf, mesg, path);
4230 #ifdef FEAT_EVAL
4231 	    // Set warningmsg here, before the unimportant and output-specific
4232 	    // mesg2 has been appended.
4233 	    set_vim_var_string(VV_WARNINGMSG, (char_u *)tbuf, -1);
4234 #endif
4235 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
4236 	    if (can_reload)
4237 	    {
4238 		if (*mesg2 != NUL)
4239 		{
4240 		    STRCAT(tbuf, "\n");
4241 		    STRCAT(tbuf, mesg2);
4242 		}
4243 		if (do_dialog(VIM_WARNING, (char_u *)_("Warning"),
4244 			    (char_u *)tbuf,
4245 			  (char_u *)_("&OK\n&Load File"), 1, NULL, TRUE) == 2)
4246 		    reload = TRUE;
4247 	    }
4248 	    else
4249 #endif
4250 	    if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned)
4251 	    {
4252 		if (*mesg2 != NUL)
4253 		{
4254 		    STRCAT(tbuf, "; ");
4255 		    STRCAT(tbuf, mesg2);
4256 		}
4257 		emsg(tbuf);
4258 		retval = 2;
4259 	    }
4260 	    else
4261 	    {
4262 		if (!autocmd_busy)
4263 		{
4264 		    msg_start();
4265 		    msg_puts_attr(tbuf, HL_ATTR(HLF_E) + MSG_HIST);
4266 		    if (*mesg2 != NUL)
4267 			msg_puts_attr(mesg2, HL_ATTR(HLF_W) + MSG_HIST);
4268 		    msg_clr_eos();
4269 		    (void)msg_end();
4270 		    if (emsg_silent == 0 && !in_assert_fails)
4271 		    {
4272 			out_flush();
4273 #ifdef FEAT_GUI
4274 			if (!focus)
4275 #endif
4276 			    // give the user some time to think about it
4277 			    ui_delay(1004L, TRUE);
4278 
4279 			// don't redraw and erase the message
4280 			redraw_cmdline = FALSE;
4281 		    }
4282 		}
4283 		already_warned = TRUE;
4284 	    }
4285 
4286 	    vim_free(path);
4287 	    vim_free(tbuf);
4288 	}
4289     }
4290 
4291     if (reload)
4292     {
4293 	// Reload the buffer.
4294 	buf_reload(buf, orig_mode);
4295 #ifdef FEAT_PERSISTENT_UNDO
4296 	if (buf->b_p_udf && buf->b_ffname != NULL)
4297 	{
4298 	    char_u	    hash[UNDO_HASH_SIZE];
4299 	    buf_T	    *save_curbuf = curbuf;
4300 
4301 	    // Any existing undo file is unusable, write it now.
4302 	    curbuf = buf;
4303 	    u_compute_hash(hash);
4304 	    u_write_undo(NULL, FALSE, buf, hash);
4305 	    curbuf = save_curbuf;
4306 	}
4307 #endif
4308     }
4309 
4310     // Trigger FileChangedShell when the file was changed in any way.
4311     if (bufref_valid(&bufref) && retval != 0)
4312 	(void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST,
4313 				      buf->b_fname, buf->b_fname, FALSE, buf);
4314 #ifdef FEAT_GUI
4315     // restore this in case an autocommand has set it; it would break
4316     // 'mousefocus'
4317     need_mouse_correct = save_mouse_correct;
4318 #endif
4319 
4320     return retval;
4321 }
4322 
4323 /*
4324  * Reload a buffer that is already loaded.
4325  * Used when the file was changed outside of Vim.
4326  * "orig_mode" is buf->b_orig_mode before the need for reloading was detected.
4327  * buf->b_orig_mode may have been reset already.
4328  */
4329     void
buf_reload(buf_T * buf,int orig_mode)4330 buf_reload(buf_T *buf, int orig_mode)
4331 {
4332     exarg_T	ea;
4333     pos_T	old_cursor;
4334     linenr_T	old_topline;
4335     int		old_ro = buf->b_p_ro;
4336     buf_T	*savebuf;
4337     bufref_T	bufref;
4338     int		saved = OK;
4339     aco_save_T	aco;
4340     int		flags = READ_NEW;
4341 
4342     // set curwin/curbuf for "buf" and save some things
4343     aucmd_prepbuf(&aco, buf);
4344 
4345     // We only want to read the text from the file, not reset the syntax
4346     // highlighting, clear marks, diff status, etc.  Force the fileformat
4347     // and encoding to be the same.
4348     if (prep_exarg(&ea, buf) == OK)
4349     {
4350 	old_cursor = curwin->w_cursor;
4351 	old_topline = curwin->w_topline;
4352 
4353 	if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)
4354 	{
4355 	    // Save all the text, so that the reload can be undone.
4356 	    // Sync first so that this is a separate undo-able action.
4357 	    u_sync(FALSE);
4358 	    saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE);
4359 	    flags |= READ_KEEP_UNDO;
4360 	}
4361 
4362 	/*
4363 	 * To behave like when a new file is edited (matters for
4364 	 * BufReadPost autocommands) we first need to delete the current
4365 	 * buffer contents.  But if reading the file fails we should keep
4366 	 * the old contents.  Can't use memory only, the file might be
4367 	 * too big.  Use a hidden buffer to move the buffer contents to.
4368 	 */
4369 	if (BUFEMPTY() || saved == FAIL)
4370 	    savebuf = NULL;
4371 	else
4372 	{
4373 	    // Allocate a buffer without putting it in the buffer list.
4374 	    savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
4375 	    set_bufref(&bufref, savebuf);
4376 	    if (savebuf != NULL && buf == curbuf)
4377 	    {
4378 		// Open the memline.
4379 		curbuf = savebuf;
4380 		curwin->w_buffer = savebuf;
4381 		saved = ml_open(curbuf);
4382 		curbuf = buf;
4383 		curwin->w_buffer = buf;
4384 	    }
4385 	    if (savebuf == NULL || saved == FAIL || buf != curbuf
4386 				      || move_lines(buf, savebuf) == FAIL)
4387 	    {
4388 		semsg(_("E462: Could not prepare for reloading \"%s\""),
4389 							    buf->b_fname);
4390 		saved = FAIL;
4391 	    }
4392 	}
4393 
4394 	if (saved == OK)
4395 	{
4396 	    curbuf->b_flags |= BF_CHECK_RO;	// check for RO again
4397 	    keep_filetype = TRUE;		// don't detect 'filetype'
4398 	    if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
4399 			(linenr_T)0,
4400 			(linenr_T)MAXLNUM, &ea, flags) != OK)
4401 	    {
4402 #if defined(FEAT_EVAL)
4403 		if (!aborting())
4404 #endif
4405 		    semsg(_("E321: Could not reload \"%s\""), buf->b_fname);
4406 		if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf)
4407 		{
4408 		    // Put the text back from the save buffer.  First
4409 		    // delete any lines that readfile() added.
4410 		    while (!BUFEMPTY())
4411 			if (ml_delete(buf->b_ml.ml_line_count) == FAIL)
4412 			    break;
4413 		    (void)move_lines(savebuf, buf);
4414 		}
4415 	    }
4416 	    else if (buf == curbuf)  // "buf" still valid
4417 	    {
4418 		// Mark the buffer as unmodified and free undo info.
4419 		unchanged(buf, TRUE, TRUE);
4420 		if ((flags & READ_KEEP_UNDO) == 0)
4421 		{
4422 		    u_blockfree(buf);
4423 		    u_clearall(buf);
4424 		}
4425 		else
4426 		{
4427 		    // Mark all undo states as changed.
4428 		    u_unchanged(curbuf);
4429 		}
4430 	    }
4431 	}
4432 	vim_free(ea.cmd);
4433 
4434 	if (savebuf != NULL && bufref_valid(&bufref))
4435 	    wipe_buffer(savebuf, FALSE);
4436 
4437 #ifdef FEAT_DIFF
4438 	// Invalidate diff info if necessary.
4439 	diff_invalidate(curbuf);
4440 #endif
4441 
4442 	// Restore the topline and cursor position and check it (lines may
4443 	// have been removed).
4444 	if (old_topline > curbuf->b_ml.ml_line_count)
4445 	    curwin->w_topline = curbuf->b_ml.ml_line_count;
4446 	else
4447 	    curwin->w_topline = old_topline;
4448 	curwin->w_cursor = old_cursor;
4449 	check_cursor();
4450 	update_topline();
4451 	keep_filetype = FALSE;
4452 #ifdef FEAT_FOLDING
4453 	{
4454 	    win_T	*wp;
4455 	    tabpage_T	*tp;
4456 
4457 	    // Update folds unless they are defined manually.
4458 	    FOR_ALL_TAB_WINDOWS(tp, wp)
4459 		if (wp->w_buffer == curwin->w_buffer
4460 			&& !foldmethodIsManual(wp))
4461 		    foldUpdateAll(wp);
4462 	}
4463 #endif
4464 	// If the mode didn't change and 'readonly' was set, keep the old
4465 	// value; the user probably used the ":view" command.  But don't
4466 	// reset it, might have had a read error.
4467 	if (orig_mode == curbuf->b_orig_mode)
4468 	    curbuf->b_p_ro |= old_ro;
4469 
4470 	// Modelines must override settings done by autocommands.
4471 	do_modelines(0);
4472     }
4473 
4474     // restore curwin/curbuf and a few other things
4475     aucmd_restbuf(&aco);
4476     // Careful: autocommands may have made "buf" invalid!
4477 }
4478 
4479     void
buf_store_time(buf_T * buf,stat_T * st,char_u * fname UNUSED)4480 buf_store_time(buf_T *buf, stat_T *st, char_u *fname UNUSED)
4481 {
4482     buf->b_mtime = (long)st->st_mtime;
4483 #ifdef ST_MTIM_NSEC
4484     buf->b_mtime_ns = (long)st->ST_MTIM_NSEC;
4485 #else
4486     buf->b_mtime_ns = 0;
4487 #endif
4488     buf->b_orig_size = st->st_size;
4489 #ifdef HAVE_ST_MODE
4490     buf->b_orig_mode = (int)st->st_mode;
4491 #else
4492     buf->b_orig_mode = mch_getperm(fname);
4493 #endif
4494 }
4495 
4496 /*
4497  * Adjust the line with missing eol, used for the next write.
4498  * Used for do_filter(), when the input lines for the filter are deleted.
4499  */
4500     void
write_lnum_adjust(linenr_T offset)4501 write_lnum_adjust(linenr_T offset)
4502 {
4503     if (curbuf->b_no_eol_lnum != 0)	// only if there is a missing eol
4504 	curbuf->b_no_eol_lnum += offset;
4505 }
4506 
4507 // Subfuncions for readdirex()
4508 #ifdef FEAT_EVAL
4509 # ifdef MSWIN
4510     static char_u *
getfpermwfd(WIN32_FIND_DATAW * wfd,char_u * perm)4511 getfpermwfd(WIN32_FIND_DATAW *wfd, char_u *perm)
4512 {
4513     stat_T	    st;
4514     unsigned short  st_mode;
4515     DWORD	    flag = wfd->dwFileAttributes;
4516     WCHAR	    *wp;
4517 
4518     st_mode = (flag & FILE_ATTRIBUTE_DIRECTORY)
4519 					? (_S_IFDIR | _S_IEXEC) : _S_IFREG;
4520     st_mode |= (flag & FILE_ATTRIBUTE_READONLY)
4521 					? _S_IREAD : (_S_IREAD | _S_IWRITE);
4522 
4523     wp = wcsrchr(wfd->cFileName, L'.');
4524     if (wp != NULL)
4525     {
4526 	if (_wcsicmp(wp, L".exe") == 0 ||
4527 		_wcsicmp(wp, L".com") == 0 ||
4528 		_wcsicmp(wp, L".cmd") == 0 ||
4529 		_wcsicmp(wp, L".bat") == 0)
4530 	    st_mode |= _S_IEXEC;
4531     }
4532 
4533     // Copy user bits to group/other.
4534     st_mode |= (st_mode & 0700) >> 3;
4535     st_mode |= (st_mode & 0700) >> 6;
4536 
4537     st.st_mode = st_mode;
4538     return getfpermst(&st, perm);
4539 }
4540 
4541     static char_u *
getftypewfd(WIN32_FIND_DATAW * wfd)4542 getftypewfd(WIN32_FIND_DATAW *wfd)
4543 {
4544     DWORD flag = wfd->dwFileAttributes;
4545     DWORD tag = wfd->dwReserved0;
4546 
4547     if (flag & FILE_ATTRIBUTE_REPARSE_POINT)
4548     {
4549 	if (tag == IO_REPARSE_TAG_MOUNT_POINT)
4550 	    return (char_u*)"junction";
4551 	else if (tag == IO_REPARSE_TAG_SYMLINK)
4552 	{
4553 	    if (flag & FILE_ATTRIBUTE_DIRECTORY)
4554 		return (char_u*)"linkd";
4555 	    else
4556 		return (char_u*)"link";
4557 	}
4558 	return (char_u*)"reparse";	// unknown reparse point type
4559     }
4560     if (flag & FILE_ATTRIBUTE_DIRECTORY)
4561 	return (char_u*)"dir";
4562     else
4563 	return (char_u*)"file";
4564 }
4565 
4566     static dict_T *
create_readdirex_item(WIN32_FIND_DATAW * wfd)4567 create_readdirex_item(WIN32_FIND_DATAW *wfd)
4568 {
4569     dict_T	*item;
4570     char_u	*p;
4571     varnumber_T	size, time;
4572     char_u	permbuf[] = "---------";
4573 
4574     item = dict_alloc();
4575     if (item == NULL)
4576 	return NULL;
4577     item->dv_refcount++;
4578 
4579     p = utf16_to_enc(wfd->cFileName, NULL);
4580     if (p == NULL)
4581 	goto theend;
4582     if (dict_add_string(item, "name", p) == FAIL)
4583     {
4584 	vim_free(p);
4585 	goto theend;
4586     }
4587     vim_free(p);
4588 
4589     size = (((varnumber_T)wfd->nFileSizeHigh) << 32) | wfd->nFileSizeLow;
4590     if (dict_add_number(item, "size", size) == FAIL)
4591 	goto theend;
4592 
4593     // Convert FILETIME to unix time.
4594     time = (((((varnumber_T)wfd->ftLastWriteTime.dwHighDateTime) << 32) |
4595 		wfd->ftLastWriteTime.dwLowDateTime)
4596 	    - 116444736000000000) / 10000000;
4597     if (dict_add_number(item, "time", time) == FAIL)
4598 	goto theend;
4599 
4600     if (dict_add_string(item, "type", getftypewfd(wfd)) == FAIL)
4601 	goto theend;
4602     if (dict_add_string(item, "perm", getfpermwfd(wfd, permbuf)) == FAIL)
4603 	goto theend;
4604 
4605     if (dict_add_string(item, "user", (char_u*)"") == FAIL)
4606 	goto theend;
4607     if (dict_add_string(item, "group", (char_u*)"") == FAIL)
4608 	goto theend;
4609 
4610     return item;
4611 
4612 theend:
4613     dict_unref(item);
4614     return NULL;
4615 }
4616 # else
4617     static dict_T *
create_readdirex_item(char_u * path,char_u * name)4618 create_readdirex_item(char_u *path, char_u *name)
4619 {
4620     dict_T	*item;
4621     char	*p;
4622     size_t	len;
4623     stat_T	st;
4624     int		ret, link = FALSE;
4625     varnumber_T	size;
4626     char_u	permbuf[] = "---------";
4627     char_u	*q = NULL;
4628     struct passwd *pw;
4629     struct group  *gr;
4630 
4631     item = dict_alloc();
4632     if (item == NULL)
4633 	return NULL;
4634     item->dv_refcount++;
4635 
4636     len = STRLEN(path) + 1 + STRLEN(name) + 1;
4637     p = alloc(len);
4638     if (p == NULL)
4639 	goto theend;
4640     vim_snprintf(p, len, "%s/%s", path, name);
4641     ret = mch_lstat(p, &st);
4642     if (ret >= 0 && S_ISLNK(st.st_mode))
4643     {
4644 	link = TRUE;
4645 	ret = mch_stat(p, &st);
4646 	if (ret < 0)
4647 	    q = (char_u*)"link";
4648 
4649     }
4650     vim_free(p);
4651 
4652     if (dict_add_string(item, "name", name) == FAIL)
4653 	goto theend;
4654 
4655     if (ret >= 0)
4656     {
4657 	size = (varnumber_T)st.st_size;
4658 	if (S_ISDIR(st.st_mode))
4659 	    size = 0;
4660 	// non-perfect check for overflow
4661 	else if ((off_T)size != (off_T)st.st_size)
4662 	    size = -2;
4663 	if (dict_add_number(item, "size", size) == FAIL)
4664 	    goto theend;
4665 	if (dict_add_number(item, "time", (varnumber_T)st.st_mtime) == FAIL)
4666 	    goto theend;
4667 
4668 	if (link)
4669 	{
4670 	    if (S_ISDIR(st.st_mode))
4671 		q = (char_u*)"linkd";
4672 	    else
4673 		q = (char_u*)"link";
4674 	}
4675 	else
4676 	    q = getftypest(&st);
4677 	if (dict_add_string(item, "type", q) == FAIL)
4678 	    goto theend;
4679 	if (dict_add_string(item, "perm", getfpermst(&st, permbuf)) == FAIL)
4680 	    goto theend;
4681 
4682 	pw = getpwuid(st.st_uid);
4683 	if (pw == NULL)
4684 	    q = (char_u*)"";
4685 	else
4686 	    q = (char_u*)pw->pw_name;
4687 	if (dict_add_string(item, "user", q) == FAIL)
4688 	    goto theend;
4689 #  if !defined(VMS) || (defined(VMS) && defined(HAVE_XOS_R_H))
4690 	gr = getgrgid(st.st_gid);
4691 	if (gr == NULL)
4692 	    q = (char_u*)"";
4693 	else
4694 	    q = (char_u*)gr->gr_name;
4695 #  endif
4696 	if (dict_add_string(item, "group", q) == FAIL)
4697 	    goto theend;
4698     }
4699     else
4700     {
4701 	if (dict_add_number(item, "size", -1) == FAIL)
4702 	    goto theend;
4703 	if (dict_add_number(item, "time", -1) == FAIL)
4704 	    goto theend;
4705 	if (dict_add_string(item, "type", q == NULL ? (char_u*)"" : q) == FAIL)
4706 	    goto theend;
4707 	if (dict_add_string(item, "perm", (char_u*)"") == FAIL)
4708 	    goto theend;
4709 	if (dict_add_string(item, "user", (char_u*)"") == FAIL)
4710 	    goto theend;
4711 	if (dict_add_string(item, "group", (char_u*)"") == FAIL)
4712 	    goto theend;
4713     }
4714     return item;
4715 
4716 theend:
4717     dict_unref(item);
4718     return NULL;
4719 }
4720 # endif
4721 
4722     static int
compare_readdirex_item(const void * p1,const void * p2)4723 compare_readdirex_item(const void *p1, const void *p2)
4724 {
4725     char_u  *name1, *name2;
4726 
4727     name1 = dict_get_string(*(dict_T**)p1, (char_u*)"name", FALSE);
4728     name2 = dict_get_string(*(dict_T**)p2, (char_u*)"name", FALSE);
4729     if (readdirex_sort == READDIR_SORT_BYTE)
4730 	return STRCMP(name1, name2);
4731     else if (readdirex_sort == READDIR_SORT_IC)
4732 	return STRICMP(name1, name2);
4733     else
4734 	return STRCOLL(name1, name2);
4735 }
4736 
4737     static int
compare_readdir_item(const void * s1,const void * s2)4738 compare_readdir_item(const void *s1, const void *s2)
4739 {
4740     if (readdirex_sort == READDIR_SORT_BYTE)
4741 	return STRCMP(*(char **)s1, *(char **)s2);
4742     else if (readdirex_sort == READDIR_SORT_IC)
4743 	return STRICMP(*(char **)s1, *(char **)s2);
4744     else
4745 	return STRCOLL(*(char **)s1, *(char **)s2);
4746 }
4747 #endif
4748 
4749 #if defined(TEMPDIRNAMES) || defined(FEAT_EVAL) || defined(PROTO)
4750 /*
4751  * Core part of "readdir()" and "readdirex()" function.
4752  * Retrieve the list of files/directories of "path" into "gap".
4753  * If "withattr" is TRUE, retrieve the names and their attributes.
4754  * If "withattr" is FALSE, retrieve the names only.
4755  * Return OK for success, FAIL for failure.
4756  */
4757     int
readdir_core(garray_T * gap,char_u * path,int withattr UNUSED,void * context,int (* checkitem)(void * context,void * item),int sort)4758 readdir_core(
4759     garray_T	*gap,
4760     char_u	*path,
4761     int		withattr UNUSED,
4762     void	*context,
4763     int		(*checkitem)(void *context, void *item),
4764     int         sort)
4765 {
4766     int			failed = FALSE;
4767     char_u		*p;
4768 # ifdef MSWIN
4769     char_u		*buf;
4770     int			ok;
4771     HANDLE		hFind = INVALID_HANDLE_VALUE;
4772     WIN32_FIND_DATAW    wfd;
4773     WCHAR		*wn = NULL;	// UTF-16 name, NULL when not used.
4774 # else
4775     DIR			*dirp;
4776     struct dirent	*dp;
4777 # endif
4778 
4779     ga_init2(gap, (int)sizeof(void *), 20);
4780 
4781 # ifdef FEAT_EVAL
4782 #  define FREE_ITEM(item)   do { \
4783 	if (withattr) \
4784 	    dict_unref((dict_T*)item); \
4785 	else \
4786 	    vim_free(item); \
4787     } while (0)
4788 
4789     readdirex_sort = READDIR_SORT_BYTE;
4790 # else
4791 #  define FREE_ITEM(item)   vim_free(item)
4792 # endif
4793 
4794 # ifdef MSWIN
4795     buf = alloc(MAXPATHL);
4796     if (buf == NULL)
4797 	return FAIL;
4798     STRNCPY(buf, path, MAXPATHL-5);
4799     p = buf + STRLEN(buf);
4800     MB_PTR_BACK(buf, p);
4801     if (*p == '\\' || *p == '/')
4802 	*p = NUL;
4803     STRCAT(p, "\\*");
4804 
4805     wn = enc_to_utf16(buf, NULL);
4806     if (wn != NULL)
4807 	hFind = FindFirstFileW(wn, &wfd);
4808     ok = (hFind != INVALID_HANDLE_VALUE);
4809     if (!ok)
4810     {
4811 	failed = TRUE;
4812 	semsg(_(e_notopen), path);
4813     }
4814     else
4815     {
4816 	while (ok)
4817 	{
4818 	    int	    ignore;
4819 	    void    *item;
4820 	    WCHAR   *wp;
4821 
4822 	    wp = wfd.cFileName;
4823 	    ignore = wp[0] == L'.' &&
4824 		    (wp[1] == NUL ||
4825 		     (wp[1] == L'.' && wp[2] == NUL));
4826 	    if (ignore)
4827 	    {
4828 		ok = FindNextFileW(hFind, &wfd);
4829 		continue;
4830 	    }
4831 #  ifdef FEAT_EVAL
4832 	    if (withattr)
4833 		item = (void*)create_readdirex_item(&wfd);
4834 	    else
4835 #  endif
4836 		item = (void*)utf16_to_enc(wfd.cFileName, NULL);
4837 	    if (item == NULL)
4838 	    {
4839 		failed = TRUE;
4840 		break;
4841 	    }
4842 
4843 	    if (!ignore && checkitem != NULL)
4844 	    {
4845 		int r = checkitem(context, item);
4846 
4847 		if (r < 0)
4848 		{
4849 		    FREE_ITEM(item);
4850 		    break;
4851 		}
4852 		if (r == 0)
4853 		    ignore = TRUE;
4854 	    }
4855 
4856 	    if (!ignore)
4857 	    {
4858 		if (ga_grow(gap, 1) == OK)
4859 		    ((void**)gap->ga_data)[gap->ga_len++] = item;
4860 		else
4861 		{
4862 		    failed = TRUE;
4863 		    FREE_ITEM(item);
4864 		    break;
4865 		}
4866 	    }
4867 	    else
4868 		FREE_ITEM(item);
4869 
4870 	    ok = FindNextFileW(hFind, &wfd);
4871 	}
4872 	FindClose(hFind);
4873     }
4874 
4875     vim_free(buf);
4876     vim_free(wn);
4877 # else	// MSWIN
4878     dirp = opendir((char *)path);
4879     if (dirp == NULL)
4880     {
4881 	failed = TRUE;
4882 	semsg(_(e_notopen), path);
4883     }
4884     else
4885     {
4886 	for (;;)
4887 	{
4888 	    int	    ignore;
4889 	    void    *item;
4890 
4891 	    dp = readdir(dirp);
4892 	    if (dp == NULL)
4893 		break;
4894 	    p = (char_u *)dp->d_name;
4895 
4896 	    ignore = p[0] == '.' &&
4897 		    (p[1] == NUL ||
4898 		     (p[1] == '.' && p[2] == NUL));
4899 	    if (ignore)
4900 		continue;
4901 #  ifdef FEAT_EVAL
4902 	    if (withattr)
4903 		item = (void*)create_readdirex_item(path, p);
4904 	    else
4905 #  endif
4906 		item = (void*)vim_strsave(p);
4907 	    if (item == NULL)
4908 	    {
4909 		failed = TRUE;
4910 		break;
4911 	    }
4912 
4913 	    if (!ignore && checkitem != NULL)
4914 	    {
4915 		int r = checkitem(context, item);
4916 
4917 		if (r < 0)
4918 		{
4919 		    FREE_ITEM(item);
4920 		    break;
4921 		}
4922 		if (r == 0)
4923 		    ignore = TRUE;
4924 	    }
4925 
4926 	    if (!ignore)
4927 	    {
4928 		if (ga_grow(gap, 1) == OK)
4929 		    ((void**)gap->ga_data)[gap->ga_len++] = item;
4930 		else
4931 		{
4932 		    failed = TRUE;
4933 		    FREE_ITEM(item);
4934 		    break;
4935 		}
4936 	    }
4937 	    else
4938 		FREE_ITEM(item);
4939 	}
4940 
4941 	closedir(dirp);
4942     }
4943 # endif	// MSWIN
4944 
4945 # undef FREE_ITEM
4946 
4947     if (!failed && gap->ga_len > 0 && sort > READDIR_SORT_NONE)
4948     {
4949 # ifdef FEAT_EVAL
4950 	readdirex_sort = sort;
4951 	if (withattr)
4952 	    qsort((void*)gap->ga_data, (size_t)gap->ga_len, sizeof(dict_T*),
4953 		    compare_readdirex_item);
4954 	else
4955 	    qsort((void*)gap->ga_data, (size_t)gap->ga_len, sizeof(char_u *),
4956 		    compare_readdir_item);
4957 # else
4958 	    sort_strings((char_u **)gap->ga_data, gap->ga_len);
4959 # endif
4960     }
4961 
4962     return failed ? FAIL : OK;
4963 }
4964 
4965 /*
4966  * Delete "name" and everything in it, recursively.
4967  * return 0 for success, -1 if some file was not deleted.
4968  */
4969     int
delete_recursive(char_u * name)4970 delete_recursive(char_u *name)
4971 {
4972     int result = 0;
4973     int		i;
4974     char_u	*exp;
4975     garray_T	ga;
4976 
4977     // A symbolic link to a directory itself is deleted, not the directory it
4978     // points to.
4979     if (
4980 # if defined(UNIX) || defined(MSWIN)
4981 	 mch_isrealdir(name)
4982 # else
4983 	 mch_isdir(name)
4984 # endif
4985 	    )
4986     {
4987 	exp = vim_strsave(name);
4988 	if (exp == NULL)
4989 	    return -1;
4990 	if (readdir_core(&ga, exp, FALSE, NULL, NULL, READDIR_SORT_NONE) == OK)
4991 	{
4992 	    for (i = 0; i < ga.ga_len; ++i)
4993 	    {
4994 		vim_snprintf((char *)NameBuff, MAXPATHL, "%s/%s", exp,
4995 					    ((char_u **)ga.ga_data)[i]);
4996 		if (delete_recursive(NameBuff) != 0)
4997 		    result = -1;
4998 	    }
4999 	    ga_clear_strings(&ga);
5000 	}
5001 	else
5002 	    result = -1;
5003 	(void)mch_rmdir(exp);
5004 	vim_free(exp);
5005     }
5006     else
5007 	result = mch_remove(name) == 0 ? 0 : -1;
5008 
5009     return result;
5010 }
5011 #endif
5012 
5013 #if defined(TEMPDIRNAMES) || defined(PROTO)
5014 static long	temp_count = 0;		// Temp filename counter.
5015 
5016 # if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
5017 /*
5018  * Open temporary directory and take file lock to prevent
5019  * to be auto-cleaned.
5020  */
5021    static void
vim_opentempdir(void)5022 vim_opentempdir(void)
5023 {
5024     DIR *dp = NULL;
5025 
5026     if (vim_tempdir_dp != NULL)
5027 	return;
5028 
5029     dp = opendir((const char*)vim_tempdir);
5030 
5031     if (dp != NULL)
5032     {
5033 	vim_tempdir_dp = dp;
5034 	flock(dirfd(vim_tempdir_dp), LOCK_SH);
5035     }
5036 }
5037 
5038 /*
5039  * Close temporary directory - it automatically release file lock.
5040  */
5041    static void
vim_closetempdir(void)5042 vim_closetempdir(void)
5043 {
5044     if (vim_tempdir_dp != NULL)
5045     {
5046 	closedir(vim_tempdir_dp);
5047 	vim_tempdir_dp = NULL;
5048     }
5049 }
5050 # endif
5051 
5052 /*
5053  * Delete the temp directory and all files it contains.
5054  */
5055     void
vim_deltempdir(void)5056 vim_deltempdir(void)
5057 {
5058     if (vim_tempdir != NULL)
5059     {
5060 # if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
5061 	vim_closetempdir();
5062 # endif
5063 	// remove the trailing path separator
5064 	gettail(vim_tempdir)[-1] = NUL;
5065 	delete_recursive(vim_tempdir);
5066 	VIM_CLEAR(vim_tempdir);
5067     }
5068 }
5069 
5070 /*
5071  * Directory "tempdir" was created.  Expand this name to a full path and put
5072  * it in "vim_tempdir".  This avoids that using ":cd" would confuse us.
5073  * "tempdir" must be no longer than MAXPATHL.
5074  */
5075     static void
vim_settempdir(char_u * tempdir)5076 vim_settempdir(char_u *tempdir)
5077 {
5078     char_u	*buf;
5079 
5080     buf = alloc(MAXPATHL + 2);
5081     if (buf != NULL)
5082     {
5083 	if (vim_FullName(tempdir, buf, MAXPATHL, FALSE) == FAIL)
5084 	    STRCPY(buf, tempdir);
5085 	add_pathsep(buf);
5086 	vim_tempdir = vim_strsave(buf);
5087 # if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD)
5088 	vim_opentempdir();
5089 # endif
5090 	vim_free(buf);
5091     }
5092 }
5093 #endif
5094 
5095 /*
5096  * vim_tempname(): Return a unique name that can be used for a temp file.
5097  *
5098  * The temp file is NOT guaranteed to be created.  If "keep" is FALSE it is
5099  * guaranteed to NOT be created.
5100  *
5101  * The returned pointer is to allocated memory.
5102  * The returned pointer is NULL if no valid name was found.
5103  */
5104     char_u  *
vim_tempname(int extra_char UNUSED,int keep UNUSED)5105 vim_tempname(
5106     int	    extra_char UNUSED,  // char to use in the name instead of '?'
5107     int	    keep UNUSED)
5108 {
5109 #ifdef USE_TMPNAM
5110     char_u	itmp[L_tmpnam];	// use tmpnam()
5111 #elif defined(MSWIN)
5112     WCHAR	itmp[TEMPNAMELEN];
5113 #else
5114     char_u	itmp[TEMPNAMELEN];
5115 #endif
5116 
5117 #ifdef TEMPDIRNAMES
5118     static char	*(tempdirs[]) = {TEMPDIRNAMES};
5119     int		i;
5120 # ifndef EEXIST
5121     stat_T	st;
5122 # endif
5123 
5124     /*
5125      * This will create a directory for private use by this instance of Vim.
5126      * This is done once, and the same directory is used for all temp files.
5127      * This method avoids security problems because of symlink attacks et al.
5128      * It's also a bit faster, because we only need to check for an existing
5129      * file when creating the directory and not for each temp file.
5130      */
5131     if (vim_tempdir == NULL)
5132     {
5133 	/*
5134 	 * Try the entries in TEMPDIRNAMES to create the temp directory.
5135 	 */
5136 	for (i = 0; i < (int)ARRAY_LENGTH(tempdirs); ++i)
5137 	{
5138 # ifndef HAVE_MKDTEMP
5139 	    size_t	itmplen;
5140 	    long	nr;
5141 	    long	off;
5142 # endif
5143 
5144 	    // Expand $TMP, leave room for "/v1100000/999999999".
5145 	    // Skip the directory check if the expansion fails.
5146 	    expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20);
5147 	    if (itmp[0] != '$' && mch_isdir(itmp))
5148 	    {
5149 		// directory exists
5150 		add_pathsep(itmp);
5151 
5152 # ifdef HAVE_MKDTEMP
5153 		{
5154 #  if defined(UNIX) || defined(VMS)
5155 		    // Make sure the umask doesn't remove the executable bit.
5156 		    // "repl" has been reported to use "177".
5157 		    mode_t	umask_save = umask(077);
5158 #  endif
5159 		    // Leave room for filename
5160 		    STRCAT(itmp, "vXXXXXX");
5161 		    if (mkdtemp((char *)itmp) != NULL)
5162 			vim_settempdir(itmp);
5163 #  if defined(UNIX) || defined(VMS)
5164 		    (void)umask(umask_save);
5165 #  endif
5166 		}
5167 # else
5168 		// Get an arbitrary number of up to 6 digits.  When it's
5169 		// unlikely that it already exists it will be faster,
5170 		// otherwise it doesn't matter.  The use of mkdir() avoids any
5171 		// security problems because of the predictable number.
5172 		nr = (mch_get_pid() + (long)time(NULL)) % 1000000L;
5173 		itmplen = STRLEN(itmp);
5174 
5175 		// Try up to 10000 different values until we find a name that
5176 		// doesn't exist.
5177 		for (off = 0; off < 10000L; ++off)
5178 		{
5179 		    int		r;
5180 #  if defined(UNIX) || defined(VMS)
5181 		    mode_t	umask_save;
5182 #  endif
5183 
5184 		    sprintf((char *)itmp + itmplen, "v%ld", nr + off);
5185 #  ifndef EEXIST
5186 		    // If mkdir() does not set errno to EEXIST, check for
5187 		    // existing file here.  There is a race condition then,
5188 		    // although it's fail-safe.
5189 		    if (mch_stat((char *)itmp, &st) >= 0)
5190 			continue;
5191 #  endif
5192 #  if defined(UNIX) || defined(VMS)
5193 		    // Make sure the umask doesn't remove the executable bit.
5194 		    // "repl" has been reported to use "177".
5195 		    umask_save = umask(077);
5196 #  endif
5197 		    r = vim_mkdir(itmp, 0700);
5198 #  if defined(UNIX) || defined(VMS)
5199 		    (void)umask(umask_save);
5200 #  endif
5201 		    if (r == 0)
5202 		    {
5203 			vim_settempdir(itmp);
5204 			break;
5205 		    }
5206 #  ifdef EEXIST
5207 		    // If the mkdir() didn't fail because the file/dir exists,
5208 		    // we probably can't create any dir here, try another
5209 		    // place.
5210 		    if (errno != EEXIST)
5211 #  endif
5212 			break;
5213 		}
5214 # endif // HAVE_MKDTEMP
5215 		if (vim_tempdir != NULL)
5216 		    break;
5217 	    }
5218 	}
5219     }
5220 
5221     if (vim_tempdir != NULL)
5222     {
5223 	// There is no need to check if the file exists, because we own the
5224 	// directory and nobody else creates a file in it.
5225 	sprintf((char *)itmp, "%s%ld", vim_tempdir, temp_count++);
5226 	return vim_strsave(itmp);
5227     }
5228 
5229     return NULL;
5230 
5231 #else // TEMPDIRNAMES
5232 
5233 # ifdef MSWIN
5234     WCHAR	wszTempFile[_MAX_PATH + 1];
5235     WCHAR	buf4[4];
5236     WCHAR	*chartab = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
5237     char_u	*retval;
5238     char_u	*p;
5239     char_u	*shname;
5240     long	i;
5241 
5242     wcscpy(itmp, L"");
5243     if (GetTempPathW(_MAX_PATH, wszTempFile) == 0)
5244     {
5245 	wszTempFile[0] = L'.';	// GetTempPathW() failed, use current dir
5246 	wszTempFile[1] = L'\\';
5247 	wszTempFile[2] = NUL;
5248     }
5249     wcscpy(buf4, L"VIM");
5250 
5251     // randomize the name to avoid collisions
5252     i = mch_get_pid() + extra_char;
5253     buf4[1] = chartab[i % 36];
5254     buf4[2] = chartab[101 * i % 36];
5255     if (GetTempFileNameW(wszTempFile, buf4, 0, itmp) == 0)
5256 	return NULL;
5257     if (!keep)
5258 	// GetTempFileName() will create the file, we don't want that
5259 	(void)DeleteFileW(itmp);
5260 
5261     // Backslashes in a temp file name cause problems when filtering with
5262     // "sh".  NOTE: This also checks 'shellcmdflag' to help those people who
5263     // didn't set 'shellslash' but only if not using PowerShell.
5264     retval = utf16_to_enc(itmp, NULL);
5265     shname = gettail(p_sh);
5266     if ((*p_shcf == '-' && !(strstr((char *)shname, "powershell") != NULL
5267 			     || strstr((char *)shname, "pwsh") != NULL ))
5268 								    || p_ssl)
5269 	for (p = retval; *p; ++p)
5270 	    if (*p == '\\')
5271 		*p = '/';
5272     return retval;
5273 
5274 # else // MSWIN
5275 
5276 #  ifdef USE_TMPNAM
5277     char_u	*p;
5278 
5279     // tmpnam() will make its own name
5280     p = tmpnam((char *)itmp);
5281     if (p == NULL || *p == NUL)
5282 	return NULL;
5283 #  else
5284     char_u	*p;
5285 
5286 #   ifdef VMS_TEMPNAM
5287     // mktemp() is not working on VMS.  It seems to be
5288     // a do-nothing function. Therefore we use tempnam().
5289     sprintf((char *)itmp, "VIM%c", extra_char);
5290     p = (char_u *)tempnam("tmp:", (char *)itmp);
5291     if (p != NULL)
5292     {
5293 	// VMS will use '.LIS' if we don't explicitly specify an extension,
5294 	// and VIM will then be unable to find the file later
5295 	STRCPY(itmp, p);
5296 	STRCAT(itmp, ".txt");
5297 	free(p);
5298     }
5299     else
5300 	return NULL;
5301 #   else
5302     STRCPY(itmp, TEMPNAME);
5303     if ((p = vim_strchr(itmp, '?')) != NULL)
5304 	*p = extra_char;
5305     if (mktemp((char *)itmp) == NULL)
5306 	return NULL;
5307 #   endif
5308 #  endif
5309 
5310     return vim_strsave(itmp);
5311 # endif // MSWIN
5312 #endif // TEMPDIRNAMES
5313 }
5314 
5315 #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
5316 /*
5317  * Convert all backslashes in fname to forward slashes in-place, unless when
5318  * it looks like a URL.
5319  */
5320     void
forward_slash(char_u * fname)5321 forward_slash(char_u *fname)
5322 {
5323     char_u	*p;
5324 
5325     if (path_with_url(fname))
5326 	return;
5327     for (p = fname; *p != NUL; ++p)
5328 	// The Big5 encoding can have '\' in the trail byte.
5329 	if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
5330 	    ++p;
5331 	else if (*p == '\\')
5332 	    *p = '/';
5333 }
5334 #endif
5335 
5336 /*
5337  * Try matching a filename with a "pattern" ("prog" is NULL), or use the
5338  * precompiled regprog "prog" ("pattern" is NULL).  That avoids calling
5339  * vim_regcomp() often.
5340  * Used for autocommands and 'wildignore'.
5341  * Returns TRUE if there is a match, FALSE otherwise.
5342  */
5343     int
match_file_pat(char_u * pattern,regprog_T ** prog,char_u * fname,char_u * sfname,char_u * tail,int allow_dirs)5344 match_file_pat(
5345     char_u	*pattern,		// pattern to match with
5346     regprog_T	**prog,			// pre-compiled regprog or NULL
5347     char_u	*fname,			// full path of file name
5348     char_u	*sfname,		// short file name or NULL
5349     char_u	*tail,			// tail of path
5350     int		allow_dirs)		// allow matching with dir
5351 {
5352     regmatch_T	regmatch;
5353     int		result = FALSE;
5354 
5355     regmatch.rm_ic = p_fic; // ignore case if 'fileignorecase' is set
5356     if (prog != NULL)
5357 	regmatch.regprog = *prog;
5358     else
5359 	regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
5360 
5361     /*
5362      * Try for a match with the pattern with:
5363      * 1. the full file name, when the pattern has a '/'.
5364      * 2. the short file name, when the pattern has a '/'.
5365      * 3. the tail of the file name, when the pattern has no '/'.
5366      */
5367     if (regmatch.regprog != NULL
5368 	     && ((allow_dirs
5369 		     && (vim_regexec(&regmatch, fname, (colnr_T)0)
5370 			 || (sfname != NULL
5371 			     && vim_regexec(&regmatch, sfname, (colnr_T)0))))
5372 		 || (!allow_dirs && vim_regexec(&regmatch, tail, (colnr_T)0))))
5373 	result = TRUE;
5374 
5375     if (prog != NULL)
5376 	*prog = regmatch.regprog;
5377     else
5378 	vim_regfree(regmatch.regprog);
5379     return result;
5380 }
5381 
5382 #if defined(FEAT_WILDIGN) || defined(PROTO)
5383 /*
5384  * Return TRUE if a file matches with a pattern in "list".
5385  * "list" is a comma-separated list of patterns, like 'wildignore'.
5386  * "sfname" is the short file name or NULL, "ffname" the long file name.
5387  */
5388     int
match_file_list(char_u * list,char_u * sfname,char_u * ffname)5389 match_file_list(char_u *list, char_u *sfname, char_u *ffname)
5390 {
5391     char_u	buf[100];
5392     char_u	*tail;
5393     char_u	*regpat;
5394     char	allow_dirs;
5395     int		match;
5396     char_u	*p;
5397 
5398     tail = gettail(sfname);
5399 
5400     // try all patterns in 'wildignore'
5401     p = list;
5402     while (*p)
5403     {
5404 	copy_option_part(&p, buf, 100, ",");
5405 	regpat = file_pat_to_reg_pat(buf, NULL, &allow_dirs, FALSE);
5406 	if (regpat == NULL)
5407 	    break;
5408 	match = match_file_pat(regpat, NULL, ffname, sfname,
5409 						       tail, (int)allow_dirs);
5410 	vim_free(regpat);
5411 	if (match)
5412 	    return TRUE;
5413     }
5414     return FALSE;
5415 }
5416 #endif
5417 
5418 /*
5419  * Convert the given pattern "pat" which has shell style wildcards in it, into
5420  * a regular expression, and return the result in allocated memory.  If there
5421  * is a directory path separator to be matched, then TRUE is put in
5422  * allow_dirs, otherwise FALSE is put there -- webb.
5423  * Handle backslashes before special characters, like "\*" and "\ ".
5424  *
5425  * Returns NULL when out of memory.
5426  */
5427     char_u *
file_pat_to_reg_pat(char_u * pat,char_u * pat_end,char * allow_dirs,int no_bslash UNUSED)5428 file_pat_to_reg_pat(
5429     char_u	*pat,
5430     char_u	*pat_end,	// first char after pattern or NULL
5431     char	*allow_dirs,	// Result passed back out in here
5432     int		no_bslash UNUSED) // Don't use a backward slash as pathsep
5433 {
5434     int		size = 2; // '^' at start, '$' at end
5435     char_u	*endp;
5436     char_u	*reg_pat;
5437     char_u	*p;
5438     int		i;
5439     int		nested = 0;
5440     int		add_dollar = TRUE;
5441 
5442     if (allow_dirs != NULL)
5443 	*allow_dirs = FALSE;
5444     if (pat_end == NULL)
5445 	pat_end = pat + STRLEN(pat);
5446 
5447     for (p = pat; p < pat_end; p++)
5448     {
5449 	switch (*p)
5450 	{
5451 	    case '*':
5452 	    case '.':
5453 	    case ',':
5454 	    case '{':
5455 	    case '}':
5456 	    case '~':
5457 		size += 2;	// extra backslash
5458 		break;
5459 #ifdef BACKSLASH_IN_FILENAME
5460 	    case '\\':
5461 	    case '/':
5462 		size += 4;	// could become "[\/]"
5463 		break;
5464 #endif
5465 	    default:
5466 		size++;
5467 		if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
5468 		{
5469 		    ++p;
5470 		    ++size;
5471 		}
5472 		break;
5473 	}
5474     }
5475     reg_pat = alloc(size + 1);
5476     if (reg_pat == NULL)
5477 	return NULL;
5478 
5479     i = 0;
5480 
5481     if (pat[0] == '*')
5482 	while (pat[0] == '*' && pat < pat_end - 1)
5483 	    pat++;
5484     else
5485 	reg_pat[i++] = '^';
5486     endp = pat_end - 1;
5487     if (endp >= pat && *endp == '*')
5488     {
5489 	while (endp - pat > 0 && *endp == '*')
5490 	    endp--;
5491 	add_dollar = FALSE;
5492     }
5493     for (p = pat; *p && nested >= 0 && p <= endp; p++)
5494     {
5495 	switch (*p)
5496 	{
5497 	    case '*':
5498 		reg_pat[i++] = '.';
5499 		reg_pat[i++] = '*';
5500 		while (p[1] == '*')	// "**" matches like "*"
5501 		    ++p;
5502 		break;
5503 	    case '.':
5504 	    case '~':
5505 		reg_pat[i++] = '\\';
5506 		reg_pat[i++] = *p;
5507 		break;
5508 	    case '?':
5509 		reg_pat[i++] = '.';
5510 		break;
5511 	    case '\\':
5512 		if (p[1] == NUL)
5513 		    break;
5514 #ifdef BACKSLASH_IN_FILENAME
5515 		if (!no_bslash)
5516 		{
5517 		    // translate:
5518 		    // "\x" to "\\x"  e.g., "dir\file"
5519 		    // "\*" to "\\.*" e.g., "dir\*.c"
5520 		    // "\?" to "\\."  e.g., "dir\??.c"
5521 		    // "\+" to "\+"   e.g., "fileX\+.c"
5522 		    if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
5523 			    && p[1] != '+')
5524 		    {
5525 			reg_pat[i++] = '[';
5526 			reg_pat[i++] = '\\';
5527 			reg_pat[i++] = '/';
5528 			reg_pat[i++] = ']';
5529 			if (allow_dirs != NULL)
5530 			    *allow_dirs = TRUE;
5531 			break;
5532 		    }
5533 		}
5534 #endif
5535 		// Undo escaping from ExpandEscape():
5536 		// foo\?bar -> foo?bar
5537 		// foo\%bar -> foo%bar
5538 		// foo\,bar -> foo,bar
5539 		// foo\ bar -> foo bar
5540 		// Don't unescape \, * and others that are also special in a
5541 		// regexp.
5542 		// An escaped { must be unescaped since we use magic not
5543 		// verymagic.  Use "\\\{n,m\}"" to get "\{n,m}".
5544 		if (*++p == '?'
5545 #ifdef BACKSLASH_IN_FILENAME
5546 			&& no_bslash
5547 #endif
5548 			)
5549 		    reg_pat[i++] = '?';
5550 		else
5551 		    if (*p == ',' || *p == '%' || *p == '#'
5552 			       || vim_isspace(*p) || *p == '{' || *p == '}')
5553 			reg_pat[i++] = *p;
5554 		    else if (*p == '\\' && p[1] == '\\' && p[2] == '{')
5555 		    {
5556 			reg_pat[i++] = '\\';
5557 			reg_pat[i++] = '{';
5558 			p += 2;
5559 		    }
5560 		    else
5561 		    {
5562 			if (allow_dirs != NULL && vim_ispathsep(*p)
5563 #ifdef BACKSLASH_IN_FILENAME
5564 				&& (!no_bslash || *p != '\\')
5565 #endif
5566 				)
5567 			    *allow_dirs = TRUE;
5568 			reg_pat[i++] = '\\';
5569 			reg_pat[i++] = *p;
5570 		    }
5571 		break;
5572 #ifdef BACKSLASH_IN_FILENAME
5573 	    case '/':
5574 		reg_pat[i++] = '[';
5575 		reg_pat[i++] = '\\';
5576 		reg_pat[i++] = '/';
5577 		reg_pat[i++] = ']';
5578 		if (allow_dirs != NULL)
5579 		    *allow_dirs = TRUE;
5580 		break;
5581 #endif
5582 	    case '{':
5583 		reg_pat[i++] = '\\';
5584 		reg_pat[i++] = '(';
5585 		nested++;
5586 		break;
5587 	    case '}':
5588 		reg_pat[i++] = '\\';
5589 		reg_pat[i++] = ')';
5590 		--nested;
5591 		break;
5592 	    case ',':
5593 		if (nested)
5594 		{
5595 		    reg_pat[i++] = '\\';
5596 		    reg_pat[i++] = '|';
5597 		}
5598 		else
5599 		    reg_pat[i++] = ',';
5600 		break;
5601 	    default:
5602 		if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
5603 		    reg_pat[i++] = *p++;
5604 		else if (allow_dirs != NULL && vim_ispathsep(*p))
5605 		    *allow_dirs = TRUE;
5606 		reg_pat[i++] = *p;
5607 		break;
5608 	}
5609     }
5610     if (add_dollar)
5611 	reg_pat[i++] = '$';
5612     reg_pat[i] = NUL;
5613     if (nested != 0)
5614     {
5615 	if (nested < 0)
5616 	    emsg(_("E219: Missing {."));
5617 	else
5618 	    emsg(_("E220: Missing }."));
5619 	VIM_CLEAR(reg_pat);
5620     }
5621     return reg_pat;
5622 }
5623 
5624 #if defined(EINTR) || defined(PROTO)
5625 /*
5626  * Version of read() that retries when interrupted by EINTR (possibly
5627  * by a SIGWINCH).
5628  */
5629     long
read_eintr(int fd,void * buf,size_t bufsize)5630 read_eintr(int fd, void *buf, size_t bufsize)
5631 {
5632     long ret;
5633 
5634     for (;;)
5635     {
5636 	ret = vim_read(fd, buf, bufsize);
5637 	if (ret >= 0 || errno != EINTR)
5638 	    break;
5639     }
5640     return ret;
5641 }
5642 
5643 /*
5644  * Version of write() that retries when interrupted by EINTR (possibly
5645  * by a SIGWINCH).
5646  */
5647     long
write_eintr(int fd,void * buf,size_t bufsize)5648 write_eintr(int fd, void *buf, size_t bufsize)
5649 {
5650     long    ret = 0;
5651     long    wlen;
5652 
5653     // Repeat the write() so long it didn't fail, other than being interrupted
5654     // by a signal.
5655     while (ret < (long)bufsize)
5656     {
5657 	wlen = vim_write(fd, (char *)buf + ret, bufsize - ret);
5658 	if (wlen < 0)
5659 	{
5660 	    if (errno != EINTR)
5661 		break;
5662 	}
5663 	else
5664 	    ret += wlen;
5665     }
5666     return ret;
5667 }
5668 #endif
5669