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