~vkolesnikov/pbxt/pbxt-maria-windows-app-ver-fixes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/* Copyright (c) 2005 PrimeBase Technologies GmbH
 *
 * PrimeBase XT
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * 2005-01-12	Paul McCullagh
 *
 * H&G2JCtL
 */
#ifndef __xt_filesys_h__
#define __xt_filesys_h__

#ifdef XT_WIN
#include <time.h>
#else
#include <sys/time.h>
#include <dirent.h>
#endif
#include <sys/stat.h>

#include "xt_defs.h"
#include "lock_xt.h"

#ifdef XT_WIN
#define XT_FILE_IN_USE(x)			((x) == ERROR_SHARING_VIOLATION)
#define XT_FILE_ACCESS_DENIED(x)	((x) == ERROR_ACCESS_DENIED || (x) == ERROR_NETWORK_ACCESS_DENIED)
#define XT_FILE_TOO_MANY_OPEN(x)	((x) == ERROR_TOO_MANY_OPEN_FILES)
#define XT_FILE_NOT_FOUND(x)		((x) == ERROR_FILE_NOT_FOUND || (x) == ERROR_PATH_NOT_FOUND)
#else
#define XT_FILE_IN_USE(x)			((x) == ETXTBSY)
#define XT_FILE_ACCESS_DENIED(x)	((x) == EACCES)
#define XT_FILE_TOO_MANY_OPEN(x)	((x) == EMFILE)
#define XT_FILE_NOT_FOUND(x)		((x) == ENOENT)
#endif

struct XTOpenFile;

#define XT_MASK				((S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP) | (S_IROTH))

#define XT_FS_DEFAULT		0		/* Open for read/write, error if does not exist. */
#define XT_FS_READONLY		1		/* Open for read only (otherwize read/write). */
#define XT_FS_CREATE		2		/* Create if the file does not exist. */
#define XT_FS_EXCLUSIVE		4		/* Create, and generate an error if it already exists. */
#define XT_FS_MISSING_OK	8		/* Set this flag if you don't want to throw an error if the file does not exist! */
#define XT_FS_MAKE_PATH		16		/* Create the path if it does not exist. */
#define XT_FS_DIRECT_IO		32		/* Use direct I/O on this file if possible (O_DIRECT). */

xtBool			xt_fs_exists(char *path);
xtBool			xt_fs_delete(struct XTThread *self, char *path);
xtBool			xt_fs_file_not_found(int err);
void			xt_fs_mkdir(struct XTThread *self, char *path);
void			xt_fs_mkpath(struct XTThread *self, char *path);
xtBool			xt_fs_rmdir(struct XTThread *self, char *path);
xtBool			xt_fs_stat(struct XTThread *self, char *path, off_t *size, struct timespec *mod_time);
void			xt_fs_move(struct XTThread *self, char *from_path, char *to_path);
xtBool			xt_fs_rename(struct XTThread *self, char *from_path, char *to_path);

#ifdef XT_WIN
#define XT_FD		HANDLE
#define XT_NULL_FD	INVALID_HANDLE_VALUE
#else
#define XT_FD		int
#define XT_NULL_FD	(-1)
#endif

/* Note, this lock must be re-entrant,
 * The only lock that satifies this is
 * FILE_MAP_USE_RWMUTEX!
 *
 * 20.05.2009: This problem should be fixed now with mf_slock_count!
 *
 * The lock need no longer be re-entrant
 */
#ifdef XT_NO_ATOMICS
#define FILE_MAP_USE_PTHREAD_RW
#else
//#define FILE_MAP_USE_RWMUTEX
//#define FILE_MAP_USE_PTHREAD_RW
//#define IDX_USE_SPINXSLOCK
#define FILE_MAP_USE_XSMUTEX
#endif

#ifdef FILE_MAP_USE_XSMUTEX
#define FILE_MAP_LOCK_TYPE				XTXSMutexRec
#define FILE_MAP_INIT_LOCK(s, i)		xt_xsmutex_init_with_autoname(s, i)
#define FILE_MAP_FREE_LOCK(s, i)		xt_xsmutex_free(s, i)	
#define FILE_MAP_READ_LOCK(i, o)		xt_xsmutex_slock(i, o)
#define FILE_MAP_WRITE_LOCK(i, o)		xt_xsmutex_xlock(i, o)
#define FILE_MAP_UNLOCK(i, o)			xt_xsmutex_unlock(i, o)
#elif defined(FILE_MAP_USE_PTHREAD_RW)
#define FILE_MAP_LOCK_TYPE				xt_rwlock_type
#define FILE_MAP_INIT_LOCK(s, i)		xt_init_rwlock_with_autoname(s, i)
#define FILE_MAP_FREE_LOCK(s, i)		xt_free_rwlock(i)	
#define FILE_MAP_READ_LOCK(i, o)		xt_slock_rwlock_ns(i)
#define FILE_MAP_WRITE_LOCK(i, o)		xt_xlock_rwlock_ns(i)
#define FILE_MAP_UNLOCK(i, o)			xt_unlock_rwlock_ns(i)
#elif defined(FILE_MAP_USE_RWMUTEX)
#define FILE_MAP_LOCK_TYPE				XTRWMutexRec
#define FILE_MAP_INIT_LOCK(s, i)		xt_rwmutex_init_with_autoname(s, i)
#define FILE_MAP_FREE_LOCK(s, i)		xt_rwmutex_free(s, i)	
#define FILE_MAP_READ_LOCK(i, o)		xt_rwmutex_slock(i, o)
#define FILE_MAP_WRITE_LOCK(i, o)		xt_rwmutex_xlock(i, o)
#define FILE_MAP_UNLOCK(i, o)			xt_rwmutex_unlock(i, o)
#elif defined(FILE_MAP_USE_SPINXSLOCK)
#define FILE_MAP_LOCK_TYPE				XTSpinXSLockRec
#define FILE_MAP_INIT_LOCK(s, i)		xt_spinxslock_init_with_autoname(s, i)
#define FILE_MAP_FREE_LOCK(s, i)		xt_spinxslock_free(s, i)	
#define FILE_MAP_READ_LOCK(i, o)		xt_spinxslock_slock(i, o)
#define FILE_MAP_WRITE_LOCK(i, o)		xt_spinxslock_xlock(i, FALSE, o)
#define FILE_MAP_UNLOCK(i, o)			xt_spinxslock_unlock(i, o)
#endif

typedef struct XTFileMemMap {
	xtWord1				*mm_start;			/* The in-memory start of the map. */
#ifdef XT_WIN
	HANDLE				mm_mapdes;
#endif
	off_t				mm_length;			/* The length of the file map. */
	FILE_MAP_LOCK_TYPE	mm_lock;			/* The file map R/W lock. */
	size_t				mm_grow_size;		/* The amount by which the map file is increased. */
} XTFileMemMapRec, *XTFileMemMapPtr;

typedef struct XTFile {
	u_int				fil_ref_count;		/* The number of open file structure referencing this file. */
	char				*fil_path;
	u_int				fil_id;				/* This is used by the disk cache to identify a file in the hash index. */
	XT_FD				fil_filedes;		/* The shared file descriptor (pread and pwrite allow this), on Windows this is used only for mmapped files */
	u_int				fil_handle_count;	/* Number of references in the case of mmapped fil_filedes, both Windows and Unix */
	XTFileMemMapPtr		fil_memmap;			/* Non-null if this file is memory mapped. */
} XTFileRec, *XTFilePtr;

typedef struct XTFileRef {
	XTFilePtr			fr_file;
	u_int				fr_id;				/* Copied from above (small optimisation). */
} XTFileRefRec, *XTFileRefPtr;

typedef struct XTOpenFile : public XTFileRef {
	XT_FD				of_filedes;
} XTOpenFileRec, *XTOpenFilePtr;

void			xt_fs_init(struct XTThread *self);
void			xt_fs_exit(struct XTThread *self);

XTFilePtr		xt_fs_get_file(struct XTThread *self, char *file_name);
void			xt_fs_release_file(struct XTThread *self, XTFilePtr file_ptr);

XTOpenFilePtr	xt_open_file(struct XTThread *self, char *file, int mode);
XTOpenFilePtr	xt_open_file_ns(char *file, int mode);
xtBool			xt_open_file_ns(XTOpenFilePtr *fh, char *file, int mode);
void			xt_close_file(struct XTThread *self, XTOpenFilePtr f);
xtBool			xt_close_file_ns(XTOpenFilePtr f);
char			*xt_file_path(struct XTFileRef *of);

xtBool			xt_lock_file(struct XTThread *self, XTOpenFilePtr of);
void			xt_unlock_file(struct XTThread *self, XTOpenFilePtr of);

off_t			xt_seek_eof_file(struct XTThread *self, XTOpenFilePtr of);
xtBool			xt_set_eof_file(struct XTThread *self, XTOpenFilePtr of, off_t offset);

xtBool			xt_pwrite_file(XTOpenFilePtr of, off_t offset, size_t size, void *data, struct XTIOStats *timer, struct XTThread *thread);
xtBool			xt_pread_file(XTOpenFilePtr of, off_t offset, size_t size, size_t min_size, void *data, size_t *red_size, struct XTIOStats *timer, struct XTThread *thread);
xtBool			xt_flush_file(XTOpenFilePtr of, struct XTIOStats *timer, struct XTThread *thread);

xtBool			xt_lock_file_ptr(XTOpenFilePtr of, xtWord1 **data, off_t offset, size_t size, struct XTIOStats *timer, struct XTThread *thread);
void			xt_unlock_file_ptr(XTOpenFilePtr of, xtWord1 *data, struct XTThread *thread);

typedef struct XTOpenDir {
	char				*od_path;
#ifdef XT_WIN
	HANDLE				od_handle;
	WIN32_FIND_DATA		od_data;
#else
	char				*od_filter;
	DIR					*od_dir;
	/* WARNING: Solaris requires od_entry.d_name member to have size at least as returned
	 * by pathconf() function on per-directory basis. This makes it impossible to statically
	 * pre-set the size. So xt_dir_open on Solaris dynamically allocates space as needed. 
	 *
	 * This also means that the od_entry member should always be last in the XTOpenDir structure.
	 */
	struct dirent		od_entry;
#endif
} XTOpenDirRec, *XTOpenDirPtr;

XTOpenDirPtr	xt_dir_open(struct XTThread *self, c_char *path, c_char *filter);
void			xt_dir_close(struct XTThread *self, XTOpenDirPtr od);
xtBool			xt_dir_next(struct XTThread *self, XTOpenDirPtr od);
char			*xt_dir_name(struct XTThread *self, XTOpenDirPtr od);
xtBool			xt_dir_is_file(struct XTThread *self, XTOpenDirPtr od);
off_t			xt_dir_file_size(struct XTThread *self, XTOpenDirPtr od);

typedef struct XTMapFile : public XTFileRef {
	u_int				mf_slock_count;
	XTFileMemMapPtr		mf_memmap;
} XTMapFileRec, *XTMapFilePtr;

XTMapFilePtr	xt_open_fmap(struct XTThread *self, char *file, size_t grow_size);
void			xt_close_fmap(struct XTThread *self, XTMapFilePtr map);
xtBool			xt_close_fmap_ns(XTMapFilePtr map);
xtBool			xt_pwrite_fmap(XTMapFilePtr map, off_t offset, size_t size, void *data, struct XTIOStats *timer, struct XTThread *thread);
xtBool			xt_pread_fmap(XTMapFilePtr map, off_t offset, size_t size, size_t min_size, void *data, size_t *red_size, struct XTIOStats *timer, struct XTThread *thread);
xtBool			xt_pread_fmap_4(XTMapFilePtr map, off_t offset, xtWord4 *value, struct XTIOStats *timer, struct XTThread *thread);
xtBool			xt_flush_fmap(XTMapFilePtr map, struct XTIOStats *stat, struct XTThread *thread);
xtWord1			*xt_lock_fmap_ptr(XTMapFilePtr map, off_t offset, size_t size, struct XTIOStats *timer, struct XTThread *thread);
void			xt_unlock_fmap_ptr(XTMapFilePtr map, struct XTThread *thread);

void			xt_fs_copy_file(struct XTThread *self, char *from_path, char *to_path);
void			xt_fs_copy_dir(struct XTThread *self, const char *from, const char *to);

#endif