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) || defined(__MINT__) 17 # include <limits.h> /* for SSIZE_MAX */ 18 #endif 19 20 #if defined(HAVE_UTIME) && defined(HAVE_UTIME_H) 21 # include <utime.h> /* for struct utimbuf */ 22 #endif 23 24 #define BUFSIZE 8192 /* size of normal write buffer */ 25 #define SMBUFSIZE 256 /* size of emergency write buffer */ 26 27 /* Is there any system that doesn't have access()? */ 28 #define USE_MCH_ACCESS 29 30 static char_u *next_fenc(char_u **pp); 31 #ifdef FEAT_EVAL 32 static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp); 33 #endif 34 #ifdef FEAT_VIMINFO 35 static void check_marks_read(void); 36 #endif 37 #ifdef FEAT_CRYPT 38 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); 39 #endif 40 static int set_rw_fname(char_u *fname, char_u *sfname); 41 static int msg_add_fileformat(int eol_type); 42 static void msg_add_eol(void); 43 static int check_mtime(buf_T *buf, stat_T *s); 44 static int time_differs(long t1, long t2); 45 46 #define HAS_BW_FLAGS 47 #define FIO_LATIN1 0x01 /* convert Latin1 */ 48 #define FIO_UTF8 0x02 /* convert UTF-8 */ 49 #define FIO_UCS2 0x04 /* convert UCS-2 */ 50 #define FIO_UCS4 0x08 /* convert UCS-4 */ 51 #define FIO_UTF16 0x10 /* convert UTF-16 */ 52 #ifdef MSWIN 53 # define FIO_CODEPAGE 0x20 /* convert MS-Windows codepage */ 54 # define FIO_PUT_CP(x) (((x) & 0xffff) << 16) /* put codepage in top word */ 55 # define FIO_GET_CP(x) (((x)>>16) & 0xffff) /* get codepage from top word */ 56 #endif 57 #ifdef MACOS_CONVERT 58 # define FIO_MACROMAN 0x20 /* convert MacRoman */ 59 #endif 60 #define FIO_ENDIAN_L 0x80 /* little endian */ 61 #define FIO_ENCRYPTED 0x1000 /* encrypt written bytes */ 62 #define FIO_NOCONVERT 0x2000 /* skip encoding conversion */ 63 #define FIO_UCSBOM 0x4000 /* check for BOM at start of file */ 64 #define FIO_ALL -1 /* allow all formats */ 65 66 /* When converting, a read() or write() may leave some bytes to be converted 67 * for the next call. The value is guessed... */ 68 #define CONV_RESTLEN 30 69 70 /* We have to guess how much a sequence of bytes may expand when converting 71 * with iconv() to be able to allocate a buffer. */ 72 #define ICONV_MULT 8 73 74 /* 75 * Structure to pass arguments from buf_write() to buf_write_bytes(). 76 */ 77 struct bw_info 78 { 79 int bw_fd; /* file descriptor */ 80 char_u *bw_buf; /* buffer with data to be written */ 81 int bw_len; /* length of data */ 82 #ifdef HAS_BW_FLAGS 83 int bw_flags; /* FIO_ flags */ 84 #endif 85 #ifdef FEAT_CRYPT 86 buf_T *bw_buffer; /* buffer being written */ 87 #endif 88 char_u bw_rest[CONV_RESTLEN]; /* not converted bytes */ 89 int bw_restlen; /* nr of bytes in bw_rest[] */ 90 int bw_first; /* first write call */ 91 char_u *bw_conv_buf; /* buffer for writing converted chars */ 92 int bw_conv_buflen; /* size of bw_conv_buf */ 93 int bw_conv_error; /* set for conversion error */ 94 linenr_T bw_conv_error_lnum; /* first line with error or zero */ 95 linenr_T bw_start_lnum; /* line number at start of buffer */ 96 #ifdef USE_ICONV 97 iconv_t bw_iconv_fd; /* descriptor for iconv() or -1 */ 98 #endif 99 }; 100 101 static int buf_write_bytes(struct bw_info *ip); 102 103 static linenr_T readfile_linenr(linenr_T linecnt, char_u *p, char_u *endp); 104 static int ucs2bytes(unsigned c, char_u **pp, int flags); 105 static int need_conversion(char_u *fenc); 106 static int get_fio_flags(char_u *ptr); 107 static char_u *check_for_bom(char_u *p, long size, int *lenp, int flags); 108 static int make_bom(char_u *buf, char_u *name); 109 #ifdef MSWIN 110 static int get_win_fio_flags(char_u *ptr); 111 #endif 112 #ifdef MACOS_CONVERT 113 static int get_mac_fio_flags(char_u *ptr); 114 #endif 115 static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name"); 116 117 void 118 filemess( 119 buf_T *buf, 120 char_u *name, 121 char_u *s, 122 int attr) 123 { 124 int msg_scroll_save; 125 126 if (msg_silent != 0) 127 return; 128 msg_add_fname(buf, name); /* put file name in IObuff with quotes */ 129 /* If it's extremely long, truncate it. */ 130 if (STRLEN(IObuff) > IOSIZE - 80) 131 IObuff[IOSIZE - 80] = NUL; 132 STRCAT(IObuff, s); 133 /* 134 * For the first message may have to start a new line. 135 * For further ones overwrite the previous one, reset msg_scroll before 136 * calling filemess(). 137 */ 138 msg_scroll_save = msg_scroll; 139 if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) 140 msg_scroll = FALSE; 141 if (!msg_scroll) /* wait a bit when overwriting an error msg */ 142 check_for_delay(FALSE); 143 msg_start(); 144 msg_scroll = msg_scroll_save; 145 msg_scrolled_ign = TRUE; 146 /* may truncate the message to avoid a hit-return prompt */ 147 msg_outtrans_attr(msg_may_trunc(FALSE, IObuff), attr); 148 msg_clr_eos(); 149 out_flush(); 150 msg_scrolled_ign = FALSE; 151 } 152 153 /* 154 * Read lines from file "fname" into the buffer after line "from". 155 * 156 * 1. We allocate blocks with lalloc, as big as possible. 157 * 2. Each block is filled with characters from the file with a single read(). 158 * 3. The lines are inserted in the buffer with ml_append(). 159 * 160 * (caller must check that fname != NULL, unless READ_STDIN is used) 161 * 162 * "lines_to_skip" is the number of lines that must be skipped 163 * "lines_to_read" is the number of lines that are appended 164 * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM. 165 * 166 * flags: 167 * READ_NEW starting to edit a new buffer 168 * READ_FILTER reading filter output 169 * READ_STDIN read from stdin instead of a file 170 * READ_BUFFER read from curbuf instead of a file (converting after reading 171 * stdin) 172 * READ_DUMMY read into a dummy buffer (to check if file contents changed) 173 * READ_KEEP_UNDO don't clear undo info or read it from a file 174 * READ_FIFO read from fifo/socket instead of a file 175 * 176 * return FAIL for failure, NOTDONE for directory (failure), or OK 177 */ 178 int 179 readfile( 180 char_u *fname, 181 char_u *sfname, 182 linenr_T from, 183 linenr_T lines_to_skip, 184 linenr_T lines_to_read, 185 exarg_T *eap, /* can be NULL! */ 186 int flags) 187 { 188 int fd = 0; 189 int newfile = (flags & READ_NEW); 190 int check_readonly; 191 int filtering = (flags & READ_FILTER); 192 int read_stdin = (flags & READ_STDIN); 193 int read_buffer = (flags & READ_BUFFER); 194 int read_fifo = (flags & READ_FIFO); 195 int set_options = newfile || read_buffer 196 || (eap != NULL && eap->read_edit); 197 linenr_T read_buf_lnum = 1; /* next line to read from curbuf */ 198 colnr_T read_buf_col = 0; /* next char to read from this line */ 199 char_u c; 200 linenr_T lnum = from; 201 char_u *ptr = NULL; /* pointer into read buffer */ 202 char_u *buffer = NULL; /* read buffer */ 203 char_u *new_buffer = NULL; /* init to shut up gcc */ 204 char_u *line_start = NULL; /* init to shut up gcc */ 205 int wasempty; /* buffer was empty before reading */ 206 colnr_T len; 207 long size = 0; 208 char_u *p; 209 off_T filesize = 0; 210 int skip_read = FALSE; 211 #ifdef FEAT_CRYPT 212 char_u *cryptkey = NULL; 213 int did_ask_for_key = FALSE; 214 #endif 215 #ifdef FEAT_PERSISTENT_UNDO 216 context_sha256_T sha_ctx; 217 int read_undo_file = FALSE; 218 #endif 219 int split = 0; /* number of split lines */ 220 #define UNKNOWN 0x0fffffff /* file size is unknown */ 221 linenr_T linecnt; 222 int error = FALSE; /* errors encountered */ 223 int ff_error = EOL_UNKNOWN; /* file format with errors */ 224 long linerest = 0; /* remaining chars in line */ 225 #ifdef UNIX 226 int perm = 0; 227 int swap_mode = -1; /* protection bits for swap file */ 228 #else 229 int perm; 230 #endif 231 int fileformat = 0; /* end-of-line format */ 232 int keep_fileformat = FALSE; 233 stat_T st; 234 int file_readonly; 235 linenr_T skip_count = 0; 236 linenr_T read_count = 0; 237 int msg_save = msg_scroll; 238 linenr_T read_no_eol_lnum = 0; /* non-zero lnum when last line of 239 * last read was missing the eol */ 240 int try_mac; 241 int try_dos; 242 int try_unix; 243 int file_rewind = FALSE; 244 int can_retry; 245 linenr_T conv_error = 0; /* line nr with conversion error */ 246 linenr_T illegal_byte = 0; /* line nr with illegal byte */ 247 int keep_dest_enc = FALSE; /* don't retry when char doesn't fit 248 in destination encoding */ 249 int bad_char_behavior = BAD_REPLACE; 250 /* BAD_KEEP, BAD_DROP or character to 251 * replace with */ 252 char_u *tmpname = NULL; /* name of 'charconvert' output file */ 253 int fio_flags = 0; 254 char_u *fenc; /* fileencoding to use */ 255 int fenc_alloced; /* fenc_next is in allocated memory */ 256 char_u *fenc_next = NULL; /* next item in 'fencs' or NULL */ 257 int advance_fenc = FALSE; 258 long real_size = 0; 259 #ifdef USE_ICONV 260 iconv_t iconv_fd = (iconv_t)-1; /* descriptor for iconv() or -1 */ 261 # ifdef FEAT_EVAL 262 int did_iconv = FALSE; /* TRUE when iconv() failed and trying 263 'charconvert' next */ 264 # endif 265 #endif 266 int converted = FALSE; /* TRUE if conversion done */ 267 int notconverted = FALSE; /* TRUE if conversion wanted but it 268 wasn't possible */ 269 char_u conv_rest[CONV_RESTLEN]; 270 int conv_restlen = 0; /* nr of bytes in conv_rest[] */ 271 buf_T *old_curbuf; 272 char_u *old_b_ffname; 273 char_u *old_b_fname; 274 int using_b_ffname; 275 int using_b_fname; 276 277 au_did_filetype = FALSE; /* reset before triggering any autocommands */ 278 279 curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */ 280 281 /* 282 * If there is no file name yet, use the one for the read file. 283 * BF_NOTEDITED is set to reflect this. 284 * Don't do this for a read from a filter. 285 * Only do this when 'cpoptions' contains the 'f' flag. 286 */ 287 if (curbuf->b_ffname == NULL 288 && !filtering 289 && fname != NULL 290 && vim_strchr(p_cpo, CPO_FNAMER) != NULL 291 && !(flags & READ_DUMMY)) 292 { 293 if (set_rw_fname(fname, sfname) == FAIL) 294 return FAIL; 295 } 296 297 /* Remember the initial values of curbuf, curbuf->b_ffname and 298 * curbuf->b_fname to detect whether they are altered as a result of 299 * executing nasty autocommands. Also check if "fname" and "sfname" 300 * point to one of these values. */ 301 old_curbuf = curbuf; 302 old_b_ffname = curbuf->b_ffname; 303 old_b_fname = curbuf->b_fname; 304 using_b_ffname = (fname == curbuf->b_ffname) 305 || (sfname == curbuf->b_ffname); 306 using_b_fname = (fname == curbuf->b_fname) || (sfname == curbuf->b_fname); 307 308 /* After reading a file the cursor line changes but we don't want to 309 * display the line. */ 310 ex_no_reprint = TRUE; 311 312 /* don't display the file info for another buffer now */ 313 need_fileinfo = FALSE; 314 315 /* 316 * For Unix: Use the short file name whenever possible. 317 * Avoids problems with networks and when directory names are changed. 318 * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to 319 * another directory, which we don't detect. 320 */ 321 if (sfname == NULL) 322 sfname = fname; 323 #if defined(UNIX) 324 fname = sfname; 325 #endif 326 327 /* 328 * The BufReadCmd and FileReadCmd events intercept the reading process by 329 * executing the associated commands instead. 330 */ 331 if (!filtering && !read_stdin && !read_buffer) 332 { 333 pos_T pos; 334 335 pos = curbuf->b_op_start; 336 337 /* Set '[ mark to the line above where the lines go (line 1 if zero). */ 338 curbuf->b_op_start.lnum = ((from == 0) ? 1 : from); 339 curbuf->b_op_start.col = 0; 340 341 if (newfile) 342 { 343 if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname, 344 FALSE, curbuf, eap)) 345 #ifdef FEAT_EVAL 346 return aborting() ? FAIL : OK; 347 #else 348 return OK; 349 #endif 350 } 351 else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname, 352 FALSE, NULL, eap)) 353 #ifdef FEAT_EVAL 354 return aborting() ? FAIL : OK; 355 #else 356 return OK; 357 #endif 358 359 curbuf->b_op_start = pos; 360 } 361 362 if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) 363 msg_scroll = FALSE; /* overwrite previous file message */ 364 else 365 msg_scroll = TRUE; /* don't overwrite previous file message */ 366 367 /* 368 * If the name ends in a path separator, we can't open it. Check here, 369 * because reading the file may actually work, but then creating the swap 370 * file may destroy it! Reported on MS-DOS and Win 95. 371 * If the name is too long we might crash further on, quit here. 372 */ 373 if (fname != NULL && *fname != NUL) 374 { 375 p = fname + STRLEN(fname); 376 if (after_pathsep(fname, p) || STRLEN(fname) >= MAXPATHL) 377 { 378 filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0); 379 msg_end(); 380 msg_scroll = msg_save; 381 return FAIL; 382 } 383 } 384 385 if (!read_stdin && !read_buffer && !read_fifo) 386 { 387 #ifdef UNIX 388 /* 389 * On Unix it is possible to read a directory, so we have to 390 * check for it before the mch_open(). 391 */ 392 perm = mch_getperm(fname); 393 if (perm >= 0 && !S_ISREG(perm) /* not a regular file ... */ 394 && !S_ISFIFO(perm) /* ... or fifo */ 395 && !S_ISSOCK(perm) /* ... or socket */ 396 # ifdef OPEN_CHR_FILES 397 && !(S_ISCHR(perm) && is_dev_fd_file(fname)) 398 /* ... or a character special file named /dev/fd/<n> */ 399 # endif 400 ) 401 { 402 int retval = FAIL; 403 404 if (S_ISDIR(perm)) 405 { 406 filemess(curbuf, fname, (char_u *)_("is a directory"), 0); 407 retval = NOTDONE; 408 } 409 else 410 filemess(curbuf, fname, (char_u *)_("is not a file"), 0); 411 msg_end(); 412 msg_scroll = msg_save; 413 return retval; 414 } 415 #endif 416 #if defined(MSWIN) 417 /* 418 * MS-Windows allows opening a device, but we will probably get stuck 419 * trying to read it. 420 */ 421 if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE) 422 { 423 filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0); 424 msg_end(); 425 msg_scroll = msg_save; 426 return FAIL; 427 } 428 #endif 429 } 430 431 /* Set default or forced 'fileformat' and 'binary'. */ 432 set_file_options(set_options, eap); 433 434 /* 435 * When opening a new file we take the readonly flag from the file. 436 * Default is r/w, can be set to r/o below. 437 * Don't reset it when in readonly mode 438 * Only set/reset b_p_ro when BF_CHECK_RO is set. 439 */ 440 check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO)); 441 if (check_readonly && !readonlymode) 442 curbuf->b_p_ro = FALSE; 443 444 if (newfile && !read_stdin && !read_buffer && !read_fifo) 445 { 446 /* Remember time of file. */ 447 if (mch_stat((char *)fname, &st) >= 0) 448 { 449 buf_store_time(curbuf, &st, fname); 450 curbuf->b_mtime_read = curbuf->b_mtime; 451 #ifdef UNIX 452 /* 453 * Use the protection bits of the original file for the swap file. 454 * This makes it possible for others to read the name of the 455 * edited file from the swapfile, but only if they can read the 456 * edited file. 457 * Remove the "write" and "execute" bits for group and others 458 * (they must not write the swapfile). 459 * Add the "read" and "write" bits for the user, otherwise we may 460 * not be able to write to the file ourselves. 461 * Setting the bits is done below, after creating the swap file. 462 */ 463 swap_mode = (st.st_mode & 0644) | 0600; 464 #endif 465 #ifdef FEAT_CW_EDITOR 466 /* Get the FSSpec on MacOS 467 * TODO: Update it properly when the buffer name changes 468 */ 469 (void)GetFSSpecFromPath(curbuf->b_ffname, &curbuf->b_FSSpec); 470 #endif 471 #ifdef VMS 472 curbuf->b_fab_rfm = st.st_fab_rfm; 473 curbuf->b_fab_rat = st.st_fab_rat; 474 curbuf->b_fab_mrs = st.st_fab_mrs; 475 #endif 476 } 477 else 478 { 479 curbuf->b_mtime = 0; 480 curbuf->b_mtime_read = 0; 481 curbuf->b_orig_size = 0; 482 curbuf->b_orig_mode = 0; 483 } 484 485 /* Reset the "new file" flag. It will be set again below when the 486 * file doesn't exist. */ 487 curbuf->b_flags &= ~(BF_NEW | BF_NEW_W); 488 } 489 490 /* 491 * for UNIX: check readonly with perm and mch_access() 492 * for Amiga: check readonly by trying to open the file for writing 493 */ 494 file_readonly = FALSE; 495 if (read_stdin) 496 { 497 #if defined(MSWIN) 498 /* Force binary I/O on stdin to avoid CR-LF -> LF conversion. */ 499 setmode(0, O_BINARY); 500 #endif 501 } 502 else if (!read_buffer) 503 { 504 #ifdef USE_MCH_ACCESS 505 if ( 506 # ifdef UNIX 507 !(perm & 0222) || 508 # endif 509 mch_access((char *)fname, W_OK)) 510 file_readonly = TRUE; 511 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); 512 #else 513 if (!newfile 514 || readonlymode 515 || (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0) 516 { 517 file_readonly = TRUE; 518 /* try to open ro */ 519 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); 520 } 521 #endif 522 } 523 524 if (fd < 0) /* cannot open at all */ 525 { 526 #ifndef UNIX 527 int isdir_f; 528 #endif 529 msg_scroll = msg_save; 530 #ifndef UNIX 531 /* 532 * On Amiga we can't open a directory, check here. 533 */ 534 isdir_f = (mch_isdir(fname)); 535 perm = mch_getperm(fname); /* check if the file exists */ 536 if (isdir_f) 537 { 538 filemess(curbuf, sfname, (char_u *)_("is a directory"), 0); 539 curbuf->b_p_ro = TRUE; /* must use "w!" now */ 540 } 541 else 542 #endif 543 if (newfile) 544 { 545 if (perm < 0 546 #ifdef ENOENT 547 && errno == ENOENT 548 #endif 549 ) 550 { 551 /* 552 * Set the 'new-file' flag, so that when the file has 553 * been created by someone else, a ":w" will complain. 554 */ 555 curbuf->b_flags |= BF_NEW; 556 557 /* Create a swap file now, so that other Vims are warned 558 * that we are editing this file. Don't do this for a 559 * "nofile" or "nowrite" buffer type. */ 560 #ifdef FEAT_QUICKFIX 561 if (!bt_dontwrite(curbuf)) 562 #endif 563 { 564 check_need_swap(newfile); 565 /* SwapExists autocommand may mess things up */ 566 if (curbuf != old_curbuf 567 || (using_b_ffname 568 && (old_b_ffname != curbuf->b_ffname)) 569 || (using_b_fname 570 && (old_b_fname != curbuf->b_fname))) 571 { 572 emsg(_(e_auchangedbuf)); 573 return FAIL; 574 } 575 } 576 if (dir_of_file_exists(fname)) 577 filemess(curbuf, sfname, (char_u *)_("[New File]"), 0); 578 else 579 filemess(curbuf, sfname, 580 (char_u *)_("[New DIRECTORY]"), 0); 581 #ifdef FEAT_VIMINFO 582 /* Even though this is a new file, it might have been 583 * edited before and deleted. Get the old marks. */ 584 check_marks_read(); 585 #endif 586 /* Set forced 'fileencoding'. */ 587 if (eap != NULL) 588 set_forced_fenc(eap); 589 apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname, 590 FALSE, curbuf, eap); 591 /* remember the current fileformat */ 592 save_file_ff(curbuf); 593 594 #if defined(FEAT_EVAL) 595 if (aborting()) /* autocmds may abort script processing */ 596 return FAIL; 597 #endif 598 return OK; /* a new file is not an error */ 599 } 600 else 601 { 602 filemess(curbuf, sfname, (char_u *)( 603 # ifdef EFBIG 604 (errno == EFBIG) ? _("[File too big]") : 605 # endif 606 # ifdef EOVERFLOW 607 (errno == EOVERFLOW) ? _("[File too big]") : 608 # endif 609 _("[Permission Denied]")), 0); 610 curbuf->b_p_ro = TRUE; /* must use "w!" now */ 611 } 612 } 613 614 return FAIL; 615 } 616 617 /* 618 * Only set the 'ro' flag for readonly files the first time they are 619 * loaded. Help files always get readonly mode 620 */ 621 if ((check_readonly && file_readonly) || curbuf->b_help) 622 curbuf->b_p_ro = TRUE; 623 624 if (set_options) 625 { 626 /* Don't change 'eol' if reading from buffer as it will already be 627 * correctly set when reading stdin. */ 628 if (!read_buffer) 629 { 630 curbuf->b_p_eol = TRUE; 631 curbuf->b_start_eol = TRUE; 632 } 633 curbuf->b_p_bomb = FALSE; 634 curbuf->b_start_bomb = FALSE; 635 } 636 637 /* Create a swap file now, so that other Vims are warned that we are 638 * editing this file. 639 * Don't do this for a "nofile" or "nowrite" buffer type. */ 640 #ifdef FEAT_QUICKFIX 641 if (!bt_dontwrite(curbuf)) 642 #endif 643 { 644 check_need_swap(newfile); 645 if (!read_stdin && (curbuf != old_curbuf 646 || (using_b_ffname && (old_b_ffname != curbuf->b_ffname)) 647 || (using_b_fname && (old_b_fname != curbuf->b_fname)))) 648 { 649 emsg(_(e_auchangedbuf)); 650 if (!read_buffer) 651 close(fd); 652 return FAIL; 653 } 654 #ifdef UNIX 655 /* Set swap file protection bits after creating it. */ 656 if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL 657 && curbuf->b_ml.ml_mfp->mf_fname != NULL) 658 { 659 char_u *swap_fname = curbuf->b_ml.ml_mfp->mf_fname; 660 661 /* 662 * If the group-read bit is set but not the world-read bit, then 663 * the group must be equal to the group of the original file. If 664 * we can't make that happen then reset the group-read bit. This 665 * avoids making the swap file readable to more users when the 666 * primary group of the user is too permissive. 667 */ 668 if ((swap_mode & 044) == 040) 669 { 670 stat_T swap_st; 671 672 if (mch_stat((char *)swap_fname, &swap_st) >= 0 673 && st.st_gid != swap_st.st_gid 674 # ifdef HAVE_FCHOWN 675 && fchown(curbuf->b_ml.ml_mfp->mf_fd, -1, st.st_gid) 676 == -1 677 # endif 678 ) 679 swap_mode &= 0600; 680 } 681 682 (void)mch_setperm(swap_fname, (long)swap_mode); 683 } 684 #endif 685 } 686 687 #if defined(HAS_SWAP_EXISTS_ACTION) 688 /* If "Quit" selected at ATTENTION dialog, don't load the file */ 689 if (swap_exists_action == SEA_QUIT) 690 { 691 if (!read_buffer && !read_stdin) 692 close(fd); 693 return FAIL; 694 } 695 #endif 696 697 ++no_wait_return; /* don't wait for return yet */ 698 699 /* 700 * Set '[ mark to the line above where the lines go (line 1 if zero). 701 */ 702 curbuf->b_op_start.lnum = ((from == 0) ? 1 : from); 703 curbuf->b_op_start.col = 0; 704 705 try_mac = (vim_strchr(p_ffs, 'm') != NULL); 706 try_dos = (vim_strchr(p_ffs, 'd') != NULL); 707 try_unix = (vim_strchr(p_ffs, 'x') != NULL); 708 709 if (!read_buffer) 710 { 711 int m = msg_scroll; 712 int n = msg_scrolled; 713 714 /* 715 * The file must be closed again, the autocommands may want to change 716 * the file before reading it. 717 */ 718 if (!read_stdin) 719 close(fd); /* ignore errors */ 720 721 /* 722 * The output from the autocommands should not overwrite anything and 723 * should not be overwritten: Set msg_scroll, restore its value if no 724 * output was done. 725 */ 726 msg_scroll = TRUE; 727 if (filtering) 728 apply_autocmds_exarg(EVENT_FILTERREADPRE, NULL, sfname, 729 FALSE, curbuf, eap); 730 else if (read_stdin) 731 apply_autocmds_exarg(EVENT_STDINREADPRE, NULL, sfname, 732 FALSE, curbuf, eap); 733 else if (newfile) 734 apply_autocmds_exarg(EVENT_BUFREADPRE, NULL, sfname, 735 FALSE, curbuf, eap); 736 else 737 apply_autocmds_exarg(EVENT_FILEREADPRE, sfname, sfname, 738 FALSE, NULL, eap); 739 /* autocommands may have changed it */ 740 try_mac = (vim_strchr(p_ffs, 'm') != NULL); 741 try_dos = (vim_strchr(p_ffs, 'd') != NULL); 742 try_unix = (vim_strchr(p_ffs, 'x') != NULL); 743 744 if (msg_scrolled == n) 745 msg_scroll = m; 746 747 #ifdef FEAT_EVAL 748 if (aborting()) /* autocmds may abort script processing */ 749 { 750 --no_wait_return; 751 msg_scroll = msg_save; 752 curbuf->b_p_ro = TRUE; /* must use "w!" now */ 753 return FAIL; 754 } 755 #endif 756 /* 757 * Don't allow the autocommands to change the current buffer. 758 * Try to re-open the file. 759 * 760 * Don't allow the autocommands to change the buffer name either 761 * (cd for example) if it invalidates fname or sfname. 762 */ 763 if (!read_stdin && (curbuf != old_curbuf 764 || (using_b_ffname && (old_b_ffname != curbuf->b_ffname)) 765 || (using_b_fname && (old_b_fname != curbuf->b_fname)) 766 || (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0)) 767 { 768 --no_wait_return; 769 msg_scroll = msg_save; 770 if (fd < 0) 771 emsg(_("E200: *ReadPre autocommands made the file unreadable")); 772 else 773 emsg(_("E201: *ReadPre autocommands must not change current buffer")); 774 curbuf->b_p_ro = TRUE; /* must use "w!" now */ 775 return FAIL; 776 } 777 } 778 779 /* Autocommands may add lines to the file, need to check if it is empty */ 780 wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY); 781 782 if (!recoverymode && !filtering && !(flags & READ_DUMMY)) 783 { 784 /* 785 * Show the user that we are busy reading the input. Sometimes this 786 * may take a while. When reading from stdin another program may 787 * still be running, don't move the cursor to the last line, unless 788 * always using the GUI. 789 */ 790 if (read_stdin) 791 { 792 if (!is_not_a_term()) 793 { 794 #ifndef ALWAYS_USE_GUI 795 mch_msg(_("Vim: Reading from stdin...\n")); 796 #endif 797 #ifdef FEAT_GUI 798 /* Also write a message in the GUI window, if there is one. */ 799 if (gui.in_use && !gui.dying && !gui.starting) 800 { 801 p = (char_u *)_("Reading from stdin..."); 802 gui_write(p, (int)STRLEN(p)); 803 } 804 #endif 805 } 806 } 807 else if (!read_buffer) 808 filemess(curbuf, sfname, (char_u *)"", 0); 809 } 810 811 msg_scroll = FALSE; /* overwrite the file message */ 812 813 /* 814 * Set linecnt now, before the "retry" caused by a wrong guess for 815 * fileformat, and after the autocommands, which may change them. 816 */ 817 linecnt = curbuf->b_ml.ml_line_count; 818 819 /* "++bad=" argument. */ 820 if (eap != NULL && eap->bad_char != 0) 821 { 822 bad_char_behavior = eap->bad_char; 823 if (set_options) 824 curbuf->b_bad_char = eap->bad_char; 825 } 826 else 827 curbuf->b_bad_char = 0; 828 829 /* 830 * Decide which 'encoding' to use or use first. 831 */ 832 if (eap != NULL && eap->force_enc != 0) 833 { 834 fenc = enc_canonize(eap->cmd + eap->force_enc); 835 fenc_alloced = TRUE; 836 keep_dest_enc = TRUE; 837 } 838 else if (curbuf->b_p_bin) 839 { 840 fenc = (char_u *)""; /* binary: don't convert */ 841 fenc_alloced = FALSE; 842 } 843 else if (curbuf->b_help) 844 { 845 char_u firstline[80]; 846 int fc; 847 848 /* Help files are either utf-8 or latin1. Try utf-8 first, if this 849 * fails it must be latin1. 850 * Always do this when 'encoding' is "utf-8". Otherwise only do 851 * this when needed to avoid [converted] remarks all the time. 852 * It is needed when the first line contains non-ASCII characters. 853 * That is only in *.??x files. */ 854 fenc = (char_u *)"latin1"; 855 c = enc_utf8; 856 if (!c && !read_stdin) 857 { 858 fc = fname[STRLEN(fname) - 1]; 859 if (TOLOWER_ASC(fc) == 'x') 860 { 861 /* Read the first line (and a bit more). Immediately rewind to 862 * the start of the file. If the read() fails "len" is -1. */ 863 len = read_eintr(fd, firstline, 80); 864 vim_lseek(fd, (off_T)0L, SEEK_SET); 865 for (p = firstline; p < firstline + len; ++p) 866 if (*p >= 0x80) 867 { 868 c = TRUE; 869 break; 870 } 871 } 872 } 873 874 if (c) 875 { 876 fenc_next = fenc; 877 fenc = (char_u *)"utf-8"; 878 879 /* When the file is utf-8 but a character doesn't fit in 880 * 'encoding' don't retry. In help text editing utf-8 bytes 881 * doesn't make sense. */ 882 if (!enc_utf8) 883 keep_dest_enc = TRUE; 884 } 885 fenc_alloced = FALSE; 886 } 887 else if (*p_fencs == NUL) 888 { 889 fenc = curbuf->b_p_fenc; /* use format from buffer */ 890 fenc_alloced = FALSE; 891 } 892 else 893 { 894 fenc_next = p_fencs; /* try items in 'fileencodings' */ 895 fenc = next_fenc(&fenc_next); 896 fenc_alloced = TRUE; 897 } 898 899 /* 900 * Jump back here to retry reading the file in different ways. 901 * Reasons to retry: 902 * - encoding conversion failed: try another one from "fenc_next" 903 * - BOM detected and fenc was set, need to setup conversion 904 * - "fileformat" check failed: try another 905 * 906 * Variables set for special retry actions: 907 * "file_rewind" Rewind the file to start reading it again. 908 * "advance_fenc" Advance "fenc" using "fenc_next". 909 * "skip_read" Re-use already read bytes (BOM detected). 910 * "did_iconv" iconv() conversion failed, try 'charconvert'. 911 * "keep_fileformat" Don't reset "fileformat". 912 * 913 * Other status indicators: 914 * "tmpname" When != NULL did conversion with 'charconvert'. 915 * Output file has to be deleted afterwards. 916 * "iconv_fd" When != -1 did conversion with iconv(). 917 */ 918 retry: 919 920 if (file_rewind) 921 { 922 if (read_buffer) 923 { 924 read_buf_lnum = 1; 925 read_buf_col = 0; 926 } 927 else if (read_stdin || vim_lseek(fd, (off_T)0L, SEEK_SET) != 0) 928 { 929 /* Can't rewind the file, give up. */ 930 error = TRUE; 931 goto failed; 932 } 933 /* Delete the previously read lines. */ 934 while (lnum > from) 935 ml_delete(lnum--, FALSE); 936 file_rewind = FALSE; 937 if (set_options) 938 { 939 curbuf->b_p_bomb = FALSE; 940 curbuf->b_start_bomb = FALSE; 941 } 942 conv_error = 0; 943 } 944 945 /* 946 * When retrying with another "fenc" and the first time "fileformat" 947 * will be reset. 948 */ 949 if (keep_fileformat) 950 keep_fileformat = FALSE; 951 else 952 { 953 if (eap != NULL && eap->force_ff != 0) 954 { 955 fileformat = get_fileformat_force(curbuf, eap); 956 try_unix = try_dos = try_mac = FALSE; 957 } 958 else if (curbuf->b_p_bin) 959 fileformat = EOL_UNIX; /* binary: use Unix format */ 960 else if (*p_ffs == NUL) 961 fileformat = get_fileformat(curbuf);/* use format from buffer */ 962 else 963 fileformat = EOL_UNKNOWN; /* detect from file */ 964 } 965 966 #ifdef USE_ICONV 967 if (iconv_fd != (iconv_t)-1) 968 { 969 /* aborted conversion with iconv(), close the descriptor */ 970 iconv_close(iconv_fd); 971 iconv_fd = (iconv_t)-1; 972 } 973 #endif 974 975 if (advance_fenc) 976 { 977 /* 978 * Try the next entry in 'fileencodings'. 979 */ 980 advance_fenc = FALSE; 981 982 if (eap != NULL && eap->force_enc != 0) 983 { 984 /* Conversion given with "++cc=" wasn't possible, read 985 * without conversion. */ 986 notconverted = TRUE; 987 conv_error = 0; 988 if (fenc_alloced) 989 vim_free(fenc); 990 fenc = (char_u *)""; 991 fenc_alloced = FALSE; 992 } 993 else 994 { 995 if (fenc_alloced) 996 vim_free(fenc); 997 if (fenc_next != NULL) 998 { 999 fenc = next_fenc(&fenc_next); 1000 fenc_alloced = (fenc_next != NULL); 1001 } 1002 else 1003 { 1004 fenc = (char_u *)""; 1005 fenc_alloced = FALSE; 1006 } 1007 } 1008 if (tmpname != NULL) 1009 { 1010 mch_remove(tmpname); /* delete converted file */ 1011 VIM_CLEAR(tmpname); 1012 } 1013 } 1014 1015 /* 1016 * Conversion may be required when the encoding of the file is different 1017 * from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4. 1018 */ 1019 fio_flags = 0; 1020 converted = need_conversion(fenc); 1021 if (converted) 1022 { 1023 1024 /* "ucs-bom" means we need to check the first bytes of the file 1025 * for a BOM. */ 1026 if (STRCMP(fenc, ENC_UCSBOM) == 0) 1027 fio_flags = FIO_UCSBOM; 1028 1029 /* 1030 * Check if UCS-2/4 or Latin1 to UTF-8 conversion needs to be 1031 * done. This is handled below after read(). Prepare the 1032 * fio_flags to avoid having to parse the string each time. 1033 * Also check for Unicode to Latin1 conversion, because iconv() 1034 * appears not to handle this correctly. This works just like 1035 * conversion to UTF-8 except how the resulting character is put in 1036 * the buffer. 1037 */ 1038 else if (enc_utf8 || STRCMP(p_enc, "latin1") == 0) 1039 fio_flags = get_fio_flags(fenc); 1040 1041 #ifdef MSWIN 1042 /* 1043 * Conversion from an MS-Windows codepage to UTF-8 or another codepage 1044 * is handled with MultiByteToWideChar(). 1045 */ 1046 if (fio_flags == 0) 1047 fio_flags = get_win_fio_flags(fenc); 1048 #endif 1049 1050 #ifdef MACOS_CONVERT 1051 /* Conversion from Apple MacRoman to latin1 or UTF-8 */ 1052 if (fio_flags == 0) 1053 fio_flags = get_mac_fio_flags(fenc); 1054 #endif 1055 1056 #ifdef USE_ICONV 1057 /* 1058 * Try using iconv() if we can't convert internally. 1059 */ 1060 if (fio_flags == 0 1061 # ifdef FEAT_EVAL 1062 && !did_iconv 1063 # endif 1064 ) 1065 iconv_fd = (iconv_t)my_iconv_open( 1066 enc_utf8 ? (char_u *)"utf-8" : p_enc, fenc); 1067 #endif 1068 1069 #ifdef FEAT_EVAL 1070 /* 1071 * Use the 'charconvert' expression when conversion is required 1072 * and we can't do it internally or with iconv(). 1073 */ 1074 if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL 1075 && !read_fifo 1076 # ifdef USE_ICONV 1077 && iconv_fd == (iconv_t)-1 1078 # endif 1079 ) 1080 { 1081 # ifdef USE_ICONV 1082 did_iconv = FALSE; 1083 # endif 1084 /* Skip conversion when it's already done (retry for wrong 1085 * "fileformat"). */ 1086 if (tmpname == NULL) 1087 { 1088 tmpname = readfile_charconvert(fname, fenc, &fd); 1089 if (tmpname == NULL) 1090 { 1091 /* Conversion failed. Try another one. */ 1092 advance_fenc = TRUE; 1093 if (fd < 0) 1094 { 1095 /* Re-opening the original file failed! */ 1096 emsg(_("E202: Conversion made file unreadable!")); 1097 error = TRUE; 1098 goto failed; 1099 } 1100 goto retry; 1101 } 1102 } 1103 } 1104 else 1105 #endif 1106 { 1107 if (fio_flags == 0 1108 #ifdef USE_ICONV 1109 && iconv_fd == (iconv_t)-1 1110 #endif 1111 ) 1112 { 1113 /* Conversion wanted but we can't. 1114 * Try the next conversion in 'fileencodings' */ 1115 advance_fenc = TRUE; 1116 goto retry; 1117 } 1118 } 1119 } 1120 1121 /* Set "can_retry" when it's possible to rewind the file and try with 1122 * another "fenc" value. It's FALSE when no other "fenc" to try, reading 1123 * stdin or fixed at a specific encoding. */ 1124 can_retry = (*fenc != NUL && !read_stdin && !read_fifo && !keep_dest_enc); 1125 1126 if (!skip_read) 1127 { 1128 linerest = 0; 1129 filesize = 0; 1130 skip_count = lines_to_skip; 1131 read_count = lines_to_read; 1132 conv_restlen = 0; 1133 #ifdef FEAT_PERSISTENT_UNDO 1134 read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0 1135 && curbuf->b_ffname != NULL 1136 && curbuf->b_p_udf 1137 && !filtering 1138 && !read_fifo 1139 && !read_stdin 1140 && !read_buffer); 1141 if (read_undo_file) 1142 sha256_start(&sha_ctx); 1143 #endif 1144 #ifdef FEAT_CRYPT 1145 if (curbuf->b_cryptstate != NULL) 1146 { 1147 /* Need to free the state, but keep the key, don't want to ask for 1148 * it again. */ 1149 crypt_free_state(curbuf->b_cryptstate); 1150 curbuf->b_cryptstate = NULL; 1151 } 1152 #endif 1153 } 1154 1155 while (!error && !got_int) 1156 { 1157 /* 1158 * We allocate as much space for the file as we can get, plus 1159 * space for the old line plus room for one terminating NUL. 1160 * The amount is limited by the fact that read() only can read 1161 * upto max_unsigned characters (and other things). 1162 */ 1163 if (!skip_read) 1164 { 1165 #if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L) 1166 size = SSIZE_MAX; /* use max I/O size, 52K */ 1167 #else 1168 /* Use buffer >= 64K. Add linerest to double the size if the 1169 * line gets very long, to avoid a lot of copying. But don't 1170 * read more than 1 Mbyte at a time, so we can be interrupted. 1171 */ 1172 size = 0x10000L + linerest; 1173 if (size > 0x100000L) 1174 size = 0x100000L; 1175 #endif 1176 } 1177 1178 /* Protect against the argument of lalloc() going negative. */ 1179 if (size < 0 || size + linerest + 1 < 0 || linerest >= MAXCOL) 1180 { 1181 ++split; 1182 *ptr = NL; /* split line by inserting a NL */ 1183 size = 1; 1184 } 1185 else 1186 { 1187 if (!skip_read) 1188 { 1189 for ( ; size >= 10; size = (long)((long_u)size >> 1)) 1190 { 1191 if ((new_buffer = lalloc((long_u)(size + linerest + 1), 1192 FALSE)) != NULL) 1193 break; 1194 } 1195 if (new_buffer == NULL) 1196 { 1197 do_outofmem_msg((long_u)(size * 2 + linerest + 1)); 1198 error = TRUE; 1199 break; 1200 } 1201 if (linerest) /* copy characters from the previous buffer */ 1202 mch_memmove(new_buffer, ptr - linerest, (size_t)linerest); 1203 vim_free(buffer); 1204 buffer = new_buffer; 1205 ptr = buffer + linerest; 1206 line_start = buffer; 1207 1208 /* May need room to translate into. 1209 * For iconv() we don't really know the required space, use a 1210 * factor ICONV_MULT. 1211 * latin1 to utf-8: 1 byte becomes up to 2 bytes 1212 * utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes 1213 * become up to 4 bytes, size must be multiple of 2 1214 * ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be 1215 * multiple of 2 1216 * ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be 1217 * multiple of 4 */ 1218 real_size = (int)size; 1219 #ifdef USE_ICONV 1220 if (iconv_fd != (iconv_t)-1) 1221 size = size / ICONV_MULT; 1222 else 1223 #endif 1224 if (fio_flags & FIO_LATIN1) 1225 size = size / 2; 1226 else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) 1227 size = (size * 2 / 3) & ~1; 1228 else if (fio_flags & FIO_UCS4) 1229 size = (size * 2 / 3) & ~3; 1230 else if (fio_flags == FIO_UCSBOM) 1231 size = size / ICONV_MULT; /* worst case */ 1232 #ifdef MSWIN 1233 else if (fio_flags & FIO_CODEPAGE) 1234 size = size / ICONV_MULT; /* also worst case */ 1235 #endif 1236 #ifdef MACOS_CONVERT 1237 else if (fio_flags & FIO_MACROMAN) 1238 size = size / ICONV_MULT; /* also worst case */ 1239 #endif 1240 1241 if (conv_restlen > 0) 1242 { 1243 /* Insert unconverted bytes from previous line. */ 1244 mch_memmove(ptr, conv_rest, conv_restlen); 1245 ptr += conv_restlen; 1246 size -= conv_restlen; 1247 } 1248 1249 if (read_buffer) 1250 { 1251 /* 1252 * Read bytes from curbuf. Used for converting text read 1253 * from stdin. 1254 */ 1255 if (read_buf_lnum > from) 1256 size = 0; 1257 else 1258 { 1259 int n, ni; 1260 long tlen; 1261 1262 tlen = 0; 1263 for (;;) 1264 { 1265 p = ml_get(read_buf_lnum) + read_buf_col; 1266 n = (int)STRLEN(p); 1267 if ((int)tlen + n + 1 > size) 1268 { 1269 /* Filled up to "size", append partial line. 1270 * Change NL to NUL to reverse the effect done 1271 * below. */ 1272 n = (int)(size - tlen); 1273 for (ni = 0; ni < n; ++ni) 1274 { 1275 if (p[ni] == NL) 1276 ptr[tlen++] = NUL; 1277 else 1278 ptr[tlen++] = p[ni]; 1279 } 1280 read_buf_col += n; 1281 break; 1282 } 1283 else 1284 { 1285 /* Append whole line and new-line. Change NL 1286 * to NUL to reverse the effect done below. */ 1287 for (ni = 0; ni < n; ++ni) 1288 { 1289 if (p[ni] == NL) 1290 ptr[tlen++] = NUL; 1291 else 1292 ptr[tlen++] = p[ni]; 1293 } 1294 ptr[tlen++] = NL; 1295 read_buf_col = 0; 1296 if (++read_buf_lnum > from) 1297 { 1298 /* When the last line didn't have an 1299 * end-of-line don't add it now either. */ 1300 if (!curbuf->b_p_eol) 1301 --tlen; 1302 size = tlen; 1303 break; 1304 } 1305 } 1306 } 1307 } 1308 } 1309 else 1310 { 1311 /* 1312 * Read bytes from the file. 1313 */ 1314 size = read_eintr(fd, ptr, size); 1315 } 1316 1317 #ifdef FEAT_CRYPT 1318 /* 1319 * At start of file: Check for magic number of encryption. 1320 */ 1321 if (filesize == 0 && size > 0) 1322 cryptkey = check_for_cryptkey(cryptkey, ptr, &size, 1323 &filesize, newfile, sfname, 1324 &did_ask_for_key); 1325 /* 1326 * Decrypt the read bytes. This is done before checking for 1327 * EOF because the crypt layer may be buffering. 1328 */ 1329 if (cryptkey != NULL && curbuf->b_cryptstate != NULL 1330 && size > 0) 1331 { 1332 # ifdef CRYPT_NOT_INPLACE 1333 if (crypt_works_inplace(curbuf->b_cryptstate)) 1334 { 1335 # endif 1336 crypt_decode_inplace(curbuf->b_cryptstate, ptr, size); 1337 # ifdef CRYPT_NOT_INPLACE 1338 } 1339 else 1340 { 1341 char_u *newptr = NULL; 1342 int decrypted_size; 1343 1344 decrypted_size = crypt_decode_alloc( 1345 curbuf->b_cryptstate, ptr, size, &newptr); 1346 1347 /* If the crypt layer is buffering, not producing 1348 * anything yet, need to read more. */ 1349 if (decrypted_size == 0) 1350 continue; 1351 1352 if (linerest == 0) 1353 { 1354 /* Simple case: reuse returned buffer (may be 1355 * NULL, checked later). */ 1356 new_buffer = newptr; 1357 } 1358 else 1359 { 1360 long_u new_size; 1361 1362 /* Need new buffer to add bytes carried over. */ 1363 new_size = (long_u)(decrypted_size + linerest + 1); 1364 new_buffer = lalloc(new_size, FALSE); 1365 if (new_buffer == NULL) 1366 { 1367 do_outofmem_msg(new_size); 1368 error = TRUE; 1369 break; 1370 } 1371 1372 mch_memmove(new_buffer, buffer, linerest); 1373 if (newptr != NULL) 1374 mch_memmove(new_buffer + linerest, newptr, 1375 decrypted_size); 1376 } 1377 1378 if (new_buffer != NULL) 1379 { 1380 vim_free(buffer); 1381 buffer = new_buffer; 1382 new_buffer = NULL; 1383 line_start = buffer; 1384 ptr = buffer + linerest; 1385 } 1386 size = decrypted_size; 1387 } 1388 # endif 1389 } 1390 #endif 1391 1392 if (size <= 0) 1393 { 1394 if (size < 0) /* read error */ 1395 error = TRUE; 1396 else if (conv_restlen > 0) 1397 { 1398 /* 1399 * Reached end-of-file but some trailing bytes could 1400 * not be converted. Truncated file? 1401 */ 1402 1403 /* When we did a conversion report an error. */ 1404 if (fio_flags != 0 1405 #ifdef USE_ICONV 1406 || iconv_fd != (iconv_t)-1 1407 #endif 1408 ) 1409 { 1410 if (can_retry) 1411 goto rewind_retry; 1412 if (conv_error == 0) 1413 conv_error = curbuf->b_ml.ml_line_count 1414 - linecnt + 1; 1415 } 1416 /* Remember the first linenr with an illegal byte */ 1417 else if (illegal_byte == 0) 1418 illegal_byte = curbuf->b_ml.ml_line_count 1419 - linecnt + 1; 1420 if (bad_char_behavior == BAD_DROP) 1421 { 1422 *(ptr - conv_restlen) = NUL; 1423 conv_restlen = 0; 1424 } 1425 else 1426 { 1427 /* Replace the trailing bytes with the replacement 1428 * character if we were converting; if we weren't, 1429 * leave the UTF8 checking code to do it, as it 1430 * works slightly differently. */ 1431 if (bad_char_behavior != BAD_KEEP && (fio_flags != 0 1432 #ifdef USE_ICONV 1433 || iconv_fd != (iconv_t)-1 1434 #endif 1435 )) 1436 { 1437 while (conv_restlen > 0) 1438 { 1439 *(--ptr) = bad_char_behavior; 1440 --conv_restlen; 1441 } 1442 } 1443 fio_flags = 0; /* don't convert this */ 1444 #ifdef USE_ICONV 1445 if (iconv_fd != (iconv_t)-1) 1446 { 1447 iconv_close(iconv_fd); 1448 iconv_fd = (iconv_t)-1; 1449 } 1450 #endif 1451 } 1452 } 1453 } 1454 } 1455 skip_read = FALSE; 1456 1457 /* 1458 * At start of file (or after crypt magic number): Check for BOM. 1459 * Also check for a BOM for other Unicode encodings, but not after 1460 * converting with 'charconvert' or when a BOM has already been 1461 * found. 1462 */ 1463 if ((filesize == 0 1464 #ifdef FEAT_CRYPT 1465 || (cryptkey != NULL 1466 && filesize == crypt_get_header_len( 1467 crypt_get_method_nr(curbuf))) 1468 #endif 1469 ) 1470 && (fio_flags == FIO_UCSBOM 1471 || (!curbuf->b_p_bomb 1472 && tmpname == NULL 1473 && (*fenc == 'u' || (*fenc == NUL && enc_utf8))))) 1474 { 1475 char_u *ccname; 1476 int blen; 1477 1478 /* no BOM detection in a short file or in binary mode */ 1479 if (size < 2 || curbuf->b_p_bin) 1480 ccname = NULL; 1481 else 1482 ccname = check_for_bom(ptr, size, &blen, 1483 fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc)); 1484 if (ccname != NULL) 1485 { 1486 /* Remove BOM from the text */ 1487 filesize += blen; 1488 size -= blen; 1489 mch_memmove(ptr, ptr + blen, (size_t)size); 1490 if (set_options) 1491 { 1492 curbuf->b_p_bomb = TRUE; 1493 curbuf->b_start_bomb = TRUE; 1494 } 1495 } 1496 1497 if (fio_flags == FIO_UCSBOM) 1498 { 1499 if (ccname == NULL) 1500 { 1501 /* No BOM detected: retry with next encoding. */ 1502 advance_fenc = TRUE; 1503 } 1504 else 1505 { 1506 /* BOM detected: set "fenc" and jump back */ 1507 if (fenc_alloced) 1508 vim_free(fenc); 1509 fenc = ccname; 1510 fenc_alloced = FALSE; 1511 } 1512 /* retry reading without getting new bytes or rewinding */ 1513 skip_read = TRUE; 1514 goto retry; 1515 } 1516 } 1517 1518 /* Include not converted bytes. */ 1519 ptr -= conv_restlen; 1520 size += conv_restlen; 1521 conv_restlen = 0; 1522 /* 1523 * Break here for a read error or end-of-file. 1524 */ 1525 if (size <= 0) 1526 break; 1527 1528 1529 #ifdef USE_ICONV 1530 if (iconv_fd != (iconv_t)-1) 1531 { 1532 /* 1533 * Attempt conversion of the read bytes to 'encoding' using 1534 * iconv(). 1535 */ 1536 const char *fromp; 1537 char *top; 1538 size_t from_size; 1539 size_t to_size; 1540 1541 fromp = (char *)ptr; 1542 from_size = size; 1543 ptr += size; 1544 top = (char *)ptr; 1545 to_size = real_size - size; 1546 1547 /* 1548 * If there is conversion error or not enough room try using 1549 * another conversion. Except for when there is no 1550 * alternative (help files). 1551 */ 1552 while ((iconv(iconv_fd, (void *)&fromp, &from_size, 1553 &top, &to_size) 1554 == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL) 1555 || from_size > CONV_RESTLEN) 1556 { 1557 if (can_retry) 1558 goto rewind_retry; 1559 if (conv_error == 0) 1560 conv_error = readfile_linenr(linecnt, 1561 ptr, (char_u *)top); 1562 1563 /* Deal with a bad byte and continue with the next. */ 1564 ++fromp; 1565 --from_size; 1566 if (bad_char_behavior == BAD_KEEP) 1567 { 1568 *top++ = *(fromp - 1); 1569 --to_size; 1570 } 1571 else if (bad_char_behavior != BAD_DROP) 1572 { 1573 *top++ = bad_char_behavior; 1574 --to_size; 1575 } 1576 } 1577 1578 if (from_size > 0) 1579 { 1580 /* Some remaining characters, keep them for the next 1581 * round. */ 1582 mch_memmove(conv_rest, (char_u *)fromp, from_size); 1583 conv_restlen = (int)from_size; 1584 } 1585 1586 /* move the linerest to before the converted characters */ 1587 line_start = ptr - linerest; 1588 mch_memmove(line_start, buffer, (size_t)linerest); 1589 size = (long)((char_u *)top - ptr); 1590 } 1591 #endif 1592 1593 #ifdef MSWIN 1594 if (fio_flags & FIO_CODEPAGE) 1595 { 1596 char_u *src, *dst; 1597 WCHAR ucs2buf[3]; 1598 int ucs2len; 1599 int codepage = FIO_GET_CP(fio_flags); 1600 int bytelen; 1601 int found_bad; 1602 char replstr[2]; 1603 1604 /* 1605 * Conversion from an MS-Windows codepage or UTF-8 to UTF-8 or 1606 * a codepage, using standard MS-Windows functions. This 1607 * requires two steps: 1608 * 1. convert from 'fileencoding' to ucs-2 1609 * 2. convert from ucs-2 to 'encoding' 1610 * 1611 * Because there may be illegal bytes AND an incomplete byte 1612 * sequence at the end, we may have to do the conversion one 1613 * character at a time to get it right. 1614 */ 1615 1616 /* Replacement string for WideCharToMultiByte(). */ 1617 if (bad_char_behavior > 0) 1618 replstr[0] = bad_char_behavior; 1619 else 1620 replstr[0] = '?'; 1621 replstr[1] = NUL; 1622 1623 /* 1624 * Move the bytes to the end of the buffer, so that we have 1625 * room to put the result at the start. 1626 */ 1627 src = ptr + real_size - size; 1628 mch_memmove(src, ptr, size); 1629 1630 /* 1631 * Do the conversion. 1632 */ 1633 dst = ptr; 1634 size = size; 1635 while (size > 0) 1636 { 1637 found_bad = FALSE; 1638 1639 # ifdef CP_UTF8 /* VC 4.1 doesn't define CP_UTF8 */ 1640 if (codepage == CP_UTF8) 1641 { 1642 /* Handle CP_UTF8 input ourselves to be able to handle 1643 * trailing bytes properly. 1644 * Get one UTF-8 character from src. */ 1645 bytelen = (int)utf_ptr2len_len(src, size); 1646 if (bytelen > size) 1647 { 1648 /* Only got some bytes of a character. Normally 1649 * it's put in "conv_rest", but if it's too long 1650 * deal with it as if they were illegal bytes. */ 1651 if (bytelen <= CONV_RESTLEN) 1652 break; 1653 1654 /* weird overlong byte sequence */ 1655 bytelen = size; 1656 found_bad = TRUE; 1657 } 1658 else 1659 { 1660 int u8c = utf_ptr2char(src); 1661 1662 if (u8c > 0xffff || (*src >= 0x80 && bytelen == 1)) 1663 found_bad = TRUE; 1664 ucs2buf[0] = u8c; 1665 ucs2len = 1; 1666 } 1667 } 1668 else 1669 # endif 1670 { 1671 /* We don't know how long the byte sequence is, try 1672 * from one to three bytes. */ 1673 for (bytelen = 1; bytelen <= size && bytelen <= 3; 1674 ++bytelen) 1675 { 1676 ucs2len = MultiByteToWideChar(codepage, 1677 MB_ERR_INVALID_CHARS, 1678 (LPCSTR)src, bytelen, 1679 ucs2buf, 3); 1680 if (ucs2len > 0) 1681 break; 1682 } 1683 if (ucs2len == 0) 1684 { 1685 /* If we have only one byte then it's probably an 1686 * incomplete byte sequence. Otherwise discard 1687 * one byte as a bad character. */ 1688 if (size == 1) 1689 break; 1690 found_bad = TRUE; 1691 bytelen = 1; 1692 } 1693 } 1694 1695 if (!found_bad) 1696 { 1697 int i; 1698 1699 /* Convert "ucs2buf[ucs2len]" to 'enc' in "dst". */ 1700 if (enc_utf8) 1701 { 1702 /* From UCS-2 to UTF-8. Cannot fail. */ 1703 for (i = 0; i < ucs2len; ++i) 1704 dst += utf_char2bytes(ucs2buf[i], dst); 1705 } 1706 else 1707 { 1708 BOOL bad = FALSE; 1709 int dstlen; 1710 1711 /* From UCS-2 to "enc_codepage". If the 1712 * conversion uses the default character "?", 1713 * the data doesn't fit in this encoding. */ 1714 dstlen = WideCharToMultiByte(enc_codepage, 0, 1715 (LPCWSTR)ucs2buf, ucs2len, 1716 (LPSTR)dst, (int)(src - dst), 1717 replstr, &bad); 1718 if (bad) 1719 found_bad = TRUE; 1720 else 1721 dst += dstlen; 1722 } 1723 } 1724 1725 if (found_bad) 1726 { 1727 /* Deal with bytes we can't convert. */ 1728 if (can_retry) 1729 goto rewind_retry; 1730 if (conv_error == 0) 1731 conv_error = readfile_linenr(linecnt, ptr, dst); 1732 if (bad_char_behavior != BAD_DROP) 1733 { 1734 if (bad_char_behavior == BAD_KEEP) 1735 { 1736 mch_memmove(dst, src, bytelen); 1737 dst += bytelen; 1738 } 1739 else 1740 *dst++ = bad_char_behavior; 1741 } 1742 } 1743 1744 src += bytelen; 1745 size -= bytelen; 1746 } 1747 1748 if (size > 0) 1749 { 1750 /* An incomplete byte sequence remaining. */ 1751 mch_memmove(conv_rest, src, size); 1752 conv_restlen = size; 1753 } 1754 1755 /* The new size is equal to how much "dst" was advanced. */ 1756 size = (long)(dst - ptr); 1757 } 1758 else 1759 #endif 1760 #ifdef MACOS_CONVERT 1761 if (fio_flags & FIO_MACROMAN) 1762 { 1763 /* 1764 * Conversion from Apple MacRoman char encoding to UTF-8 or 1765 * latin1. This is in os_mac_conv.c. 1766 */ 1767 if (macroman2enc(ptr, &size, real_size) == FAIL) 1768 goto rewind_retry; 1769 } 1770 else 1771 #endif 1772 if (fio_flags != 0) 1773 { 1774 int u8c; 1775 char_u *dest; 1776 char_u *tail = NULL; 1777 1778 /* 1779 * "enc_utf8" set: Convert Unicode or Latin1 to UTF-8. 1780 * "enc_utf8" not set: Convert Unicode to Latin1. 1781 * Go from end to start through the buffer, because the number 1782 * of bytes may increase. 1783 * "dest" points to after where the UTF-8 bytes go, "p" points 1784 * to after the next character to convert. 1785 */ 1786 dest = ptr + real_size; 1787 if (fio_flags == FIO_LATIN1 || fio_flags == FIO_UTF8) 1788 { 1789 p = ptr + size; 1790 if (fio_flags == FIO_UTF8) 1791 { 1792 /* Check for a trailing incomplete UTF-8 sequence */ 1793 tail = ptr + size - 1; 1794 while (tail > ptr && (*tail & 0xc0) == 0x80) 1795 --tail; 1796 if (tail + utf_byte2len(*tail) <= ptr + size) 1797 tail = NULL; 1798 else 1799 p = tail; 1800 } 1801 } 1802 else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) 1803 { 1804 /* Check for a trailing byte */ 1805 p = ptr + (size & ~1); 1806 if (size & 1) 1807 tail = p; 1808 if ((fio_flags & FIO_UTF16) && p > ptr) 1809 { 1810 /* Check for a trailing leading word */ 1811 if (fio_flags & FIO_ENDIAN_L) 1812 { 1813 u8c = (*--p << 8); 1814 u8c += *--p; 1815 } 1816 else 1817 { 1818 u8c = *--p; 1819 u8c += (*--p << 8); 1820 } 1821 if (u8c >= 0xd800 && u8c <= 0xdbff) 1822 tail = p; 1823 else 1824 p += 2; 1825 } 1826 } 1827 else /* FIO_UCS4 */ 1828 { 1829 /* Check for trailing 1, 2 or 3 bytes */ 1830 p = ptr + (size & ~3); 1831 if (size & 3) 1832 tail = p; 1833 } 1834 1835 /* If there is a trailing incomplete sequence move it to 1836 * conv_rest[]. */ 1837 if (tail != NULL) 1838 { 1839 conv_restlen = (int)((ptr + size) - tail); 1840 mch_memmove(conv_rest, (char_u *)tail, conv_restlen); 1841 size -= conv_restlen; 1842 } 1843 1844 1845 while (p > ptr) 1846 { 1847 if (fio_flags & FIO_LATIN1) 1848 u8c = *--p; 1849 else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) 1850 { 1851 if (fio_flags & FIO_ENDIAN_L) 1852 { 1853 u8c = (*--p << 8); 1854 u8c += *--p; 1855 } 1856 else 1857 { 1858 u8c = *--p; 1859 u8c += (*--p << 8); 1860 } 1861 if ((fio_flags & FIO_UTF16) 1862 && u8c >= 0xdc00 && u8c <= 0xdfff) 1863 { 1864 int u16c; 1865 1866 if (p == ptr) 1867 { 1868 /* Missing leading word. */ 1869 if (can_retry) 1870 goto rewind_retry; 1871 if (conv_error == 0) 1872 conv_error = readfile_linenr(linecnt, 1873 ptr, p); 1874 if (bad_char_behavior == BAD_DROP) 1875 continue; 1876 if (bad_char_behavior != BAD_KEEP) 1877 u8c = bad_char_behavior; 1878 } 1879 1880 /* found second word of double-word, get the first 1881 * word and compute the resulting character */ 1882 if (fio_flags & FIO_ENDIAN_L) 1883 { 1884 u16c = (*--p << 8); 1885 u16c += *--p; 1886 } 1887 else 1888 { 1889 u16c = *--p; 1890 u16c += (*--p << 8); 1891 } 1892 u8c = 0x10000 + ((u16c & 0x3ff) << 10) 1893 + (u8c & 0x3ff); 1894 1895 /* Check if the word is indeed a leading word. */ 1896 if (u16c < 0xd800 || u16c > 0xdbff) 1897 { 1898 if (can_retry) 1899 goto rewind_retry; 1900 if (conv_error == 0) 1901 conv_error = readfile_linenr(linecnt, 1902 ptr, p); 1903 if (bad_char_behavior == BAD_DROP) 1904 continue; 1905 if (bad_char_behavior != BAD_KEEP) 1906 u8c = bad_char_behavior; 1907 } 1908 } 1909 } 1910 else if (fio_flags & FIO_UCS4) 1911 { 1912 if (fio_flags & FIO_ENDIAN_L) 1913 { 1914 u8c = (unsigned)*--p << 24; 1915 u8c += (unsigned)*--p << 16; 1916 u8c += (unsigned)*--p << 8; 1917 u8c += *--p; 1918 } 1919 else /* big endian */ 1920 { 1921 u8c = *--p; 1922 u8c += (unsigned)*--p << 8; 1923 u8c += (unsigned)*--p << 16; 1924 u8c += (unsigned)*--p << 24; 1925 } 1926 } 1927 else /* UTF-8 */ 1928 { 1929 if (*--p < 0x80) 1930 u8c = *p; 1931 else 1932 { 1933 len = utf_head_off(ptr, p); 1934 p -= len; 1935 u8c = utf_ptr2char(p); 1936 if (len == 0) 1937 { 1938 /* Not a valid UTF-8 character, retry with 1939 * another fenc when possible, otherwise just 1940 * report the error. */ 1941 if (can_retry) 1942 goto rewind_retry; 1943 if (conv_error == 0) 1944 conv_error = readfile_linenr(linecnt, 1945 ptr, p); 1946 if (bad_char_behavior == BAD_DROP) 1947 continue; 1948 if (bad_char_behavior != BAD_KEEP) 1949 u8c = bad_char_behavior; 1950 } 1951 } 1952 } 1953 if (enc_utf8) /* produce UTF-8 */ 1954 { 1955 dest -= utf_char2len(u8c); 1956 (void)utf_char2bytes(u8c, dest); 1957 } 1958 else /* produce Latin1 */ 1959 { 1960 --dest; 1961 if (u8c >= 0x100) 1962 { 1963 /* character doesn't fit in latin1, retry with 1964 * another fenc when possible, otherwise just 1965 * report the error. */ 1966 if (can_retry) 1967 goto rewind_retry; 1968 if (conv_error == 0) 1969 conv_error = readfile_linenr(linecnt, ptr, p); 1970 if (bad_char_behavior == BAD_DROP) 1971 ++dest; 1972 else if (bad_char_behavior == BAD_KEEP) 1973 *dest = u8c; 1974 else if (eap != NULL && eap->bad_char != 0) 1975 *dest = bad_char_behavior; 1976 else 1977 *dest = 0xBF; 1978 } 1979 else 1980 *dest = u8c; 1981 } 1982 } 1983 1984 /* move the linerest to before the converted characters */ 1985 line_start = dest - linerest; 1986 mch_memmove(line_start, buffer, (size_t)linerest); 1987 size = (long)((ptr + real_size) - dest); 1988 ptr = dest; 1989 } 1990 else if (enc_utf8 && !curbuf->b_p_bin) 1991 { 1992 int incomplete_tail = FALSE; 1993 1994 /* Reading UTF-8: Check if the bytes are valid UTF-8. */ 1995 for (p = ptr; ; ++p) 1996 { 1997 int todo = (int)((ptr + size) - p); 1998 int l; 1999 2000 if (todo <= 0) 2001 break; 2002 if (*p >= 0x80) 2003 { 2004 /* A length of 1 means it's an illegal byte. Accept 2005 * an incomplete character at the end though, the next 2006 * read() will get the next bytes, we'll check it 2007 * then. */ 2008 l = utf_ptr2len_len(p, todo); 2009 if (l > todo && !incomplete_tail) 2010 { 2011 /* Avoid retrying with a different encoding when 2012 * a truncated file is more likely, or attempting 2013 * to read the rest of an incomplete sequence when 2014 * we have already done so. */ 2015 if (p > ptr || filesize > 0) 2016 incomplete_tail = TRUE; 2017 /* Incomplete byte sequence, move it to conv_rest[] 2018 * and try to read the rest of it, unless we've 2019 * already done so. */ 2020 if (p > ptr) 2021 { 2022 conv_restlen = todo; 2023 mch_memmove(conv_rest, p, conv_restlen); 2024 size -= conv_restlen; 2025 break; 2026 } 2027 } 2028 if (l == 1 || l > todo) 2029 { 2030 /* Illegal byte. If we can try another encoding 2031 * do that, unless at EOF where a truncated 2032 * file is more likely than a conversion error. */ 2033 if (can_retry && !incomplete_tail) 2034 break; 2035 #ifdef USE_ICONV 2036 /* When we did a conversion report an error. */ 2037 if (iconv_fd != (iconv_t)-1 && conv_error == 0) 2038 conv_error = readfile_linenr(linecnt, ptr, p); 2039 #endif 2040 /* Remember the first linenr with an illegal byte */ 2041 if (conv_error == 0 && illegal_byte == 0) 2042 illegal_byte = readfile_linenr(linecnt, ptr, p); 2043 2044 /* Drop, keep or replace the bad byte. */ 2045 if (bad_char_behavior == BAD_DROP) 2046 { 2047 mch_memmove(p, p + 1, todo - 1); 2048 --p; 2049 --size; 2050 } 2051 else if (bad_char_behavior != BAD_KEEP) 2052 *p = bad_char_behavior; 2053 } 2054 else 2055 p += l - 1; 2056 } 2057 } 2058 if (p < ptr + size && !incomplete_tail) 2059 { 2060 /* Detected a UTF-8 error. */ 2061 rewind_retry: 2062 /* Retry reading with another conversion. */ 2063 #if defined(FEAT_EVAL) && defined(USE_ICONV) 2064 if (*p_ccv != NUL && iconv_fd != (iconv_t)-1) 2065 /* iconv() failed, try 'charconvert' */ 2066 did_iconv = TRUE; 2067 else 2068 #endif 2069 /* use next item from 'fileencodings' */ 2070 advance_fenc = TRUE; 2071 file_rewind = TRUE; 2072 goto retry; 2073 } 2074 } 2075 2076 /* count the number of characters (after conversion!) */ 2077 filesize += size; 2078 2079 /* 2080 * when reading the first part of a file: guess EOL type 2081 */ 2082 if (fileformat == EOL_UNKNOWN) 2083 { 2084 /* First try finding a NL, for Dos and Unix */ 2085 if (try_dos || try_unix) 2086 { 2087 /* Reset the carriage return counter. */ 2088 if (try_mac) 2089 try_mac = 1; 2090 2091 for (p = ptr; p < ptr + size; ++p) 2092 { 2093 if (*p == NL) 2094 { 2095 if (!try_unix 2096 || (try_dos && p > ptr && p[-1] == CAR)) 2097 fileformat = EOL_DOS; 2098 else 2099 fileformat = EOL_UNIX; 2100 break; 2101 } 2102 else if (*p == CAR && try_mac) 2103 try_mac++; 2104 } 2105 2106 /* Don't give in to EOL_UNIX if EOL_MAC is more likely */ 2107 if (fileformat == EOL_UNIX && try_mac) 2108 { 2109 /* Need to reset the counters when retrying fenc. */ 2110 try_mac = 1; 2111 try_unix = 1; 2112 for (; p >= ptr && *p != CAR; p--) 2113 ; 2114 if (p >= ptr) 2115 { 2116 for (p = ptr; p < ptr + size; ++p) 2117 { 2118 if (*p == NL) 2119 try_unix++; 2120 else if (*p == CAR) 2121 try_mac++; 2122 } 2123 if (try_mac > try_unix) 2124 fileformat = EOL_MAC; 2125 } 2126 } 2127 else if (fileformat == EOL_UNKNOWN && try_mac == 1) 2128 /* Looking for CR but found no end-of-line markers at 2129 * all: use the default format. */ 2130 fileformat = default_fileformat(); 2131 } 2132 2133 /* No NL found: may use Mac format */ 2134 if (fileformat == EOL_UNKNOWN && try_mac) 2135 fileformat = EOL_MAC; 2136 2137 /* Still nothing found? Use first format in 'ffs' */ 2138 if (fileformat == EOL_UNKNOWN) 2139 fileformat = default_fileformat(); 2140 2141 /* if editing a new file: may set p_tx and p_ff */ 2142 if (set_options) 2143 set_fileformat(fileformat, OPT_LOCAL); 2144 } 2145 } 2146 2147 /* 2148 * This loop is executed once for every character read. 2149 * Keep it fast! 2150 */ 2151 if (fileformat == EOL_MAC) 2152 { 2153 --ptr; 2154 while (++ptr, --size >= 0) 2155 { 2156 /* catch most common case first */ 2157 if ((c = *ptr) != NUL && c != CAR && c != NL) 2158 continue; 2159 if (c == NUL) 2160 *ptr = NL; /* NULs are replaced by newlines! */ 2161 else if (c == NL) 2162 *ptr = CAR; /* NLs are replaced by CRs! */ 2163 else 2164 { 2165 if (skip_count == 0) 2166 { 2167 *ptr = NUL; /* end of line */ 2168 len = (colnr_T) (ptr - line_start + 1); 2169 if (ml_append(lnum, line_start, len, newfile) == FAIL) 2170 { 2171 error = TRUE; 2172 break; 2173 } 2174 #ifdef FEAT_PERSISTENT_UNDO 2175 if (read_undo_file) 2176 sha256_update(&sha_ctx, line_start, len); 2177 #endif 2178 ++lnum; 2179 if (--read_count == 0) 2180 { 2181 error = TRUE; /* break loop */ 2182 line_start = ptr; /* nothing left to write */ 2183 break; 2184 } 2185 } 2186 else 2187 --skip_count; 2188 line_start = ptr + 1; 2189 } 2190 } 2191 } 2192 else 2193 { 2194 --ptr; 2195 while (++ptr, --size >= 0) 2196 { 2197 if ((c = *ptr) != NUL && c != NL) /* catch most common case */ 2198 continue; 2199 if (c == NUL) 2200 *ptr = NL; /* NULs are replaced by newlines! */ 2201 else 2202 { 2203 if (skip_count == 0) 2204 { 2205 *ptr = NUL; /* end of line */ 2206 len = (colnr_T)(ptr - line_start + 1); 2207 if (fileformat == EOL_DOS) 2208 { 2209 if (ptr > line_start && ptr[-1] == CAR) 2210 { 2211 /* remove CR before NL */ 2212 ptr[-1] = NUL; 2213 --len; 2214 } 2215 /* 2216 * Reading in Dos format, but no CR-LF found! 2217 * When 'fileformats' includes "unix", delete all 2218 * the lines read so far and start all over again. 2219 * Otherwise give an error message later. 2220 */ 2221 else if (ff_error != EOL_DOS) 2222 { 2223 if ( try_unix 2224 && !read_stdin 2225 && (read_buffer 2226 || vim_lseek(fd, (off_T)0L, SEEK_SET) 2227 == 0)) 2228 { 2229 fileformat = EOL_UNIX; 2230 if (set_options) 2231 set_fileformat(EOL_UNIX, OPT_LOCAL); 2232 file_rewind = TRUE; 2233 keep_fileformat = TRUE; 2234 goto retry; 2235 } 2236 ff_error = EOL_DOS; 2237 } 2238 } 2239 if (ml_append(lnum, line_start, len, newfile) == FAIL) 2240 { 2241 error = TRUE; 2242 break; 2243 } 2244 #ifdef FEAT_PERSISTENT_UNDO 2245 if (read_undo_file) 2246 sha256_update(&sha_ctx, line_start, len); 2247 #endif 2248 ++lnum; 2249 if (--read_count == 0) 2250 { 2251 error = TRUE; /* break loop */ 2252 line_start = ptr; /* nothing left to write */ 2253 break; 2254 } 2255 } 2256 else 2257 --skip_count; 2258 line_start = ptr + 1; 2259 } 2260 } 2261 } 2262 linerest = (long)(ptr - line_start); 2263 ui_breakcheck(); 2264 } 2265 2266 failed: 2267 /* not an error, max. number of lines reached */ 2268 if (error && read_count == 0) 2269 error = FALSE; 2270 2271 /* 2272 * If we get EOF in the middle of a line, note the fact and 2273 * complete the line ourselves. 2274 * In Dos format ignore a trailing CTRL-Z, unless 'binary' set. 2275 */ 2276 if (!error 2277 && !got_int 2278 && linerest != 0 2279 && !(!curbuf->b_p_bin 2280 && fileformat == EOL_DOS 2281 && *line_start == Ctrl_Z 2282 && ptr == line_start + 1)) 2283 { 2284 /* remember for when writing */ 2285 if (set_options) 2286 curbuf->b_p_eol = FALSE; 2287 *ptr = NUL; 2288 len = (colnr_T)(ptr - line_start + 1); 2289 if (ml_append(lnum, line_start, len, newfile) == FAIL) 2290 error = TRUE; 2291 else 2292 { 2293 #ifdef FEAT_PERSISTENT_UNDO 2294 if (read_undo_file) 2295 sha256_update(&sha_ctx, line_start, len); 2296 #endif 2297 read_no_eol_lnum = ++lnum; 2298 } 2299 } 2300 2301 if (set_options) 2302 save_file_ff(curbuf); /* remember the current file format */ 2303 2304 #ifdef FEAT_CRYPT 2305 if (curbuf->b_cryptstate != NULL) 2306 { 2307 crypt_free_state(curbuf->b_cryptstate); 2308 curbuf->b_cryptstate = NULL; 2309 } 2310 if (cryptkey != NULL && cryptkey != curbuf->b_p_key) 2311 crypt_free_key(cryptkey); 2312 /* Don't set cryptkey to NULL, it's used below as a flag that 2313 * encryption was used. */ 2314 #endif 2315 2316 /* If editing a new file: set 'fenc' for the current buffer. 2317 * Also for ":read ++edit file". */ 2318 if (set_options) 2319 set_string_option_direct((char_u *)"fenc", -1, fenc, 2320 OPT_FREE|OPT_LOCAL, 0); 2321 if (fenc_alloced) 2322 vim_free(fenc); 2323 #ifdef USE_ICONV 2324 if (iconv_fd != (iconv_t)-1) 2325 iconv_close(iconv_fd); 2326 #endif 2327 2328 if (!read_buffer && !read_stdin) 2329 close(fd); /* errors are ignored */ 2330 #ifdef HAVE_FD_CLOEXEC 2331 else 2332 { 2333 int fdflags = fcntl(fd, F_GETFD); 2334 if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) 2335 (void)fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC); 2336 } 2337 #endif 2338 vim_free(buffer); 2339 2340 #ifdef HAVE_DUP 2341 if (read_stdin) 2342 { 2343 /* Use stderr for stdin, makes shell commands work. */ 2344 close(0); 2345 vim_ignored = dup(2); 2346 } 2347 #endif 2348 2349 if (tmpname != NULL) 2350 { 2351 mch_remove(tmpname); /* delete converted file */ 2352 vim_free(tmpname); 2353 } 2354 --no_wait_return; /* may wait for return now */ 2355 2356 /* 2357 * In recovery mode everything but autocommands is skipped. 2358 */ 2359 if (!recoverymode) 2360 { 2361 /* need to delete the last line, which comes from the empty buffer */ 2362 if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) 2363 { 2364 #ifdef FEAT_NETBEANS_INTG 2365 netbeansFireChanges = 0; 2366 #endif 2367 ml_delete(curbuf->b_ml.ml_line_count, FALSE); 2368 #ifdef FEAT_NETBEANS_INTG 2369 netbeansFireChanges = 1; 2370 #endif 2371 --linecnt; 2372 } 2373 linecnt = curbuf->b_ml.ml_line_count - linecnt; 2374 if (filesize == 0) 2375 linecnt = 0; 2376 if (newfile || read_buffer) 2377 { 2378 redraw_curbuf_later(NOT_VALID); 2379 #ifdef FEAT_DIFF 2380 /* After reading the text into the buffer the diff info needs to 2381 * be updated. */ 2382 diff_invalidate(curbuf); 2383 #endif 2384 #ifdef FEAT_FOLDING 2385 /* All folds in the window are invalid now. Mark them for update 2386 * before triggering autocommands. */ 2387 foldUpdateAll(curwin); 2388 #endif 2389 } 2390 else if (linecnt) /* appended at least one line */ 2391 appended_lines_mark(from, linecnt); 2392 2393 #ifndef ALWAYS_USE_GUI 2394 /* 2395 * If we were reading from the same terminal as where messages go, 2396 * the screen will have been messed up. 2397 * Switch on raw mode now and clear the screen. 2398 */ 2399 if (read_stdin) 2400 { 2401 settmode(TMODE_RAW); /* set to raw mode */ 2402 starttermcap(); 2403 screenclear(); 2404 } 2405 #endif 2406 2407 if (got_int) 2408 { 2409 if (!(flags & READ_DUMMY)) 2410 { 2411 filemess(curbuf, sfname, (char_u *)_(e_interr), 0); 2412 if (newfile) 2413 curbuf->b_p_ro = TRUE; /* must use "w!" now */ 2414 } 2415 msg_scroll = msg_save; 2416 #ifdef FEAT_VIMINFO 2417 check_marks_read(); 2418 #endif 2419 return OK; /* an interrupt isn't really an error */ 2420 } 2421 2422 if (!filtering && !(flags & READ_DUMMY)) 2423 { 2424 msg_add_fname(curbuf, sfname); /* fname in IObuff with quotes */ 2425 c = FALSE; 2426 2427 #ifdef UNIX 2428 if (S_ISFIFO(perm)) /* fifo */ 2429 { 2430 STRCAT(IObuff, _("[fifo]")); 2431 c = TRUE; 2432 } 2433 if (S_ISSOCK(perm)) /* or socket */ 2434 { 2435 STRCAT(IObuff, _("[socket]")); 2436 c = TRUE; 2437 } 2438 # ifdef OPEN_CHR_FILES 2439 if (S_ISCHR(perm)) /* or character special */ 2440 { 2441 STRCAT(IObuff, _("[character special]")); 2442 c = TRUE; 2443 } 2444 # endif 2445 #endif 2446 if (curbuf->b_p_ro) 2447 { 2448 STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]")); 2449 c = TRUE; 2450 } 2451 if (read_no_eol_lnum) 2452 { 2453 msg_add_eol(); 2454 c = TRUE; 2455 } 2456 if (ff_error == EOL_DOS) 2457 { 2458 STRCAT(IObuff, _("[CR missing]")); 2459 c = TRUE; 2460 } 2461 if (split) 2462 { 2463 STRCAT(IObuff, _("[long lines split]")); 2464 c = TRUE; 2465 } 2466 if (notconverted) 2467 { 2468 STRCAT(IObuff, _("[NOT converted]")); 2469 c = TRUE; 2470 } 2471 else if (converted) 2472 { 2473 STRCAT(IObuff, _("[converted]")); 2474 c = TRUE; 2475 } 2476 #ifdef FEAT_CRYPT 2477 if (cryptkey != NULL) 2478 { 2479 crypt_append_msg(curbuf); 2480 c = TRUE; 2481 } 2482 #endif 2483 if (conv_error != 0) 2484 { 2485 sprintf((char *)IObuff + STRLEN(IObuff), 2486 _("[CONVERSION ERROR in line %ld]"), (long)conv_error); 2487 c = TRUE; 2488 } 2489 else if (illegal_byte > 0) 2490 { 2491 sprintf((char *)IObuff + STRLEN(IObuff), 2492 _("[ILLEGAL BYTE in line %ld]"), (long)illegal_byte); 2493 c = TRUE; 2494 } 2495 else if (error) 2496 { 2497 STRCAT(IObuff, _("[READ ERRORS]")); 2498 c = TRUE; 2499 } 2500 if (msg_add_fileformat(fileformat)) 2501 c = TRUE; 2502 #ifdef FEAT_CRYPT 2503 if (cryptkey != NULL) 2504 msg_add_lines(c, (long)linecnt, filesize 2505 - crypt_get_header_len(crypt_get_method_nr(curbuf))); 2506 else 2507 #endif 2508 msg_add_lines(c, (long)linecnt, filesize); 2509 2510 VIM_CLEAR(keep_msg); 2511 msg_scrolled_ign = TRUE; 2512 #ifdef ALWAYS_USE_GUI 2513 /* Don't show the message when reading stdin, it would end up in a 2514 * message box (which might be shown when exiting!) */ 2515 if (read_stdin || read_buffer) 2516 p = msg_may_trunc(FALSE, IObuff); 2517 else 2518 #endif 2519 p = (char_u *)msg_trunc_attr((char *)IObuff, FALSE, 0); 2520 if (read_stdin || read_buffer || restart_edit != 0 2521 || (msg_scrolled != 0 && !need_wait_return)) 2522 /* Need to repeat the message after redrawing when: 2523 * - When reading from stdin (the screen will be cleared next). 2524 * - When restart_edit is set (otherwise there will be a delay 2525 * before redrawing). 2526 * - When the screen was scrolled but there is no wait-return 2527 * prompt. */ 2528 set_keep_msg(p, 0); 2529 msg_scrolled_ign = FALSE; 2530 } 2531 2532 /* with errors writing the file requires ":w!" */ 2533 if (newfile && (error 2534 || conv_error != 0 2535 || (illegal_byte > 0 && bad_char_behavior != BAD_KEEP))) 2536 curbuf->b_p_ro = TRUE; 2537 2538 u_clearline(); /* cannot use "U" command after adding lines */ 2539 2540 /* 2541 * In Ex mode: cursor at last new line. 2542 * Otherwise: cursor at first new line. 2543 */ 2544 if (exmode_active) 2545 curwin->w_cursor.lnum = from + linecnt; 2546 else 2547 curwin->w_cursor.lnum = from + 1; 2548 check_cursor_lnum(); 2549 beginline(BL_WHITE | BL_FIX); /* on first non-blank */ 2550 2551 /* 2552 * Set '[ and '] marks to the newly read lines. 2553 */ 2554 curbuf->b_op_start.lnum = from + 1; 2555 curbuf->b_op_start.col = 0; 2556 curbuf->b_op_end.lnum = from + linecnt; 2557 curbuf->b_op_end.col = 0; 2558 2559 #ifdef MSWIN 2560 /* 2561 * Work around a weird problem: When a file has two links (only 2562 * possible on NTFS) and we write through one link, then stat() it 2563 * through the other link, the timestamp information may be wrong. 2564 * It's correct again after reading the file, thus reset the timestamp 2565 * here. 2566 */ 2567 if (newfile && !read_stdin && !read_buffer 2568 && mch_stat((char *)fname, &st) >= 0) 2569 { 2570 buf_store_time(curbuf, &st, fname); 2571 curbuf->b_mtime_read = curbuf->b_mtime; 2572 } 2573 #endif 2574 } 2575 msg_scroll = msg_save; 2576 2577 #ifdef FEAT_VIMINFO 2578 /* 2579 * Get the marks before executing autocommands, so they can be used there. 2580 */ 2581 check_marks_read(); 2582 #endif 2583 2584 /* 2585 * We remember if the last line of the read didn't have 2586 * an eol even when 'binary' is off, to support turning 'fixeol' off, 2587 * or writing the read again with 'binary' on. The latter is required 2588 * for ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work. 2589 */ 2590 curbuf->b_no_eol_lnum = read_no_eol_lnum; 2591 2592 /* When reloading a buffer put the cursor at the first line that is 2593 * different. */ 2594 if (flags & READ_KEEP_UNDO) 2595 u_find_first_changed(); 2596 2597 #ifdef FEAT_PERSISTENT_UNDO 2598 /* 2599 * When opening a new file locate undo info and read it. 2600 */ 2601 if (read_undo_file) 2602 { 2603 char_u hash[UNDO_HASH_SIZE]; 2604 2605 sha256_finish(&sha_ctx, hash); 2606 u_read_undo(NULL, hash, fname); 2607 } 2608 #endif 2609 2610 if (!read_stdin && !read_fifo && (!read_buffer || sfname != NULL)) 2611 { 2612 int m = msg_scroll; 2613 int n = msg_scrolled; 2614 2615 /* Save the fileformat now, otherwise the buffer will be considered 2616 * modified if the format/encoding was automatically detected. */ 2617 if (set_options) 2618 save_file_ff(curbuf); 2619 2620 /* 2621 * The output from the autocommands should not overwrite anything and 2622 * should not be overwritten: Set msg_scroll, restore its value if no 2623 * output was done. 2624 */ 2625 msg_scroll = TRUE; 2626 if (filtering) 2627 apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname, 2628 FALSE, curbuf, eap); 2629 else if (newfile || (read_buffer && sfname != NULL)) 2630 { 2631 apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname, 2632 FALSE, curbuf, eap); 2633 if (!au_did_filetype && *curbuf->b_p_ft != NUL) 2634 /* 2635 * EVENT_FILETYPE was not triggered but the buffer already has a 2636 * filetype. Trigger EVENT_FILETYPE using the existing filetype. 2637 */ 2638 apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname, 2639 TRUE, curbuf); 2640 } 2641 else 2642 apply_autocmds_exarg(EVENT_FILEREADPOST, sfname, sfname, 2643 FALSE, NULL, eap); 2644 if (msg_scrolled == n) 2645 msg_scroll = m; 2646 # ifdef FEAT_EVAL 2647 if (aborting()) /* autocmds may abort script processing */ 2648 return FAIL; 2649 # endif 2650 } 2651 2652 if (recoverymode && error) 2653 return FAIL; 2654 return OK; 2655 } 2656 2657 #if defined(OPEN_CHR_FILES) || defined(PROTO) 2658 /* 2659 * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+", 2660 * which is the name of files used for process substitution output by 2661 * some shells on some operating systems, e.g., bash on SunOS. 2662 * Do not accept "/dev/fd/[012]", opening these may hang Vim. 2663 */ 2664 int 2665 is_dev_fd_file(char_u *fname) 2666 { 2667 return (STRNCMP(fname, "/dev/fd/", 8) == 0 2668 && VIM_ISDIGIT(fname[8]) 2669 && *skipdigits(fname + 9) == NUL 2670 && (fname[9] != NUL 2671 || (fname[8] != '0' && fname[8] != '1' && fname[8] != '2'))); 2672 } 2673 #endif 2674 2675 /* 2676 * From the current line count and characters read after that, estimate the 2677 * line number where we are now. 2678 * Used for error messages that include a line number. 2679 */ 2680 static linenr_T 2681 readfile_linenr( 2682 linenr_T linecnt, /* line count before reading more bytes */ 2683 char_u *p, /* start of more bytes read */ 2684 char_u *endp) /* end of more bytes read */ 2685 { 2686 char_u *s; 2687 linenr_T lnum; 2688 2689 lnum = curbuf->b_ml.ml_line_count - linecnt + 1; 2690 for (s = p; s < endp; ++s) 2691 if (*s == '\n') 2692 ++lnum; 2693 return lnum; 2694 } 2695 2696 /* 2697 * Fill "*eap" to force the 'fileencoding', 'fileformat' and 'binary to be 2698 * equal to the buffer "buf". Used for calling readfile(). 2699 * Returns OK or FAIL. 2700 */ 2701 int 2702 prep_exarg(exarg_T *eap, buf_T *buf) 2703 { 2704 eap->cmd = alloc(15 + (unsigned)STRLEN(buf->b_p_fenc)); 2705 if (eap->cmd == NULL) 2706 return FAIL; 2707 2708 sprintf((char *)eap->cmd, "e ++enc=%s", buf->b_p_fenc); 2709 eap->force_enc = 8; 2710 eap->bad_char = buf->b_bad_char; 2711 eap->force_ff = *buf->b_p_ff; 2712 2713 eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN; 2714 eap->read_edit = FALSE; 2715 eap->forceit = FALSE; 2716 return OK; 2717 } 2718 2719 /* 2720 * Set default or forced 'fileformat' and 'binary'. 2721 */ 2722 void 2723 set_file_options(int set_options, exarg_T *eap) 2724 { 2725 /* set default 'fileformat' */ 2726 if (set_options) 2727 { 2728 if (eap != NULL && eap->force_ff != 0) 2729 set_fileformat(get_fileformat_force(curbuf, eap), OPT_LOCAL); 2730 else if (*p_ffs != NUL) 2731 set_fileformat(default_fileformat(), OPT_LOCAL); 2732 } 2733 2734 /* set or reset 'binary' */ 2735 if (eap != NULL && eap->force_bin != 0) 2736 { 2737 int oldval = curbuf->b_p_bin; 2738 2739 curbuf->b_p_bin = (eap->force_bin == FORCE_BIN); 2740 set_options_bin(oldval, curbuf->b_p_bin, OPT_LOCAL); 2741 } 2742 } 2743 2744 /* 2745 * Set forced 'fileencoding'. 2746 */ 2747 void 2748 set_forced_fenc(exarg_T *eap) 2749 { 2750 if (eap->force_enc != 0) 2751 { 2752 char_u *fenc = enc_canonize(eap->cmd + eap->force_enc); 2753 2754 if (fenc != NULL) 2755 set_string_option_direct((char_u *)"fenc", -1, 2756 fenc, OPT_FREE|OPT_LOCAL, 0); 2757 vim_free(fenc); 2758 } 2759 } 2760 2761 /* 2762 * Find next fileencoding to use from 'fileencodings'. 2763 * "pp" points to fenc_next. It's advanced to the next item. 2764 * When there are no more items, an empty string is returned and *pp is set to 2765 * NULL. 2766 * When *pp is not set to NULL, the result is in allocated memory. 2767 */ 2768 static char_u * 2769 next_fenc(char_u **pp) 2770 { 2771 char_u *p; 2772 char_u *r; 2773 2774 if (**pp == NUL) 2775 { 2776 *pp = NULL; 2777 return (char_u *)""; 2778 } 2779 p = vim_strchr(*pp, ','); 2780 if (p == NULL) 2781 { 2782 r = enc_canonize(*pp); 2783 *pp += STRLEN(*pp); 2784 } 2785 else 2786 { 2787 r = vim_strnsave(*pp, (int)(p - *pp)); 2788 *pp = p + 1; 2789 if (r != NULL) 2790 { 2791 p = enc_canonize(r); 2792 vim_free(r); 2793 r = p; 2794 } 2795 } 2796 if (r == NULL) /* out of memory */ 2797 { 2798 r = (char_u *)""; 2799 *pp = NULL; 2800 } 2801 return r; 2802 } 2803 2804 #ifdef FEAT_EVAL 2805 /* 2806 * Convert a file with the 'charconvert' expression. 2807 * This closes the file which is to be read, converts it and opens the 2808 * resulting file for reading. 2809 * Returns name of the resulting converted file (the caller should delete it 2810 * after reading it). 2811 * Returns NULL if the conversion failed ("*fdp" is not set) . 2812 */ 2813 static char_u * 2814 readfile_charconvert( 2815 char_u *fname, /* name of input file */ 2816 char_u *fenc, /* converted from */ 2817 int *fdp) /* in/out: file descriptor of file */ 2818 { 2819 char_u *tmpname; 2820 char *errmsg = NULL; 2821 2822 tmpname = vim_tempname('r', FALSE); 2823 if (tmpname == NULL) 2824 errmsg = _("Can't find temp file for conversion"); 2825 else 2826 { 2827 close(*fdp); /* close the input file, ignore errors */ 2828 *fdp = -1; 2829 if (eval_charconvert(fenc, enc_utf8 ? (char_u *)"utf-8" : p_enc, 2830 fname, tmpname) == FAIL) 2831 errmsg = _("Conversion with 'charconvert' failed"); 2832 if (errmsg == NULL && (*fdp = mch_open((char *)tmpname, 2833 O_RDONLY | O_EXTRA, 0)) < 0) 2834 errmsg = _("can't read output of 'charconvert'"); 2835 } 2836 2837 if (errmsg != NULL) 2838 { 2839 /* Don't use emsg(), it breaks mappings, the retry with 2840 * another type of conversion might still work. */ 2841 msg(errmsg); 2842 if (tmpname != NULL) 2843 { 2844 mch_remove(tmpname); /* delete converted file */ 2845 VIM_CLEAR(tmpname); 2846 } 2847 } 2848 2849 /* If the input file is closed, open it (caller should check for error). */ 2850 if (*fdp < 0) 2851 *fdp = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); 2852 2853 return tmpname; 2854 } 2855 #endif 2856 2857 2858 #ifdef FEAT_VIMINFO 2859 /* 2860 * Read marks for the current buffer from the viminfo file, when we support 2861 * buffer marks and the buffer has a name. 2862 */ 2863 static void 2864 check_marks_read(void) 2865 { 2866 if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0 2867 && curbuf->b_ffname != NULL) 2868 read_viminfo(NULL, VIF_WANT_MARKS); 2869 2870 /* Always set b_marks_read; needed when 'viminfo' is changed to include 2871 * the ' parameter after opening a buffer. */ 2872 curbuf->b_marks_read = TRUE; 2873 } 2874 #endif 2875 2876 #if defined(FEAT_CRYPT) || defined(PROTO) 2877 /* 2878 * Check for magic number used for encryption. Applies to the current buffer. 2879 * If found, the magic number is removed from ptr[*sizep] and *sizep and 2880 * *filesizep are updated. 2881 * Return the (new) encryption key, NULL for no encryption. 2882 */ 2883 static char_u * 2884 check_for_cryptkey( 2885 char_u *cryptkey, /* previous encryption key or NULL */ 2886 char_u *ptr, /* pointer to read bytes */ 2887 long *sizep, /* length of read bytes */ 2888 off_T *filesizep, /* nr of bytes used from file */ 2889 int newfile, /* editing a new buffer */ 2890 char_u *fname, /* file name to display */ 2891 int *did_ask) /* flag: whether already asked for key */ 2892 { 2893 int method = crypt_method_nr_from_magic((char *)ptr, *sizep); 2894 int b_p_ro = curbuf->b_p_ro; 2895 2896 if (method >= 0) 2897 { 2898 /* Mark the buffer as read-only until the decryption has taken place. 2899 * Avoids accidentally overwriting the file with garbage. */ 2900 curbuf->b_p_ro = TRUE; 2901 2902 /* Set the cryptmethod local to the buffer. */ 2903 crypt_set_cm_option(curbuf, method); 2904 if (cryptkey == NULL && !*did_ask) 2905 { 2906 if (*curbuf->b_p_key) 2907 cryptkey = curbuf->b_p_key; 2908 else 2909 { 2910 /* When newfile is TRUE, store the typed key in the 'key' 2911 * option and don't free it. bf needs hash of the key saved. 2912 * Don't ask for the key again when first time Enter was hit. 2913 * Happens when retrying to detect encoding. */ 2914 smsg(_(need_key_msg), fname); 2915 msg_scroll = TRUE; 2916 crypt_check_method(method); 2917 cryptkey = crypt_get_key(newfile, FALSE); 2918 *did_ask = TRUE; 2919 2920 /* check if empty key entered */ 2921 if (cryptkey != NULL && *cryptkey == NUL) 2922 { 2923 if (cryptkey != curbuf->b_p_key) 2924 vim_free(cryptkey); 2925 cryptkey = NULL; 2926 } 2927 } 2928 } 2929 2930 if (cryptkey != NULL) 2931 { 2932 int header_len; 2933 2934 curbuf->b_cryptstate = crypt_create_from_header( 2935 method, cryptkey, ptr); 2936 crypt_set_cm_option(curbuf, method); 2937 2938 /* Remove cryptmethod specific header from the text. */ 2939 header_len = crypt_get_header_len(method); 2940 if (*sizep <= header_len) 2941 /* invalid header, buffer can't be encrypted */ 2942 return NULL; 2943 *filesizep += header_len; 2944 *sizep -= header_len; 2945 mch_memmove(ptr, ptr + header_len, (size_t)*sizep); 2946 2947 /* Restore the read-only flag. */ 2948 curbuf->b_p_ro = b_p_ro; 2949 } 2950 } 2951 /* When starting to edit a new file which does not have encryption, clear 2952 * the 'key' option, except when starting up (called with -x argument) */ 2953 else if (newfile && *curbuf->b_p_key != NUL && !starting) 2954 set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL); 2955 2956 return cryptkey; 2957 } 2958 #endif /* FEAT_CRYPT */ 2959 2960 #ifdef UNIX 2961 static void 2962 set_file_time( 2963 char_u *fname, 2964 time_t atime, /* access time */ 2965 time_t mtime) /* modification time */ 2966 { 2967 # if defined(HAVE_UTIME) && defined(HAVE_UTIME_H) 2968 struct utimbuf buf; 2969 2970 buf.actime = atime; 2971 buf.modtime = mtime; 2972 (void)utime((char *)fname, &buf); 2973 # else 2974 # if defined(HAVE_UTIMES) 2975 struct timeval tvp[2]; 2976 2977 tvp[0].tv_sec = atime; 2978 tvp[0].tv_usec = 0; 2979 tvp[1].tv_sec = mtime; 2980 tvp[1].tv_usec = 0; 2981 # ifdef NeXT 2982 (void)utimes((char *)fname, tvp); 2983 # else 2984 (void)utimes((char *)fname, (const struct timeval *)&tvp); 2985 # endif 2986 # endif 2987 # endif 2988 } 2989 #endif /* UNIX */ 2990 2991 #if defined(VMS) && !defined(MIN) 2992 /* Older DECC compiler for VAX doesn't define MIN() */ 2993 # define MIN(a, b) ((a) < (b) ? (a) : (b)) 2994 #endif 2995 2996 /* 2997 * Return TRUE if a file appears to be read-only from the file permissions. 2998 */ 2999 int 3000 check_file_readonly( 3001 char_u *fname, /* full path to file */ 3002 int perm) /* known permissions on file */ 3003 { 3004 #ifndef USE_MCH_ACCESS 3005 int fd = 0; 3006 #endif 3007 3008 return ( 3009 #ifdef USE_MCH_ACCESS 3010 # ifdef UNIX 3011 (perm & 0222) == 0 || 3012 # endif 3013 mch_access((char *)fname, W_OK) 3014 #else 3015 (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0 3016 ? TRUE : (close(fd), FALSE) 3017 #endif 3018 ); 3019 } 3020 3021 3022 /* 3023 * buf_write() - write to file "fname" lines "start" through "end" 3024 * 3025 * We do our own buffering here because fwrite() is so slow. 3026 * 3027 * If "forceit" is true, we don't care for errors when attempting backups. 3028 * In case of an error everything possible is done to restore the original 3029 * file. But when "forceit" is TRUE, we risk losing it. 3030 * 3031 * When "reset_changed" is TRUE and "append" == FALSE and "start" == 1 and 3032 * "end" == curbuf->b_ml.ml_line_count, reset curbuf->b_changed. 3033 * 3034 * This function must NOT use NameBuff (because it's called by autowrite()). 3035 * 3036 * return FAIL for failure, OK otherwise 3037 */ 3038 int 3039 buf_write( 3040 buf_T *buf, 3041 char_u *fname, 3042 char_u *sfname, 3043 linenr_T start, 3044 linenr_T end, 3045 exarg_T *eap, /* for forced 'ff' and 'fenc', can be 3046 NULL! */ 3047 int append, /* append to the file */ 3048 int forceit, 3049 int reset_changed, 3050 int filtering) 3051 { 3052 int fd; 3053 char_u *backup = NULL; 3054 int backup_copy = FALSE; /* copy the original file? */ 3055 int dobackup; 3056 char_u *ffname; 3057 char_u *wfname = NULL; /* name of file to write to */ 3058 char_u *s; 3059 char_u *ptr; 3060 char_u c; 3061 int len; 3062 linenr_T lnum; 3063 long nchars; 3064 char_u *errmsg = NULL; 3065 int errmsg_allocated = FALSE; 3066 char_u *errnum = NULL; 3067 char_u *buffer; 3068 char_u smallbuf[SMBUFSIZE]; 3069 char_u *backup_ext; 3070 int bufsize; 3071 long perm; /* file permissions */ 3072 int retval = OK; 3073 int newfile = FALSE; /* TRUE if file doesn't exist yet */ 3074 int msg_save = msg_scroll; 3075 int overwriting; /* TRUE if writing over original */ 3076 int no_eol = FALSE; /* no end-of-line written */ 3077 int device = FALSE; /* writing to a device */ 3078 stat_T st_old; 3079 int prev_got_int = got_int; 3080 int checking_conversion; 3081 int file_readonly = FALSE; /* overwritten file is read-only */ 3082 static char *err_readonly = "is read-only (cannot override: \"W\" in 'cpoptions')"; 3083 #if defined(UNIX) /*XXX fix me sometime? */ 3084 int made_writable = FALSE; /* 'w' bit has been set */ 3085 #endif 3086 /* writing everything */ 3087 int whole = (start == 1 && end == buf->b_ml.ml_line_count); 3088 linenr_T old_line_count = buf->b_ml.ml_line_count; 3089 int attr; 3090 int fileformat; 3091 int write_bin; 3092 struct bw_info write_info; /* info for buf_write_bytes() */ 3093 int converted = FALSE; 3094 int notconverted = FALSE; 3095 char_u *fenc; /* effective 'fileencoding' */ 3096 char_u *fenc_tofree = NULL; /* allocated "fenc" */ 3097 #ifdef HAS_BW_FLAGS 3098 int wb_flags = 0; 3099 #endif 3100 #ifdef HAVE_ACL 3101 vim_acl_T acl = NULL; /* ACL copied from original file to 3102 backup or new file */ 3103 #endif 3104 #ifdef FEAT_PERSISTENT_UNDO 3105 int write_undo_file = FALSE; 3106 context_sha256_T sha_ctx; 3107 #endif 3108 unsigned int bkc = get_bkc_value(buf); 3109 3110 if (fname == NULL || *fname == NUL) /* safety check */ 3111 return FAIL; 3112 if (buf->b_ml.ml_mfp == NULL) 3113 { 3114 /* This can happen during startup when there is a stray "w" in the 3115 * vimrc file. */ 3116 emsg(_(e_emptybuf)); 3117 return FAIL; 3118 } 3119 3120 /* 3121 * Disallow writing from .exrc and .vimrc in current directory for 3122 * security reasons. 3123 */ 3124 if (check_secure()) 3125 return FAIL; 3126 3127 /* Avoid a crash for a long name. */ 3128 if (STRLEN(fname) >= MAXPATHL) 3129 { 3130 emsg(_(e_longname)); 3131 return FAIL; 3132 } 3133 3134 /* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */ 3135 write_info.bw_conv_buf = NULL; 3136 write_info.bw_conv_error = FALSE; 3137 write_info.bw_conv_error_lnum = 0; 3138 write_info.bw_restlen = 0; 3139 #ifdef USE_ICONV 3140 write_info.bw_iconv_fd = (iconv_t)-1; 3141 #endif 3142 #ifdef FEAT_CRYPT 3143 write_info.bw_buffer = buf; 3144 #endif 3145 3146 /* After writing a file changedtick changes but we don't want to display 3147 * the line. */ 3148 ex_no_reprint = TRUE; 3149 3150 /* 3151 * If there is no file name yet, use the one for the written file. 3152 * BF_NOTEDITED is set to reflect this (in case the write fails). 3153 * Don't do this when the write is for a filter command. 3154 * Don't do this when appending. 3155 * Only do this when 'cpoptions' contains the 'F' flag. 3156 */ 3157 if (buf->b_ffname == NULL 3158 && reset_changed 3159 && whole 3160 && buf == curbuf 3161 #ifdef FEAT_QUICKFIX 3162 && !bt_nofile(buf) 3163 #endif 3164 && !filtering 3165 && (!append || vim_strchr(p_cpo, CPO_FNAMEAPP) != NULL) 3166 && vim_strchr(p_cpo, CPO_FNAMEW) != NULL) 3167 { 3168 if (set_rw_fname(fname, sfname) == FAIL) 3169 return FAIL; 3170 buf = curbuf; /* just in case autocmds made "buf" invalid */ 3171 } 3172 3173 if (sfname == NULL) 3174 sfname = fname; 3175 /* 3176 * For Unix: Use the short file name whenever possible. 3177 * Avoids problems with networks and when directory names are changed. 3178 * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to 3179 * another directory, which we don't detect 3180 */ 3181 ffname = fname; /* remember full fname */ 3182 #ifdef UNIX 3183 fname = sfname; 3184 #endif 3185 3186 if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0) 3187 overwriting = TRUE; 3188 else 3189 overwriting = FALSE; 3190 3191 if (exiting) 3192 settmode(TMODE_COOK); /* when exiting allow typeahead now */ 3193 3194 ++no_wait_return; /* don't wait for return yet */ 3195 3196 /* 3197 * Set '[ and '] marks to the lines to be written. 3198 */ 3199 buf->b_op_start.lnum = start; 3200 buf->b_op_start.col = 0; 3201 buf->b_op_end.lnum = end; 3202 buf->b_op_end.col = 0; 3203 3204 { 3205 aco_save_T aco; 3206 int buf_ffname = FALSE; 3207 int buf_sfname = FALSE; 3208 int buf_fname_f = FALSE; 3209 int buf_fname_s = FALSE; 3210 int did_cmd = FALSE; 3211 int nofile_err = FALSE; 3212 int empty_memline = (buf->b_ml.ml_mfp == NULL); 3213 bufref_T bufref; 3214 3215 /* 3216 * Apply PRE autocommands. 3217 * Set curbuf to the buffer to be written. 3218 * Careful: The autocommands may call buf_write() recursively! 3219 */ 3220 if (ffname == buf->b_ffname) 3221 buf_ffname = TRUE; 3222 if (sfname == buf->b_sfname) 3223 buf_sfname = TRUE; 3224 if (fname == buf->b_ffname) 3225 buf_fname_f = TRUE; 3226 if (fname == buf->b_sfname) 3227 buf_fname_s = TRUE; 3228 3229 /* set curwin/curbuf to buf and save a few things */ 3230 aucmd_prepbuf(&aco, buf); 3231 set_bufref(&bufref, buf); 3232 3233 if (append) 3234 { 3235 if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD, 3236 sfname, sfname, FALSE, curbuf, eap))) 3237 { 3238 #ifdef FEAT_QUICKFIX 3239 if (overwriting && bt_nofile(curbuf)) 3240 nofile_err = TRUE; 3241 else 3242 #endif 3243 apply_autocmds_exarg(EVENT_FILEAPPENDPRE, 3244 sfname, sfname, FALSE, curbuf, eap); 3245 } 3246 } 3247 else if (filtering) 3248 { 3249 apply_autocmds_exarg(EVENT_FILTERWRITEPRE, 3250 NULL, sfname, FALSE, curbuf, eap); 3251 } 3252 else if (reset_changed && whole) 3253 { 3254 int was_changed = curbufIsChanged(); 3255 3256 did_cmd = apply_autocmds_exarg(EVENT_BUFWRITECMD, 3257 sfname, sfname, FALSE, curbuf, eap); 3258 if (did_cmd) 3259 { 3260 if (was_changed && !curbufIsChanged()) 3261 { 3262 /* Written everything correctly and BufWriteCmd has reset 3263 * 'modified': Correct the undo information so that an 3264 * undo now sets 'modified'. */ 3265 u_unchanged(curbuf); 3266 u_update_save_nr(curbuf); 3267 } 3268 } 3269 else 3270 { 3271 #ifdef FEAT_QUICKFIX 3272 if (overwriting && bt_nofile(curbuf)) 3273 nofile_err = TRUE; 3274 else 3275 #endif 3276 apply_autocmds_exarg(EVENT_BUFWRITEPRE, 3277 sfname, sfname, FALSE, curbuf, eap); 3278 } 3279 } 3280 else 3281 { 3282 if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEWRITECMD, 3283 sfname, sfname, FALSE, curbuf, eap))) 3284 { 3285 #ifdef FEAT_QUICKFIX 3286 if (overwriting && bt_nofile(curbuf)) 3287 nofile_err = TRUE; 3288 else 3289 #endif 3290 apply_autocmds_exarg(EVENT_FILEWRITEPRE, 3291 sfname, sfname, FALSE, curbuf, eap); 3292 } 3293 } 3294 3295 /* restore curwin/curbuf and a few other things */ 3296 aucmd_restbuf(&aco); 3297 3298 /* 3299 * In three situations we return here and don't write the file: 3300 * 1. the autocommands deleted or unloaded the buffer. 3301 * 2. The autocommands abort script processing. 3302 * 3. If one of the "Cmd" autocommands was executed. 3303 */ 3304 if (!bufref_valid(&bufref)) 3305 buf = NULL; 3306 if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline) 3307 || did_cmd || nofile_err 3308 #ifdef FEAT_EVAL 3309 || aborting() 3310 #endif 3311 ) 3312 { 3313 --no_wait_return; 3314 msg_scroll = msg_save; 3315 if (nofile_err) 3316 emsg(_("E676: No matching autocommands for acwrite buffer")); 3317 3318 if (nofile_err 3319 #ifdef FEAT_EVAL 3320 || aborting() 3321 #endif 3322 ) 3323 /* An aborting error, interrupt or exception in the 3324 * autocommands. */ 3325 return FAIL; 3326 if (did_cmd) 3327 { 3328 if (buf == NULL) 3329 /* The buffer was deleted. We assume it was written 3330 * (can't retry anyway). */ 3331 return OK; 3332 if (overwriting) 3333 { 3334 /* Assume the buffer was written, update the timestamp. */ 3335 ml_timestamp(buf); 3336 if (append) 3337 buf->b_flags &= ~BF_NEW; 3338 else 3339 buf->b_flags &= ~BF_WRITE_MASK; 3340 } 3341 if (reset_changed && buf->b_changed && !append 3342 && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)) 3343 /* Buffer still changed, the autocommands didn't work 3344 * properly. */ 3345 return FAIL; 3346 return OK; 3347 } 3348 #ifdef FEAT_EVAL 3349 if (!aborting()) 3350 #endif 3351 emsg(_("E203: Autocommands deleted or unloaded buffer to be written")); 3352 return FAIL; 3353 } 3354 3355 /* 3356 * The autocommands may have changed the number of lines in the file. 3357 * When writing the whole file, adjust the end. 3358 * When writing part of the file, assume that the autocommands only 3359 * changed the number of lines that are to be written (tricky!). 3360 */ 3361 if (buf->b_ml.ml_line_count != old_line_count) 3362 { 3363 if (whole) /* write all */ 3364 end = buf->b_ml.ml_line_count; 3365 else if (buf->b_ml.ml_line_count > old_line_count) /* more lines */ 3366 end += buf->b_ml.ml_line_count - old_line_count; 3367 else /* less lines */ 3368 { 3369 end -= old_line_count - buf->b_ml.ml_line_count; 3370 if (end < start) 3371 { 3372 --no_wait_return; 3373 msg_scroll = msg_save; 3374 emsg(_("E204: Autocommand changed number of lines in unexpected way")); 3375 return FAIL; 3376 } 3377 } 3378 } 3379 3380 /* 3381 * The autocommands may have changed the name of the buffer, which may 3382 * be kept in fname, ffname and sfname. 3383 */ 3384 if (buf_ffname) 3385 ffname = buf->b_ffname; 3386 if (buf_sfname) 3387 sfname = buf->b_sfname; 3388 if (buf_fname_f) 3389 fname = buf->b_ffname; 3390 if (buf_fname_s) 3391 fname = buf->b_sfname; 3392 } 3393 3394 #ifdef FEAT_NETBEANS_INTG 3395 if (netbeans_active() && isNetbeansBuffer(buf)) 3396 { 3397 if (whole) 3398 { 3399 /* 3400 * b_changed can be 0 after an undo, but we still need to write 3401 * the buffer to NetBeans. 3402 */ 3403 if (buf->b_changed || isNetbeansModified(buf)) 3404 { 3405 --no_wait_return; /* may wait for return now */ 3406 msg_scroll = msg_save; 3407 netbeans_save_buffer(buf); /* no error checking... */ 3408 return retval; 3409 } 3410 else 3411 { 3412 errnum = (char_u *)"E656: "; 3413 errmsg = (char_u *)_("NetBeans disallows writes of unmodified buffers"); 3414 buffer = NULL; 3415 goto fail; 3416 } 3417 } 3418 else 3419 { 3420 errnum = (char_u *)"E657: "; 3421 errmsg = (char_u *)_("Partial writes disallowed for NetBeans buffers"); 3422 buffer = NULL; 3423 goto fail; 3424 } 3425 } 3426 #endif 3427 3428 if (shortmess(SHM_OVER) && !exiting) 3429 msg_scroll = FALSE; /* overwrite previous file message */ 3430 else 3431 msg_scroll = TRUE; /* don't overwrite previous file message */ 3432 if (!filtering) 3433 filemess(buf, 3434 #ifndef UNIX 3435 sfname, 3436 #else 3437 fname, 3438 #endif 3439 (char_u *)"", 0); /* show that we are busy */ 3440 msg_scroll = FALSE; /* always overwrite the file message now */ 3441 3442 buffer = alloc(BUFSIZE); 3443 if (buffer == NULL) /* can't allocate big buffer, use small 3444 * one (to be able to write when out of 3445 * memory) */ 3446 { 3447 buffer = smallbuf; 3448 bufsize = SMBUFSIZE; 3449 } 3450 else 3451 bufsize = BUFSIZE; 3452 3453 /* 3454 * Get information about original file (if there is one). 3455 */ 3456 #if defined(UNIX) 3457 st_old.st_dev = 0; 3458 st_old.st_ino = 0; 3459 perm = -1; 3460 if (mch_stat((char *)fname, &st_old) < 0) 3461 newfile = TRUE; 3462 else 3463 { 3464 perm = st_old.st_mode; 3465 if (!S_ISREG(st_old.st_mode)) /* not a file */ 3466 { 3467 if (S_ISDIR(st_old.st_mode)) 3468 { 3469 errnum = (char_u *)"E502: "; 3470 errmsg = (char_u *)_("is a directory"); 3471 goto fail; 3472 } 3473 if (mch_nodetype(fname) != NODE_WRITABLE) 3474 { 3475 errnum = (char_u *)"E503: "; 3476 errmsg = (char_u *)_("is not a file or writable device"); 3477 goto fail; 3478 } 3479 /* It's a device of some kind (or a fifo) which we can write to 3480 * but for which we can't make a backup. */ 3481 device = TRUE; 3482 newfile = TRUE; 3483 perm = -1; 3484 } 3485 } 3486 #else /* !UNIX */ 3487 /* 3488 * Check for a writable device name. 3489 */ 3490 c = mch_nodetype(fname); 3491 if (c == NODE_OTHER) 3492 { 3493 errnum = (char_u *)"E503: "; 3494 errmsg = (char_u *)_("is not a file or writable device"); 3495 goto fail; 3496 } 3497 if (c == NODE_WRITABLE) 3498 { 3499 # if defined(MSWIN) 3500 /* MS-Windows allows opening a device, but we will probably get stuck 3501 * trying to write to it. */ 3502 if (!p_odev) 3503 { 3504 errnum = (char_u *)"E796: "; 3505 errmsg = (char_u *)_("writing to device disabled with 'opendevice' option"); 3506 goto fail; 3507 } 3508 # endif 3509 device = TRUE; 3510 newfile = TRUE; 3511 perm = -1; 3512 } 3513 else 3514 { 3515 perm = mch_getperm(fname); 3516 if (perm < 0) 3517 newfile = TRUE; 3518 else if (mch_isdir(fname)) 3519 { 3520 errnum = (char_u *)"E502: "; 3521 errmsg = (char_u *)_("is a directory"); 3522 goto fail; 3523 } 3524 if (overwriting) 3525 (void)mch_stat((char *)fname, &st_old); 3526 } 3527 #endif /* !UNIX */ 3528 3529 if (!device && !newfile) 3530 { 3531 /* 3532 * Check if the file is really writable (when renaming the file to 3533 * make a backup we won't discover it later). 3534 */ 3535 file_readonly = check_file_readonly(fname, (int)perm); 3536 3537 if (!forceit && file_readonly) 3538 { 3539 if (vim_strchr(p_cpo, CPO_FWRITE) != NULL) 3540 { 3541 errnum = (char_u *)"E504: "; 3542 errmsg = (char_u *)_(err_readonly); 3543 } 3544 else 3545 { 3546 errnum = (char_u *)"E505: "; 3547 errmsg = (char_u *)_("is read-only (add ! to override)"); 3548 } 3549 goto fail; 3550 } 3551 3552 /* 3553 * Check if the timestamp hasn't changed since reading the file. 3554 */ 3555 if (overwriting) 3556 { 3557 retval = check_mtime(buf, &st_old); 3558 if (retval == FAIL) 3559 goto fail; 3560 } 3561 } 3562 3563 #ifdef HAVE_ACL 3564 /* 3565 * For systems that support ACL: get the ACL from the original file. 3566 */ 3567 if (!newfile) 3568 acl = mch_get_acl(fname); 3569 #endif 3570 3571 /* 3572 * If 'backupskip' is not empty, don't make a backup for some files. 3573 */ 3574 dobackup = (p_wb || p_bk || *p_pm != NUL); 3575 #ifdef FEAT_WILDIGN 3576 if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname)) 3577 dobackup = FALSE; 3578 #endif 3579 3580 /* 3581 * Save the value of got_int and reset it. We don't want a previous 3582 * interruption cancel writing, only hitting CTRL-C while writing should 3583 * abort it. 3584 */ 3585 prev_got_int = got_int; 3586 got_int = FALSE; 3587 3588 /* Mark the buffer as 'being saved' to prevent changed buffer warnings */ 3589 buf->b_saving = TRUE; 3590 3591 /* 3592 * If we are not appending or filtering, the file exists, and the 3593 * 'writebackup', 'backup' or 'patchmode' option is set, need a backup. 3594 * When 'patchmode' is set also make a backup when appending. 3595 * 3596 * Do not make any backup, if 'writebackup' and 'backup' are both switched 3597 * off. This helps when editing large files on almost-full disks. 3598 */ 3599 if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup) 3600 { 3601 #if defined(UNIX) || defined(MSWIN) 3602 stat_T st; 3603 #endif 3604 3605 if ((bkc & BKC_YES) || append) /* "yes" */ 3606 backup_copy = TRUE; 3607 #if defined(UNIX) || defined(MSWIN) 3608 else if ((bkc & BKC_AUTO)) /* "auto" */ 3609 { 3610 int i; 3611 3612 # ifdef UNIX 3613 /* 3614 * Don't rename the file when: 3615 * - it's a hard link 3616 * - it's a symbolic link 3617 * - we don't have write permission in the directory 3618 * - we can't set the owner/group of the new file 3619 */ 3620 if (st_old.st_nlink > 1 3621 || mch_lstat((char *)fname, &st) < 0 3622 || st.st_dev != st_old.st_dev 3623 || st.st_ino != st_old.st_ino 3624 # ifndef HAVE_FCHOWN 3625 || st.st_uid != st_old.st_uid 3626 || st.st_gid != st_old.st_gid 3627 # endif 3628 ) 3629 backup_copy = TRUE; 3630 else 3631 # else 3632 # ifdef MSWIN 3633 /* On NTFS file systems hard links are possible. */ 3634 if (mch_is_linked(fname)) 3635 backup_copy = TRUE; 3636 else 3637 # endif 3638 # endif 3639 { 3640 /* 3641 * Check if we can create a file and set the owner/group to 3642 * the ones from the original file. 3643 * First find a file name that doesn't exist yet (use some 3644 * arbitrary numbers). 3645 */ 3646 STRCPY(IObuff, fname); 3647 for (i = 4913; ; i += 123) 3648 { 3649 sprintf((char *)gettail(IObuff), "%d", i); 3650 if (mch_lstat((char *)IObuff, &st) < 0) 3651 break; 3652 } 3653 fd = mch_open((char *)IObuff, 3654 O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm); 3655 if (fd < 0) /* can't write in directory */ 3656 backup_copy = TRUE; 3657 else 3658 { 3659 # ifdef UNIX 3660 # ifdef HAVE_FCHOWN 3661 vim_ignored = fchown(fd, st_old.st_uid, st_old.st_gid); 3662 # endif 3663 if (mch_stat((char *)IObuff, &st) < 0 3664 || st.st_uid != st_old.st_uid 3665 || st.st_gid != st_old.st_gid 3666 || (long)st.st_mode != perm) 3667 backup_copy = TRUE; 3668 # endif 3669 /* Close the file before removing it, on MS-Windows we 3670 * can't delete an open file. */ 3671 close(fd); 3672 mch_remove(IObuff); 3673 # ifdef MSWIN 3674 /* MS-Windows may trigger a virus scanner to open the 3675 * file, we can't delete it then. Keep trying for half a 3676 * second. */ 3677 { 3678 int try; 3679 3680 for (try = 0; try < 10; ++try) 3681 { 3682 if (mch_lstat((char *)IObuff, &st) < 0) 3683 break; 3684 ui_delay(50L, TRUE); /* wait 50 msec */ 3685 mch_remove(IObuff); 3686 } 3687 } 3688 # endif 3689 } 3690 } 3691 } 3692 3693 /* 3694 * Break symlinks and/or hardlinks if we've been asked to. 3695 */ 3696 if ((bkc & BKC_BREAKSYMLINK) || (bkc & BKC_BREAKHARDLINK)) 3697 { 3698 # ifdef UNIX 3699 int lstat_res; 3700 3701 lstat_res = mch_lstat((char *)fname, &st); 3702 3703 /* Symlinks. */ 3704 if ((bkc & BKC_BREAKSYMLINK) 3705 && lstat_res == 0 3706 && st.st_ino != st_old.st_ino) 3707 backup_copy = FALSE; 3708 3709 /* Hardlinks. */ 3710 if ((bkc & BKC_BREAKHARDLINK) 3711 && st_old.st_nlink > 1 3712 && (lstat_res != 0 || st.st_ino == st_old.st_ino)) 3713 backup_copy = FALSE; 3714 # else 3715 # if defined(MSWIN) 3716 /* Symlinks. */ 3717 if ((bkc & BKC_BREAKSYMLINK) && mch_is_symbolic_link(fname)) 3718 backup_copy = FALSE; 3719 3720 /* Hardlinks. */ 3721 if ((bkc & BKC_BREAKHARDLINK) && mch_is_hard_link(fname)) 3722 backup_copy = FALSE; 3723 # endif 3724 # endif 3725 } 3726 3727 #endif 3728 3729 /* make sure we have a valid backup extension to use */ 3730 if (*p_bex == NUL) 3731 backup_ext = (char_u *)".bak"; 3732 else 3733 backup_ext = p_bex; 3734 3735 if (backup_copy 3736 && (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0) 3737 { 3738 int bfd; 3739 char_u *copybuf, *wp; 3740 int some_error = FALSE; 3741 stat_T st_new; 3742 char_u *dirp; 3743 char_u *rootname; 3744 #if defined(UNIX) || defined(MSWIN) 3745 char_u *p; 3746 #endif 3747 #if defined(UNIX) 3748 int did_set_shortname; 3749 mode_t umask_save; 3750 #endif 3751 3752 copybuf = alloc(BUFSIZE + 1); 3753 if (copybuf == NULL) 3754 { 3755 some_error = TRUE; /* out of memory */ 3756 goto nobackup; 3757 } 3758 3759 /* 3760 * Try to make the backup in each directory in the 'bdir' option. 3761 * 3762 * Unix semantics has it, that we may have a writable file, 3763 * that cannot be recreated with a simple open(..., O_CREAT, ) e.g: 3764 * - the directory is not writable, 3765 * - the file may be a symbolic link, 3766 * - the file may belong to another user/group, etc. 3767 * 3768 * For these reasons, the existing writable file must be truncated 3769 * and reused. Creation of a backup COPY will be attempted. 3770 */ 3771 dirp = p_bdir; 3772 while (*dirp) 3773 { 3774 #ifdef UNIX 3775 st_new.st_ino = 0; 3776 st_new.st_dev = 0; 3777 st_new.st_gid = 0; 3778 #endif 3779 3780 /* 3781 * Isolate one directory name, using an entry in 'bdir'. 3782 */ 3783 (void)copy_option_part(&dirp, copybuf, BUFSIZE, ","); 3784 3785 #if defined(UNIX) || defined(MSWIN) 3786 p = copybuf + STRLEN(copybuf); 3787 if (after_pathsep(copybuf, p) && p[-1] == p[-2]) 3788 // Ends with '//', use full path 3789 if ((p = make_percent_swname(copybuf, fname)) != NULL) 3790 { 3791 backup = modname(p, backup_ext, FALSE); 3792 vim_free(p); 3793 } 3794 #endif 3795 rootname = get_file_in_dir(fname, copybuf); 3796 if (rootname == NULL) 3797 { 3798 some_error = TRUE; /* out of memory */ 3799 goto nobackup; 3800 } 3801 3802 #if defined(UNIX) 3803 did_set_shortname = FALSE; 3804 #endif 3805 3806 /* 3807 * May try twice if 'shortname' not set. 3808 */ 3809 for (;;) 3810 { 3811 /* 3812 * Make the backup file name. 3813 */ 3814 if (backup == NULL) 3815 backup = buf_modname((buf->b_p_sn || buf->b_shortname), 3816 rootname, backup_ext, FALSE); 3817 if (backup == NULL) 3818 { 3819 vim_free(rootname); 3820 some_error = TRUE; /* out of memory */ 3821 goto nobackup; 3822 } 3823 3824 /* 3825 * Check if backup file already exists. 3826 */ 3827 if (mch_stat((char *)backup, &st_new) >= 0) 3828 { 3829 #ifdef UNIX 3830 /* 3831 * Check if backup file is same as original file. 3832 * May happen when modname() gave the same file back. 3833 * E.g. silly link, or file name-length reached. 3834 * If we don't check here, we either ruin the file 3835 * when copying or erase it after writing. jw. 3836 */ 3837 if (st_new.st_dev == st_old.st_dev 3838 && st_new.st_ino == st_old.st_ino) 3839 { 3840 VIM_CLEAR(backup); /* no backup file to delete */ 3841 /* 3842 * may try again with 'shortname' set 3843 */ 3844 if (!(buf->b_shortname || buf->b_p_sn)) 3845 { 3846 buf->b_shortname = TRUE; 3847 did_set_shortname = TRUE; 3848 continue; 3849 } 3850 /* setting shortname didn't help */ 3851 if (did_set_shortname) 3852 buf->b_shortname = FALSE; 3853 break; 3854 } 3855 #endif 3856 3857 /* 3858 * If we are not going to keep the backup file, don't 3859 * delete an existing one, try to use another name. 3860 * Change one character, just before the extension. 3861 */ 3862 if (!p_bk) 3863 { 3864 wp = backup + STRLEN(backup) - 1 3865 - STRLEN(backup_ext); 3866 if (wp < backup) /* empty file name ??? */ 3867 wp = backup; 3868 *wp = 'z'; 3869 while (*wp > 'a' 3870 && mch_stat((char *)backup, &st_new) >= 0) 3871 --*wp; 3872 /* They all exist??? Must be something wrong. */ 3873 if (*wp == 'a') 3874 VIM_CLEAR(backup); 3875 } 3876 } 3877 break; 3878 } 3879 vim_free(rootname); 3880 3881 /* 3882 * Try to create the backup file 3883 */ 3884 if (backup != NULL) 3885 { 3886 /* remove old backup, if present */ 3887 mch_remove(backup); 3888 /* Open with O_EXCL to avoid the file being created while 3889 * we were sleeping (symlink hacker attack?). Reset umask 3890 * if possible to avoid mch_setperm() below. */ 3891 #ifdef UNIX 3892 umask_save = umask(0); 3893 #endif 3894 bfd = mch_open((char *)backup, 3895 O_WRONLY|O_CREAT|O_EXTRA|O_EXCL|O_NOFOLLOW, 3896 perm & 0777); 3897 #ifdef UNIX 3898 (void)umask(umask_save); 3899 #endif 3900 if (bfd < 0) 3901 VIM_CLEAR(backup); 3902 else 3903 { 3904 /* Set file protection same as original file, but 3905 * strip s-bit. Only needed if umask() wasn't used 3906 * above. */ 3907 #ifndef UNIX 3908 (void)mch_setperm(backup, perm & 0777); 3909 #else 3910 /* 3911 * Try to set the group of the backup same as the 3912 * original file. If this fails, set the protection 3913 * bits for the group same as the protection bits for 3914 * others. 3915 */ 3916 if (st_new.st_gid != st_old.st_gid 3917 # ifdef HAVE_FCHOWN /* sequent-ptx lacks fchown() */ 3918 && fchown(bfd, (uid_t)-1, st_old.st_gid) != 0 3919 # endif 3920 ) 3921 mch_setperm(backup, 3922 (perm & 0707) | ((perm & 07) << 3)); 3923 # if defined(HAVE_SELINUX) || defined(HAVE_SMACK) 3924 mch_copy_sec(fname, backup); 3925 # endif 3926 #endif 3927 3928 /* 3929 * copy the file. 3930 */ 3931 write_info.bw_fd = bfd; 3932 write_info.bw_buf = copybuf; 3933 #ifdef HAS_BW_FLAGS 3934 write_info.bw_flags = FIO_NOCONVERT; 3935 #endif 3936 while ((write_info.bw_len = read_eintr(fd, copybuf, 3937 BUFSIZE)) > 0) 3938 { 3939 if (buf_write_bytes(&write_info) == FAIL) 3940 { 3941 errmsg = (char_u *)_("E506: Can't write to backup file (add ! to override)"); 3942 break; 3943 } 3944 ui_breakcheck(); 3945 if (got_int) 3946 { 3947 errmsg = (char_u *)_(e_interr); 3948 break; 3949 } 3950 } 3951 3952 if (close(bfd) < 0 && errmsg == NULL) 3953 errmsg = (char_u *)_("E507: Close error for backup file (add ! to override)"); 3954 if (write_info.bw_len < 0) 3955 errmsg = (char_u *)_("E508: Can't read file for backup (add ! to override)"); 3956 #ifdef UNIX 3957 set_file_time(backup, st_old.st_atime, st_old.st_mtime); 3958 #endif 3959 #ifdef HAVE_ACL 3960 mch_set_acl(backup, acl); 3961 #endif 3962 #if defined(HAVE_SELINUX) || defined(HAVE_SMACK) 3963 mch_copy_sec(fname, backup); 3964 #endif 3965 break; 3966 } 3967 } 3968 } 3969 nobackup: 3970 close(fd); /* ignore errors for closing read file */ 3971 vim_free(copybuf); 3972 3973 if (backup == NULL && errmsg == NULL) 3974 errmsg = (char_u *)_("E509: Cannot create backup file (add ! to override)"); 3975 /* ignore errors when forceit is TRUE */ 3976 if ((some_error || errmsg != NULL) && !forceit) 3977 { 3978 retval = FAIL; 3979 goto fail; 3980 } 3981 errmsg = NULL; 3982 } 3983 else 3984 { 3985 char_u *dirp; 3986 char_u *p; 3987 char_u *rootname; 3988 3989 /* 3990 * Make a backup by renaming the original file. 3991 */ 3992 /* 3993 * If 'cpoptions' includes the "W" flag, we don't want to 3994 * overwrite a read-only file. But rename may be possible 3995 * anyway, thus we need an extra check here. 3996 */ 3997 if (file_readonly && vim_strchr(p_cpo, CPO_FWRITE) != NULL) 3998 { 3999 errnum = (char_u *)"E504: "; 4000 errmsg = (char_u *)_(err_readonly); 4001 goto fail; 4002 } 4003 4004 /* 4005 * 4006 * Form the backup file name - change path/fo.o.h to 4007 * path/fo.o.h.bak Try all directories in 'backupdir', first one 4008 * that works is used. 4009 */ 4010 dirp = p_bdir; 4011 while (*dirp) 4012 { 4013 /* 4014 * Isolate one directory name and make the backup file name. 4015 */ 4016 (void)copy_option_part(&dirp, IObuff, IOSIZE, ","); 4017 4018 #if defined(UNIX) || defined(MSWIN) 4019 p = IObuff + STRLEN(IObuff); 4020 if (after_pathsep(IObuff, p) && p[-1] == p[-2]) 4021 // path ends with '//', use full path 4022 if ((p = make_percent_swname(IObuff, fname)) != NULL) 4023 { 4024 backup = modname(p, backup_ext, FALSE); 4025 vim_free(p); 4026 } 4027 #endif 4028 if (backup == NULL) 4029 { 4030 rootname = get_file_in_dir(fname, IObuff); 4031 if (rootname == NULL) 4032 backup = NULL; 4033 else 4034 { 4035 backup = buf_modname( 4036 (buf->b_p_sn || buf->b_shortname), 4037 rootname, backup_ext, FALSE); 4038 vim_free(rootname); 4039 } 4040 } 4041 4042 if (backup != NULL) 4043 { 4044 /* 4045 * If we are not going to keep the backup file, don't 4046 * delete an existing one, try to use another name. 4047 * Change one character, just before the extension. 4048 */ 4049 if (!p_bk && mch_getperm(backup) >= 0) 4050 { 4051 p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext); 4052 if (p < backup) /* empty file name ??? */ 4053 p = backup; 4054 *p = 'z'; 4055 while (*p > 'a' && mch_getperm(backup) >= 0) 4056 --*p; 4057 /* They all exist??? Must be something wrong! */ 4058 if (*p == 'a') 4059 VIM_CLEAR(backup); 4060 } 4061 } 4062 if (backup != NULL) 4063 { 4064 /* 4065 * Delete any existing backup and move the current version 4066 * to the backup. For safety, we don't remove the backup 4067 * until the write has finished successfully. And if the 4068 * 'backup' option is set, leave it around. 4069 */ 4070 /* 4071 * If the renaming of the original file to the backup file 4072 * works, quit here. 4073 */ 4074 if (vim_rename(fname, backup) == 0) 4075 break; 4076 4077 VIM_CLEAR(backup); /* don't do the rename below */ 4078 } 4079 } 4080 if (backup == NULL && !forceit) 4081 { 4082 errmsg = (char_u *)_("E510: Can't make backup file (add ! to override)"); 4083 goto fail; 4084 } 4085 } 4086 } 4087 4088 #if defined(UNIX) 4089 /* When using ":w!" and the file was read-only: make it writable */ 4090 if (forceit && perm >= 0 && !(perm & 0200) && st_old.st_uid == getuid() 4091 && vim_strchr(p_cpo, CPO_FWRITE) == NULL) 4092 { 4093 perm |= 0200; 4094 (void)mch_setperm(fname, perm); 4095 made_writable = TRUE; 4096 } 4097 #endif 4098 4099 /* When using ":w!" and writing to the current file, 'readonly' makes no 4100 * sense, reset it, unless 'Z' appears in 'cpoptions'. */ 4101 if (forceit && overwriting && vim_strchr(p_cpo, CPO_KEEPRO) == NULL) 4102 { 4103 buf->b_p_ro = FALSE; 4104 #ifdef FEAT_TITLE 4105 need_maketitle = TRUE; /* set window title later */ 4106 #endif 4107 status_redraw_all(); /* redraw status lines later */ 4108 } 4109 4110 if (end > buf->b_ml.ml_line_count) 4111 end = buf->b_ml.ml_line_count; 4112 if (buf->b_ml.ml_flags & ML_EMPTY) 4113 start = end + 1; 4114 4115 /* 4116 * If the original file is being overwritten, there is a small chance that 4117 * we crash in the middle of writing. Therefore the file is preserved now. 4118 * This makes all block numbers positive so that recovery does not need 4119 * the original file. 4120 * Don't do this if there is a backup file and we are exiting. 4121 */ 4122 if (reset_changed && !newfile && overwriting 4123 && !(exiting && backup != NULL)) 4124 { 4125 ml_preserve(buf, FALSE); 4126 if (got_int) 4127 { 4128 errmsg = (char_u *)_(e_interr); 4129 goto restore_backup; 4130 } 4131 } 4132 4133 #ifdef VMS 4134 vms_remove_version(fname); /* remove version */ 4135 #endif 4136 /* Default: write the file directly. May write to a temp file for 4137 * multi-byte conversion. */ 4138 wfname = fname; 4139 4140 /* Check for forced 'fileencoding' from "++opt=val" argument. */ 4141 if (eap != NULL && eap->force_enc != 0) 4142 { 4143 fenc = eap->cmd + eap->force_enc; 4144 fenc = enc_canonize(fenc); 4145 fenc_tofree = fenc; 4146 } 4147 else 4148 fenc = buf->b_p_fenc; 4149 4150 /* 4151 * Check if the file needs to be converted. 4152 */ 4153 converted = need_conversion(fenc); 4154 4155 /* 4156 * Check if UTF-8 to UCS-2/4 or Latin1 conversion needs to be done. Or 4157 * Latin1 to Unicode conversion. This is handled in buf_write_bytes(). 4158 * Prepare the flags for it and allocate bw_conv_buf when needed. 4159 */ 4160 if (converted && (enc_utf8 || STRCMP(p_enc, "latin1") == 0)) 4161 { 4162 wb_flags = get_fio_flags(fenc); 4163 if (wb_flags & (FIO_UCS2 | FIO_UCS4 | FIO_UTF16 | FIO_UTF8)) 4164 { 4165 /* Need to allocate a buffer to translate into. */ 4166 if (wb_flags & (FIO_UCS2 | FIO_UTF16 | FIO_UTF8)) 4167 write_info.bw_conv_buflen = bufsize * 2; 4168 else /* FIO_UCS4 */ 4169 write_info.bw_conv_buflen = bufsize * 4; 4170 write_info.bw_conv_buf 4171 = lalloc((long_u)write_info.bw_conv_buflen, TRUE); 4172 if (write_info.bw_conv_buf == NULL) 4173 end = 0; 4174 } 4175 } 4176 4177 #ifdef MSWIN 4178 if (converted && wb_flags == 0 && (wb_flags = get_win_fio_flags(fenc)) != 0) 4179 { 4180 /* Convert UTF-8 -> UCS-2 and UCS-2 -> DBCS. Worst-case * 4: */ 4181 write_info.bw_conv_buflen = bufsize * 4; 4182 write_info.bw_conv_buf 4183 = lalloc((long_u)write_info.bw_conv_buflen, TRUE); 4184 if (write_info.bw_conv_buf == NULL) 4185 end = 0; 4186 } 4187 #endif 4188 4189 #ifdef MACOS_CONVERT 4190 if (converted && wb_flags == 0 && (wb_flags = get_mac_fio_flags(fenc)) != 0) 4191 { 4192 write_info.bw_conv_buflen = bufsize * 3; 4193 write_info.bw_conv_buf 4194 = lalloc((long_u)write_info.bw_conv_buflen, TRUE); 4195 if (write_info.bw_conv_buf == NULL) 4196 end = 0; 4197 } 4198 #endif 4199 4200 #if defined(FEAT_EVAL) || defined(USE_ICONV) 4201 if (converted && wb_flags == 0) 4202 { 4203 # ifdef USE_ICONV 4204 /* 4205 * Use iconv() conversion when conversion is needed and it's not done 4206 * internally. 4207 */ 4208 write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc, 4209 enc_utf8 ? (char_u *)"utf-8" : p_enc); 4210 if (write_info.bw_iconv_fd != (iconv_t)-1) 4211 { 4212 /* We're going to use iconv(), allocate a buffer to convert in. */ 4213 write_info.bw_conv_buflen = bufsize * ICONV_MULT; 4214 write_info.bw_conv_buf 4215 = lalloc((long_u)write_info.bw_conv_buflen, TRUE); 4216 if (write_info.bw_conv_buf == NULL) 4217 end = 0; 4218 write_info.bw_first = TRUE; 4219 } 4220 # ifdef FEAT_EVAL 4221 else 4222 # endif 4223 # endif 4224 4225 # ifdef FEAT_EVAL 4226 /* 4227 * When the file needs to be converted with 'charconvert' after 4228 * writing, write to a temp file instead and let the conversion 4229 * overwrite the original file. 4230 */ 4231 if (*p_ccv != NUL) 4232 { 4233 wfname = vim_tempname('w', FALSE); 4234 if (wfname == NULL) /* Can't write without a tempfile! */ 4235 { 4236 errmsg = (char_u *)_("E214: Can't find temp file for writing"); 4237 goto restore_backup; 4238 } 4239 } 4240 # endif 4241 } 4242 #endif 4243 if (converted && wb_flags == 0 4244 #ifdef USE_ICONV 4245 && write_info.bw_iconv_fd == (iconv_t)-1 4246 # endif 4247 # ifdef FEAT_EVAL 4248 && wfname == fname 4249 # endif 4250 ) 4251 { 4252 if (!forceit) 4253 { 4254 errmsg = (char_u *)_("E213: Cannot convert (add ! to write without conversion)"); 4255 goto restore_backup; 4256 } 4257 notconverted = TRUE; 4258 } 4259 4260 /* 4261 * If conversion is taking place, we may first pretend to write and check 4262 * for conversion errors. Then loop again to write for real. 4263 * When not doing conversion this writes for real right away. 4264 */ 4265 for (checking_conversion = TRUE; ; checking_conversion = FALSE) 4266 { 4267 /* 4268 * There is no need to check conversion when: 4269 * - there is no conversion 4270 * - we make a backup file, that can be restored in case of conversion 4271 * failure. 4272 */ 4273 if (!converted || dobackup) 4274 checking_conversion = FALSE; 4275 4276 if (checking_conversion) 4277 { 4278 /* Make sure we don't write anything. */ 4279 fd = -1; 4280 write_info.bw_fd = fd; 4281 } 4282 else 4283 { 4284 #ifdef HAVE_FTRUNCATE 4285 # define TRUNC_ON_OPEN 0 4286 #else 4287 # define TRUNC_ON_OPEN O_TRUNC 4288 #endif 4289 /* 4290 * Open the file "wfname" for writing. 4291 * We may try to open the file twice: If we can't write to the file 4292 * and forceit is TRUE we delete the existing file and try to 4293 * create a new one. If this still fails we may have lost the 4294 * original file! (this may happen when the user reached his 4295 * quotum for number of files). 4296 * Appending will fail if the file does not exist and forceit is 4297 * FALSE. 4298 */ 4299 while ((fd = mch_open((char *)wfname, O_WRONLY | O_EXTRA | (append 4300 ? (forceit ? (O_APPEND | O_CREAT) : O_APPEND) 4301 : (O_CREAT | TRUNC_ON_OPEN)) 4302 , perm < 0 ? 0666 : (perm & 0777))) < 0) 4303 { 4304 /* 4305 * A forced write will try to create a new file if the old one 4306 * is still readonly. This may also happen when the directory 4307 * is read-only. In that case the mch_remove() will fail. 4308 */ 4309 if (errmsg == NULL) 4310 { 4311 #ifdef UNIX 4312 stat_T st; 4313 4314 /* Don't delete the file when it's a hard or symbolic link. 4315 */ 4316 if ((!newfile && st_old.st_nlink > 1) 4317 || (mch_lstat((char *)fname, &st) == 0 4318 && (st.st_dev != st_old.st_dev 4319 || st.st_ino != st_old.st_ino))) 4320 errmsg = (char_u *)_("E166: Can't open linked file for writing"); 4321 else 4322 #endif 4323 { 4324 errmsg = (char_u *)_("E212: Can't open file for writing"); 4325 if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL 4326 && perm >= 0) 4327 { 4328 #ifdef UNIX 4329 /* we write to the file, thus it should be marked 4330 writable after all */ 4331 if (!(perm & 0200)) 4332 made_writable = TRUE; 4333 perm |= 0200; 4334 if (st_old.st_uid != getuid() 4335 || st_old.st_gid != getgid()) 4336 perm &= 0777; 4337 #endif 4338 if (!append) /* don't remove when appending */ 4339 mch_remove(wfname); 4340 continue; 4341 } 4342 } 4343 } 4344 4345 restore_backup: 4346 { 4347 stat_T st; 4348 4349 /* 4350 * If we failed to open the file, we don't need a backup. 4351 * Throw it away. If we moved or removed the original file 4352 * try to put the backup in its place. 4353 */ 4354 if (backup != NULL && wfname == fname) 4355 { 4356 if (backup_copy) 4357 { 4358 /* 4359 * There is a small chance that we removed the 4360 * original, try to move the copy in its place. 4361 * This may not work if the vim_rename() fails. 4362 * In that case we leave the copy around. 4363 */ 4364 /* If file does not exist, put the copy in its 4365 * place */ 4366 if (mch_stat((char *)fname, &st) < 0) 4367 vim_rename(backup, fname); 4368 /* if original file does exist throw away the copy 4369 */ 4370 if (mch_stat((char *)fname, &st) >= 0) 4371 mch_remove(backup); 4372 } 4373 else 4374 { 4375 /* try to put the original file back */ 4376 vim_rename(backup, fname); 4377 } 4378 } 4379 4380 /* if original file no longer exists give an extra warning 4381 */ 4382 if (!newfile && mch_stat((char *)fname, &st) < 0) 4383 end = 0; 4384 } 4385 4386 if (wfname != fname) 4387 vim_free(wfname); 4388 goto fail; 4389 } 4390 write_info.bw_fd = fd; 4391 4392 #if defined(UNIX) 4393 { 4394 stat_T st; 4395 4396 /* Double check we are writing the intended file before making 4397 * any changes. */ 4398 if (overwriting 4399 && (!dobackup || backup_copy) 4400 && fname == wfname 4401 && perm >= 0 4402 && mch_fstat(fd, &st) == 0 4403 && st.st_ino != st_old.st_ino) 4404 { 4405 close(fd); 4406 errmsg = (char_u *)_("E949: File changed while writing"); 4407 goto fail; 4408 } 4409 } 4410 #endif 4411 #ifdef HAVE_FTRUNCATE 4412 if (!append) 4413 vim_ignored = ftruncate(fd, (off_t)0); 4414 #endif 4415 4416 #if defined(MSWIN) 4417 if (backup != NULL && overwriting && !append) 4418 { 4419 if (backup_copy) 4420 (void)mch_copy_file_attribute(wfname, backup); 4421 else 4422 (void)mch_copy_file_attribute(backup, wfname); 4423 } 4424 4425 if (!overwriting && !append) 4426 { 4427 if (buf->b_ffname != NULL) 4428 (void)mch_copy_file_attribute(buf->b_ffname, wfname); 4429 /* Should copy resource fork */ 4430 } 4431 #endif 4432 4433 #ifdef FEAT_CRYPT 4434 if (*buf->b_p_key != NUL && !filtering) 4435 { 4436 char_u *header; 4437 int header_len; 4438 4439 buf->b_cryptstate = crypt_create_for_writing( 4440 crypt_get_method_nr(buf), 4441 buf->b_p_key, &header, &header_len); 4442 if (buf->b_cryptstate == NULL || header == NULL) 4443 end = 0; 4444 else 4445 { 4446 /* Write magic number, so that Vim knows how this file is 4447 * encrypted when reading it back. */ 4448 write_info.bw_buf = header; 4449 write_info.bw_len = header_len; 4450 write_info.bw_flags = FIO_NOCONVERT; 4451 if (buf_write_bytes(&write_info) == FAIL) 4452 end = 0; 4453 wb_flags |= FIO_ENCRYPTED; 4454 vim_free(header); 4455 } 4456 } 4457 #endif 4458 } 4459 errmsg = NULL; 4460 4461 write_info.bw_buf = buffer; 4462 nchars = 0; 4463 4464 /* use "++bin", "++nobin" or 'binary' */ 4465 if (eap != NULL && eap->force_bin != 0) 4466 write_bin = (eap->force_bin == FORCE_BIN); 4467 else 4468 write_bin = buf->b_p_bin; 4469 4470 /* 4471 * The BOM is written just after the encryption magic number. 4472 * Skip it when appending and the file already existed, the BOM only 4473 * makes sense at the start of the file. 4474 */ 4475 if (buf->b_p_bomb && !write_bin && (!append || perm < 0)) 4476 { 4477 write_info.bw_len = make_bom(buffer, fenc); 4478 if (write_info.bw_len > 0) 4479 { 4480 /* don't convert, do encryption */ 4481 write_info.bw_flags = FIO_NOCONVERT | wb_flags; 4482 if (buf_write_bytes(&write_info) == FAIL) 4483 end = 0; 4484 else 4485 nchars += write_info.bw_len; 4486 } 4487 } 4488 write_info.bw_start_lnum = start; 4489 4490 #ifdef FEAT_PERSISTENT_UNDO 4491 write_undo_file = (buf->b_p_udf 4492 && overwriting 4493 && !append 4494 && !filtering 4495 && reset_changed 4496 && !checking_conversion); 4497 if (write_undo_file) 4498 /* Prepare for computing the hash value of the text. */ 4499 sha256_start(&sha_ctx); 4500 #endif 4501 4502 write_info.bw_len = bufsize; 4503 #ifdef HAS_BW_FLAGS 4504 write_info.bw_flags = wb_flags; 4505 #endif 4506 fileformat = get_fileformat_force(buf, eap); 4507 s = buffer; 4508 len = 0; 4509 for (lnum = start; lnum <= end; ++lnum) 4510 { 4511 /* 4512 * The next while loop is done once for each character written. 4513 * Keep it fast! 4514 */ 4515 ptr = ml_get_buf(buf, lnum, FALSE) - 1; 4516 #ifdef FEAT_PERSISTENT_UNDO 4517 if (write_undo_file) 4518 sha256_update(&sha_ctx, ptr + 1, 4519 (UINT32_T)(STRLEN(ptr + 1) + 1)); 4520 #endif 4521 while ((c = *++ptr) != NUL) 4522 { 4523 if (c == NL) 4524 *s = NUL; /* replace newlines with NULs */ 4525 else if (c == CAR && fileformat == EOL_MAC) 4526 *s = NL; /* Mac: replace CRs with NLs */ 4527 else 4528 *s = c; 4529 ++s; 4530 if (++len != bufsize) 4531 continue; 4532 if (buf_write_bytes(&write_info) == FAIL) 4533 { 4534 end = 0; /* write error: break loop */ 4535 break; 4536 } 4537 nchars += bufsize; 4538 s = buffer; 4539 len = 0; 4540 write_info.bw_start_lnum = lnum; 4541 } 4542 /* write failed or last line has no EOL: stop here */ 4543 if (end == 0 4544 || (lnum == end 4545 && (write_bin || !buf->b_p_fixeol) 4546 && (lnum == buf->b_no_eol_lnum 4547 || (lnum == buf->b_ml.ml_line_count 4548 && !buf->b_p_eol)))) 4549 { 4550 ++lnum; /* written the line, count it */ 4551 no_eol = TRUE; 4552 break; 4553 } 4554 if (fileformat == EOL_UNIX) 4555 *s++ = NL; 4556 else 4557 { 4558 *s++ = CAR; /* EOL_MAC or EOL_DOS: write CR */ 4559 if (fileformat == EOL_DOS) /* write CR-NL */ 4560 { 4561 if (++len == bufsize) 4562 { 4563 if (buf_write_bytes(&write_info) == FAIL) 4564 { 4565 end = 0; /* write error: break loop */ 4566 break; 4567 } 4568 nchars += bufsize; 4569 s = buffer; 4570 len = 0; 4571 } 4572 *s++ = NL; 4573 } 4574 } 4575 if (++len == bufsize && end) 4576 { 4577 if (buf_write_bytes(&write_info) == FAIL) 4578 { 4579 end = 0; /* write error: break loop */ 4580 break; 4581 } 4582 nchars += bufsize; 4583 s = buffer; 4584 len = 0; 4585 4586 ui_breakcheck(); 4587 if (got_int) 4588 { 4589 end = 0; /* Interrupted, break loop */ 4590 break; 4591 } 4592 } 4593 #ifdef VMS 4594 /* 4595 * On VMS there is a problem: newlines get added when writing 4596 * blocks at a time. Fix it by writing a line at a time. 4597 * This is much slower! 4598 * Explanation: VAX/DECC RTL insists that records in some RMS 4599 * structures end with a newline (carriage return) character, and 4600 * if they don't it adds one. 4601 * With other RMS structures it works perfect without this fix. 4602 */ 4603 if (buf->b_fab_rfm == FAB$C_VFC 4604 || ((buf->b_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0)) 4605 { 4606 int b2write; 4607 4608 buf->b_fab_mrs = (buf->b_fab_mrs == 0 4609 ? MIN(4096, bufsize) 4610 : MIN(buf->b_fab_mrs, bufsize)); 4611 4612 b2write = len; 4613 while (b2write > 0) 4614 { 4615 write_info.bw_len = MIN(b2write, buf->b_fab_mrs); 4616 if (buf_write_bytes(&write_info) == FAIL) 4617 { 4618 end = 0; 4619 break; 4620 } 4621 b2write -= MIN(b2write, buf->b_fab_mrs); 4622 } 4623 write_info.bw_len = bufsize; 4624 nchars += len; 4625 s = buffer; 4626 len = 0; 4627 } 4628 #endif 4629 } 4630 if (len > 0 && end > 0) 4631 { 4632 write_info.bw_len = len; 4633 if (buf_write_bytes(&write_info) == FAIL) 4634 end = 0; /* write error */ 4635 nchars += len; 4636 } 4637 4638 /* Stop when writing done or an error was encountered. */ 4639 if (!checking_conversion || end == 0) 4640 break; 4641 4642 /* If no error happened until now, writing should be ok, so loop to 4643 * really write the buffer. */ 4644 } 4645 4646 /* If we started writing, finish writing. Also when an error was 4647 * encountered. */ 4648 if (!checking_conversion) 4649 { 4650 #if defined(UNIX) && defined(HAVE_FSYNC) 4651 /* 4652 * On many journalling file systems there is a bug that causes both the 4653 * original and the backup file to be lost when halting the system 4654 * right after writing the file. That's because only the meta-data is 4655 * journalled. Syncing the file slows down the system, but assures it 4656 * has been written to disk and we don't lose it. 4657 * For a device do try the fsync() but don't complain if it does not 4658 * work (could be a pipe). 4659 * If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. 4660 */ 4661 if (p_fs && vim_fsync(fd) != 0 && !device) 4662 { 4663 errmsg = (char_u *)_(e_fsync); 4664 end = 0; 4665 } 4666 #endif 4667 4668 #if defined(HAVE_SELINUX) || defined(HAVE_SMACK) 4669 /* Probably need to set the security context. */ 4670 if (!backup_copy) 4671 mch_copy_sec(backup, wfname); 4672 #endif 4673 4674 #ifdef UNIX 4675 /* When creating a new file, set its owner/group to that of the 4676 * original file. Get the new device and inode number. */ 4677 if (backup != NULL && !backup_copy) 4678 { 4679 # ifdef HAVE_FCHOWN 4680 stat_T st; 4681 4682 /* Don't change the owner when it's already OK, some systems remove 4683 * permission or ACL stuff. */ 4684 if (mch_stat((char *)wfname, &st) < 0 4685 || st.st_uid != st_old.st_uid 4686 || st.st_gid != st_old.st_gid) 4687 { 4688 /* changing owner might not be possible */ 4689 vim_ignored = fchown(fd, st_old.st_uid, -1); 4690 /* if changing group fails clear the group permissions */ 4691 if (fchown(fd, -1, st_old.st_gid) == -1 && perm > 0) 4692 perm &= ~070; 4693 } 4694 # endif 4695 buf_setino(buf); 4696 } 4697 else if (!buf->b_dev_valid) 4698 /* Set the inode when creating a new file. */ 4699 buf_setino(buf); 4700 #endif 4701 4702 #ifdef UNIX 4703 if (made_writable) 4704 perm &= ~0200; /* reset 'w' bit for security reasons */ 4705 #endif 4706 #ifdef HAVE_FCHMOD 4707 /* set permission of new file same as old file */ 4708 if (perm >= 0) 4709 (void)mch_fsetperm(fd, perm); 4710 #endif 4711 if (close(fd) != 0) 4712 { 4713 errmsg = (char_u *)_("E512: Close failed"); 4714 end = 0; 4715 } 4716 4717 #ifndef HAVE_FCHMOD 4718 /* set permission of new file same as old file */ 4719 if (perm >= 0) 4720 (void)mch_setperm(wfname, perm); 4721 #endif 4722 #ifdef HAVE_ACL 4723 /* 4724 * Probably need to set the ACL before changing the user (can't set the 4725 * ACL on a file the user doesn't own). 4726 * On Solaris, with ZFS and the aclmode property set to "discard" (the 4727 * default), chmod() discards all part of a file's ACL that don't 4728 * represent the mode of the file. It's non-trivial for us to discover 4729 * whether we're in that situation, so we simply always re-set the ACL. 4730 */ 4731 # ifndef HAVE_SOLARIS_ZFS_ACL 4732 if (!backup_copy) 4733 # endif 4734 mch_set_acl(wfname, acl); 4735 #endif 4736 #ifdef FEAT_CRYPT 4737 if (buf->b_cryptstate != NULL) 4738 { 4739 crypt_free_state(buf->b_cryptstate); 4740 buf->b_cryptstate = NULL; 4741 } 4742 #endif 4743 4744 #if defined(FEAT_EVAL) 4745 if (wfname != fname) 4746 { 4747 /* 4748 * The file was written to a temp file, now it needs to be 4749 * converted with 'charconvert' to (overwrite) the output file. 4750 */ 4751 if (end != 0) 4752 { 4753 if (eval_charconvert(enc_utf8 ? (char_u *)"utf-8" : p_enc, 4754 fenc, wfname, fname) == FAIL) 4755 { 4756 write_info.bw_conv_error = TRUE; 4757 end = 0; 4758 } 4759 } 4760 mch_remove(wfname); 4761 vim_free(wfname); 4762 } 4763 #endif 4764 } 4765 4766 if (end == 0) 4767 { 4768 /* 4769 * Error encountered. 4770 */ 4771 if (errmsg == NULL) 4772 { 4773 if (write_info.bw_conv_error) 4774 { 4775 if (write_info.bw_conv_error_lnum == 0) 4776 errmsg = (char_u *)_("E513: write error, conversion failed (make 'fenc' empty to override)"); 4777 else 4778 { 4779 errmsg_allocated = TRUE; 4780 errmsg = alloc(300); 4781 vim_snprintf((char *)errmsg, 300, _("E513: write error, conversion failed in line %ld (make 'fenc' empty to override)"), 4782 (long)write_info.bw_conv_error_lnum); 4783 } 4784 } 4785 else if (got_int) 4786 errmsg = (char_u *)_(e_interr); 4787 else 4788 errmsg = (char_u *)_("E514: write error (file system full?)"); 4789 } 4790 4791 /* 4792 * If we have a backup file, try to put it in place of the new file, 4793 * because the new file is probably corrupt. This avoids losing the 4794 * original file when trying to make a backup when writing the file a 4795 * second time. 4796 * When "backup_copy" is set we need to copy the backup over the new 4797 * file. Otherwise rename the backup file. 4798 * If this is OK, don't give the extra warning message. 4799 */ 4800 if (backup != NULL) 4801 { 4802 if (backup_copy) 4803 { 4804 /* This may take a while, if we were interrupted let the user 4805 * know we got the message. */ 4806 if (got_int) 4807 { 4808 msg(_(e_interr)); 4809 out_flush(); 4810 } 4811 if ((fd = mch_open((char *)backup, O_RDONLY | O_EXTRA, 0)) >= 0) 4812 { 4813 if ((write_info.bw_fd = mch_open((char *)fname, 4814 O_WRONLY | O_CREAT | O_TRUNC | O_EXTRA, 4815 perm & 0777)) >= 0) 4816 { 4817 /* copy the file. */ 4818 write_info.bw_buf = smallbuf; 4819 #ifdef HAS_BW_FLAGS 4820 write_info.bw_flags = FIO_NOCONVERT; 4821 #endif 4822 while ((write_info.bw_len = read_eintr(fd, smallbuf, 4823 SMBUFSIZE)) > 0) 4824 if (buf_write_bytes(&write_info) == FAIL) 4825 break; 4826 4827 if (close(write_info.bw_fd) >= 0 4828 && write_info.bw_len == 0) 4829 end = 1; /* success */ 4830 } 4831 close(fd); /* ignore errors for closing read file */ 4832 } 4833 } 4834 else 4835 { 4836 if (vim_rename(backup, fname) == 0) 4837 end = 1; 4838 } 4839 } 4840 goto fail; 4841 } 4842 4843 lnum -= start; /* compute number of written lines */ 4844 --no_wait_return; /* may wait for return now */ 4845 4846 #if !(defined(UNIX) || defined(VMS)) 4847 fname = sfname; /* use shortname now, for the messages */ 4848 #endif 4849 if (!filtering) 4850 { 4851 msg_add_fname(buf, fname); /* put fname in IObuff with quotes */ 4852 c = FALSE; 4853 if (write_info.bw_conv_error) 4854 { 4855 STRCAT(IObuff, _(" CONVERSION ERROR")); 4856 c = TRUE; 4857 if (write_info.bw_conv_error_lnum != 0) 4858 vim_snprintf_add((char *)IObuff, IOSIZE, _(" in line %ld;"), 4859 (long)write_info.bw_conv_error_lnum); 4860 } 4861 else if (notconverted) 4862 { 4863 STRCAT(IObuff, _("[NOT converted]")); 4864 c = TRUE; 4865 } 4866 else if (converted) 4867 { 4868 STRCAT(IObuff, _("[converted]")); 4869 c = TRUE; 4870 } 4871 if (device) 4872 { 4873 STRCAT(IObuff, _("[Device]")); 4874 c = TRUE; 4875 } 4876 else if (newfile) 4877 { 4878 STRCAT(IObuff, shortmess(SHM_NEW) ? _("[New]") : _("[New File]")); 4879 c = TRUE; 4880 } 4881 if (no_eol) 4882 { 4883 msg_add_eol(); 4884 c = TRUE; 4885 } 4886 /* may add [unix/dos/mac] */ 4887 if (msg_add_fileformat(fileformat)) 4888 c = TRUE; 4889 #ifdef FEAT_CRYPT 4890 if (wb_flags & FIO_ENCRYPTED) 4891 { 4892 crypt_append_msg(buf); 4893 c = TRUE; 4894 } 4895 #endif 4896 msg_add_lines(c, (long)lnum, nchars); /* add line/char count */ 4897 if (!shortmess(SHM_WRITE)) 4898 { 4899 if (append) 4900 STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended")); 4901 else 4902 STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written")); 4903 } 4904 4905 set_keep_msg((char_u *)msg_trunc_attr((char *)IObuff, FALSE, 0), 0); 4906 } 4907 4908 /* When written everything correctly: reset 'modified'. Unless not 4909 * writing to the original file and '+' is not in 'cpoptions'. */ 4910 if (reset_changed && whole && !append 4911 && !write_info.bw_conv_error 4912 && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)) 4913 { 4914 unchanged(buf, TRUE); 4915 /* b:changedtick is always incremented in unchanged() but that 4916 * should not trigger a TextChanged event. */ 4917 if (buf->b_last_changedtick + 1 == CHANGEDTICK(buf)) 4918 buf->b_last_changedtick = CHANGEDTICK(buf); 4919 u_unchanged(buf); 4920 u_update_save_nr(buf); 4921 } 4922 4923 /* 4924 * If written to the current file, update the timestamp of the swap file 4925 * and reset the BF_WRITE_MASK flags. Also sets buf->b_mtime. 4926 */ 4927 if (overwriting) 4928 { 4929 ml_timestamp(buf); 4930 if (append) 4931 buf->b_flags &= ~BF_NEW; 4932 else 4933 buf->b_flags &= ~BF_WRITE_MASK; 4934 } 4935 4936 /* 4937 * If we kept a backup until now, and we are in patch mode, then we make 4938 * the backup file our 'original' file. 4939 */ 4940 if (*p_pm && dobackup) 4941 { 4942 char *org = (char *)buf_modname((buf->b_p_sn || buf->b_shortname), 4943 fname, p_pm, FALSE); 4944 4945 if (backup != NULL) 4946 { 4947 stat_T st; 4948 4949 /* 4950 * If the original file does not exist yet 4951 * the current backup file becomes the original file 4952 */ 4953 if (org == NULL) 4954 emsg(_("E205: Patchmode: can't save original file")); 4955 else if (mch_stat(org, &st) < 0) 4956 { 4957 vim_rename(backup, (char_u *)org); 4958 VIM_CLEAR(backup); /* don't delete the file */ 4959 #ifdef UNIX 4960 set_file_time((char_u *)org, st_old.st_atime, st_old.st_mtime); 4961 #endif 4962 } 4963 } 4964 /* 4965 * If there is no backup file, remember that a (new) file was 4966 * created. 4967 */ 4968 else 4969 { 4970 int empty_fd; 4971 4972 if (org == NULL 4973 || (empty_fd = mch_open(org, 4974 O_CREAT | O_EXTRA | O_EXCL | O_NOFOLLOW, 4975 perm < 0 ? 0666 : (perm & 0777))) < 0) 4976 emsg(_("E206: patchmode: can't touch empty original file")); 4977 else 4978 close(empty_fd); 4979 } 4980 if (org != NULL) 4981 { 4982 mch_setperm((char_u *)org, mch_getperm(fname) & 0777); 4983 vim_free(org); 4984 } 4985 } 4986 4987 /* 4988 * Remove the backup unless 'backup' option is set 4989 */ 4990 if (!p_bk && backup != NULL && mch_remove(backup) != 0) 4991 emsg(_("E207: Can't delete backup file")); 4992 4993 goto nofail; 4994 4995 /* 4996 * Finish up. We get here either after failure or success. 4997 */ 4998 fail: 4999 --no_wait_return; /* may wait for return now */ 5000 nofail: 5001 5002 /* Done saving, we accept changed buffer warnings again */ 5003 buf->b_saving = FALSE; 5004 5005 vim_free(backup); 5006 if (buffer != smallbuf) 5007 vim_free(buffer); 5008 vim_free(fenc_tofree); 5009 vim_free(write_info.bw_conv_buf); 5010 #ifdef USE_ICONV 5011 if (write_info.bw_iconv_fd != (iconv_t)-1) 5012 { 5013 iconv_close(write_info.bw_iconv_fd); 5014 write_info.bw_iconv_fd = (iconv_t)-1; 5015 } 5016 #endif 5017 #ifdef HAVE_ACL 5018 mch_free_acl(acl); 5019 #endif 5020 5021 if (errmsg != NULL) 5022 { 5023 int numlen = errnum != NULL ? (int)STRLEN(errnum) : 0; 5024 5025 attr = HL_ATTR(HLF_E); /* set highlight for error messages */ 5026 msg_add_fname(buf, 5027 #ifndef UNIX 5028 sfname 5029 #else 5030 fname 5031 #endif 5032 ); /* put file name in IObuff with quotes */ 5033 if (STRLEN(IObuff) + STRLEN(errmsg) + numlen >= IOSIZE) 5034 IObuff[IOSIZE - STRLEN(errmsg) - numlen - 1] = NUL; 5035 /* If the error message has the form "is ...", put the error number in 5036 * front of the file name. */ 5037 if (errnum != NULL) 5038 { 5039 STRMOVE(IObuff + numlen, IObuff); 5040 mch_memmove(IObuff, errnum, (size_t)numlen); 5041 } 5042 STRCAT(IObuff, errmsg); 5043 emsg((char *)IObuff); 5044 if (errmsg_allocated) 5045 vim_free(errmsg); 5046 5047 retval = FAIL; 5048 if (end == 0) 5049 { 5050 msg_puts_attr(_("\nWARNING: Original file may be lost or damaged\n"), 5051 attr | MSG_HIST); 5052 msg_puts_attr(_("don't quit the editor until the file is successfully written!"), 5053 attr | MSG_HIST); 5054 5055 /* Update the timestamp to avoid an "overwrite changed file" 5056 * prompt when writing again. */ 5057 if (mch_stat((char *)fname, &st_old) >= 0) 5058 { 5059 buf_store_time(buf, &st_old, fname); 5060 buf->b_mtime_read = buf->b_mtime; 5061 } 5062 } 5063 } 5064 msg_scroll = msg_save; 5065 5066 #ifdef FEAT_PERSISTENT_UNDO 5067 /* 5068 * When writing the whole file and 'undofile' is set, also write the undo 5069 * file. 5070 */ 5071 if (retval == OK && write_undo_file) 5072 { 5073 char_u hash[UNDO_HASH_SIZE]; 5074 5075 sha256_finish(&sha_ctx, hash); 5076 u_write_undo(NULL, FALSE, buf, hash); 5077 } 5078 #endif 5079 5080 #ifdef FEAT_EVAL 5081 if (!should_abort(retval)) 5082 #else 5083 if (!got_int) 5084 #endif 5085 { 5086 aco_save_T aco; 5087 5088 curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */ 5089 5090 /* 5091 * Apply POST autocommands. 5092 * Careful: The autocommands may call buf_write() recursively! 5093 */ 5094 aucmd_prepbuf(&aco, buf); 5095 5096 if (append) 5097 apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname, 5098 FALSE, curbuf, eap); 5099 else if (filtering) 5100 apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname, 5101 FALSE, curbuf, eap); 5102 else if (reset_changed && whole) 5103 apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname, 5104 FALSE, curbuf, eap); 5105 else 5106 apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname, 5107 FALSE, curbuf, eap); 5108 5109 /* restore curwin/curbuf and a few other things */ 5110 aucmd_restbuf(&aco); 5111 5112 #ifdef FEAT_EVAL 5113 if (aborting()) /* autocmds may abort script processing */ 5114 retval = FALSE; 5115 #endif 5116 } 5117 5118 got_int |= prev_got_int; 5119 5120 return retval; 5121 } 5122 5123 #if defined(HAVE_FSYNC) || defined(PROTO) 5124 /* 5125 * Call fsync() with Mac-specific exception. 5126 * Return fsync() result: zero for success. 5127 */ 5128 int 5129 vim_fsync(int fd) 5130 { 5131 int r; 5132 5133 # ifdef MACOS_X 5134 r = fcntl(fd, F_FULLFSYNC); 5135 if (r != 0) // F_FULLFSYNC not working or not supported 5136 # endif 5137 r = fsync(fd); 5138 return r; 5139 } 5140 #endif 5141 5142 /* 5143 * Set the name of the current buffer. Use when the buffer doesn't have a 5144 * name and a ":r" or ":w" command with a file name is used. 5145 */ 5146 static int 5147 set_rw_fname(char_u *fname, char_u *sfname) 5148 { 5149 buf_T *buf = curbuf; 5150 5151 /* It's like the unnamed buffer is deleted.... */ 5152 if (curbuf->b_p_bl) 5153 apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf); 5154 apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf); 5155 #ifdef FEAT_EVAL 5156 if (aborting()) /* autocmds may abort script processing */ 5157 return FAIL; 5158 #endif 5159 if (curbuf != buf) 5160 { 5161 /* We are in another buffer now, don't do the renaming. */ 5162 emsg(_(e_auchangedbuf)); 5163 return FAIL; 5164 } 5165 5166 if (setfname(curbuf, fname, sfname, FALSE) == OK) 5167 curbuf->b_flags |= BF_NOTEDITED; 5168 5169 /* ....and a new named one is created */ 5170 apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf); 5171 if (curbuf->b_p_bl) 5172 apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf); 5173 #ifdef FEAT_EVAL 5174 if (aborting()) /* autocmds may abort script processing */ 5175 return FAIL; 5176 #endif 5177 5178 /* Do filetype detection now if 'filetype' is empty. */ 5179 if (*curbuf->b_p_ft == NUL) 5180 { 5181 if (au_has_group((char_u *)"filetypedetect")) 5182 (void)do_doautocmd((char_u *)"filetypedetect BufRead", FALSE, NULL); 5183 do_modelines(0); 5184 } 5185 5186 return OK; 5187 } 5188 5189 /* 5190 * Put file name into IObuff with quotes. 5191 */ 5192 void 5193 msg_add_fname(buf_T *buf, char_u *fname) 5194 { 5195 if (fname == NULL) 5196 fname = (char_u *)"-stdin-"; 5197 home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE); 5198 IObuff[0] = '"'; 5199 STRCAT(IObuff, "\" "); 5200 } 5201 5202 /* 5203 * Append message for text mode to IObuff. 5204 * Return TRUE if something appended. 5205 */ 5206 static int 5207 msg_add_fileformat(int eol_type) 5208 { 5209 #ifndef USE_CRNL 5210 if (eol_type == EOL_DOS) 5211 { 5212 STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]")); 5213 return TRUE; 5214 } 5215 #endif 5216 if (eol_type == EOL_MAC) 5217 { 5218 STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]")); 5219 return TRUE; 5220 } 5221 #ifdef USE_CRNL 5222 if (eol_type == EOL_UNIX) 5223 { 5224 STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]")); 5225 return TRUE; 5226 } 5227 #endif 5228 return FALSE; 5229 } 5230 5231 /* 5232 * Append line and character count to IObuff. 5233 */ 5234 void 5235 msg_add_lines( 5236 int insert_space, 5237 long lnum, 5238 off_T nchars) 5239 { 5240 char_u *p; 5241 5242 p = IObuff + STRLEN(IObuff); 5243 5244 if (insert_space) 5245 *p++ = ' '; 5246 if (shortmess(SHM_LINES)) 5247 vim_snprintf((char *)p, IOSIZE - (p - IObuff), 5248 "%ldL, %lldC", lnum, (long_long_T)nchars); 5249 else 5250 { 5251 sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum); 5252 p += STRLEN(p); 5253 vim_snprintf((char *)p, IOSIZE - (p - IObuff), 5254 NGETTEXT("%lld character", "%lld characters", nchars), 5255 (long_long_T)nchars); 5256 } 5257 } 5258 5259 /* 5260 * Append message for missing line separator to IObuff. 5261 */ 5262 static void 5263 msg_add_eol(void) 5264 { 5265 STRCAT(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]")); 5266 } 5267 5268 /* 5269 * Check modification time of file, before writing to it. 5270 * The size isn't checked, because using a tool like "gzip" takes care of 5271 * using the same timestamp but can't set the size. 5272 */ 5273 static int 5274 check_mtime(buf_T *buf, stat_T *st) 5275 { 5276 if (buf->b_mtime_read != 0 5277 && time_differs((long)st->st_mtime, buf->b_mtime_read)) 5278 { 5279 msg_scroll = TRUE; /* don't overwrite messages here */ 5280 msg_silent = 0; /* must give this prompt */ 5281 /* don't use emsg() here, don't want to flush the buffers */ 5282 msg_attr(_("WARNING: The file has been changed since reading it!!!"), 5283 HL_ATTR(HLF_E)); 5284 if (ask_yesno((char_u *)_("Do you really want to write to it"), 5285 TRUE) == 'n') 5286 return FAIL; 5287 msg_scroll = FALSE; /* always overwrite the file message now */ 5288 } 5289 return OK; 5290 } 5291 5292 static int 5293 time_differs(long t1, long t2) 5294 { 5295 #if defined(__linux__) || defined(MSWIN) 5296 /* On a FAT filesystem, esp. under Linux, there are only 5 bits to store 5297 * the seconds. Since the roundoff is done when flushing the inode, the 5298 * time may change unexpectedly by one second!!! */ 5299 return (t1 - t2 > 1 || t2 - t1 > 1); 5300 #else 5301 return (t1 != t2); 5302 #endif 5303 } 5304 5305 /* 5306 * Call write() to write a number of bytes to the file. 5307 * Handles encryption and 'encoding' conversion. 5308 * 5309 * Return FAIL for failure, OK otherwise. 5310 */ 5311 static int 5312 buf_write_bytes(struct bw_info *ip) 5313 { 5314 int wlen; 5315 char_u *buf = ip->bw_buf; /* data to write */ 5316 int len = ip->bw_len; /* length of data */ 5317 #ifdef HAS_BW_FLAGS 5318 int flags = ip->bw_flags; /* extra flags */ 5319 #endif 5320 5321 /* 5322 * Skip conversion when writing the crypt magic number or the BOM. 5323 */ 5324 if (!(flags & FIO_NOCONVERT)) 5325 { 5326 char_u *p; 5327 unsigned c; 5328 int n; 5329 5330 if (flags & FIO_UTF8) 5331 { 5332 /* 5333 * Convert latin1 in the buffer to UTF-8 in the file. 5334 */ 5335 p = ip->bw_conv_buf; /* translate to buffer */ 5336 for (wlen = 0; wlen < len; ++wlen) 5337 p += utf_char2bytes(buf[wlen], p); 5338 buf = ip->bw_conv_buf; 5339 len = (int)(p - ip->bw_conv_buf); 5340 } 5341 else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1)) 5342 { 5343 /* 5344 * Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or 5345 * Latin1 chars in the file. 5346 */ 5347 if (flags & FIO_LATIN1) 5348 p = buf; /* translate in-place (can only get shorter) */ 5349 else 5350 p = ip->bw_conv_buf; /* translate to buffer */ 5351 for (wlen = 0; wlen < len; wlen += n) 5352 { 5353 if (wlen == 0 && ip->bw_restlen != 0) 5354 { 5355 int l; 5356 5357 /* Use remainder of previous call. Append the start of 5358 * buf[] to get a full sequence. Might still be too 5359 * short! */ 5360 l = CONV_RESTLEN - ip->bw_restlen; 5361 if (l > len) 5362 l = len; 5363 mch_memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l); 5364 n = utf_ptr2len_len(ip->bw_rest, ip->bw_restlen + l); 5365 if (n > ip->bw_restlen + len) 5366 { 5367 /* We have an incomplete byte sequence at the end to 5368 * be written. We can't convert it without the 5369 * remaining bytes. Keep them for the next call. */ 5370 if (ip->bw_restlen + len > CONV_RESTLEN) 5371 return FAIL; 5372 ip->bw_restlen += len; 5373 break; 5374 } 5375 if (n > 1) 5376 c = utf_ptr2char(ip->bw_rest); 5377 else 5378 c = ip->bw_rest[0]; 5379 if (n >= ip->bw_restlen) 5380 { 5381 n -= ip->bw_restlen; 5382 ip->bw_restlen = 0; 5383 } 5384 else 5385 { 5386 ip->bw_restlen -= n; 5387 mch_memmove(ip->bw_rest, ip->bw_rest + n, 5388 (size_t)ip->bw_restlen); 5389 n = 0; 5390 } 5391 } 5392 else 5393 { 5394 n = utf_ptr2len_len(buf + wlen, len - wlen); 5395 if (n > len - wlen) 5396 { 5397 /* We have an incomplete byte sequence at the end to 5398 * be written. We can't convert it without the 5399 * remaining bytes. Keep them for the next call. */ 5400 if (len - wlen > CONV_RESTLEN) 5401 return FAIL; 5402 ip->bw_restlen = len - wlen; 5403 mch_memmove(ip->bw_rest, buf + wlen, 5404 (size_t)ip->bw_restlen); 5405 break; 5406 } 5407 if (n > 1) 5408 c = utf_ptr2char(buf + wlen); 5409 else 5410 c = buf[wlen]; 5411 } 5412 5413 if (ucs2bytes(c, &p, flags) && !ip->bw_conv_error) 5414 { 5415 ip->bw_conv_error = TRUE; 5416 ip->bw_conv_error_lnum = ip->bw_start_lnum; 5417 } 5418 if (c == NL) 5419 ++ip->bw_start_lnum; 5420 } 5421 if (flags & FIO_LATIN1) 5422 len = (int)(p - buf); 5423 else 5424 { 5425 buf = ip->bw_conv_buf; 5426 len = (int)(p - ip->bw_conv_buf); 5427 } 5428 } 5429 5430 #ifdef MSWIN 5431 else if (flags & FIO_CODEPAGE) 5432 { 5433 /* 5434 * Convert UTF-8 or codepage to UCS-2 and then to MS-Windows 5435 * codepage. 5436 */ 5437 char_u *from; 5438 size_t fromlen; 5439 char_u *to; 5440 int u8c; 5441 BOOL bad = FALSE; 5442 int needed; 5443 5444 if (ip->bw_restlen > 0) 5445 { 5446 /* Need to concatenate the remainder of the previous call and 5447 * the bytes of the current call. Use the end of the 5448 * conversion buffer for this. */ 5449 fromlen = len + ip->bw_restlen; 5450 from = ip->bw_conv_buf + ip->bw_conv_buflen - fromlen; 5451 mch_memmove(from, ip->bw_rest, (size_t)ip->bw_restlen); 5452 mch_memmove(from + ip->bw_restlen, buf, (size_t)len); 5453 } 5454 else 5455 { 5456 from = buf; 5457 fromlen = len; 5458 } 5459 5460 to = ip->bw_conv_buf; 5461 if (enc_utf8) 5462 { 5463 /* Convert from UTF-8 to UCS-2, to the start of the buffer. 5464 * The buffer has been allocated to be big enough. */ 5465 while (fromlen > 0) 5466 { 5467 n = (int)utf_ptr2len_len(from, (int)fromlen); 5468 if (n > (int)fromlen) /* incomplete byte sequence */ 5469 break; 5470 u8c = utf_ptr2char(from); 5471 *to++ = (u8c & 0xff); 5472 *to++ = (u8c >> 8); 5473 fromlen -= n; 5474 from += n; 5475 } 5476 5477 /* Copy remainder to ip->bw_rest[] to be used for the next 5478 * call. */ 5479 if (fromlen > CONV_RESTLEN) 5480 { 5481 /* weird overlong sequence */ 5482 ip->bw_conv_error = TRUE; 5483 return FAIL; 5484 } 5485 mch_memmove(ip->bw_rest, from, fromlen); 5486 ip->bw_restlen = (int)fromlen; 5487 } 5488 else 5489 { 5490 /* Convert from enc_codepage to UCS-2, to the start of the 5491 * buffer. The buffer has been allocated to be big enough. */ 5492 ip->bw_restlen = 0; 5493 needed = MultiByteToWideChar(enc_codepage, 5494 MB_ERR_INVALID_CHARS, (LPCSTR)from, (int)fromlen, 5495 NULL, 0); 5496 if (needed == 0) 5497 { 5498 /* When conversion fails there may be a trailing byte. */ 5499 needed = MultiByteToWideChar(enc_codepage, 5500 MB_ERR_INVALID_CHARS, (LPCSTR)from, (int)fromlen - 1, 5501 NULL, 0); 5502 if (needed == 0) 5503 { 5504 /* Conversion doesn't work. */ 5505 ip->bw_conv_error = TRUE; 5506 return FAIL; 5507 } 5508 /* Save the trailing byte for the next call. */ 5509 ip->bw_rest[0] = from[fromlen - 1]; 5510 ip->bw_restlen = 1; 5511 } 5512 needed = MultiByteToWideChar(enc_codepage, MB_ERR_INVALID_CHARS, 5513 (LPCSTR)from, (int)(fromlen - ip->bw_restlen), 5514 (LPWSTR)to, needed); 5515 if (needed == 0) 5516 { 5517 /* Safety check: Conversion doesn't work. */ 5518 ip->bw_conv_error = TRUE; 5519 return FAIL; 5520 } 5521 to += needed * 2; 5522 } 5523 5524 fromlen = to - ip->bw_conv_buf; 5525 buf = to; 5526 # ifdef CP_UTF8 /* VC 4.1 doesn't define CP_UTF8 */ 5527 if (FIO_GET_CP(flags) == CP_UTF8) 5528 { 5529 /* Convert from UCS-2 to UTF-8, using the remainder of the 5530 * conversion buffer. Fails when out of space. */ 5531 for (from = ip->bw_conv_buf; fromlen > 1; fromlen -= 2) 5532 { 5533 u8c = *from++; 5534 u8c += (*from++ << 8); 5535 to += utf_char2bytes(u8c, to); 5536 if (to + 6 >= ip->bw_conv_buf + ip->bw_conv_buflen) 5537 { 5538 ip->bw_conv_error = TRUE; 5539 return FAIL; 5540 } 5541 } 5542 len = (int)(to - buf); 5543 } 5544 else 5545 # endif 5546 { 5547 /* Convert from UCS-2 to the codepage, using the remainder of 5548 * the conversion buffer. If the conversion uses the default 5549 * character "0", the data doesn't fit in this encoding, so 5550 * fail. */ 5551 len = WideCharToMultiByte(FIO_GET_CP(flags), 0, 5552 (LPCWSTR)ip->bw_conv_buf, (int)fromlen / sizeof(WCHAR), 5553 (LPSTR)to, (int)(ip->bw_conv_buflen - fromlen), 0, 5554 &bad); 5555 if (bad) 5556 { 5557 ip->bw_conv_error = TRUE; 5558 return FAIL; 5559 } 5560 } 5561 } 5562 #endif 5563 5564 #ifdef MACOS_CONVERT 5565 else if (flags & FIO_MACROMAN) 5566 { 5567 /* 5568 * Convert UTF-8 or latin1 to Apple MacRoman. 5569 */ 5570 char_u *from; 5571 size_t fromlen; 5572 5573 if (ip->bw_restlen > 0) 5574 { 5575 /* Need to concatenate the remainder of the previous call and 5576 * the bytes of the current call. Use the end of the 5577 * conversion buffer for this. */ 5578 fromlen = len + ip->bw_restlen; 5579 from = ip->bw_conv_buf + ip->bw_conv_buflen - fromlen; 5580 mch_memmove(from, ip->bw_rest, (size_t)ip->bw_restlen); 5581 mch_memmove(from + ip->bw_restlen, buf, (size_t)len); 5582 } 5583 else 5584 { 5585 from = buf; 5586 fromlen = len; 5587 } 5588 5589 if (enc2macroman(from, fromlen, 5590 ip->bw_conv_buf, &len, ip->bw_conv_buflen, 5591 ip->bw_rest, &ip->bw_restlen) == FAIL) 5592 { 5593 ip->bw_conv_error = TRUE; 5594 return FAIL; 5595 } 5596 buf = ip->bw_conv_buf; 5597 } 5598 #endif 5599 5600 #ifdef USE_ICONV 5601 if (ip->bw_iconv_fd != (iconv_t)-1) 5602 { 5603 const char *from; 5604 size_t fromlen; 5605 char *to; 5606 size_t tolen; 5607 5608 /* Convert with iconv(). */ 5609 if (ip->bw_restlen > 0) 5610 { 5611 char *fp; 5612 5613 /* Need to concatenate the remainder of the previous call and 5614 * the bytes of the current call. Use the end of the 5615 * conversion buffer for this. */ 5616 fromlen = len + ip->bw_restlen; 5617 fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen; 5618 mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen); 5619 mch_memmove(fp + ip->bw_restlen, buf, (size_t)len); 5620 from = fp; 5621 tolen = ip->bw_conv_buflen - fromlen; 5622 } 5623 else 5624 { 5625 from = (const char *)buf; 5626 fromlen = len; 5627 tolen = ip->bw_conv_buflen; 5628 } 5629 to = (char *)ip->bw_conv_buf; 5630 5631 if (ip->bw_first) 5632 { 5633 size_t save_len = tolen; 5634 5635 /* output the initial shift state sequence */ 5636 (void)iconv(ip->bw_iconv_fd, NULL, NULL, &to, &tolen); 5637 5638 /* There is a bug in iconv() on Linux (which appears to be 5639 * wide-spread) which sets "to" to NULL and messes up "tolen". 5640 */ 5641 if (to == NULL) 5642 { 5643 to = (char *)ip->bw_conv_buf; 5644 tolen = save_len; 5645 } 5646 ip->bw_first = FALSE; 5647 } 5648 5649 /* 5650 * If iconv() has an error or there is not enough room, fail. 5651 */ 5652 if ((iconv(ip->bw_iconv_fd, (void *)&from, &fromlen, &to, &tolen) 5653 == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL) 5654 || fromlen > CONV_RESTLEN) 5655 { 5656 ip->bw_conv_error = TRUE; 5657 return FAIL; 5658 } 5659 5660 /* copy remainder to ip->bw_rest[] to be used for the next call. */ 5661 if (fromlen > 0) 5662 mch_memmove(ip->bw_rest, (void *)from, fromlen); 5663 ip->bw_restlen = (int)fromlen; 5664 5665 buf = ip->bw_conv_buf; 5666 len = (int)((char_u *)to - ip->bw_conv_buf); 5667 } 5668 #endif 5669 } 5670 5671 if (ip->bw_fd < 0) 5672 /* Only checking conversion, which is OK if we get here. */ 5673 return OK; 5674 5675 #ifdef FEAT_CRYPT 5676 if (flags & FIO_ENCRYPTED) 5677 { 5678 /* Encrypt the data. Do it in-place if possible, otherwise use an 5679 * allocated buffer. */ 5680 # ifdef CRYPT_NOT_INPLACE 5681 if (crypt_works_inplace(ip->bw_buffer->b_cryptstate)) 5682 { 5683 # endif 5684 crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len); 5685 # ifdef CRYPT_NOT_INPLACE 5686 } 5687 else 5688 { 5689 char_u *outbuf; 5690 5691 len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf); 5692 if (len == 0) 5693 return OK; /* Crypt layer is buffering, will flush later. */ 5694 wlen = write_eintr(ip->bw_fd, outbuf, len); 5695 vim_free(outbuf); 5696 return (wlen < len) ? FAIL : OK; 5697 } 5698 # endif 5699 } 5700 #endif 5701 5702 wlen = write_eintr(ip->bw_fd, buf, len); 5703 return (wlen < len) ? FAIL : OK; 5704 } 5705 5706 /* 5707 * Convert a Unicode character to bytes. 5708 * Return TRUE for an error, FALSE when it's OK. 5709 */ 5710 static int 5711 ucs2bytes( 5712 unsigned c, /* in: character */ 5713 char_u **pp, /* in/out: pointer to result */ 5714 int flags) /* FIO_ flags */ 5715 { 5716 char_u *p = *pp; 5717 int error = FALSE; 5718 int cc; 5719 5720 5721 if (flags & FIO_UCS4) 5722 { 5723 if (flags & FIO_ENDIAN_L) 5724 { 5725 *p++ = c; 5726 *p++ = (c >> 8); 5727 *p++ = (c >> 16); 5728 *p++ = (c >> 24); 5729 } 5730 else 5731 { 5732 *p++ = (c >> 24); 5733 *p++ = (c >> 16); 5734 *p++ = (c >> 8); 5735 *p++ = c; 5736 } 5737 } 5738 else if (flags & (FIO_UCS2 | FIO_UTF16)) 5739 { 5740 if (c >= 0x10000) 5741 { 5742 if (flags & FIO_UTF16) 5743 { 5744 /* Make two words, ten bits of the character in each. First 5745 * word is 0xd800 - 0xdbff, second one 0xdc00 - 0xdfff */ 5746 c -= 0x10000; 5747 if (c >= 0x100000) 5748 error = TRUE; 5749 cc = ((c >> 10) & 0x3ff) + 0xd800; 5750 if (flags & FIO_ENDIAN_L) 5751 { 5752 *p++ = cc; 5753 *p++ = ((unsigned)cc >> 8); 5754 } 5755 else 5756 { 5757 *p++ = ((unsigned)cc >> 8); 5758 *p++ = cc; 5759 } 5760 c = (c & 0x3ff) + 0xdc00; 5761 } 5762 else 5763 error = TRUE; 5764 } 5765 if (flags & FIO_ENDIAN_L) 5766 { 5767 *p++ = c; 5768 *p++ = (c >> 8); 5769 } 5770 else 5771 { 5772 *p++ = (c >> 8); 5773 *p++ = c; 5774 } 5775 } 5776 else /* Latin1 */ 5777 { 5778 if (c >= 0x100) 5779 { 5780 error = TRUE; 5781 *p++ = 0xBF; 5782 } 5783 else 5784 *p++ = c; 5785 } 5786 5787 *pp = p; 5788 return error; 5789 } 5790 5791 /* 5792 * Return TRUE if file encoding "fenc" requires conversion from or to 5793 * 'encoding'. 5794 */ 5795 static int 5796 need_conversion(char_u *fenc) 5797 { 5798 int same_encoding; 5799 int enc_flags; 5800 int fenc_flags; 5801 5802 if (*fenc == NUL || STRCMP(p_enc, fenc) == 0) 5803 { 5804 same_encoding = TRUE; 5805 fenc_flags = 0; 5806 } 5807 else 5808 { 5809 /* Ignore difference between "ansi" and "latin1", "ucs-4" and 5810 * "ucs-4be", etc. */ 5811 enc_flags = get_fio_flags(p_enc); 5812 fenc_flags = get_fio_flags(fenc); 5813 same_encoding = (enc_flags != 0 && fenc_flags == enc_flags); 5814 } 5815 if (same_encoding) 5816 { 5817 /* Specified encoding matches with 'encoding'. This requires 5818 * conversion when 'encoding' is Unicode but not UTF-8. */ 5819 return enc_unicode != 0; 5820 } 5821 5822 /* Encodings differ. However, conversion is not needed when 'enc' is any 5823 * Unicode encoding and the file is UTF-8. */ 5824 return !(enc_utf8 && fenc_flags == FIO_UTF8); 5825 } 5826 5827 /* 5828 * Check "ptr" for a unicode encoding and return the FIO_ flags needed for the 5829 * internal conversion. 5830 * if "ptr" is an empty string, use 'encoding'. 5831 */ 5832 static int 5833 get_fio_flags(char_u *ptr) 5834 { 5835 int prop; 5836 5837 if (*ptr == NUL) 5838 ptr = p_enc; 5839 5840 prop = enc_canon_props(ptr); 5841 if (prop & ENC_UNICODE) 5842 { 5843 if (prop & ENC_2BYTE) 5844 { 5845 if (prop & ENC_ENDIAN_L) 5846 return FIO_UCS2 | FIO_ENDIAN_L; 5847 return FIO_UCS2; 5848 } 5849 if (prop & ENC_4BYTE) 5850 { 5851 if (prop & ENC_ENDIAN_L) 5852 return FIO_UCS4 | FIO_ENDIAN_L; 5853 return FIO_UCS4; 5854 } 5855 if (prop & ENC_2WORD) 5856 { 5857 if (prop & ENC_ENDIAN_L) 5858 return FIO_UTF16 | FIO_ENDIAN_L; 5859 return FIO_UTF16; 5860 } 5861 return FIO_UTF8; 5862 } 5863 if (prop & ENC_LATIN1) 5864 return FIO_LATIN1; 5865 /* must be ENC_DBCS, requires iconv() */ 5866 return 0; 5867 } 5868 5869 #ifdef MSWIN 5870 /* 5871 * Check "ptr" for a MS-Windows codepage name and return the FIO_ flags needed 5872 * for the conversion MS-Windows can do for us. Also accept "utf-8". 5873 * Used for conversion between 'encoding' and 'fileencoding'. 5874 */ 5875 static int 5876 get_win_fio_flags(char_u *ptr) 5877 { 5878 int cp; 5879 5880 /* Cannot do this when 'encoding' is not utf-8 and not a codepage. */ 5881 if (!enc_utf8 && enc_codepage <= 0) 5882 return 0; 5883 5884 cp = encname2codepage(ptr); 5885 if (cp == 0) 5886 { 5887 # ifdef CP_UTF8 /* VC 4.1 doesn't define CP_UTF8 */ 5888 if (STRCMP(ptr, "utf-8") == 0) 5889 cp = CP_UTF8; 5890 else 5891 # endif 5892 return 0; 5893 } 5894 return FIO_PUT_CP(cp) | FIO_CODEPAGE; 5895 } 5896 #endif 5897 5898 #ifdef MACOS_CONVERT 5899 /* 5900 * Check "ptr" for a Carbon supported encoding and return the FIO_ flags 5901 * needed for the internal conversion to/from utf-8 or latin1. 5902 */ 5903 static int 5904 get_mac_fio_flags(char_u *ptr) 5905 { 5906 if ((enc_utf8 || STRCMP(p_enc, "latin1") == 0) 5907 && (enc_canon_props(ptr) & ENC_MACROMAN)) 5908 return FIO_MACROMAN; 5909 return 0; 5910 } 5911 #endif 5912 5913 /* 5914 * Check for a Unicode BOM (Byte Order Mark) at the start of p[size]. 5915 * "size" must be at least 2. 5916 * Return the name of the encoding and set "*lenp" to the length. 5917 * Returns NULL when no BOM found. 5918 */ 5919 static char_u * 5920 check_for_bom( 5921 char_u *p, 5922 long size, 5923 int *lenp, 5924 int flags) 5925 { 5926 char *name = NULL; 5927 int len = 2; 5928 5929 if (p[0] == 0xef && p[1] == 0xbb && size >= 3 && p[2] == 0xbf 5930 && (flags == FIO_ALL || flags == FIO_UTF8 || flags == 0)) 5931 { 5932 name = "utf-8"; /* EF BB BF */ 5933 len = 3; 5934 } 5935 else if (p[0] == 0xff && p[1] == 0xfe) 5936 { 5937 if (size >= 4 && p[2] == 0 && p[3] == 0 5938 && (flags == FIO_ALL || flags == (FIO_UCS4 | FIO_ENDIAN_L))) 5939 { 5940 name = "ucs-4le"; /* FF FE 00 00 */ 5941 len = 4; 5942 } 5943 else if (flags == (FIO_UCS2 | FIO_ENDIAN_L)) 5944 name = "ucs-2le"; /* FF FE */ 5945 else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L)) 5946 /* utf-16le is preferred, it also works for ucs-2le text */ 5947 name = "utf-16le"; /* FF FE */ 5948 } 5949 else if (p[0] == 0xfe && p[1] == 0xff 5950 && (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16)) 5951 { 5952 /* Default to utf-16, it works also for ucs-2 text. */ 5953 if (flags == FIO_UCS2) 5954 name = "ucs-2"; /* FE FF */ 5955 else 5956 name = "utf-16"; /* FE FF */ 5957 } 5958 else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe 5959 && p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4)) 5960 { 5961 name = "ucs-4"; /* 00 00 FE FF */ 5962 len = 4; 5963 } 5964 5965 *lenp = len; 5966 return (char_u *)name; 5967 } 5968 5969 /* 5970 * Generate a BOM in "buf[4]" for encoding "name". 5971 * Return the length of the BOM (zero when no BOM). 5972 */ 5973 static int 5974 make_bom(char_u *buf, char_u *name) 5975 { 5976 int flags; 5977 char_u *p; 5978 5979 flags = get_fio_flags(name); 5980 5981 /* Can't put a BOM in a non-Unicode file. */ 5982 if (flags == FIO_LATIN1 || flags == 0) 5983 return 0; 5984 5985 if (flags == FIO_UTF8) /* UTF-8 */ 5986 { 5987 buf[0] = 0xef; 5988 buf[1] = 0xbb; 5989 buf[2] = 0xbf; 5990 return 3; 5991 } 5992 p = buf; 5993 (void)ucs2bytes(0xfeff, &p, flags); 5994 return (int)(p - buf); 5995 } 5996 5997 /* 5998 * Try to find a shortname by comparing the fullname with the current 5999 * directory. 6000 * Returns "full_path" or pointer into "full_path" if shortened. 6001 */ 6002 char_u * 6003 shorten_fname1(char_u *full_path) 6004 { 6005 char_u *dirname; 6006 char_u *p = full_path; 6007 6008 dirname = alloc(MAXPATHL); 6009 if (dirname == NULL) 6010 return full_path; 6011 if (mch_dirname(dirname, MAXPATHL) == OK) 6012 { 6013 p = shorten_fname(full_path, dirname); 6014 if (p == NULL || *p == NUL) 6015 p = full_path; 6016 } 6017 vim_free(dirname); 6018 return p; 6019 } 6020 6021 /* 6022 * Try to find a shortname by comparing the fullname with the current 6023 * directory. 6024 * Returns NULL if not shorter name possible, pointer into "full_path" 6025 * otherwise. 6026 */ 6027 char_u * 6028 shorten_fname(char_u *full_path, char_u *dir_name) 6029 { 6030 int len; 6031 char_u *p; 6032 6033 if (full_path == NULL) 6034 return NULL; 6035 len = (int)STRLEN(dir_name); 6036 if (fnamencmp(dir_name, full_path, len) == 0) 6037 { 6038 p = full_path + len; 6039 #if defined(MSWIN) 6040 /* 6041 * MS-Windows: when a file is in the root directory, dir_name will end 6042 * in a slash, since C: by itself does not define a specific dir. In 6043 * this case p may already be correct. <negri> 6044 */ 6045 if (!((len > 2) && (*(p - 2) == ':'))) 6046 #endif 6047 { 6048 if (vim_ispathsep(*p)) 6049 ++p; 6050 #ifndef VMS /* the path separator is always part of the path */ 6051 else 6052 p = NULL; 6053 #endif 6054 } 6055 } 6056 #if defined(MSWIN) 6057 /* 6058 * When using a file in the current drive, remove the drive name: 6059 * "A:\dir\file" -> "\dir\file". This helps when moving a session file on 6060 * a floppy from "A:\dir" to "B:\dir". 6061 */ 6062 else if (len > 3 6063 && TOUPPER_LOC(full_path[0]) == TOUPPER_LOC(dir_name[0]) 6064 && full_path[1] == ':' 6065 && vim_ispathsep(full_path[2])) 6066 p = full_path + 2; 6067 #endif 6068 else 6069 p = NULL; 6070 return p; 6071 } 6072 6073 /* 6074 * Shorten filename of a buffer. 6075 * When "force" is TRUE: Use full path from now on for files currently being 6076 * edited, both for file name and swap file name. Try to shorten the file 6077 * names a bit, if safe to do so. 6078 * When "force" is FALSE: Only try to shorten absolute file names. 6079 * For buffers that have buftype "nofile" or "scratch": never change the file 6080 * name. 6081 */ 6082 void 6083 shorten_buf_fname(buf_T *buf, char_u *dirname, int force) 6084 { 6085 char_u *p; 6086 6087 if (buf->b_fname != NULL 6088 #ifdef FEAT_QUICKFIX 6089 && !bt_nofile(buf) 6090 #endif 6091 && !path_with_url(buf->b_fname) 6092 && (force 6093 || buf->b_sfname == NULL 6094 || mch_isFullName(buf->b_sfname))) 6095 { 6096 if (buf->b_sfname != buf->b_ffname) 6097 VIM_CLEAR(buf->b_sfname); 6098 p = shorten_fname(buf->b_ffname, dirname); 6099 if (p != NULL) 6100 { 6101 buf->b_sfname = vim_strsave(p); 6102 buf->b_fname = buf->b_sfname; 6103 } 6104 if (p == NULL || buf->b_fname == NULL) 6105 buf->b_fname = buf->b_ffname; 6106 } 6107 } 6108 6109 /* 6110 * Shorten filenames for all buffers. 6111 */ 6112 void 6113 shorten_fnames(int force) 6114 { 6115 char_u dirname[MAXPATHL]; 6116 buf_T *buf; 6117 6118 mch_dirname(dirname, MAXPATHL); 6119 FOR_ALL_BUFFERS(buf) 6120 { 6121 shorten_buf_fname(buf, dirname, force); 6122 6123 /* Always make the swap file name a full path, a "nofile" buffer may 6124 * also have a swap file. */ 6125 mf_fullname(buf->b_ml.ml_mfp); 6126 } 6127 status_redraw_all(); 6128 redraw_tabline = TRUE; 6129 } 6130 6131 #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \ 6132 || defined(FEAT_GUI_MSWIN) \ 6133 || defined(FEAT_GUI_MAC) \ 6134 || defined(PROTO) 6135 /* 6136 * Shorten all filenames in "fnames[count]" by current directory. 6137 */ 6138 void 6139 shorten_filenames(char_u **fnames, int count) 6140 { 6141 int i; 6142 char_u dirname[MAXPATHL]; 6143 char_u *p; 6144 6145 if (fnames == NULL || count < 1) 6146 return; 6147 mch_dirname(dirname, sizeof(dirname)); 6148 for (i = 0; i < count; ++i) 6149 { 6150 if ((p = shorten_fname(fnames[i], dirname)) != NULL) 6151 { 6152 /* shorten_fname() returns pointer in given "fnames[i]". If free 6153 * "fnames[i]" first, "p" becomes invalid. So we need to copy 6154 * "p" first then free fnames[i]. */ 6155 p = vim_strsave(p); 6156 vim_free(fnames[i]); 6157 fnames[i] = p; 6158 } 6159 } 6160 } 6161 #endif 6162 6163 /* 6164 * Add extension to file name - change path/fo.o.h to path/fo.o.h.ext or 6165 * fo_o_h.ext for MSDOS or when shortname option set. 6166 * 6167 * Assumed that fname is a valid name found in the filesystem we assure that 6168 * the return value is a different name and ends in 'ext'. 6169 * "ext" MUST be at most 4 characters long if it starts with a dot, 3 6170 * characters otherwise. 6171 * Space for the returned name is allocated, must be freed later. 6172 * Returns NULL when out of memory. 6173 */ 6174 char_u * 6175 modname( 6176 char_u *fname, 6177 char_u *ext, 6178 int prepend_dot) /* may prepend a '.' to file name */ 6179 { 6180 return buf_modname((curbuf->b_p_sn || curbuf->b_shortname), 6181 fname, ext, prepend_dot); 6182 } 6183 6184 char_u * 6185 buf_modname( 6186 int shortname, /* use 8.3 file name */ 6187 char_u *fname, 6188 char_u *ext, 6189 int prepend_dot) /* may prepend a '.' to file name */ 6190 { 6191 char_u *retval; 6192 char_u *s; 6193 char_u *e; 6194 char_u *ptr; 6195 int fnamelen, extlen; 6196 6197 extlen = (int)STRLEN(ext); 6198 6199 /* 6200 * If there is no file name we must get the name of the current directory 6201 * (we need the full path in case :cd is used). 6202 */ 6203 if (fname == NULL || *fname == NUL) 6204 { 6205 retval = alloc((unsigned)(MAXPATHL + extlen + 3)); 6206 if (retval == NULL) 6207 return NULL; 6208 if (mch_dirname(retval, MAXPATHL) == FAIL || 6209 (fnamelen = (int)STRLEN(retval)) == 0) 6210 { 6211 vim_free(retval); 6212 return NULL; 6213 } 6214 if (!after_pathsep(retval, retval + fnamelen)) 6215 { 6216 retval[fnamelen++] = PATHSEP; 6217 retval[fnamelen] = NUL; 6218 } 6219 prepend_dot = FALSE; /* nothing to prepend a dot to */ 6220 } 6221 else 6222 { 6223 fnamelen = (int)STRLEN(fname); 6224 retval = alloc((unsigned)(fnamelen + extlen + 3)); 6225 if (retval == NULL) 6226 return NULL; 6227 STRCPY(retval, fname); 6228 #ifdef VMS 6229 vms_remove_version(retval); /* we do not need versions here */ 6230 #endif 6231 } 6232 6233 /* 6234 * search backwards until we hit a '/', '\' or ':' replacing all '.' 6235 * by '_' for MSDOS or when shortname option set and ext starts with a dot. 6236 * Then truncate what is after the '/', '\' or ':' to 8 characters for 6237 * MSDOS and 26 characters for AMIGA, a lot more for UNIX. 6238 */ 6239 for (ptr = retval + fnamelen; ptr > retval; MB_PTR_BACK(retval, ptr)) 6240 { 6241 if (*ext == '.' && shortname) 6242 if (*ptr == '.') /* replace '.' by '_' */ 6243 *ptr = '_'; 6244 if (vim_ispathsep(*ptr)) 6245 { 6246 ++ptr; 6247 break; 6248 } 6249 } 6250 6251 /* the file name has at most BASENAMELEN characters. */ 6252 if (STRLEN(ptr) > (unsigned)BASENAMELEN) 6253 ptr[BASENAMELEN] = '\0'; 6254 6255 s = ptr + STRLEN(ptr); 6256 6257 /* 6258 * For 8.3 file names we may have to reduce the length. 6259 */ 6260 if (shortname) 6261 { 6262 /* 6263 * If there is no file name, or the file name ends in '/', and the 6264 * extension starts with '.', put a '_' before the dot, because just 6265 * ".ext" is invalid. 6266 */ 6267 if (fname == NULL || *fname == NUL 6268 || vim_ispathsep(fname[STRLEN(fname) - 1])) 6269 { 6270 if (*ext == '.') 6271 *s++ = '_'; 6272 } 6273 /* 6274 * If the extension starts with '.', truncate the base name at 8 6275 * characters 6276 */ 6277 else if (*ext == '.') 6278 { 6279 if ((size_t)(s - ptr) > (size_t)8) 6280 { 6281 s = ptr + 8; 6282 *s = '\0'; 6283 } 6284 } 6285 /* 6286 * If the extension doesn't start with '.', and the file name 6287 * doesn't have an extension yet, append a '.' 6288 */ 6289 else if ((e = vim_strchr(ptr, '.')) == NULL) 6290 *s++ = '.'; 6291 /* 6292 * If the extension doesn't start with '.', and there already is an 6293 * extension, it may need to be truncated 6294 */ 6295 else if ((int)STRLEN(e) + extlen > 4) 6296 s = e + 4 - extlen; 6297 } 6298 #ifdef MSWIN 6299 /* 6300 * If there is no file name, and the extension starts with '.', put a 6301 * '_' before the dot, because just ".ext" may be invalid if it's on a 6302 * FAT partition, and on HPFS it doesn't matter. 6303 */ 6304 else if ((fname == NULL || *fname == NUL) && *ext == '.') 6305 *s++ = '_'; 6306 #endif 6307 6308 /* 6309 * Append the extension. 6310 * ext can start with '.' and cannot exceed 3 more characters. 6311 */ 6312 STRCPY(s, ext); 6313 6314 /* 6315 * Prepend the dot. 6316 */ 6317 if (prepend_dot && !shortname && *(e = gettail(retval)) != '.') 6318 { 6319 STRMOVE(e + 1, e); 6320 *e = '.'; 6321 } 6322 6323 /* 6324 * Check that, after appending the extension, the file name is really 6325 * different. 6326 */ 6327 if (fname != NULL && STRCMP(fname, retval) == 0) 6328 { 6329 /* we search for a character that can be replaced by '_' */ 6330 while (--s >= ptr) 6331 { 6332 if (*s != '_') 6333 { 6334 *s = '_'; 6335 break; 6336 } 6337 } 6338 if (s < ptr) /* fname was "________.<ext>", how tricky! */ 6339 *ptr = 'v'; 6340 } 6341 return retval; 6342 } 6343 6344 /* 6345 * Like fgets(), but if the file line is too long, it is truncated and the 6346 * rest of the line is thrown away. Returns TRUE for end-of-file. 6347 * If the line is truncated then buf[size - 2] will not be NUL. 6348 */ 6349 int 6350 vim_fgets(char_u *buf, int size, FILE *fp) 6351 { 6352 char *eof; 6353 #define FGETS_SIZE 200 6354 char tbuf[FGETS_SIZE]; 6355 6356 buf[size - 2] = NUL; 6357 eof = fgets((char *)buf, size, fp); 6358 if (buf[size - 2] != NUL && buf[size - 2] != '\n') 6359 { 6360 buf[size - 1] = NUL; /* Truncate the line */ 6361 6362 /* Now throw away the rest of the line: */ 6363 do 6364 { 6365 tbuf[FGETS_SIZE - 2] = NUL; 6366 vim_ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp); 6367 } while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n'); 6368 } 6369 return (eof == NULL); 6370 } 6371 6372 /* 6373 * rename() only works if both files are on the same file system, this 6374 * function will (attempts to?) copy the file across if rename fails -- webb 6375 * Return -1 for failure, 0 for success. 6376 */ 6377 int 6378 vim_rename(char_u *from, char_u *to) 6379 { 6380 int fd_in; 6381 int fd_out; 6382 int n; 6383 char *errmsg = NULL; 6384 char *buffer; 6385 #ifdef AMIGA 6386 BPTR flock; 6387 #endif 6388 stat_T st; 6389 long perm; 6390 #ifdef HAVE_ACL 6391 vim_acl_T acl; /* ACL from original file */ 6392 #endif 6393 int use_tmp_file = FALSE; 6394 6395 /* 6396 * When the names are identical, there is nothing to do. When they refer 6397 * to the same file (ignoring case and slash/backslash differences) but 6398 * the file name differs we need to go through a temp file. 6399 */ 6400 if (fnamecmp(from, to) == 0) 6401 { 6402 if (p_fic && STRCMP(gettail(from), gettail(to)) != 0) 6403 use_tmp_file = TRUE; 6404 else 6405 return 0; 6406 } 6407 6408 /* 6409 * Fail if the "from" file doesn't exist. Avoids that "to" is deleted. 6410 */ 6411 if (mch_stat((char *)from, &st) < 0) 6412 return -1; 6413 6414 #ifdef UNIX 6415 { 6416 stat_T st_to; 6417 6418 /* It's possible for the source and destination to be the same file. 6419 * This happens when "from" and "to" differ in case and are on a FAT32 6420 * filesystem. In that case go through a temp file name. */ 6421 if (mch_stat((char *)to, &st_to) >= 0 6422 && st.st_dev == st_to.st_dev 6423 && st.st_ino == st_to.st_ino) 6424 use_tmp_file = TRUE; 6425 } 6426 #endif 6427 #ifdef MSWIN 6428 { 6429 BY_HANDLE_FILE_INFORMATION info1, info2; 6430 6431 /* It's possible for the source and destination to be the same file. 6432 * In that case go through a temp file name. This makes rename("foo", 6433 * "./foo") a no-op (in a complicated way). */ 6434 if (win32_fileinfo(from, &info1) == FILEINFO_OK 6435 && win32_fileinfo(to, &info2) == FILEINFO_OK 6436 && info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber 6437 && info1.nFileIndexHigh == info2.nFileIndexHigh 6438 && info1.nFileIndexLow == info2.nFileIndexLow) 6439 use_tmp_file = TRUE; 6440 } 6441 #endif 6442 6443 if (use_tmp_file) 6444 { 6445 char tempname[MAXPATHL + 1]; 6446 6447 /* 6448 * Find a name that doesn't exist and is in the same directory. 6449 * Rename "from" to "tempname" and then rename "tempname" to "to". 6450 */ 6451 if (STRLEN(from) >= MAXPATHL - 5) 6452 return -1; 6453 STRCPY(tempname, from); 6454 for (n = 123; n < 99999; ++n) 6455 { 6456 sprintf((char *)gettail((char_u *)tempname), "%d", n); 6457 if (mch_stat(tempname, &st) < 0) 6458 { 6459 if (mch_rename((char *)from, tempname) == 0) 6460 { 6461 if (mch_rename(tempname, (char *)to) == 0) 6462 return 0; 6463 /* Strange, the second step failed. Try moving the 6464 * file back and return failure. */ 6465 mch_rename(tempname, (char *)from); 6466 return -1; 6467 } 6468 /* If it fails for one temp name it will most likely fail 6469 * for any temp name, give up. */ 6470 return -1; 6471 } 6472 } 6473 return -1; 6474 } 6475 6476 /* 6477 * Delete the "to" file, this is required on some systems to make the 6478 * mch_rename() work, on other systems it makes sure that we don't have 6479 * two files when the mch_rename() fails. 6480 */ 6481 6482 #ifdef AMIGA 6483 /* 6484 * With MSDOS-compatible filesystems (crossdos, messydos) it is possible 6485 * that the name of the "to" file is the same as the "from" file, even 6486 * though the names are different. To avoid the chance of accidentally 6487 * deleting the "from" file (horror!) we lock it during the remove. 6488 * 6489 * When used for making a backup before writing the file: This should not 6490 * happen with ":w", because startscript() should detect this problem and 6491 * set buf->b_shortname, causing modname() to return a correct ".bak" file 6492 * name. This problem does exist with ":w filename", but then the 6493 * original file will be somewhere else so the backup isn't really 6494 * important. If autoscripting is off the rename may fail. 6495 */ 6496 flock = Lock((UBYTE *)from, (long)ACCESS_READ); 6497 #endif 6498 mch_remove(to); 6499 #ifdef AMIGA 6500 if (flock) 6501 UnLock(flock); 6502 #endif 6503 6504 /* 6505 * First try a normal rename, return if it works. 6506 */ 6507 if (mch_rename((char *)from, (char *)to) == 0) 6508 return 0; 6509 6510 /* 6511 * Rename() failed, try copying the file. 6512 */ 6513 perm = mch_getperm(from); 6514 #ifdef HAVE_ACL 6515 /* For systems that support ACL: get the ACL from the original file. */ 6516 acl = mch_get_acl(from); 6517 #endif 6518 fd_in = mch_open((char *)from, O_RDONLY|O_EXTRA, 0); 6519 if (fd_in == -1) 6520 { 6521 #ifdef HAVE_ACL 6522 mch_free_acl(acl); 6523 #endif 6524 return -1; 6525 } 6526 6527 /* Create the new file with same permissions as the original. */ 6528 fd_out = mch_open((char *)to, 6529 O_CREAT|O_EXCL|O_WRONLY|O_EXTRA|O_NOFOLLOW, (int)perm); 6530 if (fd_out == -1) 6531 { 6532 close(fd_in); 6533 #ifdef HAVE_ACL 6534 mch_free_acl(acl); 6535 #endif 6536 return -1; 6537 } 6538 6539 buffer = (char *)alloc(BUFSIZE); 6540 if (buffer == NULL) 6541 { 6542 close(fd_out); 6543 close(fd_in); 6544 #ifdef HAVE_ACL 6545 mch_free_acl(acl); 6546 #endif 6547 return -1; 6548 } 6549 6550 while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0) 6551 if (write_eintr(fd_out, buffer, n) != n) 6552 { 6553 errmsg = _("E208: Error writing to \"%s\""); 6554 break; 6555 } 6556 6557 vim_free(buffer); 6558 close(fd_in); 6559 if (close(fd_out) < 0) 6560 errmsg = _("E209: Error closing \"%s\""); 6561 if (n < 0) 6562 { 6563 errmsg = _("E210: Error reading \"%s\""); 6564 to = from; 6565 } 6566 #ifndef UNIX /* for Unix mch_open() already set the permission */ 6567 mch_setperm(to, perm); 6568 #endif 6569 #ifdef HAVE_ACL 6570 mch_set_acl(to, acl); 6571 mch_free_acl(acl); 6572 #endif 6573 #if defined(HAVE_SELINUX) || defined(HAVE_SMACK) 6574 mch_copy_sec(from, to); 6575 #endif 6576 if (errmsg != NULL) 6577 { 6578 semsg(errmsg, to); 6579 return -1; 6580 } 6581 mch_remove(from); 6582 return 0; 6583 } 6584 6585 static int already_warned = FALSE; 6586 6587 /* 6588 * Check if any not hidden buffer has been changed. 6589 * Postpone the check if there are characters in the stuff buffer, a global 6590 * command is being executed, a mapping is being executed or an autocommand is 6591 * busy. 6592 * Returns TRUE if some message was written (screen should be redrawn and 6593 * cursor positioned). 6594 */ 6595 int 6596 check_timestamps( 6597 int focus) /* called for GUI focus event */ 6598 { 6599 buf_T *buf; 6600 int didit = 0; 6601 int n; 6602 6603 /* Don't check timestamps while system() or another low-level function may 6604 * cause us to lose and gain focus. */ 6605 if (no_check_timestamps > 0) 6606 return FALSE; 6607 6608 /* Avoid doing a check twice. The OK/Reload dialog can cause a focus 6609 * event and we would keep on checking if the file is steadily growing. 6610 * Do check again after typing something. */ 6611 if (focus && did_check_timestamps) 6612 { 6613 need_check_timestamps = TRUE; 6614 return FALSE; 6615 } 6616 6617 if (!stuff_empty() || global_busy || !typebuf_typed() 6618 || autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0) 6619 need_check_timestamps = TRUE; /* check later */ 6620 else 6621 { 6622 ++no_wait_return; 6623 did_check_timestamps = TRUE; 6624 already_warned = FALSE; 6625 FOR_ALL_BUFFERS(buf) 6626 { 6627 /* Only check buffers in a window. */ 6628 if (buf->b_nwindows > 0) 6629 { 6630 bufref_T bufref; 6631 6632 set_bufref(&bufref, buf); 6633 n = buf_check_timestamp(buf, focus); 6634 if (didit < n) 6635 didit = n; 6636 if (n > 0 && !bufref_valid(&bufref)) 6637 { 6638 /* Autocommands have removed the buffer, start at the 6639 * first one again. */ 6640 buf = firstbuf; 6641 continue; 6642 } 6643 } 6644 } 6645 --no_wait_return; 6646 need_check_timestamps = FALSE; 6647 if (need_wait_return && didit == 2) 6648 { 6649 /* make sure msg isn't overwritten */ 6650 msg_puts("\n"); 6651 out_flush(); 6652 } 6653 } 6654 return didit; 6655 } 6656 6657 /* 6658 * Move all the lines from buffer "frombuf" to buffer "tobuf". 6659 * Return OK or FAIL. When FAIL "tobuf" is incomplete and/or "frombuf" is not 6660 * empty. 6661 */ 6662 static int 6663 move_lines(buf_T *frombuf, buf_T *tobuf) 6664 { 6665 buf_T *tbuf = curbuf; 6666 int retval = OK; 6667 linenr_T lnum; 6668 char_u *p; 6669 6670 /* Copy the lines in "frombuf" to "tobuf". */ 6671 curbuf = tobuf; 6672 for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum) 6673 { 6674 p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE)); 6675 if (p == NULL || ml_append(lnum - 1, p, 0, FALSE) == FAIL) 6676 { 6677 vim_free(p); 6678 retval = FAIL; 6679 break; 6680 } 6681 vim_free(p); 6682 } 6683 6684 /* Delete all the lines in "frombuf". */ 6685 if (retval != FAIL) 6686 { 6687 curbuf = frombuf; 6688 for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; --lnum) 6689 if (ml_delete(lnum, FALSE) == FAIL) 6690 { 6691 /* Oops! We could try putting back the saved lines, but that 6692 * might fail again... */ 6693 retval = FAIL; 6694 break; 6695 } 6696 } 6697 6698 curbuf = tbuf; 6699 return retval; 6700 } 6701 6702 /* 6703 * Check if buffer "buf" has been changed. 6704 * Also check if the file for a new buffer unexpectedly appeared. 6705 * return 1 if a changed buffer was found. 6706 * return 2 if a message has been displayed. 6707 * return 0 otherwise. 6708 */ 6709 int 6710 buf_check_timestamp( 6711 buf_T *buf, 6712 int focus UNUSED) /* called for GUI focus event */ 6713 { 6714 stat_T st; 6715 int stat_res; 6716 int retval = 0; 6717 char_u *path; 6718 char *tbuf; 6719 char *mesg = NULL; 6720 char *mesg2 = ""; 6721 int helpmesg = FALSE; 6722 int reload = FALSE; 6723 char *reason; 6724 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) 6725 int can_reload = FALSE; 6726 #endif 6727 off_T orig_size = buf->b_orig_size; 6728 int orig_mode = buf->b_orig_mode; 6729 #ifdef FEAT_GUI 6730 int save_mouse_correct = need_mouse_correct; 6731 #endif 6732 static int busy = FALSE; 6733 int n; 6734 #ifdef FEAT_EVAL 6735 char_u *s; 6736 #endif 6737 bufref_T bufref; 6738 6739 set_bufref(&bufref, buf); 6740 6741 /* If there is no file name, the buffer is not loaded, 'buftype' is 6742 * set, we are in the middle of a save or being called recursively: ignore 6743 * this buffer. */ 6744 if (buf->b_ffname == NULL 6745 || buf->b_ml.ml_mfp == NULL 6746 || !bt_normal(buf) 6747 || buf->b_saving 6748 || busy 6749 #ifdef FEAT_NETBEANS_INTG 6750 || isNetbeansBuffer(buf) 6751 #endif 6752 #ifdef FEAT_TERMINAL 6753 || buf->b_term != NULL 6754 #endif 6755 ) 6756 return 0; 6757 6758 if ( !(buf->b_flags & BF_NOTEDITED) 6759 && buf->b_mtime != 0 6760 && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0 6761 || time_differs((long)st.st_mtime, buf->b_mtime) 6762 || st.st_size != buf->b_orig_size 6763 #ifdef HAVE_ST_MODE 6764 || (int)st.st_mode != buf->b_orig_mode 6765 #else 6766 || mch_getperm(buf->b_ffname) != buf->b_orig_mode 6767 #endif 6768 )) 6769 { 6770 retval = 1; 6771 6772 // set b_mtime to stop further warnings (e.g., when executing 6773 // FileChangedShell autocmd) 6774 if (stat_res < 0) 6775 { 6776 // When 'autoread' is set we'll check the file again to see if it 6777 // re-appears. 6778 buf->b_mtime = buf->b_p_ar; 6779 buf->b_orig_size = 0; 6780 buf->b_orig_mode = 0; 6781 } 6782 else 6783 buf_store_time(buf, &st, buf->b_ffname); 6784 6785 /* Don't do anything for a directory. Might contain the file 6786 * explorer. */ 6787 if (mch_isdir(buf->b_fname)) 6788 ; 6789 6790 /* 6791 * If 'autoread' is set, the buffer has no changes and the file still 6792 * exists, reload the buffer. Use the buffer-local option value if it 6793 * was set, the global option value otherwise. 6794 */ 6795 else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar) 6796 && !bufIsChanged(buf) && stat_res >= 0) 6797 reload = TRUE; 6798 else 6799 { 6800 if (stat_res < 0) 6801 reason = "deleted"; 6802 else if (bufIsChanged(buf)) 6803 reason = "conflict"; 6804 /* 6805 * Check if the file contents really changed to avoid giving a 6806 * warning when only the timestamp was set (e.g., checked out of 6807 * CVS). Always warn when the buffer was changed. 6808 */ 6809 else if (orig_size != buf->b_orig_size || buf_contents_changed(buf)) 6810 reason = "changed"; 6811 else if (orig_mode != buf->b_orig_mode) 6812 reason = "mode"; 6813 else 6814 reason = "time"; 6815 6816 /* 6817 * Only give the warning if there are no FileChangedShell 6818 * autocommands. 6819 * Avoid being called recursively by setting "busy". 6820 */ 6821 busy = TRUE; 6822 #ifdef FEAT_EVAL 6823 set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1); 6824 set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1); 6825 #endif 6826 ++allbuf_lock; 6827 n = apply_autocmds(EVENT_FILECHANGEDSHELL, 6828 buf->b_fname, buf->b_fname, FALSE, buf); 6829 --allbuf_lock; 6830 busy = FALSE; 6831 if (n) 6832 { 6833 if (!bufref_valid(&bufref)) 6834 emsg(_("E246: FileChangedShell autocommand deleted buffer")); 6835 #ifdef FEAT_EVAL 6836 s = get_vim_var_str(VV_FCS_CHOICE); 6837 if (STRCMP(s, "reload") == 0 && *reason != 'd') 6838 reload = TRUE; 6839 else if (STRCMP(s, "ask") == 0) 6840 n = FALSE; 6841 else 6842 #endif 6843 return 2; 6844 } 6845 if (!n) 6846 { 6847 if (*reason == 'd') 6848 mesg = _("E211: File \"%s\" no longer available"); 6849 else 6850 { 6851 helpmesg = TRUE; 6852 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) 6853 can_reload = TRUE; 6854 #endif 6855 if (reason[2] == 'n') 6856 { 6857 mesg = _("W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well"); 6858 mesg2 = _("See \":help W12\" for more info."); 6859 } 6860 else if (reason[1] == 'h') 6861 { 6862 mesg = _("W11: Warning: File \"%s\" has changed since editing started"); 6863 mesg2 = _("See \":help W11\" for more info."); 6864 } 6865 else if (*reason == 'm') 6866 { 6867 mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started"); 6868 mesg2 = _("See \":help W16\" for more info."); 6869 } 6870 else 6871 /* Only timestamp changed, store it to avoid a warning 6872 * in check_mtime() later. */ 6873 buf->b_mtime_read = buf->b_mtime; 6874 } 6875 } 6876 } 6877 6878 } 6879 else if ((buf->b_flags & BF_NEW) && !(buf->b_flags & BF_NEW_W) 6880 && vim_fexists(buf->b_ffname)) 6881 { 6882 retval = 1; 6883 mesg = _("W13: Warning: File \"%s\" has been created after editing started"); 6884 buf->b_flags |= BF_NEW_W; 6885 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) 6886 can_reload = TRUE; 6887 #endif 6888 } 6889 6890 if (mesg != NULL) 6891 { 6892 path = home_replace_save(buf, buf->b_fname); 6893 if (path != NULL) 6894 { 6895 if (!helpmesg) 6896 mesg2 = ""; 6897 tbuf = (char *)alloc((unsigned)(STRLEN(path) + STRLEN(mesg) 6898 + STRLEN(mesg2) + 2)); 6899 sprintf(tbuf, mesg, path); 6900 #ifdef FEAT_EVAL 6901 /* Set warningmsg here, before the unimportant and output-specific 6902 * mesg2 has been appended. */ 6903 set_vim_var_string(VV_WARNINGMSG, (char_u *)tbuf, -1); 6904 #endif 6905 #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) 6906 if (can_reload) 6907 { 6908 if (*mesg2 != NUL) 6909 { 6910 STRCAT(tbuf, "\n"); 6911 STRCAT(tbuf, mesg2); 6912 } 6913 if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), 6914 (char_u *)tbuf, 6915 (char_u *)_("&OK\n&Load File"), 1, NULL, TRUE) == 2) 6916 reload = TRUE; 6917 } 6918 else 6919 #endif 6920 if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) 6921 { 6922 if (*mesg2 != NUL) 6923 { 6924 STRCAT(tbuf, "; "); 6925 STRCAT(tbuf, mesg2); 6926 } 6927 emsg(tbuf); 6928 retval = 2; 6929 } 6930 else 6931 { 6932 if (!autocmd_busy) 6933 { 6934 msg_start(); 6935 msg_puts_attr(tbuf, HL_ATTR(HLF_E) + MSG_HIST); 6936 if (*mesg2 != NUL) 6937 msg_puts_attr(mesg2, HL_ATTR(HLF_W) + MSG_HIST); 6938 msg_clr_eos(); 6939 (void)msg_end(); 6940 if (emsg_silent == 0) 6941 { 6942 out_flush(); 6943 #ifdef FEAT_GUI 6944 if (!focus) 6945 #endif 6946 /* give the user some time to think about it */ 6947 ui_delay(1000L, TRUE); 6948 6949 /* don't redraw and erase the message */ 6950 redraw_cmdline = FALSE; 6951 } 6952 } 6953 already_warned = TRUE; 6954 } 6955 6956 vim_free(path); 6957 vim_free(tbuf); 6958 } 6959 } 6960 6961 if (reload) 6962 { 6963 /* Reload the buffer. */ 6964 buf_reload(buf, orig_mode); 6965 #ifdef FEAT_PERSISTENT_UNDO 6966 if (buf->b_p_udf && buf->b_ffname != NULL) 6967 { 6968 char_u hash[UNDO_HASH_SIZE]; 6969 buf_T *save_curbuf = curbuf; 6970 6971 /* Any existing undo file is unusable, write it now. */ 6972 curbuf = buf; 6973 u_compute_hash(hash); 6974 u_write_undo(NULL, FALSE, buf, hash); 6975 curbuf = save_curbuf; 6976 } 6977 #endif 6978 } 6979 6980 /* Trigger FileChangedShell when the file was changed in any way. */ 6981 if (bufref_valid(&bufref) && retval != 0) 6982 (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST, 6983 buf->b_fname, buf->b_fname, FALSE, buf); 6984 #ifdef FEAT_GUI 6985 /* restore this in case an autocommand has set it; it would break 6986 * 'mousefocus' */ 6987 need_mouse_correct = save_mouse_correct; 6988 #endif 6989 6990 return retval; 6991 } 6992 6993 /* 6994 * Reload a buffer that is already loaded. 6995 * Used when the file was changed outside of Vim. 6996 * "orig_mode" is buf->b_orig_mode before the need for reloading was detected. 6997 * buf->b_orig_mode may have been reset already. 6998 */ 6999 void 7000 buf_reload(buf_T *buf, int orig_mode) 7001 { 7002 exarg_T ea; 7003 pos_T old_cursor; 7004 linenr_T old_topline; 7005 int old_ro = buf->b_p_ro; 7006 buf_T *savebuf; 7007 bufref_T bufref; 7008 int saved = OK; 7009 aco_save_T aco; 7010 int flags = READ_NEW; 7011 7012 /* set curwin/curbuf for "buf" and save some things */ 7013 aucmd_prepbuf(&aco, buf); 7014 7015 /* We only want to read the text from the file, not reset the syntax 7016 * highlighting, clear marks, diff status, etc. Force the fileformat 7017 * and encoding to be the same. */ 7018 if (prep_exarg(&ea, buf) == OK) 7019 { 7020 old_cursor = curwin->w_cursor; 7021 old_topline = curwin->w_topline; 7022 7023 if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) 7024 { 7025 /* Save all the text, so that the reload can be undone. 7026 * Sync first so that this is a separate undo-able action. */ 7027 u_sync(FALSE); 7028 saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE); 7029 flags |= READ_KEEP_UNDO; 7030 } 7031 7032 /* 7033 * To behave like when a new file is edited (matters for 7034 * BufReadPost autocommands) we first need to delete the current 7035 * buffer contents. But if reading the file fails we should keep 7036 * the old contents. Can't use memory only, the file might be 7037 * too big. Use a hidden buffer to move the buffer contents to. 7038 */ 7039 if (BUFEMPTY() || saved == FAIL) 7040 savebuf = NULL; 7041 else 7042 { 7043 /* Allocate a buffer without putting it in the buffer list. */ 7044 savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); 7045 set_bufref(&bufref, savebuf); 7046 if (savebuf != NULL && buf == curbuf) 7047 { 7048 /* Open the memline. */ 7049 curbuf = savebuf; 7050 curwin->w_buffer = savebuf; 7051 saved = ml_open(curbuf); 7052 curbuf = buf; 7053 curwin->w_buffer = buf; 7054 } 7055 if (savebuf == NULL || saved == FAIL || buf != curbuf 7056 || move_lines(buf, savebuf) == FAIL) 7057 { 7058 semsg(_("E462: Could not prepare for reloading \"%s\""), 7059 buf->b_fname); 7060 saved = FAIL; 7061 } 7062 } 7063 7064 if (saved == OK) 7065 { 7066 curbuf->b_flags |= BF_CHECK_RO; /* check for RO again */ 7067 keep_filetype = TRUE; /* don't detect 'filetype' */ 7068 if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, 7069 (linenr_T)0, 7070 (linenr_T)MAXLNUM, &ea, flags) != OK) 7071 { 7072 #if defined(FEAT_EVAL) 7073 if (!aborting()) 7074 #endif 7075 semsg(_("E321: Could not reload \"%s\""), buf->b_fname); 7076 if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf) 7077 { 7078 /* Put the text back from the save buffer. First 7079 * delete any lines that readfile() added. */ 7080 while (!BUFEMPTY()) 7081 if (ml_delete(buf->b_ml.ml_line_count, FALSE) == FAIL) 7082 break; 7083 (void)move_lines(savebuf, buf); 7084 } 7085 } 7086 else if (buf == curbuf) /* "buf" still valid */ 7087 { 7088 /* Mark the buffer as unmodified and free undo info. */ 7089 unchanged(buf, TRUE); 7090 if ((flags & READ_KEEP_UNDO) == 0) 7091 { 7092 u_blockfree(buf); 7093 u_clearall(buf); 7094 } 7095 else 7096 { 7097 /* Mark all undo states as changed. */ 7098 u_unchanged(curbuf); 7099 } 7100 } 7101 } 7102 vim_free(ea.cmd); 7103 7104 if (savebuf != NULL && bufref_valid(&bufref)) 7105 wipe_buffer(savebuf, FALSE); 7106 7107 #ifdef FEAT_DIFF 7108 /* Invalidate diff info if necessary. */ 7109 diff_invalidate(curbuf); 7110 #endif 7111 7112 /* Restore the topline and cursor position and check it (lines may 7113 * have been removed). */ 7114 if (old_topline > curbuf->b_ml.ml_line_count) 7115 curwin->w_topline = curbuf->b_ml.ml_line_count; 7116 else 7117 curwin->w_topline = old_topline; 7118 curwin->w_cursor = old_cursor; 7119 check_cursor(); 7120 update_topline(); 7121 keep_filetype = FALSE; 7122 #ifdef FEAT_FOLDING 7123 { 7124 win_T *wp; 7125 tabpage_T *tp; 7126 7127 /* Update folds unless they are defined manually. */ 7128 FOR_ALL_TAB_WINDOWS(tp, wp) 7129 if (wp->w_buffer == curwin->w_buffer 7130 && !foldmethodIsManual(wp)) 7131 foldUpdateAll(wp); 7132 } 7133 #endif 7134 /* If the mode didn't change and 'readonly' was set, keep the old 7135 * value; the user probably used the ":view" command. But don't 7136 * reset it, might have had a read error. */ 7137 if (orig_mode == curbuf->b_orig_mode) 7138 curbuf->b_p_ro |= old_ro; 7139 7140 /* Modelines must override settings done by autocommands. */ 7141 do_modelines(0); 7142 } 7143 7144 /* restore curwin/curbuf and a few other things */ 7145 aucmd_restbuf(&aco); 7146 /* Careful: autocommands may have made "buf" invalid! */ 7147 } 7148 7149 void 7150 buf_store_time(buf_T *buf, stat_T *st, char_u *fname UNUSED) 7151 { 7152 buf->b_mtime = (long)st->st_mtime; 7153 buf->b_orig_size = st->st_size; 7154 #ifdef HAVE_ST_MODE 7155 buf->b_orig_mode = (int)st->st_mode; 7156 #else 7157 buf->b_orig_mode = mch_getperm(fname); 7158 #endif 7159 } 7160 7161 /* 7162 * Adjust the line with missing eol, used for the next write. 7163 * Used for do_filter(), when the input lines for the filter are deleted. 7164 */ 7165 void 7166 write_lnum_adjust(linenr_T offset) 7167 { 7168 if (curbuf->b_no_eol_lnum != 0) /* only if there is a missing eol */ 7169 curbuf->b_no_eol_lnum += offset; 7170 } 7171 7172 #if defined(TEMPDIRNAMES) || defined(FEAT_EVAL) || defined(PROTO) 7173 /* 7174 * Delete "name" and everything in it, recursively. 7175 * return 0 for succes, -1 if some file was not deleted. 7176 */ 7177 int 7178 delete_recursive(char_u *name) 7179 { 7180 int result = 0; 7181 char_u **files; 7182 int file_count; 7183 int i; 7184 char_u *exp; 7185 7186 /* A symbolic link to a directory itself is deleted, not the directory it 7187 * points to. */ 7188 if ( 7189 # if defined(UNIX) || defined(MSWIN) 7190 mch_isrealdir(name) 7191 # else 7192 mch_isdir(name) 7193 # endif 7194 ) 7195 { 7196 vim_snprintf((char *)NameBuff, MAXPATHL, "%s/*", name); 7197 exp = vim_strsave(NameBuff); 7198 if (exp == NULL) 7199 return -1; 7200 if (gen_expand_wildcards(1, &exp, &file_count, &files, 7201 EW_DIR|EW_FILE|EW_SILENT|EW_ALLLINKS|EW_DODOT|EW_EMPTYOK) == OK) 7202 { 7203 for (i = 0; i < file_count; ++i) 7204 if (delete_recursive(files[i]) != 0) 7205 result = -1; 7206 FreeWild(file_count, files); 7207 } 7208 else 7209 result = -1; 7210 vim_free(exp); 7211 (void)mch_rmdir(name); 7212 } 7213 else 7214 result = mch_remove(name) == 0 ? 0 : -1; 7215 7216 return result; 7217 } 7218 #endif 7219 7220 #if defined(TEMPDIRNAMES) || defined(PROTO) 7221 static long temp_count = 0; /* Temp filename counter. */ 7222 7223 /* 7224 * Delete the temp directory and all files it contains. 7225 */ 7226 void 7227 vim_deltempdir(void) 7228 { 7229 if (vim_tempdir != NULL) 7230 { 7231 /* remove the trailing path separator */ 7232 gettail(vim_tempdir)[-1] = NUL; 7233 delete_recursive(vim_tempdir); 7234 VIM_CLEAR(vim_tempdir); 7235 } 7236 } 7237 7238 /* 7239 * Directory "tempdir" was created. Expand this name to a full path and put 7240 * it in "vim_tempdir". This avoids that using ":cd" would confuse us. 7241 * "tempdir" must be no longer than MAXPATHL. 7242 */ 7243 static void 7244 vim_settempdir(char_u *tempdir) 7245 { 7246 char_u *buf; 7247 7248 buf = alloc((unsigned)MAXPATHL + 2); 7249 if (buf != NULL) 7250 { 7251 if (vim_FullName(tempdir, buf, MAXPATHL, FALSE) == FAIL) 7252 STRCPY(buf, tempdir); 7253 add_pathsep(buf); 7254 vim_tempdir = vim_strsave(buf); 7255 vim_free(buf); 7256 } 7257 } 7258 #endif 7259 7260 /* 7261 * vim_tempname(): Return a unique name that can be used for a temp file. 7262 * 7263 * The temp file is NOT guaranteed to be created. If "keep" is FALSE it is 7264 * guaranteed to NOT be created. 7265 * 7266 * The returned pointer is to allocated memory. 7267 * The returned pointer is NULL if no valid name was found. 7268 */ 7269 char_u * 7270 vim_tempname( 7271 int extra_char UNUSED, /* char to use in the name instead of '?' */ 7272 int keep UNUSED) 7273 { 7274 #ifdef USE_TMPNAM 7275 char_u itmp[L_tmpnam]; /* use tmpnam() */ 7276 #elif defined(MSWIN) 7277 WCHAR itmp[TEMPNAMELEN]; 7278 #else 7279 char_u itmp[TEMPNAMELEN]; 7280 #endif 7281 7282 #ifdef TEMPDIRNAMES 7283 static char *(tempdirs[]) = {TEMPDIRNAMES}; 7284 int i; 7285 # ifndef EEXIST 7286 stat_T st; 7287 # endif 7288 7289 /* 7290 * This will create a directory for private use by this instance of Vim. 7291 * This is done once, and the same directory is used for all temp files. 7292 * This method avoids security problems because of symlink attacks et al. 7293 * It's also a bit faster, because we only need to check for an existing 7294 * file when creating the directory and not for each temp file. 7295 */ 7296 if (vim_tempdir == NULL) 7297 { 7298 /* 7299 * Try the entries in TEMPDIRNAMES to create the temp directory. 7300 */ 7301 for (i = 0; i < (int)(sizeof(tempdirs) / sizeof(char *)); ++i) 7302 { 7303 # ifndef HAVE_MKDTEMP 7304 size_t itmplen; 7305 long nr; 7306 long off; 7307 # endif 7308 7309 /* Expand $TMP, leave room for "/v1100000/999999999". 7310 * Skip the directory check if the expansion fails. */ 7311 expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20); 7312 if (itmp[0] != '$' && mch_isdir(itmp)) 7313 { 7314 /* directory exists */ 7315 add_pathsep(itmp); 7316 7317 # ifdef HAVE_MKDTEMP 7318 { 7319 # if defined(UNIX) || defined(VMS) 7320 /* Make sure the umask doesn't remove the executable bit. 7321 * "repl" has been reported to use "177". */ 7322 mode_t umask_save = umask(077); 7323 # endif 7324 /* Leave room for filename */ 7325 STRCAT(itmp, "vXXXXXX"); 7326 if (mkdtemp((char *)itmp) != NULL) 7327 vim_settempdir(itmp); 7328 # if defined(UNIX) || defined(VMS) 7329 (void)umask(umask_save); 7330 # endif 7331 } 7332 # else 7333 /* Get an arbitrary number of up to 6 digits. When it's 7334 * unlikely that it already exists it will be faster, 7335 * otherwise it doesn't matter. The use of mkdir() avoids any 7336 * security problems because of the predictable number. */ 7337 nr = (mch_get_pid() + (long)time(NULL)) % 1000000L; 7338 itmplen = STRLEN(itmp); 7339 7340 /* Try up to 10000 different values until we find a name that 7341 * doesn't exist. */ 7342 for (off = 0; off < 10000L; ++off) 7343 { 7344 int r; 7345 # if defined(UNIX) || defined(VMS) 7346 mode_t umask_save; 7347 # endif 7348 7349 sprintf((char *)itmp + itmplen, "v%ld", nr + off); 7350 # ifndef EEXIST 7351 /* If mkdir() does not set errno to EEXIST, check for 7352 * existing file here. There is a race condition then, 7353 * although it's fail-safe. */ 7354 if (mch_stat((char *)itmp, &st) >= 0) 7355 continue; 7356 # endif 7357 # if defined(UNIX) || defined(VMS) 7358 /* Make sure the umask doesn't remove the executable bit. 7359 * "repl" has been reported to use "177". */ 7360 umask_save = umask(077); 7361 # endif 7362 r = vim_mkdir(itmp, 0700); 7363 # if defined(UNIX) || defined(VMS) 7364 (void)umask(umask_save); 7365 # endif 7366 if (r == 0) 7367 { 7368 vim_settempdir(itmp); 7369 break; 7370 } 7371 # ifdef EEXIST 7372 /* If the mkdir() didn't fail because the file/dir exists, 7373 * we probably can't create any dir here, try another 7374 * place. */ 7375 if (errno != EEXIST) 7376 # endif 7377 break; 7378 } 7379 # endif /* HAVE_MKDTEMP */ 7380 if (vim_tempdir != NULL) 7381 break; 7382 } 7383 } 7384 } 7385 7386 if (vim_tempdir != NULL) 7387 { 7388 /* There is no need to check if the file exists, because we own the 7389 * directory and nobody else creates a file in it. */ 7390 sprintf((char *)itmp, "%s%ld", vim_tempdir, temp_count++); 7391 return vim_strsave(itmp); 7392 } 7393 7394 return NULL; 7395 7396 #else /* TEMPDIRNAMES */ 7397 7398 # ifdef MSWIN 7399 WCHAR wszTempFile[_MAX_PATH + 1]; 7400 WCHAR buf4[4]; 7401 char_u *retval; 7402 char_u *p; 7403 7404 wcscpy(itmp, L""); 7405 if (GetTempPathW(_MAX_PATH, wszTempFile) == 0) 7406 { 7407 wszTempFile[0] = L'.'; // GetTempPathW() failed, use current dir 7408 wszTempFile[1] = NUL; 7409 } 7410 wcscpy(buf4, L"VIM"); 7411 buf4[2] = extra_char; /* make it "VIa", "VIb", etc. */ 7412 if (GetTempFileNameW(wszTempFile, buf4, 0, itmp) == 0) 7413 return NULL; 7414 if (!keep) 7415 // GetTempFileName() will create the file, we don't want that 7416 (void)DeleteFileW(itmp); 7417 7418 // Backslashes in a temp file name cause problems when filtering with 7419 // "sh". NOTE: This also checks 'shellcmdflag' to help those people who 7420 // didn't set 'shellslash'. 7421 retval = utf16_to_enc(itmp, NULL); 7422 if (*p_shcf == '-' || p_ssl) 7423 for (p = retval; *p; ++p) 7424 if (*p == '\\') 7425 *p = '/'; 7426 return retval; 7427 7428 # else // MSWIN 7429 7430 # ifdef USE_TMPNAM 7431 char_u *p; 7432 7433 /* tmpnam() will make its own name */ 7434 p = tmpnam((char *)itmp); 7435 if (p == NULL || *p == NUL) 7436 return NULL; 7437 # else 7438 char_u *p; 7439 7440 # ifdef VMS_TEMPNAM 7441 /* mktemp() is not working on VMS. It seems to be 7442 * a do-nothing function. Therefore we use tempnam(). 7443 */ 7444 sprintf((char *)itmp, "VIM%c", extra_char); 7445 p = (char_u *)tempnam("tmp:", (char *)itmp); 7446 if (p != NULL) 7447 { 7448 /* VMS will use '.LIS' if we don't explicitly specify an extension, 7449 * and VIM will then be unable to find the file later */ 7450 STRCPY(itmp, p); 7451 STRCAT(itmp, ".txt"); 7452 free(p); 7453 } 7454 else 7455 return NULL; 7456 # else 7457 STRCPY(itmp, TEMPNAME); 7458 if ((p = vim_strchr(itmp, '?')) != NULL) 7459 *p = extra_char; 7460 if (mktemp((char *)itmp) == NULL) 7461 return NULL; 7462 # endif 7463 # endif 7464 7465 return vim_strsave(itmp); 7466 # endif // MSWIN 7467 #endif /* TEMPDIRNAMES */ 7468 } 7469 7470 #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) 7471 /* 7472 * Convert all backslashes in fname to forward slashes in-place, unless when 7473 * it looks like a URL. 7474 */ 7475 void 7476 forward_slash(char_u *fname) 7477 { 7478 char_u *p; 7479 7480 if (path_with_url(fname)) 7481 return; 7482 for (p = fname; *p != NUL; ++p) 7483 /* The Big5 encoding can have '\' in the trail byte. */ 7484 if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1) 7485 ++p; 7486 else if (*p == '\\') 7487 *p = '/'; 7488 } 7489 #endif 7490 7491 /* 7492 * Try matching a filename with a "pattern" ("prog" is NULL), or use the 7493 * precompiled regprog "prog" ("pattern" is NULL). That avoids calling 7494 * vim_regcomp() often. 7495 * Used for autocommands and 'wildignore'. 7496 * Returns TRUE if there is a match, FALSE otherwise. 7497 */ 7498 int 7499 match_file_pat( 7500 char_u *pattern, /* pattern to match with */ 7501 regprog_T **prog, /* pre-compiled regprog or NULL */ 7502 char_u *fname, /* full path of file name */ 7503 char_u *sfname, /* short file name or NULL */ 7504 char_u *tail, /* tail of path */ 7505 int allow_dirs) /* allow matching with dir */ 7506 { 7507 regmatch_T regmatch; 7508 int result = FALSE; 7509 7510 regmatch.rm_ic = p_fic; /* ignore case if 'fileignorecase' is set */ 7511 if (prog != NULL) 7512 regmatch.regprog = *prog; 7513 else 7514 regmatch.regprog = vim_regcomp(pattern, RE_MAGIC); 7515 7516 /* 7517 * Try for a match with the pattern with: 7518 * 1. the full file name, when the pattern has a '/'. 7519 * 2. the short file name, when the pattern has a '/'. 7520 * 3. the tail of the file name, when the pattern has no '/'. 7521 */ 7522 if (regmatch.regprog != NULL 7523 && ((allow_dirs 7524 && (vim_regexec(®match, fname, (colnr_T)0) 7525 || (sfname != NULL 7526 && vim_regexec(®match, sfname, (colnr_T)0)))) 7527 || (!allow_dirs && vim_regexec(®match, tail, (colnr_T)0)))) 7528 result = TRUE; 7529 7530 if (prog != NULL) 7531 *prog = regmatch.regprog; 7532 else 7533 vim_regfree(regmatch.regprog); 7534 return result; 7535 } 7536 7537 #if defined(FEAT_WILDIGN) || defined(PROTO) 7538 /* 7539 * Return TRUE if a file matches with a pattern in "list". 7540 * "list" is a comma-separated list of patterns, like 'wildignore'. 7541 * "sfname" is the short file name or NULL, "ffname" the long file name. 7542 */ 7543 int 7544 match_file_list(char_u *list, char_u *sfname, char_u *ffname) 7545 { 7546 char_u buf[100]; 7547 char_u *tail; 7548 char_u *regpat; 7549 char allow_dirs; 7550 int match; 7551 char_u *p; 7552 7553 tail = gettail(sfname); 7554 7555 /* try all patterns in 'wildignore' */ 7556 p = list; 7557 while (*p) 7558 { 7559 copy_option_part(&p, buf, 100, ","); 7560 regpat = file_pat_to_reg_pat(buf, NULL, &allow_dirs, FALSE); 7561 if (regpat == NULL) 7562 break; 7563 match = match_file_pat(regpat, NULL, ffname, sfname, 7564 tail, (int)allow_dirs); 7565 vim_free(regpat); 7566 if (match) 7567 return TRUE; 7568 } 7569 return FALSE; 7570 } 7571 #endif 7572 7573 /* 7574 * Convert the given pattern "pat" which has shell style wildcards in it, into 7575 * a regular expression, and return the result in allocated memory. If there 7576 * is a directory path separator to be matched, then TRUE is put in 7577 * allow_dirs, otherwise FALSE is put there -- webb. 7578 * Handle backslashes before special characters, like "\*" and "\ ". 7579 * 7580 * Returns NULL when out of memory. 7581 */ 7582 char_u * 7583 file_pat_to_reg_pat( 7584 char_u *pat, 7585 char_u *pat_end, /* first char after pattern or NULL */ 7586 char *allow_dirs, /* Result passed back out in here */ 7587 int no_bslash UNUSED) /* Don't use a backward slash as pathsep */ 7588 { 7589 int size = 2; /* '^' at start, '$' at end */ 7590 char_u *endp; 7591 char_u *reg_pat; 7592 char_u *p; 7593 int i; 7594 int nested = 0; 7595 int add_dollar = TRUE; 7596 7597 if (allow_dirs != NULL) 7598 *allow_dirs = FALSE; 7599 if (pat_end == NULL) 7600 pat_end = pat + STRLEN(pat); 7601 7602 for (p = pat; p < pat_end; p++) 7603 { 7604 switch (*p) 7605 { 7606 case '*': 7607 case '.': 7608 case ',': 7609 case '{': 7610 case '}': 7611 case '~': 7612 size += 2; /* extra backslash */ 7613 break; 7614 #ifdef BACKSLASH_IN_FILENAME 7615 case '\\': 7616 case '/': 7617 size += 4; /* could become "[\/]" */ 7618 break; 7619 #endif 7620 default: 7621 size++; 7622 if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1) 7623 { 7624 ++p; 7625 ++size; 7626 } 7627 break; 7628 } 7629 } 7630 reg_pat = alloc(size + 1); 7631 if (reg_pat == NULL) 7632 return NULL; 7633 7634 i = 0; 7635 7636 if (pat[0] == '*') 7637 while (pat[0] == '*' && pat < pat_end - 1) 7638 pat++; 7639 else 7640 reg_pat[i++] = '^'; 7641 endp = pat_end - 1; 7642 if (endp >= pat && *endp == '*') 7643 { 7644 while (endp - pat > 0 && *endp == '*') 7645 endp--; 7646 add_dollar = FALSE; 7647 } 7648 for (p = pat; *p && nested >= 0 && p <= endp; p++) 7649 { 7650 switch (*p) 7651 { 7652 case '*': 7653 reg_pat[i++] = '.'; 7654 reg_pat[i++] = '*'; 7655 while (p[1] == '*') /* "**" matches like "*" */ 7656 ++p; 7657 break; 7658 case '.': 7659 case '~': 7660 reg_pat[i++] = '\\'; 7661 reg_pat[i++] = *p; 7662 break; 7663 case '?': 7664 reg_pat[i++] = '.'; 7665 break; 7666 case '\\': 7667 if (p[1] == NUL) 7668 break; 7669 #ifdef BACKSLASH_IN_FILENAME 7670 if (!no_bslash) 7671 { 7672 /* translate: 7673 * "\x" to "\\x" e.g., "dir\file" 7674 * "\*" to "\\.*" e.g., "dir\*.c" 7675 * "\?" to "\\." e.g., "dir\??.c" 7676 * "\+" to "\+" e.g., "fileX\+.c" 7677 */ 7678 if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?') 7679 && p[1] != '+') 7680 { 7681 reg_pat[i++] = '['; 7682 reg_pat[i++] = '\\'; 7683 reg_pat[i++] = '/'; 7684 reg_pat[i++] = ']'; 7685 if (allow_dirs != NULL) 7686 *allow_dirs = TRUE; 7687 break; 7688 } 7689 } 7690 #endif 7691 /* Undo escaping from ExpandEscape(): 7692 * foo\?bar -> foo?bar 7693 * foo\%bar -> foo%bar 7694 * foo\,bar -> foo,bar 7695 * foo\ bar -> foo bar 7696 * Don't unescape \, * and others that are also special in a 7697 * regexp. 7698 * An escaped { must be unescaped since we use magic not 7699 * verymagic. Use "\\\{n,m\}"" to get "\{n,m}". 7700 */ 7701 if (*++p == '?' 7702 #ifdef BACKSLASH_IN_FILENAME 7703 && no_bslash 7704 #endif 7705 ) 7706 reg_pat[i++] = '?'; 7707 else 7708 if (*p == ',' || *p == '%' || *p == '#' 7709 || vim_isspace(*p) || *p == '{' || *p == '}') 7710 reg_pat[i++] = *p; 7711 else if (*p == '\\' && p[1] == '\\' && p[2] == '{') 7712 { 7713 reg_pat[i++] = '\\'; 7714 reg_pat[i++] = '{'; 7715 p += 2; 7716 } 7717 else 7718 { 7719 if (allow_dirs != NULL && vim_ispathsep(*p) 7720 #ifdef BACKSLASH_IN_FILENAME 7721 && (!no_bslash || *p != '\\') 7722 #endif 7723 ) 7724 *allow_dirs = TRUE; 7725 reg_pat[i++] = '\\'; 7726 reg_pat[i++] = *p; 7727 } 7728 break; 7729 #ifdef BACKSLASH_IN_FILENAME 7730 case '/': 7731 reg_pat[i++] = '['; 7732 reg_pat[i++] = '\\'; 7733 reg_pat[i++] = '/'; 7734 reg_pat[i++] = ']'; 7735 if (allow_dirs != NULL) 7736 *allow_dirs = TRUE; 7737 break; 7738 #endif 7739 case '{': 7740 reg_pat[i++] = '\\'; 7741 reg_pat[i++] = '('; 7742 nested++; 7743 break; 7744 case '}': 7745 reg_pat[i++] = '\\'; 7746 reg_pat[i++] = ')'; 7747 --nested; 7748 break; 7749 case ',': 7750 if (nested) 7751 { 7752 reg_pat[i++] = '\\'; 7753 reg_pat[i++] = '|'; 7754 } 7755 else 7756 reg_pat[i++] = ','; 7757 break; 7758 default: 7759 if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1) 7760 reg_pat[i++] = *p++; 7761 else if (allow_dirs != NULL && vim_ispathsep(*p)) 7762 *allow_dirs = TRUE; 7763 reg_pat[i++] = *p; 7764 break; 7765 } 7766 } 7767 if (add_dollar) 7768 reg_pat[i++] = '$'; 7769 reg_pat[i] = NUL; 7770 if (nested != 0) 7771 { 7772 if (nested < 0) 7773 emsg(_("E219: Missing {.")); 7774 else 7775 emsg(_("E220: Missing }.")); 7776 VIM_CLEAR(reg_pat); 7777 } 7778 return reg_pat; 7779 } 7780 7781 #if defined(EINTR) || defined(PROTO) 7782 /* 7783 * Version of read() that retries when interrupted by EINTR (possibly 7784 * by a SIGWINCH). 7785 */ 7786 long 7787 read_eintr(int fd, void *buf, size_t bufsize) 7788 { 7789 long ret; 7790 7791 for (;;) 7792 { 7793 ret = vim_read(fd, buf, bufsize); 7794 if (ret >= 0 || errno != EINTR) 7795 break; 7796 } 7797 return ret; 7798 } 7799 7800 /* 7801 * Version of write() that retries when interrupted by EINTR (possibly 7802 * by a SIGWINCH). 7803 */ 7804 long 7805 write_eintr(int fd, void *buf, size_t bufsize) 7806 { 7807 long ret = 0; 7808 long wlen; 7809 7810 /* Repeat the write() so long it didn't fail, other than being interrupted 7811 * by a signal. */ 7812 while (ret < (long)bufsize) 7813 { 7814 wlen = vim_write(fd, (char *)buf + ret, bufsize - ret); 7815 if (wlen < 0) 7816 { 7817 if (errno != EINTR) 7818 break; 7819 } 7820 else 7821 ret += wlen; 7822 } 7823 return ret; 7824 } 7825 #endif 7826