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