annotate src/memfile.c @ 33879:d418c82f02a4 v9.0.2149

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