OLD | NEW |
1 /* | 1 /* |
2 ** 2004 May 22 | 2 ** 2004 May 22 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 */ | 65 */ |
66 #if !defined(SQLITE_ENABLE_LOCKING_STYLE) | 66 #if !defined(SQLITE_ENABLE_LOCKING_STYLE) |
67 # if defined(__APPLE__) | 67 # if defined(__APPLE__) |
68 # define SQLITE_ENABLE_LOCKING_STYLE 1 | 68 # define SQLITE_ENABLE_LOCKING_STYLE 1 |
69 # else | 69 # else |
70 # define SQLITE_ENABLE_LOCKING_STYLE 0 | 70 # define SQLITE_ENABLE_LOCKING_STYLE 0 |
71 # endif | 71 # endif |
72 #endif | 72 #endif |
73 | 73 |
74 /* | 74 /* |
75 ** Define the OS_VXWORKS pre-processor macro to 1 if building on | |
76 ** vxworks, or 0 otherwise. | |
77 */ | |
78 #ifndef OS_VXWORKS | |
79 # if defined(__RTP__) || defined(_WRS_KERNEL) | |
80 # define OS_VXWORKS 1 | |
81 # else | |
82 # define OS_VXWORKS 0 | |
83 # endif | |
84 #endif | |
85 | |
86 /* | |
87 ** standard include files. | 75 ** standard include files. |
88 */ | 76 */ |
89 #include <sys/types.h> | 77 #include <sys/types.h> |
90 #include <sys/stat.h> | 78 #include <sys/stat.h> |
91 #include <fcntl.h> | 79 #include <fcntl.h> |
92 #include <unistd.h> | 80 #include <unistd.h> |
93 #include <time.h> | 81 #include <time.h> |
94 #include <sys/time.h> | 82 #include <sys/time.h> |
95 #include <errno.h> | 83 #include <errno.h> |
96 #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 | 84 #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
97 # include <sys/mman.h> | 85 # include <sys/mman.h> |
98 #endif | 86 #endif |
99 | 87 |
100 #if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS | 88 #if SQLITE_ENABLE_LOCKING_STYLE |
101 # include <sys/ioctl.h> | 89 # include <sys/ioctl.h> |
102 # if OS_VXWORKS | 90 # include <sys/file.h> |
103 # include <semaphore.h> | 91 # include <sys/param.h> |
104 # include <limits.h> | |
105 # else | |
106 # include <sys/file.h> | |
107 # include <sys/param.h> | |
108 # endif | |
109 #endif /* SQLITE_ENABLE_LOCKING_STYLE */ | 92 #endif /* SQLITE_ENABLE_LOCKING_STYLE */ |
110 | 93 |
111 #if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) | 94 #if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ |
| 95 (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) |
| 96 # if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ |
| 97 && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0)) |
| 98 # define HAVE_GETHOSTUUID 1 |
| 99 # else |
| 100 # warning "gethostuuid() is disabled." |
| 101 # endif |
| 102 #endif |
| 103 |
| 104 |
| 105 #if OS_VXWORKS |
| 106 # include <sys/ioctl.h> |
| 107 # include <semaphore.h> |
| 108 # include <limits.h> |
| 109 #endif /* OS_VXWORKS */ |
| 110 |
| 111 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE |
112 # include <sys/mount.h> | 112 # include <sys/mount.h> |
113 #endif | 113 #endif |
114 | 114 |
115 #ifdef HAVE_UTIME | 115 #ifdef HAVE_UTIME |
116 # include <utime.h> | 116 # include <utime.h> |
117 #endif | 117 #endif |
118 | 118 |
119 /* | 119 /* |
120 ** Allowed values of unixFile.fsFlags | 120 ** Allowed values of unixFile.fsFlags |
121 */ | 121 */ |
(...skipping 20 matching lines...) Expand all Loading... |
142 */ | 142 */ |
143 #ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS | 143 #ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS |
144 # define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 | 144 # define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 |
145 #endif | 145 #endif |
146 | 146 |
147 /* | 147 /* |
148 ** Maximum supported path-length. | 148 ** Maximum supported path-length. |
149 */ | 149 */ |
150 #define MAX_PATHNAME 512 | 150 #define MAX_PATHNAME 512 |
151 | 151 |
| 152 /* Always cast the getpid() return type for compatibility with |
| 153 ** kernel modules in VxWorks. */ |
| 154 #define osGetpid(X) (pid_t)getpid() |
| 155 |
152 /* | 156 /* |
153 ** Only set the lastErrno if the error code is a real error and not | 157 ** Only set the lastErrno if the error code is a real error and not |
154 ** a normal expected return code of SQLITE_BUSY or SQLITE_OK | 158 ** a normal expected return code of SQLITE_BUSY or SQLITE_OK |
155 */ | 159 */ |
156 #define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) | 160 #define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) |
157 | 161 |
158 /* Forward references */ | 162 /* Forward references */ |
159 typedef struct unixShm unixShm; /* Connection shared memory */ | 163 typedef struct unixShm unixShm; /* Connection shared memory */ |
160 typedef struct unixShmNode unixShmNode; /* Shared memory instance */ | 164 typedef struct unixShmNode unixShmNode; /* Shared memory instance */ |
161 typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ | 165 typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 ** it is larger than the struct CrashFile defined in test6.c. | 234 ** it is larger than the struct CrashFile defined in test6.c. |
231 */ | 235 */ |
232 char aPadding[32]; | 236 char aPadding[32]; |
233 #endif | 237 #endif |
234 }; | 238 }; |
235 | 239 |
236 /* This variable holds the process id (pid) from when the xRandomness() | 240 /* This variable holds the process id (pid) from when the xRandomness() |
237 ** method was called. If xOpen() is called from a different process id, | 241 ** method was called. If xOpen() is called from a different process id, |
238 ** indicating that a fork() has occurred, the PRNG will be reset. | 242 ** indicating that a fork() has occurred, the PRNG will be reset. |
239 */ | 243 */ |
240 static int randomnessPid = 0; | 244 static pid_t randomnessPid = 0; |
241 | 245 |
242 /* | 246 /* |
243 ** Allowed values for the unixFile.ctrlFlags bitmask: | 247 ** Allowed values for the unixFile.ctrlFlags bitmask: |
244 */ | 248 */ |
245 #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ | 249 #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ |
246 #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ | 250 #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ |
247 #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ | 251 #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ |
248 #ifndef SQLITE_DISABLE_DIRSYNC | 252 #ifndef SQLITE_DISABLE_DIRSYNC |
249 # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ | 253 # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ |
250 #else | 254 #else |
251 # define UNIXFILE_DIRSYNC 0x00 | 255 # define UNIXFILE_DIRSYNC 0x00 |
252 #endif | 256 #endif |
253 #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ | 257 #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ |
254 #define UNIXFILE_DELETE 0x20 /* Delete on close */ | 258 #define UNIXFILE_DELETE 0x20 /* Delete on close */ |
255 #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ | 259 #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ |
256 #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ | 260 #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ |
257 #define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issue
d */ | |
258 | 261 |
259 /* | 262 /* |
260 ** Include code that is common to all os_*.c files | 263 ** Include code that is common to all os_*.c files |
261 */ | 264 */ |
262 #include "os_common.h" | 265 #include "os_common.h" |
263 | 266 |
264 /* | 267 /* |
265 ** Define various macros that are missing from some systems. | 268 ** Define various macros that are missing from some systems. |
266 */ | 269 */ |
267 #ifndef O_LARGEFILE | 270 #ifndef O_LARGEFILE |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 ** open(const char*,int,mode_t). Others use open(const char*,int,...). | 315 ** open(const char*,int,mode_t). Others use open(const char*,int,...). |
313 ** The difference is important when using a pointer to the function. | 316 ** The difference is important when using a pointer to the function. |
314 ** | 317 ** |
315 ** The safest way to deal with the problem is to always use this wrapper | 318 ** The safest way to deal with the problem is to always use this wrapper |
316 ** which always has the same well-defined interface. | 319 ** which always has the same well-defined interface. |
317 */ | 320 */ |
318 static int posixOpen(const char *zFile, int flags, int mode){ | 321 static int posixOpen(const char *zFile, int flags, int mode){ |
319 return open(zFile, flags, mode); | 322 return open(zFile, flags, mode); |
320 } | 323 } |
321 | 324 |
322 /* | |
323 ** On some systems, calls to fchown() will trigger a message in a security | |
324 ** log if they come from non-root processes. So avoid calling fchown() if | |
325 ** we are not running as root. | |
326 */ | |
327 static int posixFchown(int fd, uid_t uid, gid_t gid){ | |
328 #if OS_VXWORKS | |
329 return 0; | |
330 #else | |
331 return geteuid() ? 0 : fchown(fd,uid,gid); | |
332 #endif | |
333 } | |
334 | |
335 /* Forward reference */ | 325 /* Forward reference */ |
336 static int openDirectory(const char*, int*); | 326 static int openDirectory(const char*, int*); |
337 static int unixGetpagesize(void); | 327 static int unixGetpagesize(void); |
338 | 328 |
339 /* | 329 /* |
340 ** Many system calls are accessed through pointer-to-functions so that | 330 ** Many system calls are accessed through pointer-to-functions so that |
341 ** they may be overridden at runtime to facilitate fault injection during | 331 ** they may be overridden at runtime to facilitate fault injection during |
342 ** testing and sandboxing. The following array holds the names and pointers | 332 ** testing and sandboxing. The following array holds the names and pointers |
343 ** to all overrideable system calls. | 333 ** to all overrideable system calls. |
344 */ | 334 */ |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 | 368 |
379 { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, | 369 { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, |
380 #define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) | 370 #define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) |
381 | 371 |
382 { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, | 372 { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, |
383 #define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) | 373 #define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) |
384 | 374 |
385 { "read", (sqlite3_syscall_ptr)read, 0 }, | 375 { "read", (sqlite3_syscall_ptr)read, 0 }, |
386 #define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) | 376 #define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) |
387 | 377 |
388 #if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) | 378 #if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE |
389 { "pread", (sqlite3_syscall_ptr)pread, 0 }, | 379 { "pread", (sqlite3_syscall_ptr)pread, 0 }, |
390 #else | 380 #else |
391 { "pread", (sqlite3_syscall_ptr)0, 0 }, | 381 { "pread", (sqlite3_syscall_ptr)0, 0 }, |
392 #endif | 382 #endif |
393 #define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) | 383 #define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) |
394 | 384 |
395 #if defined(USE_PREAD64) | 385 #if defined(USE_PREAD64) |
396 { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, | 386 { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, |
397 #else | 387 #else |
398 { "pread64", (sqlite3_syscall_ptr)0, 0 }, | 388 { "pread64", (sqlite3_syscall_ptr)0, 0 }, |
399 #endif | 389 #endif |
400 #define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent) | 390 #define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent) |
401 | 391 |
402 { "write", (sqlite3_syscall_ptr)write, 0 }, | 392 { "write", (sqlite3_syscall_ptr)write, 0 }, |
403 #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) | 393 #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) |
404 | 394 |
405 #if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) | 395 #if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE |
406 { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, | 396 { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, |
407 #else | 397 #else |
408 { "pwrite", (sqlite3_syscall_ptr)0, 0 }, | 398 { "pwrite", (sqlite3_syscall_ptr)0, 0 }, |
409 #endif | 399 #endif |
410 #define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ | 400 #define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ |
411 aSyscall[12].pCurrent) | 401 aSyscall[12].pCurrent) |
412 | 402 |
413 #if defined(USE_PREAD64) | 403 #if defined(USE_PREAD64) |
414 { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, | 404 { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, |
415 #else | 405 #else |
416 { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, | 406 { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, |
417 #endif | 407 #endif |
418 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ | 408 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ |
419 aSyscall[13].pCurrent) | 409 aSyscall[13].pCurrent) |
420 | 410 |
421 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, | 411 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, |
422 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) | 412 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) |
423 | 413 |
424 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE | 414 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE |
425 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, | 415 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, |
426 #else | 416 #else |
427 { "fallocate", (sqlite3_syscall_ptr)0, 0 }, | 417 { "fallocate", (sqlite3_syscall_ptr)0, 0 }, |
428 #endif | 418 #endif |
429 #define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) | 419 #define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) |
430 | 420 |
431 { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, | 421 { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, |
432 #define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) | 422 #define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) |
433 | 423 |
434 { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, | 424 { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, |
435 #define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) | 425 #define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) |
436 | 426 |
437 { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, | 427 { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, |
438 #define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) | 428 #define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) |
439 | 429 |
440 { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, | 430 { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, |
441 #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) | 431 #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
442 | 432 |
443 { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, | 433 { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, |
444 #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) | 434 #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
445 | 435 |
| 436 { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, |
| 437 #define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) |
| 438 |
446 #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 | 439 #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
447 { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, | 440 { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
448 #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) | 441 #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) |
449 | 442 |
450 { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, | 443 { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
451 #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) | 444 #define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent) |
452 | 445 |
453 #if HAVE_MREMAP | 446 #if HAVE_MREMAP |
454 { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, | 447 { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, |
455 #else | 448 #else |
456 { "mremap", (sqlite3_syscall_ptr)0, 0 }, | 449 { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
457 #endif | 450 #endif |
458 #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) | 451 #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent) |
| 452 |
459 { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, | 453 { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, |
460 #define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent) | 454 #define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent) |
| 455 |
| 456 { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, |
| 457 #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) |
461 | 458 |
462 #endif | 459 #endif |
463 | 460 |
464 }; /* End of the overrideable system calls */ | 461 }; /* End of the overrideable system calls */ |
465 | 462 |
| 463 |
| 464 /* |
| 465 ** On some systems, calls to fchown() will trigger a message in a security |
| 466 ** log if they come from non-root processes. So avoid calling fchown() if |
| 467 ** we are not running as root. |
| 468 */ |
| 469 static int robustFchown(int fd, uid_t uid, gid_t gid){ |
| 470 #if OS_VXWORKS |
| 471 return 0; |
| 472 #else |
| 473 return osGeteuid() ? 0 : osFchown(fd,uid,gid); |
| 474 #endif |
| 475 } |
| 476 |
466 /* | 477 /* |
467 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the | 478 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
468 ** "unix" VFSes. Return SQLITE_OK opon successfully updating the | 479 ** "unix" VFSes. Return SQLITE_OK opon successfully updating the |
469 ** system call pointer, or SQLITE_NOTFOUND if there is no configurable | 480 ** system call pointer, or SQLITE_NOTFOUND if there is no configurable |
470 ** system call named zName. | 481 ** system call named zName. |
471 */ | 482 */ |
472 static int unixSetSystemCall( | 483 static int unixSetSystemCall( |
473 sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ | 484 sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ |
474 const char *zName, /* Name of system call to override */ | 485 const char *zName, /* Name of system call to override */ |
475 sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ | 486 sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 ** | 628 ** |
618 ** Function unixMutexHeld() is used to assert() that the global mutex | 629 ** Function unixMutexHeld() is used to assert() that the global mutex |
619 ** is held when required. This function is only used as part of assert() | 630 ** is held when required. This function is only used as part of assert() |
620 ** statements. e.g. | 631 ** statements. e.g. |
621 ** | 632 ** |
622 ** unixEnterMutex() | 633 ** unixEnterMutex() |
623 ** assert( unixMutexHeld() ); | 634 ** assert( unixMutexHeld() ); |
624 ** unixEnterLeave() | 635 ** unixEnterLeave() |
625 */ | 636 */ |
626 static void unixEnterMutex(void){ | 637 static void unixEnterMutex(void){ |
627 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); | 638 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); |
628 } | 639 } |
629 static void unixLeaveMutex(void){ | 640 static void unixLeaveMutex(void){ |
630 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); | 641 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); |
631 } | 642 } |
632 #ifdef SQLITE_DEBUG | 643 #ifdef SQLITE_DEBUG |
633 static int unixMutexHeld(void) { | 644 static int unixMutexHeld(void) { |
634 return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); | 645 return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); |
635 } | 646 } |
636 #endif | 647 #endif |
637 | 648 |
638 | 649 |
639 #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) | 650 #ifdef SQLITE_HAVE_OS_TRACE |
640 /* | 651 /* |
641 ** Helper function for printing out trace information from debugging | 652 ** Helper function for printing out trace information from debugging |
642 ** binaries. This returns the string representation of the supplied | 653 ** binaries. This returns the string representation of the supplied |
643 ** integer lock-type. | 654 ** integer lock-type. |
644 */ | 655 */ |
645 static const char *azFileLock(int eFileLock){ | 656 static const char *azFileLock(int eFileLock){ |
646 switch( eFileLock ){ | 657 switch( eFileLock ){ |
647 case NO_LOCK: return "NONE"; | 658 case NO_LOCK: return "NONE"; |
648 case SHARED_LOCK: return "SHARED"; | 659 case SHARED_LOCK: return "SHARED"; |
649 case RESERVED_LOCK: return "RESERVED"; | 660 case RESERVED_LOCK: return "RESERVED"; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 errno = savedErrno; | 721 errno = savedErrno; |
711 return s; | 722 return s; |
712 } | 723 } |
713 #undef osFcntl | 724 #undef osFcntl |
714 #define osFcntl lockTrace | 725 #define osFcntl lockTrace |
715 #endif /* SQLITE_LOCK_TRACE */ | 726 #endif /* SQLITE_LOCK_TRACE */ |
716 | 727 |
717 /* | 728 /* |
718 ** Retry ftruncate() calls that fail due to EINTR | 729 ** Retry ftruncate() calls that fail due to EINTR |
719 ** | 730 ** |
720 ** All calls to ftruncate() within this file should be made through this wrapper
. | 731 ** All calls to ftruncate() within this file should be made through |
721 ** On the Android platform, bypassing the logic below could lead to a corrupt | 732 ** this wrapper. On the Android platform, bypassing the logic below |
722 ** database. | 733 ** could lead to a corrupt database. |
723 */ | 734 */ |
724 static int robust_ftruncate(int h, sqlite3_int64 sz){ | 735 static int robust_ftruncate(int h, sqlite3_int64 sz){ |
725 int rc; | 736 int rc; |
726 #ifdef __ANDROID__ | 737 #ifdef __ANDROID__ |
727 /* On Android, ftruncate() always uses 32-bit offsets, even if | 738 /* On Android, ftruncate() always uses 32-bit offsets, even if |
728 ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to | 739 ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to |
729 ** truncate a file to any size larger than 2GiB. Silently ignore any | 740 ** truncate a file to any size larger than 2GiB. Silently ignore any |
730 ** such attempts. */ | 741 ** such attempts. */ |
731 if( sz>(sqlite3_int64)0x7FFFFFFF ){ | 742 if( sz>(sqlite3_int64)0x7FFFFFFF ){ |
732 rc = SQLITE_OK; | 743 rc = SQLITE_OK; |
733 }else | 744 }else |
734 #endif | 745 #endif |
735 do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); | 746 do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); |
736 return rc; | 747 return rc; |
737 } | 748 } |
738 | 749 |
739 /* | 750 /* |
740 ** This routine translates a standard POSIX errno code into something | 751 ** This routine translates a standard POSIX errno code into something |
741 ** useful to the clients of the sqlite3 functions. Specifically, it is | 752 ** useful to the clients of the sqlite3 functions. Specifically, it is |
742 ** intended to translate a variety of "try again" errors into SQLITE_BUSY | 753 ** intended to translate a variety of "try again" errors into SQLITE_BUSY |
743 ** and a variety of "please close the file descriptor NOW" errors into | 754 ** and a variety of "please close the file descriptor NOW" errors into |
744 ** SQLITE_IOERR | 755 ** SQLITE_IOERR |
745 ** | 756 ** |
746 ** Errors during initialization of locks, or file system support for locks, | 757 ** Errors during initialization of locks, or file system support for locks, |
747 ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. | 758 ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. |
748 */ | 759 */ |
749 static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { | 760 static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { |
| 761 assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || |
| 762 (sqliteIOErr == SQLITE_IOERR_UNLOCK) || |
| 763 (sqliteIOErr == SQLITE_IOERR_RDLOCK) || |
| 764 (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ); |
750 switch (posixError) { | 765 switch (posixError) { |
751 #if 0 | 766 case EACCES: |
752 /* At one point this code was not commented out. In theory, this branch | |
753 ** should never be hit, as this function should only be called after | |
754 ** a locking-related function (i.e. fcntl()) has returned non-zero with | |
755 ** the value of errno as the first argument. Since a system call has failed, | |
756 ** errno should be non-zero. | |
757 ** | |
758 ** Despite this, if errno really is zero, we still don't want to return | |
759 ** SQLITE_OK. The system call failed, and *some* SQLite error should be | |
760 ** propagated back to the caller. Commenting this branch out means errno==0 | |
761 ** will be handled by the "default:" case below. | |
762 */ | |
763 case 0: | |
764 return SQLITE_OK; | |
765 #endif | |
766 | |
767 case EAGAIN: | 767 case EAGAIN: |
768 case ETIMEDOUT: | 768 case ETIMEDOUT: |
769 case EBUSY: | 769 case EBUSY: |
770 case EINTR: | 770 case EINTR: |
771 case ENOLCK: | 771 case ENOLCK: |
772 /* random NFS retry error, unless during file system support | 772 /* random NFS retry error, unless during file system support |
773 * introspection, in which it actually means what it says */ | 773 * introspection, in which it actually means what it says */ |
774 return SQLITE_BUSY; | 774 return SQLITE_BUSY; |
775 | 775 |
776 case EACCES: | |
777 /* EACCES is like EAGAIN during locking operations, but not any other time*/ | |
778 if( (sqliteIOErr == SQLITE_IOERR_LOCK) || | |
779 (sqliteIOErr == SQLITE_IOERR_UNLOCK) || | |
780 (sqliteIOErr == SQLITE_IOERR_RDLOCK) || | |
781 (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){ | |
782 return SQLITE_BUSY; | |
783 } | |
784 /* else fall through */ | |
785 case EPERM: | 776 case EPERM: |
786 return SQLITE_PERM; | 777 return SQLITE_PERM; |
787 | 778 |
788 #if EOPNOTSUPP!=ENOTSUP | |
789 case EOPNOTSUPP: | |
790 /* something went terribly awry, unless during file system support | |
791 * introspection, in which it actually means what it says */ | |
792 #endif | |
793 #ifdef ENOTSUP | |
794 case ENOTSUP: | |
795 /* invalid fd, unless during file system support introspection, in which | |
796 * it actually means what it says */ | |
797 #endif | |
798 case EIO: | |
799 case EBADF: | |
800 case EINVAL: | |
801 case ENOTCONN: | |
802 case ENODEV: | |
803 case ENXIO: | |
804 case ENOENT: | |
805 #ifdef ESTALE /* ESTALE is not defined on Interix systems */ | |
806 case ESTALE: | |
807 #endif | |
808 case ENOSYS: | |
809 /* these should force the client to close the file and reconnect */ | |
810 | |
811 default: | 779 default: |
812 return sqliteIOErr; | 780 return sqliteIOErr; |
813 } | 781 } |
814 } | 782 } |
815 | 783 |
816 | 784 |
817 /****************************************************************************** | 785 /****************************************************************************** |
818 ****************** Begin Unique File ID Utility Used By VxWorks *************** | 786 ****************** Begin Unique File ID Utility Used By VxWorks *************** |
819 ** | 787 ** |
820 ** On most versions of unix, we can get a unique ID for a file by concatenating | 788 ** On most versions of unix, we can get a unique ID for a file by concatenating |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 ** | 860 ** |
893 ** If a memory allocation error occurs, return NULL. | 861 ** If a memory allocation error occurs, return NULL. |
894 */ | 862 */ |
895 static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ | 863 static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ |
896 struct vxworksFileId *pNew; /* search key and new file ID */ | 864 struct vxworksFileId *pNew; /* search key and new file ID */ |
897 struct vxworksFileId *pCandidate; /* For looping over existing file IDs */ | 865 struct vxworksFileId *pCandidate; /* For looping over existing file IDs */ |
898 int n; /* Length of zAbsoluteName string */ | 866 int n; /* Length of zAbsoluteName string */ |
899 | 867 |
900 assert( zAbsoluteName[0]=='/' ); | 868 assert( zAbsoluteName[0]=='/' ); |
901 n = (int)strlen(zAbsoluteName); | 869 n = (int)strlen(zAbsoluteName); |
902 pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) ); | 870 pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) ); |
903 if( pNew==0 ) return 0; | 871 if( pNew==0 ) return 0; |
904 pNew->zCanonicalName = (char*)&pNew[1]; | 872 pNew->zCanonicalName = (char*)&pNew[1]; |
905 memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); | 873 memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); |
906 n = vxworksSimplifyName(pNew->zCanonicalName, n); | 874 n = vxworksSimplifyName(pNew->zCanonicalName, n); |
907 | 875 |
908 /* Search for an existing entry that matching the canonical name. | 876 /* Search for an existing entry that matching the canonical name. |
909 ** If found, increment the reference count and return a pointer to | 877 ** If found, increment the reference count and return a pointer to |
910 ** the existing file ID. | 878 ** the existing file ID. |
911 */ | 879 */ |
912 unixEnterMutex(); | 880 unixEnterMutex(); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 #endif | 1052 #endif |
1085 }; | 1053 }; |
1086 | 1054 |
1087 /* | 1055 /* |
1088 ** A lists of all unixInodeInfo objects. | 1056 ** A lists of all unixInodeInfo objects. |
1089 */ | 1057 */ |
1090 static unixInodeInfo *inodeList = 0; | 1058 static unixInodeInfo *inodeList = 0; |
1091 | 1059 |
1092 /* | 1060 /* |
1093 ** | 1061 ** |
1094 ** This function - unixLogError_x(), is only ever called via the macro | 1062 ** This function - unixLogErrorAtLine(), is only ever called via the macro |
1095 ** unixLogError(). | 1063 ** unixLogError(). |
1096 ** | 1064 ** |
1097 ** It is invoked after an error occurs in an OS function and errno has been | 1065 ** It is invoked after an error occurs in an OS function and errno has been |
1098 ** set. It logs a message using sqlite3_log() containing the current value of | 1066 ** set. It logs a message using sqlite3_log() containing the current value of |
1099 ** errno and, if possible, the human-readable equivalent from strerror() or | 1067 ** errno and, if possible, the human-readable equivalent from strerror() or |
1100 ** strerror_r(). | 1068 ** strerror_r(). |
1101 ** | 1069 ** |
1102 ** The first argument passed to the macro should be the error code that | 1070 ** The first argument passed to the macro should be the error code that |
1103 ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). | 1071 ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). |
1104 ** The two subsequent arguments should be the name of the OS function that | 1072 ** The two subsequent arguments should be the name of the OS function that |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 ** and move on. | 1140 ** and move on. |
1173 */ | 1141 */ |
1174 static void robust_close(unixFile *pFile, int h, int lineno){ | 1142 static void robust_close(unixFile *pFile, int h, int lineno){ |
1175 if( osClose(h) ){ | 1143 if( osClose(h) ){ |
1176 unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", | 1144 unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", |
1177 pFile ? pFile->zPath : 0, lineno); | 1145 pFile ? pFile->zPath : 0, lineno); |
1178 } | 1146 } |
1179 } | 1147 } |
1180 | 1148 |
1181 /* | 1149 /* |
| 1150 ** Set the pFile->lastErrno. Do this in a subroutine as that provides |
| 1151 ** a convenient place to set a breakpoint. |
| 1152 */ |
| 1153 static void storeLastErrno(unixFile *pFile, int error){ |
| 1154 pFile->lastErrno = error; |
| 1155 } |
| 1156 |
| 1157 /* |
1182 ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. | 1158 ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. |
1183 */ | 1159 */ |
1184 static void closePendingFds(unixFile *pFile){ | 1160 static void closePendingFds(unixFile *pFile){ |
1185 unixInodeInfo *pInode = pFile->pInode; | 1161 unixInodeInfo *pInode = pFile->pInode; |
1186 UnixUnusedFd *p; | 1162 UnixUnusedFd *p; |
1187 UnixUnusedFd *pNext; | 1163 UnixUnusedFd *pNext; |
1188 for(p=pInode->pUnused; p; p=pNext){ | 1164 for(p=pInode->pUnused; p; p=pNext){ |
1189 pNext = p->pNext; | 1165 pNext = p->pNext; |
1190 robust_close(pFile, p->fd, __LINE__); | 1166 robust_close(pFile, p->fd, __LINE__); |
1191 sqlite3_free(p); | 1167 sqlite3_free(p); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ | 1220 unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ |
1245 | 1221 |
1246 assert( unixMutexHeld() ); | 1222 assert( unixMutexHeld() ); |
1247 | 1223 |
1248 /* Get low-level information about the file that we can used to | 1224 /* Get low-level information about the file that we can used to |
1249 ** create a unique name for the file. | 1225 ** create a unique name for the file. |
1250 */ | 1226 */ |
1251 fd = pFile->h; | 1227 fd = pFile->h; |
1252 rc = osFstat(fd, &statbuf); | 1228 rc = osFstat(fd, &statbuf); |
1253 if( rc!=0 ){ | 1229 if( rc!=0 ){ |
1254 pFile->lastErrno = errno; | 1230 storeLastErrno(pFile, errno); |
1255 #ifdef EOVERFLOW | 1231 #if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS) |
1256 if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; | 1232 if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; |
1257 #endif | 1233 #endif |
1258 return SQLITE_IOERR; | 1234 return SQLITE_IOERR; |
1259 } | 1235 } |
1260 | 1236 |
1261 #ifdef __APPLE__ | 1237 #ifdef __APPLE__ |
1262 /* On OS X on an msdos filesystem, the inode number is reported | 1238 /* On OS X on an msdos filesystem, the inode number is reported |
1263 ** incorrectly for zero-size files. See ticket #3260. To work | 1239 ** incorrectly for zero-size files. See ticket #3260. To work |
1264 ** around this problem (we consider it a bug in OS X, not SQLite) | 1240 ** around this problem (we consider it a bug in OS X, not SQLite) |
1265 ** we always increase the file size to 1 by writing a single byte | 1241 ** we always increase the file size to 1 by writing a single byte |
1266 ** prior to accessing the inode number. The one byte written is | 1242 ** prior to accessing the inode number. The one byte written is |
1267 ** an ASCII 'S' character which also happens to be the first byte | 1243 ** an ASCII 'S' character which also happens to be the first byte |
1268 ** in the header of every SQLite database. In this way, if there | 1244 ** in the header of every SQLite database. In this way, if there |
1269 ** is a race condition such that another thread has already populated | 1245 ** is a race condition such that another thread has already populated |
1270 ** the first page of the database, no damage is done. | 1246 ** the first page of the database, no damage is done. |
1271 */ | 1247 */ |
1272 if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ | 1248 if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ |
1273 do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); | 1249 do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); |
1274 if( rc!=1 ){ | 1250 if( rc!=1 ){ |
1275 pFile->lastErrno = errno; | 1251 storeLastErrno(pFile, errno); |
1276 return SQLITE_IOERR; | 1252 return SQLITE_IOERR; |
1277 } | 1253 } |
1278 rc = osFstat(fd, &statbuf); | 1254 rc = osFstat(fd, &statbuf); |
1279 if( rc!=0 ){ | 1255 if( rc!=0 ){ |
1280 pFile->lastErrno = errno; | 1256 storeLastErrno(pFile, errno); |
1281 return SQLITE_IOERR; | 1257 return SQLITE_IOERR; |
1282 } | 1258 } |
1283 } | 1259 } |
1284 #endif | 1260 #endif |
1285 | 1261 |
1286 memset(&fileId, 0, sizeof(fileId)); | 1262 memset(&fileId, 0, sizeof(fileId)); |
1287 fileId.dev = statbuf.st_dev; | 1263 fileId.dev = statbuf.st_dev; |
1288 #if OS_VXWORKS | 1264 #if OS_VXWORKS |
1289 fileId.pId = pFile->pId; | 1265 fileId.pId = pFile->pId; |
1290 #else | 1266 #else |
1291 fileId.ino = statbuf.st_ino; | 1267 fileId.ino = statbuf.st_ino; |
1292 #endif | 1268 #endif |
1293 pInode = inodeList; | 1269 pInode = inodeList; |
1294 while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ | 1270 while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ |
1295 pInode = pInode->pNext; | 1271 pInode = pInode->pNext; |
1296 } | 1272 } |
1297 if( pInode==0 ){ | 1273 if( pInode==0 ){ |
1298 pInode = sqlite3_malloc( sizeof(*pInode) ); | 1274 pInode = sqlite3_malloc64( sizeof(*pInode) ); |
1299 if( pInode==0 ){ | 1275 if( pInode==0 ){ |
1300 return SQLITE_NOMEM; | 1276 return SQLITE_NOMEM; |
1301 } | 1277 } |
1302 memset(pInode, 0, sizeof(*pInode)); | 1278 memset(pInode, 0, sizeof(*pInode)); |
1303 memcpy(&pInode->fileId, &fileId, sizeof(fileId)); | 1279 memcpy(&pInode->fileId, &fileId, sizeof(fileId)); |
1304 pInode->nRef = 1; | 1280 pInode->nRef = 1; |
1305 pInode->pNext = inodeList; | 1281 pInode->pNext = inodeList; |
1306 pInode->pPrev = 0; | 1282 pInode->pPrev = 0; |
1307 if( inodeList ) inodeList->pPrev = pInode; | 1283 if( inodeList ) inodeList->pPrev = pInode; |
1308 inodeList = pInode; | 1284 inodeList = pInode; |
(...skipping 23 matching lines...) Expand all Loading... |
1332 ** | 1308 ** |
1333 ** (1) There is exactly one hard link on the file | 1309 ** (1) There is exactly one hard link on the file |
1334 ** (2) The file is not a symbolic link | 1310 ** (2) The file is not a symbolic link |
1335 ** (3) The file has not been renamed or unlinked | 1311 ** (3) The file has not been renamed or unlinked |
1336 ** | 1312 ** |
1337 ** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. | 1313 ** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. |
1338 */ | 1314 */ |
1339 static void verifyDbFile(unixFile *pFile){ | 1315 static void verifyDbFile(unixFile *pFile){ |
1340 struct stat buf; | 1316 struct stat buf; |
1341 int rc; | 1317 int rc; |
1342 if( pFile->ctrlFlags & UNIXFILE_WARNED ){ | |
1343 /* One or more of the following warnings have already been issued. Do not | |
1344 ** repeat them so as not to clutter the error log */ | |
1345 return; | |
1346 } | |
1347 rc = osFstat(pFile->h, &buf); | 1318 rc = osFstat(pFile->h, &buf); |
1348 if( rc!=0 ){ | 1319 if( rc!=0 ){ |
1349 sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); | 1320 sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); |
1350 pFile->ctrlFlags |= UNIXFILE_WARNED; | |
1351 return; | 1321 return; |
1352 } | 1322 } |
1353 if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ | 1323 if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ |
1354 sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); | 1324 sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); |
1355 pFile->ctrlFlags |= UNIXFILE_WARNED; | |
1356 return; | 1325 return; |
1357 } | 1326 } |
1358 if( buf.st_nlink>1 ){ | 1327 if( buf.st_nlink>1 ){ |
1359 sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); | 1328 sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); |
1360 pFile->ctrlFlags |= UNIXFILE_WARNED; | |
1361 return; | 1329 return; |
1362 } | 1330 } |
1363 if( fileHasMoved(pFile) ){ | 1331 if( fileHasMoved(pFile) ){ |
1364 sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); | 1332 sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); |
1365 pFile->ctrlFlags |= UNIXFILE_WARNED; | |
1366 return; | 1333 return; |
1367 } | 1334 } |
1368 } | 1335 } |
1369 | 1336 |
1370 | 1337 |
1371 /* | 1338 /* |
1372 ** This routine checks if there is a RESERVED lock held on the specified | 1339 ** This routine checks if there is a RESERVED lock held on the specified |
1373 ** file by this or any other process. If such a lock is held, set *pResOut | 1340 ** file by this or any other process. If such a lock is held, set *pResOut |
1374 ** to a non-zero value otherwise *pResOut is set to zero. The return value | 1341 ** to a non-zero value otherwise *pResOut is set to zero. The return value |
1375 ** is set to SQLITE_OK unless an I/O error occurs during lock checking. | 1342 ** is set to SQLITE_OK unless an I/O error occurs during lock checking. |
1376 */ | 1343 */ |
1377 static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ | 1344 static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ |
1378 int rc = SQLITE_OK; | 1345 int rc = SQLITE_OK; |
1379 int reserved = 0; | 1346 int reserved = 0; |
1380 unixFile *pFile = (unixFile*)id; | 1347 unixFile *pFile = (unixFile*)id; |
1381 | 1348 |
1382 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); | 1349 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
1383 | 1350 |
1384 assert( pFile ); | 1351 assert( pFile ); |
| 1352 assert( pFile->eFileLock<=SHARED_LOCK ); |
1385 unixEnterMutex(); /* Because pFile->pInode is shared across threads */ | 1353 unixEnterMutex(); /* Because pFile->pInode is shared across threads */ |
1386 | 1354 |
1387 /* Check if a thread in this process holds such a lock */ | 1355 /* Check if a thread in this process holds such a lock */ |
1388 if( pFile->pInode->eFileLock>SHARED_LOCK ){ | 1356 if( pFile->pInode->eFileLock>SHARED_LOCK ){ |
1389 reserved = 1; | 1357 reserved = 1; |
1390 } | 1358 } |
1391 | 1359 |
1392 /* Otherwise see if some other process holds it. | 1360 /* Otherwise see if some other process holds it. |
1393 */ | 1361 */ |
1394 #ifndef __DJGPP__ | 1362 #ifndef __DJGPP__ |
1395 if( !reserved && !pFile->pInode->bProcessLock ){ | 1363 if( !reserved && !pFile->pInode->bProcessLock ){ |
1396 struct flock lock; | 1364 struct flock lock; |
1397 lock.l_whence = SEEK_SET; | 1365 lock.l_whence = SEEK_SET; |
1398 lock.l_start = RESERVED_BYTE; | 1366 lock.l_start = RESERVED_BYTE; |
1399 lock.l_len = 1; | 1367 lock.l_len = 1; |
1400 lock.l_type = F_WRLCK; | 1368 lock.l_type = F_WRLCK; |
1401 if( osFcntl(pFile->h, F_GETLK, &lock) ){ | 1369 if( osFcntl(pFile->h, F_GETLK, &lock) ){ |
1402 rc = SQLITE_IOERR_CHECKRESERVEDLOCK; | 1370 rc = SQLITE_IOERR_CHECKRESERVEDLOCK; |
1403 pFile->lastErrno = errno; | 1371 storeLastErrno(pFile, errno); |
1404 } else if( lock.l_type!=F_UNLCK ){ | 1372 } else if( lock.l_type!=F_UNLCK ){ |
1405 reserved = 1; | 1373 reserved = 1; |
1406 } | 1374 } |
1407 } | 1375 } |
1408 #endif | 1376 #endif |
1409 | 1377 |
1410 unixLeaveMutex(); | 1378 unixLeaveMutex(); |
1411 OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); | 1379 OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); |
1412 | 1380 |
1413 *pResOut = reserved; | 1381 *pResOut = reserved; |
(...skipping 17 matching lines...) Expand all Loading... |
1431 ** and is read-only. | 1399 ** and is read-only. |
1432 ** | 1400 ** |
1433 ** Zero is returned if the call completes successfully, or -1 if a call | 1401 ** Zero is returned if the call completes successfully, or -1 if a call |
1434 ** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). | 1402 ** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). |
1435 */ | 1403 */ |
1436 static int unixFileLock(unixFile *pFile, struct flock *pLock){ | 1404 static int unixFileLock(unixFile *pFile, struct flock *pLock){ |
1437 int rc; | 1405 int rc; |
1438 unixInodeInfo *pInode = pFile->pInode; | 1406 unixInodeInfo *pInode = pFile->pInode; |
1439 assert( unixMutexHeld() ); | 1407 assert( unixMutexHeld() ); |
1440 assert( pInode!=0 ); | 1408 assert( pInode!=0 ); |
1441 if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock) | 1409 if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ |
1442 && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0) | |
1443 ){ | |
1444 if( pInode->bProcessLock==0 ){ | 1410 if( pInode->bProcessLock==0 ){ |
1445 struct flock lock; | 1411 struct flock lock; |
1446 assert( pInode->nLock==0 ); | 1412 assert( pInode->nLock==0 ); |
1447 lock.l_whence = SEEK_SET; | 1413 lock.l_whence = SEEK_SET; |
1448 lock.l_start = SHARED_FIRST; | 1414 lock.l_start = SHARED_FIRST; |
1449 lock.l_len = SHARED_SIZE; | 1415 lock.l_len = SHARED_SIZE; |
1450 lock.l_type = F_WRLCK; | 1416 lock.l_type = F_WRLCK; |
1451 rc = osFcntl(pFile->h, F_SETLK, &lock); | 1417 rc = osFcntl(pFile->h, F_SETLK, &lock); |
1452 if( rc<0 ) return rc; | 1418 if( rc<0 ) return rc; |
1453 pInode->bProcessLock = 1; | 1419 pInode->bProcessLock = 1; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1526 */ | 1492 */ |
1527 int rc = SQLITE_OK; | 1493 int rc = SQLITE_OK; |
1528 unixFile *pFile = (unixFile*)id; | 1494 unixFile *pFile = (unixFile*)id; |
1529 unixInodeInfo *pInode; | 1495 unixInodeInfo *pInode; |
1530 struct flock lock; | 1496 struct flock lock; |
1531 int tErrno = 0; | 1497 int tErrno = 0; |
1532 | 1498 |
1533 assert( pFile ); | 1499 assert( pFile ); |
1534 OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, | 1500 OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, |
1535 azFileLock(eFileLock), azFileLock(pFile->eFileLock), | 1501 azFileLock(eFileLock), azFileLock(pFile->eFileLock), |
1536 azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid())); | 1502 azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared, |
| 1503 osGetpid(0))); |
1537 | 1504 |
1538 /* If there is already a lock of this type or more restrictive on the | 1505 /* If there is already a lock of this type or more restrictive on the |
1539 ** unixFile, do nothing. Don't use the end_lock: exit path, as | 1506 ** unixFile, do nothing. Don't use the end_lock: exit path, as |
1540 ** unixEnterMutex() hasn't been called yet. | 1507 ** unixEnterMutex() hasn't been called yet. |
1541 */ | 1508 */ |
1542 if( pFile->eFileLock>=eFileLock ){ | 1509 if( pFile->eFileLock>=eFileLock ){ |
1543 OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, | 1510 OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, |
1544 azFileLock(eFileLock))); | 1511 azFileLock(eFileLock))); |
1545 return SQLITE_OK; | 1512 return SQLITE_OK; |
1546 } | 1513 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 lock.l_whence = SEEK_SET; | 1560 lock.l_whence = SEEK_SET; |
1594 if( eFileLock==SHARED_LOCK | 1561 if( eFileLock==SHARED_LOCK |
1595 || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) | 1562 || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) |
1596 ){ | 1563 ){ |
1597 lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); | 1564 lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); |
1598 lock.l_start = PENDING_BYTE; | 1565 lock.l_start = PENDING_BYTE; |
1599 if( unixFileLock(pFile, &lock) ){ | 1566 if( unixFileLock(pFile, &lock) ){ |
1600 tErrno = errno; | 1567 tErrno = errno; |
1601 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); | 1568 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); |
1602 if( rc!=SQLITE_BUSY ){ | 1569 if( rc!=SQLITE_BUSY ){ |
1603 pFile->lastErrno = tErrno; | 1570 storeLastErrno(pFile, tErrno); |
1604 } | 1571 } |
1605 goto end_lock; | 1572 goto end_lock; |
1606 } | 1573 } |
1607 } | 1574 } |
1608 | 1575 |
1609 | 1576 |
1610 /* If control gets to this point, then actually go ahead and make | 1577 /* If control gets to this point, then actually go ahead and make |
1611 ** operating system calls for the specified lock. | 1578 ** operating system calls for the specified lock. |
1612 */ | 1579 */ |
1613 if( eFileLock==SHARED_LOCK ){ | 1580 if( eFileLock==SHARED_LOCK ){ |
(...skipping 14 matching lines...) Expand all Loading... |
1628 lock.l_len = 1L; | 1595 lock.l_len = 1L; |
1629 lock.l_type = F_UNLCK; | 1596 lock.l_type = F_UNLCK; |
1630 if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ | 1597 if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ |
1631 /* This could happen with a network mount */ | 1598 /* This could happen with a network mount */ |
1632 tErrno = errno; | 1599 tErrno = errno; |
1633 rc = SQLITE_IOERR_UNLOCK; | 1600 rc = SQLITE_IOERR_UNLOCK; |
1634 } | 1601 } |
1635 | 1602 |
1636 if( rc ){ | 1603 if( rc ){ |
1637 if( rc!=SQLITE_BUSY ){ | 1604 if( rc!=SQLITE_BUSY ){ |
1638 pFile->lastErrno = tErrno; | 1605 storeLastErrno(pFile, tErrno); |
1639 } | 1606 } |
1640 goto end_lock; | 1607 goto end_lock; |
1641 }else{ | 1608 }else{ |
1642 pFile->eFileLock = SHARED_LOCK; | 1609 pFile->eFileLock = SHARED_LOCK; |
1643 pInode->nLock++; | 1610 pInode->nLock++; |
1644 pInode->nShared = 1; | 1611 pInode->nShared = 1; |
1645 } | 1612 } |
1646 }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ | 1613 }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ |
1647 /* We are trying for an exclusive lock but another thread in this | 1614 /* We are trying for an exclusive lock but another thread in this |
1648 ** same process is still holding a shared lock. */ | 1615 ** same process is still holding a shared lock. */ |
(...skipping 12 matching lines...) Expand all Loading... |
1661 lock.l_len = 1L; | 1628 lock.l_len = 1L; |
1662 }else{ | 1629 }else{ |
1663 lock.l_start = SHARED_FIRST; | 1630 lock.l_start = SHARED_FIRST; |
1664 lock.l_len = SHARED_SIZE; | 1631 lock.l_len = SHARED_SIZE; |
1665 } | 1632 } |
1666 | 1633 |
1667 if( unixFileLock(pFile, &lock) ){ | 1634 if( unixFileLock(pFile, &lock) ){ |
1668 tErrno = errno; | 1635 tErrno = errno; |
1669 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); | 1636 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); |
1670 if( rc!=SQLITE_BUSY ){ | 1637 if( rc!=SQLITE_BUSY ){ |
1671 pFile->lastErrno = tErrno; | 1638 storeLastErrno(pFile, tErrno); |
1672 } | 1639 } |
1673 } | 1640 } |
1674 } | 1641 } |
1675 | 1642 |
1676 | 1643 |
1677 #ifdef SQLITE_DEBUG | 1644 #ifdef SQLITE_DEBUG |
1678 /* Set up the transaction-counter change checking flags when | 1645 /* Set up the transaction-counter change checking flags when |
1679 ** transitioning from a SHARED to a RESERVED lock. The change | 1646 ** transitioning from a SHARED to a RESERVED lock. The change |
1680 ** from SHARED to RESERVED marks the beginning of a normal | 1647 ** from SHARED to RESERVED marks the beginning of a normal |
1681 ** write operation (not a hot journal rollback). | 1648 ** write operation (not a hot journal rollback). |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1734 */ | 1701 */ |
1735 static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ | 1702 static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ |
1736 unixFile *pFile = (unixFile*)id; | 1703 unixFile *pFile = (unixFile*)id; |
1737 unixInodeInfo *pInode; | 1704 unixInodeInfo *pInode; |
1738 struct flock lock; | 1705 struct flock lock; |
1739 int rc = SQLITE_OK; | 1706 int rc = SQLITE_OK; |
1740 | 1707 |
1741 assert( pFile ); | 1708 assert( pFile ); |
1742 OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, | 1709 OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, |
1743 pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, | 1710 pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, |
1744 getpid())); | 1711 osGetpid(0))); |
1745 | 1712 |
1746 assert( eFileLock<=SHARED_LOCK ); | 1713 assert( eFileLock<=SHARED_LOCK ); |
1747 if( pFile->eFileLock<=eFileLock ){ | 1714 if( pFile->eFileLock<=eFileLock ){ |
1748 return SQLITE_OK; | 1715 return SQLITE_OK; |
1749 } | 1716 } |
1750 unixEnterMutex(); | 1717 unixEnterMutex(); |
1751 pInode = pFile->pInode; | 1718 pInode = pFile->pInode; |
1752 assert( pInode->nShared!=0 ); | 1719 assert( pInode->nShared!=0 ); |
1753 if( pFile->eFileLock>SHARED_LOCK ){ | 1720 if( pFile->eFileLock>SHARED_LOCK ){ |
1754 assert( pInode->eFileLock==pFile->eFileLock ); | 1721 assert( pInode->eFileLock==pFile->eFileLock ); |
(...skipping 13 matching lines...) Expand all Loading... |
1768 /* downgrading to a shared lock on NFS involves clearing the write lock | 1735 /* downgrading to a shared lock on NFS involves clearing the write lock |
1769 ** before establishing the readlock - to avoid a race condition we downgrade | 1736 ** before establishing the readlock - to avoid a race condition we downgrade |
1770 ** the lock in 2 blocks, so that part of the range will be covered by a | 1737 ** the lock in 2 blocks, so that part of the range will be covered by a |
1771 ** write lock until the rest is covered by a read lock: | 1738 ** write lock until the rest is covered by a read lock: |
1772 ** 1: [WWWWW] | 1739 ** 1: [WWWWW] |
1773 ** 2: [....W] | 1740 ** 2: [....W] |
1774 ** 3: [RRRRW] | 1741 ** 3: [RRRRW] |
1775 ** 4: [RRRR.] | 1742 ** 4: [RRRR.] |
1776 */ | 1743 */ |
1777 if( eFileLock==SHARED_LOCK ){ | 1744 if( eFileLock==SHARED_LOCK ){ |
1778 | |
1779 #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE | 1745 #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE |
1780 (void)handleNFSUnlock; | 1746 (void)handleNFSUnlock; |
1781 assert( handleNFSUnlock==0 ); | 1747 assert( handleNFSUnlock==0 ); |
1782 #endif | 1748 #endif |
1783 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE | 1749 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
1784 if( handleNFSUnlock ){ | 1750 if( handleNFSUnlock ){ |
1785 int tErrno; /* Error code from system call errors */ | 1751 int tErrno; /* Error code from system call errors */ |
1786 off_t divSize = SHARED_SIZE - 1; | 1752 off_t divSize = SHARED_SIZE - 1; |
1787 | 1753 |
1788 lock.l_type = F_UNLCK; | 1754 lock.l_type = F_UNLCK; |
1789 lock.l_whence = SEEK_SET; | 1755 lock.l_whence = SEEK_SET; |
1790 lock.l_start = SHARED_FIRST; | 1756 lock.l_start = SHARED_FIRST; |
1791 lock.l_len = divSize; | 1757 lock.l_len = divSize; |
1792 if( unixFileLock(pFile, &lock)==(-1) ){ | 1758 if( unixFileLock(pFile, &lock)==(-1) ){ |
1793 tErrno = errno; | 1759 tErrno = errno; |
1794 rc = SQLITE_IOERR_UNLOCK; | 1760 rc = SQLITE_IOERR_UNLOCK; |
1795 if( IS_LOCK_ERROR(rc) ){ | 1761 storeLastErrno(pFile, tErrno); |
1796 pFile->lastErrno = tErrno; | |
1797 } | |
1798 goto end_unlock; | 1762 goto end_unlock; |
1799 } | 1763 } |
1800 lock.l_type = F_RDLCK; | 1764 lock.l_type = F_RDLCK; |
1801 lock.l_whence = SEEK_SET; | 1765 lock.l_whence = SEEK_SET; |
1802 lock.l_start = SHARED_FIRST; | 1766 lock.l_start = SHARED_FIRST; |
1803 lock.l_len = divSize; | 1767 lock.l_len = divSize; |
1804 if( unixFileLock(pFile, &lock)==(-1) ){ | 1768 if( unixFileLock(pFile, &lock)==(-1) ){ |
1805 tErrno = errno; | 1769 tErrno = errno; |
1806 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); | 1770 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); |
1807 if( IS_LOCK_ERROR(rc) ){ | 1771 if( IS_LOCK_ERROR(rc) ){ |
1808 pFile->lastErrno = tErrno; | 1772 storeLastErrno(pFile, tErrno); |
1809 } | 1773 } |
1810 goto end_unlock; | 1774 goto end_unlock; |
1811 } | 1775 } |
1812 lock.l_type = F_UNLCK; | 1776 lock.l_type = F_UNLCK; |
1813 lock.l_whence = SEEK_SET; | 1777 lock.l_whence = SEEK_SET; |
1814 lock.l_start = SHARED_FIRST+divSize; | 1778 lock.l_start = SHARED_FIRST+divSize; |
1815 lock.l_len = SHARED_SIZE-divSize; | 1779 lock.l_len = SHARED_SIZE-divSize; |
1816 if( unixFileLock(pFile, &lock)==(-1) ){ | 1780 if( unixFileLock(pFile, &lock)==(-1) ){ |
1817 tErrno = errno; | 1781 tErrno = errno; |
1818 rc = SQLITE_IOERR_UNLOCK; | 1782 rc = SQLITE_IOERR_UNLOCK; |
1819 if( IS_LOCK_ERROR(rc) ){ | 1783 storeLastErrno(pFile, tErrno); |
1820 pFile->lastErrno = tErrno; | |
1821 } | |
1822 goto end_unlock; | 1784 goto end_unlock; |
1823 } | 1785 } |
1824 }else | 1786 }else |
1825 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ | 1787 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ |
1826 { | 1788 { |
1827 lock.l_type = F_RDLCK; | 1789 lock.l_type = F_RDLCK; |
1828 lock.l_whence = SEEK_SET; | 1790 lock.l_whence = SEEK_SET; |
1829 lock.l_start = SHARED_FIRST; | 1791 lock.l_start = SHARED_FIRST; |
1830 lock.l_len = SHARED_SIZE; | 1792 lock.l_len = SHARED_SIZE; |
1831 if( unixFileLock(pFile, &lock) ){ | 1793 if( unixFileLock(pFile, &lock) ){ |
1832 /* In theory, the call to unixFileLock() cannot fail because another | 1794 /* In theory, the call to unixFileLock() cannot fail because another |
1833 ** process is holding an incompatible lock. If it does, this | 1795 ** process is holding an incompatible lock. If it does, this |
1834 ** indicates that the other process is not following the locking | 1796 ** indicates that the other process is not following the locking |
1835 ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning | 1797 ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning |
1836 ** SQLITE_BUSY would confuse the upper layer (in practice it causes | 1798 ** SQLITE_BUSY would confuse the upper layer (in practice it causes |
1837 ** an assert to fail). */ | 1799 ** an assert to fail). */ |
1838 rc = SQLITE_IOERR_RDLOCK; | 1800 rc = SQLITE_IOERR_RDLOCK; |
1839 pFile->lastErrno = errno; | 1801 storeLastErrno(pFile, errno); |
1840 goto end_unlock; | 1802 goto end_unlock; |
1841 } | 1803 } |
1842 } | 1804 } |
1843 } | 1805 } |
1844 lock.l_type = F_UNLCK; | 1806 lock.l_type = F_UNLCK; |
1845 lock.l_whence = SEEK_SET; | 1807 lock.l_whence = SEEK_SET; |
1846 lock.l_start = PENDING_BYTE; | 1808 lock.l_start = PENDING_BYTE; |
1847 lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); | 1809 lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); |
1848 if( unixFileLock(pFile, &lock)==0 ){ | 1810 if( unixFileLock(pFile, &lock)==0 ){ |
1849 pInode->eFileLock = SHARED_LOCK; | 1811 pInode->eFileLock = SHARED_LOCK; |
1850 }else{ | 1812 }else{ |
1851 rc = SQLITE_IOERR_UNLOCK; | 1813 rc = SQLITE_IOERR_UNLOCK; |
1852 pFile->lastErrno = errno; | 1814 storeLastErrno(pFile, errno); |
1853 goto end_unlock; | 1815 goto end_unlock; |
1854 } | 1816 } |
1855 } | 1817 } |
1856 if( eFileLock==NO_LOCK ){ | 1818 if( eFileLock==NO_LOCK ){ |
1857 /* Decrement the shared lock counter. Release the lock using an | 1819 /* Decrement the shared lock counter. Release the lock using an |
1858 ** OS call only when all threads in this same process have released | 1820 ** OS call only when all threads in this same process have released |
1859 ** the lock. | 1821 ** the lock. |
1860 */ | 1822 */ |
1861 pInode->nShared--; | 1823 pInode->nShared--; |
1862 if( pInode->nShared==0 ){ | 1824 if( pInode->nShared==0 ){ |
1863 lock.l_type = F_UNLCK; | 1825 lock.l_type = F_UNLCK; |
1864 lock.l_whence = SEEK_SET; | 1826 lock.l_whence = SEEK_SET; |
1865 lock.l_start = lock.l_len = 0L; | 1827 lock.l_start = lock.l_len = 0L; |
1866 if( unixFileLock(pFile, &lock)==0 ){ | 1828 if( unixFileLock(pFile, &lock)==0 ){ |
1867 pInode->eFileLock = NO_LOCK; | 1829 pInode->eFileLock = NO_LOCK; |
1868 }else{ | 1830 }else{ |
1869 rc = SQLITE_IOERR_UNLOCK; | 1831 rc = SQLITE_IOERR_UNLOCK; |
1870 pFile->lastErrno = errno; | 1832 storeLastErrno(pFile, errno); |
1871 pInode->eFileLock = NO_LOCK; | 1833 pInode->eFileLock = NO_LOCK; |
1872 pFile->eFileLock = NO_LOCK; | 1834 pFile->eFileLock = NO_LOCK; |
1873 } | 1835 } |
1874 } | 1836 } |
1875 | 1837 |
1876 /* Decrement the count of locks against this same file. When the | 1838 /* Decrement the count of locks against this same file. When the |
1877 ** count reaches zero, close any other file descriptors whose close | 1839 ** count reaches zero, close any other file descriptors whose close |
1878 ** was deferred because of outstanding locks. | 1840 ** was deferred because of outstanding locks. |
1879 */ | 1841 */ |
1880 pInode->nLock--; | 1842 pInode->nLock--; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2062 ** is held on the file and false if the file is unlocked. | 2024 ** is held on the file and false if the file is unlocked. |
2063 */ | 2025 */ |
2064 static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { | 2026 static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { |
2065 int rc = SQLITE_OK; | 2027 int rc = SQLITE_OK; |
2066 int reserved = 0; | 2028 int reserved = 0; |
2067 unixFile *pFile = (unixFile*)id; | 2029 unixFile *pFile = (unixFile*)id; |
2068 | 2030 |
2069 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); | 2031 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
2070 | 2032 |
2071 assert( pFile ); | 2033 assert( pFile ); |
2072 | 2034 reserved = osAccess((const char*)pFile->lockingContext, 0)==0; |
2073 /* Check if a thread in this process holds such a lock */ | |
2074 if( pFile->eFileLock>SHARED_LOCK ){ | |
2075 /* Either this connection or some other connection in the same process | |
2076 ** holds a lock on the file. No need to check further. */ | |
2077 reserved = 1; | |
2078 }else{ | |
2079 /* The lock is held if and only if the lockfile exists */ | |
2080 const char *zLockFile = (const char*)pFile->lockingContext; | |
2081 reserved = osAccess(zLockFile, 0)==0; | |
2082 } | |
2083 OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); | 2035 OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); |
2084 *pResOut = reserved; | 2036 *pResOut = reserved; |
2085 return rc; | 2037 return rc; |
2086 } | 2038 } |
2087 | 2039 |
2088 /* | 2040 /* |
2089 ** Lock the file with the lock specified by parameter eFileLock - one | 2041 ** Lock the file with the lock specified by parameter eFileLock - one |
2090 ** of the following: | 2042 ** of the following: |
2091 ** | 2043 ** |
2092 ** (1) SHARED_LOCK | 2044 ** (1) SHARED_LOCK |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2134 | 2086 |
2135 /* grab an exclusive lock */ | 2087 /* grab an exclusive lock */ |
2136 rc = osMkdir(zLockFile, 0777); | 2088 rc = osMkdir(zLockFile, 0777); |
2137 if( rc<0 ){ | 2089 if( rc<0 ){ |
2138 /* failed to open/create the lock directory */ | 2090 /* failed to open/create the lock directory */ |
2139 int tErrno = errno; | 2091 int tErrno = errno; |
2140 if( EEXIST == tErrno ){ | 2092 if( EEXIST == tErrno ){ |
2141 rc = SQLITE_BUSY; | 2093 rc = SQLITE_BUSY; |
2142 } else { | 2094 } else { |
2143 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); | 2095 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); |
2144 if( IS_LOCK_ERROR(rc) ){ | 2096 if( rc!=SQLITE_BUSY ){ |
2145 pFile->lastErrno = tErrno; | 2097 storeLastErrno(pFile, tErrno); |
2146 } | 2098 } |
2147 } | 2099 } |
2148 return rc; | 2100 return rc; |
2149 } | 2101 } |
2150 | 2102 |
2151 /* got it, set the type and return ok */ | 2103 /* got it, set the type and return ok */ |
2152 pFile->eFileLock = eFileLock; | 2104 pFile->eFileLock = eFileLock; |
2153 return rc; | 2105 return rc; |
2154 } | 2106 } |
2155 | 2107 |
2156 /* | 2108 /* |
2157 ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock | 2109 ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock |
2158 ** must be either NO_LOCK or SHARED_LOCK. | 2110 ** must be either NO_LOCK or SHARED_LOCK. |
2159 ** | 2111 ** |
2160 ** If the locking level of the file descriptor is already at or below | 2112 ** If the locking level of the file descriptor is already at or below |
2161 ** the requested locking level, this routine is a no-op. | 2113 ** the requested locking level, this routine is a no-op. |
2162 ** | 2114 ** |
2163 ** When the locking level reaches NO_LOCK, delete the lock file. | 2115 ** When the locking level reaches NO_LOCK, delete the lock file. |
2164 */ | 2116 */ |
2165 static int dotlockUnlock(sqlite3_file *id, int eFileLock) { | 2117 static int dotlockUnlock(sqlite3_file *id, int eFileLock) { |
2166 unixFile *pFile = (unixFile*)id; | 2118 unixFile *pFile = (unixFile*)id; |
2167 char *zLockFile = (char *)pFile->lockingContext; | 2119 char *zLockFile = (char *)pFile->lockingContext; |
2168 int rc; | 2120 int rc; |
2169 | 2121 |
2170 assert( pFile ); | 2122 assert( pFile ); |
2171 OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, | 2123 OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, |
2172 pFile->eFileLock, getpid())); | 2124 pFile->eFileLock, osGetpid(0))); |
2173 assert( eFileLock<=SHARED_LOCK ); | 2125 assert( eFileLock<=SHARED_LOCK ); |
2174 | 2126 |
2175 /* no-op if possible */ | 2127 /* no-op if possible */ |
2176 if( pFile->eFileLock==eFileLock ){ | 2128 if( pFile->eFileLock==eFileLock ){ |
2177 return SQLITE_OK; | 2129 return SQLITE_OK; |
2178 } | 2130 } |
2179 | 2131 |
2180 /* To downgrade to shared, simply update our internal notion of the | 2132 /* To downgrade to shared, simply update our internal notion of the |
2181 ** lock state. No need to mess with the file on disk. | 2133 ** lock state. No need to mess with the file on disk. |
2182 */ | 2134 */ |
2183 if( eFileLock==SHARED_LOCK ){ | 2135 if( eFileLock==SHARED_LOCK ){ |
2184 pFile->eFileLock = SHARED_LOCK; | 2136 pFile->eFileLock = SHARED_LOCK; |
2185 return SQLITE_OK; | 2137 return SQLITE_OK; |
2186 } | 2138 } |
2187 | 2139 |
2188 /* To fully unlock the database, delete the lock file */ | 2140 /* To fully unlock the database, delete the lock file */ |
2189 assert( eFileLock==NO_LOCK ); | 2141 assert( eFileLock==NO_LOCK ); |
2190 rc = osRmdir(zLockFile); | 2142 rc = osRmdir(zLockFile); |
2191 if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile); | |
2192 if( rc<0 ){ | 2143 if( rc<0 ){ |
2193 int tErrno = errno; | 2144 int tErrno = errno; |
2194 rc = 0; | 2145 if( tErrno==ENOENT ){ |
2195 if( ENOENT != tErrno ){ | 2146 rc = SQLITE_OK; |
| 2147 }else{ |
2196 rc = SQLITE_IOERR_UNLOCK; | 2148 rc = SQLITE_IOERR_UNLOCK; |
2197 } | 2149 storeLastErrno(pFile, tErrno); |
2198 if( IS_LOCK_ERROR(rc) ){ | |
2199 pFile->lastErrno = tErrno; | |
2200 } | 2150 } |
2201 return rc; | 2151 return rc; |
2202 } | 2152 } |
2203 pFile->eFileLock = NO_LOCK; | 2153 pFile->eFileLock = NO_LOCK; |
2204 return SQLITE_OK; | 2154 return SQLITE_OK; |
2205 } | 2155 } |
2206 | 2156 |
2207 /* | 2157 /* |
2208 ** Close a file. Make sure the lock has been released before closing. | 2158 ** Close a file. Make sure the lock has been released before closing. |
2209 */ | 2159 */ |
2210 static int dotlockClose(sqlite3_file *id) { | 2160 static int dotlockClose(sqlite3_file *id) { |
2211 int rc = SQLITE_OK; | 2161 unixFile *pFile = (unixFile*)id; |
2212 if( id ){ | 2162 assert( id!=0 ); |
2213 unixFile *pFile = (unixFile*)id; | 2163 dotlockUnlock(id, NO_LOCK); |
2214 dotlockUnlock(id, NO_LOCK); | 2164 sqlite3_free(pFile->lockingContext); |
2215 sqlite3_free(pFile->lockingContext); | 2165 return closeUnixFile(id); |
2216 rc = closeUnixFile(id); | |
2217 } | |
2218 return rc; | |
2219 } | 2166 } |
2220 /****************** End of the dot-file lock implementation ******************* | 2167 /****************** End of the dot-file lock implementation ******************* |
2221 ******************************************************************************/ | 2168 ******************************************************************************/ |
2222 | 2169 |
2223 /****************************************************************************** | 2170 /****************************************************************************** |
2224 ************************** Begin flock Locking ******************************** | 2171 ************************** Begin flock Locking ******************************** |
2225 ** | 2172 ** |
2226 ** Use the flock() system call to do file locking. | 2173 ** Use the flock() system call to do file locking. |
2227 ** | 2174 ** |
2228 ** flock() locking is like dot-file locking in that the various | 2175 ** flock() locking is like dot-file locking in that the various |
2229 ** fine-grain locking levels supported by SQLite are collapsed into | 2176 ** fine-grain locking levels supported by SQLite are collapsed into |
2230 ** a single exclusive lock. In other words, SHARED, RESERVED, and | 2177 ** a single exclusive lock. In other words, SHARED, RESERVED, and |
2231 ** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite | 2178 ** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite |
2232 ** still works when you do this, but concurrency is reduced since | 2179 ** still works when you do this, but concurrency is reduced since |
2233 ** only a single process can be reading the database at a time. | 2180 ** only a single process can be reading the database at a time. |
2234 ** | 2181 ** |
2235 ** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if | 2182 ** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off |
2236 ** compiling for VXWORKS. | |
2237 */ | 2183 */ |
2238 #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS | 2184 #if SQLITE_ENABLE_LOCKING_STYLE |
2239 | 2185 |
2240 /* | 2186 /* |
2241 ** Retry flock() calls that fail with EINTR | 2187 ** Retry flock() calls that fail with EINTR |
2242 */ | 2188 */ |
2243 #ifdef EINTR | 2189 #ifdef EINTR |
2244 static int robust_flock(int fd, int op){ | 2190 static int robust_flock(int fd, int op){ |
2245 int rc; | 2191 int rc; |
2246 do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); | 2192 do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); |
2247 return rc; | 2193 return rc; |
2248 } | 2194 } |
(...skipping 26 matching lines...) Expand all Loading... |
2275 if( !reserved ){ | 2221 if( !reserved ){ |
2276 /* attempt to get the lock */ | 2222 /* attempt to get the lock */ |
2277 int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); | 2223 int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); |
2278 if( !lrc ){ | 2224 if( !lrc ){ |
2279 /* got the lock, unlock it */ | 2225 /* got the lock, unlock it */ |
2280 lrc = robust_flock(pFile->h, LOCK_UN); | 2226 lrc = robust_flock(pFile->h, LOCK_UN); |
2281 if ( lrc ) { | 2227 if ( lrc ) { |
2282 int tErrno = errno; | 2228 int tErrno = errno; |
2283 /* unlock failed with an error */ | 2229 /* unlock failed with an error */ |
2284 lrc = SQLITE_IOERR_UNLOCK; | 2230 lrc = SQLITE_IOERR_UNLOCK; |
2285 if( IS_LOCK_ERROR(lrc) ){ | 2231 storeLastErrno(pFile, tErrno); |
2286 pFile->lastErrno = tErrno; | 2232 rc = lrc; |
2287 rc = lrc; | |
2288 } | |
2289 } | 2233 } |
2290 } else { | 2234 } else { |
2291 int tErrno = errno; | 2235 int tErrno = errno; |
2292 reserved = 1; | 2236 reserved = 1; |
2293 /* someone else might have it reserved */ | 2237 /* someone else might have it reserved */ |
2294 lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); | 2238 lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); |
2295 if( IS_LOCK_ERROR(lrc) ){ | 2239 if( IS_LOCK_ERROR(lrc) ){ |
2296 pFile->lastErrno = tErrno; | 2240 storeLastErrno(pFile, tErrno); |
2297 rc = lrc; | 2241 rc = lrc; |
2298 } | 2242 } |
2299 } | 2243 } |
2300 } | 2244 } |
2301 OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); | 2245 OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); |
2302 | 2246 |
2303 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS | 2247 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS |
2304 if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ | 2248 if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ |
2305 rc = SQLITE_OK; | 2249 rc = SQLITE_OK; |
2306 reserved=1; | 2250 reserved=1; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2352 return SQLITE_OK; | 2296 return SQLITE_OK; |
2353 } | 2297 } |
2354 | 2298 |
2355 /* grab an exclusive lock */ | 2299 /* grab an exclusive lock */ |
2356 | 2300 |
2357 if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { | 2301 if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { |
2358 int tErrno = errno; | 2302 int tErrno = errno; |
2359 /* didn't get, must be busy */ | 2303 /* didn't get, must be busy */ |
2360 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); | 2304 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); |
2361 if( IS_LOCK_ERROR(rc) ){ | 2305 if( IS_LOCK_ERROR(rc) ){ |
2362 pFile->lastErrno = tErrno; | 2306 storeLastErrno(pFile, tErrno); |
2363 } | 2307 } |
2364 } else { | 2308 } else { |
2365 /* got it, set the type and return ok */ | 2309 /* got it, set the type and return ok */ |
2366 pFile->eFileLock = eFileLock; | 2310 pFile->eFileLock = eFileLock; |
2367 } | 2311 } |
2368 OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), | 2312 OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), |
2369 rc==SQLITE_OK ? "ok" : "failed")); | 2313 rc==SQLITE_OK ? "ok" : "failed")); |
2370 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS | 2314 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS |
2371 if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ | 2315 if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ |
2372 rc = SQLITE_BUSY; | 2316 rc = SQLITE_BUSY; |
2373 } | 2317 } |
2374 #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ | 2318 #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ |
2375 return rc; | 2319 return rc; |
2376 } | 2320 } |
2377 | 2321 |
2378 | 2322 |
2379 /* | 2323 /* |
2380 ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock | 2324 ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock |
2381 ** must be either NO_LOCK or SHARED_LOCK. | 2325 ** must be either NO_LOCK or SHARED_LOCK. |
2382 ** | 2326 ** |
2383 ** If the locking level of the file descriptor is already at or below | 2327 ** If the locking level of the file descriptor is already at or below |
2384 ** the requested locking level, this routine is a no-op. | 2328 ** the requested locking level, this routine is a no-op. |
2385 */ | 2329 */ |
2386 static int flockUnlock(sqlite3_file *id, int eFileLock) { | 2330 static int flockUnlock(sqlite3_file *id, int eFileLock) { |
2387 unixFile *pFile = (unixFile*)id; | 2331 unixFile *pFile = (unixFile*)id; |
2388 | 2332 |
2389 assert( pFile ); | 2333 assert( pFile ); |
2390 OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, | 2334 OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, |
2391 pFile->eFileLock, getpid())); | 2335 pFile->eFileLock, osGetpid(0))); |
2392 assert( eFileLock<=SHARED_LOCK ); | 2336 assert( eFileLock<=SHARED_LOCK ); |
2393 | 2337 |
2394 /* no-op if possible */ | 2338 /* no-op if possible */ |
2395 if( pFile->eFileLock==eFileLock ){ | 2339 if( pFile->eFileLock==eFileLock ){ |
2396 return SQLITE_OK; | 2340 return SQLITE_OK; |
2397 } | 2341 } |
2398 | 2342 |
2399 /* shared can just be set because we always have an exclusive */ | 2343 /* shared can just be set because we always have an exclusive */ |
2400 if (eFileLock==SHARED_LOCK) { | 2344 if (eFileLock==SHARED_LOCK) { |
2401 pFile->eFileLock = eFileLock; | 2345 pFile->eFileLock = eFileLock; |
2402 return SQLITE_OK; | 2346 return SQLITE_OK; |
2403 } | 2347 } |
2404 | 2348 |
2405 /* no, really, unlock. */ | 2349 /* no, really, unlock. */ |
2406 if( robust_flock(pFile->h, LOCK_UN) ){ | 2350 if( robust_flock(pFile->h, LOCK_UN) ){ |
2407 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS | 2351 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS |
2408 return SQLITE_OK; | 2352 return SQLITE_OK; |
2409 #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ | 2353 #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ |
2410 return SQLITE_IOERR_UNLOCK; | 2354 return SQLITE_IOERR_UNLOCK; |
2411 }else{ | 2355 }else{ |
2412 pFile->eFileLock = NO_LOCK; | 2356 pFile->eFileLock = NO_LOCK; |
2413 return SQLITE_OK; | 2357 return SQLITE_OK; |
2414 } | 2358 } |
2415 } | 2359 } |
2416 | 2360 |
2417 /* | 2361 /* |
2418 ** Close a file. | 2362 ** Close a file. |
2419 */ | 2363 */ |
2420 static int flockClose(sqlite3_file *id) { | 2364 static int flockClose(sqlite3_file *id) { |
2421 int rc = SQLITE_OK; | 2365 assert( id!=0 ); |
2422 if( id ){ | 2366 flockUnlock(id, NO_LOCK); |
2423 flockUnlock(id, NO_LOCK); | 2367 return closeUnixFile(id); |
2424 rc = closeUnixFile(id); | |
2425 } | |
2426 return rc; | |
2427 } | 2368 } |
2428 | 2369 |
2429 #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ | 2370 #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ |
2430 | 2371 |
2431 /******************* End of the flock lock implementation ********************* | 2372 /******************* End of the flock lock implementation ********************* |
2432 ******************************************************************************/ | 2373 ******************************************************************************/ |
2433 | 2374 |
2434 /****************************************************************************** | 2375 /****************************************************************************** |
2435 ************************ Begin Named Semaphore Locking ************************ | 2376 ************************ Begin Named Semaphore Locking ************************ |
2436 ** | 2377 ** |
2437 ** Named semaphore locking is only supported on VxWorks. | 2378 ** Named semaphore locking is only supported on VxWorks. |
2438 ** | 2379 ** |
2439 ** Semaphore locking is like dot-lock and flock in that it really only | 2380 ** Semaphore locking is like dot-lock and flock in that it really only |
2440 ** supports EXCLUSIVE locking. Only a single process can read or write | 2381 ** supports EXCLUSIVE locking. Only a single process can read or write |
2441 ** the database file at a time. This reduces potential concurrency, but | 2382 ** the database file at a time. This reduces potential concurrency, but |
2442 ** makes the lock implementation much easier. | 2383 ** makes the lock implementation much easier. |
2443 */ | 2384 */ |
2444 #if OS_VXWORKS | 2385 #if OS_VXWORKS |
2445 | 2386 |
2446 /* | 2387 /* |
2447 ** This routine checks if there is a RESERVED lock held on the specified | 2388 ** This routine checks if there is a RESERVED lock held on the specified |
2448 ** file by this or any other process. If such a lock is held, set *pResOut | 2389 ** file by this or any other process. If such a lock is held, set *pResOut |
2449 ** to a non-zero value otherwise *pResOut is set to zero. The return value | 2390 ** to a non-zero value otherwise *pResOut is set to zero. The return value |
2450 ** is set to SQLITE_OK unless an I/O error occurs during lock checking. | 2391 ** is set to SQLITE_OK unless an I/O error occurs during lock checking. |
2451 */ | 2392 */ |
2452 static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { | 2393 static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { |
2453 int rc = SQLITE_OK; | 2394 int rc = SQLITE_OK; |
2454 int reserved = 0; | 2395 int reserved = 0; |
2455 unixFile *pFile = (unixFile*)id; | 2396 unixFile *pFile = (unixFile*)id; |
2456 | 2397 |
2457 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); | 2398 SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
2458 | 2399 |
2459 assert( pFile ); | 2400 assert( pFile ); |
2460 | 2401 |
2461 /* Check if a thread in this process holds such a lock */ | 2402 /* Check if a thread in this process holds such a lock */ |
2462 if( pFile->eFileLock>SHARED_LOCK ){ | 2403 if( pFile->eFileLock>SHARED_LOCK ){ |
2463 reserved = 1; | 2404 reserved = 1; |
2464 } | 2405 } |
2465 | 2406 |
2466 /* Otherwise see if some other process holds it. */ | 2407 /* Otherwise see if some other process holds it. */ |
2467 if( !reserved ){ | 2408 if( !reserved ){ |
2468 sem_t *pSem = pFile->pInode->pSem; | 2409 sem_t *pSem = pFile->pInode->pSem; |
2469 | 2410 |
2470 if( sem_trywait(pSem)==-1 ){ | 2411 if( sem_trywait(pSem)==-1 ){ |
2471 int tErrno = errno; | 2412 int tErrno = errno; |
2472 if( EAGAIN != tErrno ){ | 2413 if( EAGAIN != tErrno ){ |
2473 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); | 2414 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); |
2474 pFile->lastErrno = tErrno; | 2415 storeLastErrno(pFile, tErrno); |
2475 } else { | 2416 } else { |
2476 /* someone else has the lock when we are in NO_LOCK */ | 2417 /* someone else has the lock when we are in NO_LOCK */ |
2477 reserved = (pFile->eFileLock < SHARED_LOCK); | 2418 reserved = (pFile->eFileLock < SHARED_LOCK); |
2478 } | 2419 } |
2479 }else{ | 2420 }else{ |
2480 /* we could have it if we want it */ | 2421 /* we could have it if we want it */ |
2481 sem_post(pSem); | 2422 sem_post(pSem); |
2482 } | 2423 } |
2483 } | 2424 } |
2484 OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); | 2425 OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); |
(...skipping 24 matching lines...) Expand all Loading... |
2509 ** PENDING -> EXCLUSIVE | 2450 ** PENDING -> EXCLUSIVE |
2510 ** | 2451 ** |
2511 ** Semaphore locks only really support EXCLUSIVE locks. We track intermediate | 2452 ** Semaphore locks only really support EXCLUSIVE locks. We track intermediate |
2512 ** lock states in the sqlite3_file structure, but all locks SHARED or | 2453 ** lock states in the sqlite3_file structure, but all locks SHARED or |
2513 ** above are really EXCLUSIVE locks and exclude all other processes from | 2454 ** above are really EXCLUSIVE locks and exclude all other processes from |
2514 ** access the file. | 2455 ** access the file. |
2515 ** | 2456 ** |
2516 ** This routine will only increase a lock. Use the sqlite3OsUnlock() | 2457 ** This routine will only increase a lock. Use the sqlite3OsUnlock() |
2517 ** routine to lower a locking level. | 2458 ** routine to lower a locking level. |
2518 */ | 2459 */ |
2519 static int semLock(sqlite3_file *id, int eFileLock) { | 2460 static int semXLock(sqlite3_file *id, int eFileLock) { |
2520 unixFile *pFile = (unixFile*)id; | 2461 unixFile *pFile = (unixFile*)id; |
2521 sem_t *pSem = pFile->pInode->pSem; | 2462 sem_t *pSem = pFile->pInode->pSem; |
2522 int rc = SQLITE_OK; | 2463 int rc = SQLITE_OK; |
2523 | 2464 |
2524 /* if we already have a lock, it is exclusive. | 2465 /* if we already have a lock, it is exclusive. |
2525 ** Just adjust level and punt on outta here. */ | 2466 ** Just adjust level and punt on outta here. */ |
2526 if (pFile->eFileLock > NO_LOCK) { | 2467 if (pFile->eFileLock > NO_LOCK) { |
2527 pFile->eFileLock = eFileLock; | 2468 pFile->eFileLock = eFileLock; |
2528 rc = SQLITE_OK; | 2469 rc = SQLITE_OK; |
2529 goto sem_end_lock; | 2470 goto sem_end_lock; |
(...skipping 12 matching lines...) Expand all Loading... |
2542 return rc; | 2483 return rc; |
2543 } | 2484 } |
2544 | 2485 |
2545 /* | 2486 /* |
2546 ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock | 2487 ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock |
2547 ** must be either NO_LOCK or SHARED_LOCK. | 2488 ** must be either NO_LOCK or SHARED_LOCK. |
2548 ** | 2489 ** |
2549 ** If the locking level of the file descriptor is already at or below | 2490 ** If the locking level of the file descriptor is already at or below |
2550 ** the requested locking level, this routine is a no-op. | 2491 ** the requested locking level, this routine is a no-op. |
2551 */ | 2492 */ |
2552 static int semUnlock(sqlite3_file *id, int eFileLock) { | 2493 static int semXUnlock(sqlite3_file *id, int eFileLock) { |
2553 unixFile *pFile = (unixFile*)id; | 2494 unixFile *pFile = (unixFile*)id; |
2554 sem_t *pSem = pFile->pInode->pSem; | 2495 sem_t *pSem = pFile->pInode->pSem; |
2555 | 2496 |
2556 assert( pFile ); | 2497 assert( pFile ); |
2557 assert( pSem ); | 2498 assert( pSem ); |
2558 OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, | 2499 OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, |
2559 pFile->eFileLock, getpid())); | 2500 pFile->eFileLock, osGetpid(0))); |
2560 assert( eFileLock<=SHARED_LOCK ); | 2501 assert( eFileLock<=SHARED_LOCK ); |
2561 | 2502 |
2562 /* no-op if possible */ | 2503 /* no-op if possible */ |
2563 if( pFile->eFileLock==eFileLock ){ | 2504 if( pFile->eFileLock==eFileLock ){ |
2564 return SQLITE_OK; | 2505 return SQLITE_OK; |
2565 } | 2506 } |
2566 | 2507 |
2567 /* shared can just be set because we always have an exclusive */ | 2508 /* shared can just be set because we always have an exclusive */ |
2568 if (eFileLock==SHARED_LOCK) { | 2509 if (eFileLock==SHARED_LOCK) { |
2569 pFile->eFileLock = eFileLock; | 2510 pFile->eFileLock = eFileLock; |
2570 return SQLITE_OK; | 2511 return SQLITE_OK; |
2571 } | 2512 } |
2572 | 2513 |
2573 /* no, really unlock. */ | 2514 /* no, really unlock. */ |
2574 if ( sem_post(pSem)==-1 ) { | 2515 if ( sem_post(pSem)==-1 ) { |
2575 int rc, tErrno = errno; | 2516 int rc, tErrno = errno; |
2576 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); | 2517 rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); |
2577 if( IS_LOCK_ERROR(rc) ){ | 2518 if( IS_LOCK_ERROR(rc) ){ |
2578 pFile->lastErrno = tErrno; | 2519 storeLastErrno(pFile, tErrno); |
2579 } | 2520 } |
2580 return rc; | 2521 return rc; |
2581 } | 2522 } |
2582 pFile->eFileLock = NO_LOCK; | 2523 pFile->eFileLock = NO_LOCK; |
2583 return SQLITE_OK; | 2524 return SQLITE_OK; |
2584 } | 2525 } |
2585 | 2526 |
2586 /* | 2527 /* |
2587 ** Close a file. | 2528 ** Close a file. |
2588 */ | 2529 */ |
2589 static int semClose(sqlite3_file *id) { | 2530 static int semXClose(sqlite3_file *id) { |
2590 if( id ){ | 2531 if( id ){ |
2591 unixFile *pFile = (unixFile*)id; | 2532 unixFile *pFile = (unixFile*)id; |
2592 semUnlock(id, NO_LOCK); | 2533 semXUnlock(id, NO_LOCK); |
2593 assert( pFile ); | 2534 assert( pFile ); |
2594 unixEnterMutex(); | 2535 unixEnterMutex(); |
2595 releaseInodeInfo(pFile); | 2536 releaseInodeInfo(pFile); |
2596 unixLeaveMutex(); | 2537 unixLeaveMutex(); |
2597 closeUnixFile(id); | 2538 closeUnixFile(id); |
2598 } | 2539 } |
2599 return SQLITE_OK; | 2540 return SQLITE_OK; |
2600 } | 2541 } |
2601 | 2542 |
2602 #endif /* OS_VXWORKS */ | 2543 #endif /* OS_VXWORKS */ |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2670 int tErrno = errno; | 2611 int tErrno = errno; |
2671 OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", | 2612 OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", |
2672 path, tErrno, strerror(tErrno))); | 2613 path, tErrno, strerror(tErrno))); |
2673 #ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS | 2614 #ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS |
2674 rc = SQLITE_BUSY; | 2615 rc = SQLITE_BUSY; |
2675 #else | 2616 #else |
2676 rc = sqliteErrorFromPosixError(tErrno, | 2617 rc = sqliteErrorFromPosixError(tErrno, |
2677 setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); | 2618 setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); |
2678 #endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ | 2619 #endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ |
2679 if( IS_LOCK_ERROR(rc) ){ | 2620 if( IS_LOCK_ERROR(rc) ){ |
2680 pFile->lastErrno = tErrno; | 2621 storeLastErrno(pFile, tErrno); |
2681 } | 2622 } |
2682 return rc; | 2623 return rc; |
2683 } else { | 2624 } else { |
2684 return SQLITE_OK; | 2625 return SQLITE_OK; |
2685 } | 2626 } |
2686 } | 2627 } |
2687 | 2628 |
2688 /* | 2629 /* |
2689 ** This routine checks if there is a RESERVED lock held on the specified | 2630 ** This routine checks if there is a RESERVED lock held on the specified |
2690 ** file by this or any other process. If such a lock is held, set *pResOut | 2631 ** file by this or any other process. If such a lock is held, set *pResOut |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2763 */ | 2704 */ |
2764 static int afpLock(sqlite3_file *id, int eFileLock){ | 2705 static int afpLock(sqlite3_file *id, int eFileLock){ |
2765 int rc = SQLITE_OK; | 2706 int rc = SQLITE_OK; |
2766 unixFile *pFile = (unixFile*)id; | 2707 unixFile *pFile = (unixFile*)id; |
2767 unixInodeInfo *pInode = pFile->pInode; | 2708 unixInodeInfo *pInode = pFile->pInode; |
2768 afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; | 2709 afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; |
2769 | 2710 |
2770 assert( pFile ); | 2711 assert( pFile ); |
2771 OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, | 2712 OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, |
2772 azFileLock(eFileLock), azFileLock(pFile->eFileLock), | 2713 azFileLock(eFileLock), azFileLock(pFile->eFileLock), |
2773 azFileLock(pInode->eFileLock), pInode->nShared , getpid())); | 2714 azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0))); |
2774 | 2715 |
2775 /* If there is already a lock of this type or more restrictive on the | 2716 /* If there is already a lock of this type or more restrictive on the |
2776 ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as | 2717 ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as |
2777 ** unixEnterMutex() hasn't been called yet. | 2718 ** unixEnterMutex() hasn't been called yet. |
2778 */ | 2719 */ |
2779 if( pFile->eFileLock>=eFileLock ){ | 2720 if( pFile->eFileLock>=eFileLock ){ |
2780 OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, | 2721 OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, |
2781 azFileLock(eFileLock))); | 2722 azFileLock(eFileLock))); |
2782 return SQLITE_OK; | 2723 return SQLITE_OK; |
2783 } | 2724 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2853 pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); | 2794 pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); |
2854 lrc1 = afpSetLock(context->dbPath, pFile, | 2795 lrc1 = afpSetLock(context->dbPath, pFile, |
2855 SHARED_FIRST+pInode->sharedByte, 1, 1); | 2796 SHARED_FIRST+pInode->sharedByte, 1, 1); |
2856 if( IS_LOCK_ERROR(lrc1) ){ | 2797 if( IS_LOCK_ERROR(lrc1) ){ |
2857 lrc1Errno = pFile->lastErrno; | 2798 lrc1Errno = pFile->lastErrno; |
2858 } | 2799 } |
2859 /* Drop the temporary PENDING lock */ | 2800 /* Drop the temporary PENDING lock */ |
2860 lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); | 2801 lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); |
2861 | 2802 |
2862 if( IS_LOCK_ERROR(lrc1) ) { | 2803 if( IS_LOCK_ERROR(lrc1) ) { |
2863 pFile->lastErrno = lrc1Errno; | 2804 storeLastErrno(pFile, lrc1Errno); |
2864 rc = lrc1; | 2805 rc = lrc1; |
2865 goto afp_end_lock; | 2806 goto afp_end_lock; |
2866 } else if( IS_LOCK_ERROR(lrc2) ){ | 2807 } else if( IS_LOCK_ERROR(lrc2) ){ |
2867 rc = lrc2; | 2808 rc = lrc2; |
2868 goto afp_end_lock; | 2809 goto afp_end_lock; |
2869 } else if( lrc1 != SQLITE_OK ) { | 2810 } else if( lrc1 != SQLITE_OK ) { |
2870 rc = lrc1; | 2811 rc = lrc1; |
2871 } else { | 2812 } else { |
2872 pFile->eFileLock = SHARED_LOCK; | 2813 pFile->eFileLock = SHARED_LOCK; |
2873 pInode->nLock++; | 2814 pInode->nLock++; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2949 unixInodeInfo *pInode; | 2890 unixInodeInfo *pInode; |
2950 afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; | 2891 afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; |
2951 int skipShared = 0; | 2892 int skipShared = 0; |
2952 #ifdef SQLITE_TEST | 2893 #ifdef SQLITE_TEST |
2953 int h = pFile->h; | 2894 int h = pFile->h; |
2954 #endif | 2895 #endif |
2955 | 2896 |
2956 assert( pFile ); | 2897 assert( pFile ); |
2957 OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, | 2898 OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, |
2958 pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, | 2899 pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, |
2959 getpid())); | 2900 osGetpid(0))); |
2960 | 2901 |
2961 assert( eFileLock<=SHARED_LOCK ); | 2902 assert( eFileLock<=SHARED_LOCK ); |
2962 if( pFile->eFileLock<=eFileLock ){ | 2903 if( pFile->eFileLock<=eFileLock ){ |
2963 return SQLITE_OK; | 2904 return SQLITE_OK; |
2964 } | 2905 } |
2965 unixEnterMutex(); | 2906 unixEnterMutex(); |
2966 pInode = pFile->pInode; | 2907 pInode = pFile->pInode; |
2967 assert( pInode->nShared!=0 ); | 2908 assert( pInode->nShared!=0 ); |
2968 if( pFile->eFileLock>SHARED_LOCK ){ | 2909 if( pFile->eFileLock>SHARED_LOCK ){ |
2969 assert( pInode->eFileLock==pFile->eFileLock ); | 2910 assert( pInode->eFileLock==pFile->eFileLock ); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3041 unixLeaveMutex(); | 2982 unixLeaveMutex(); |
3042 if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; | 2983 if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; |
3043 return rc; | 2984 return rc; |
3044 } | 2985 } |
3045 | 2986 |
3046 /* | 2987 /* |
3047 ** Close a file & cleanup AFP specific locking context | 2988 ** Close a file & cleanup AFP specific locking context |
3048 */ | 2989 */ |
3049 static int afpClose(sqlite3_file *id) { | 2990 static int afpClose(sqlite3_file *id) { |
3050 int rc = SQLITE_OK; | 2991 int rc = SQLITE_OK; |
3051 if( id ){ | 2992 unixFile *pFile = (unixFile*)id; |
3052 unixFile *pFile = (unixFile*)id; | 2993 assert( id!=0 ); |
3053 afpUnlock(id, NO_LOCK); | 2994 afpUnlock(id, NO_LOCK); |
3054 unixEnterMutex(); | 2995 unixEnterMutex(); |
3055 if( pFile->pInode && pFile->pInode->nLock ){ | 2996 if( pFile->pInode && pFile->pInode->nLock ){ |
3056 /* If there are outstanding locks, do not actually close the file just | 2997 /* If there are outstanding locks, do not actually close the file just |
3057 ** yet because that would clear those locks. Instead, add the file | 2998 ** yet because that would clear those locks. Instead, add the file |
3058 ** descriptor to pInode->aPending. It will be automatically closed when | 2999 ** descriptor to pInode->aPending. It will be automatically closed when |
3059 ** the last lock is cleared. | 3000 ** the last lock is cleared. |
3060 */ | 3001 */ |
3061 setPendingFd(pFile); | 3002 setPendingFd(pFile); |
3062 } | |
3063 releaseInodeInfo(pFile); | |
3064 sqlite3_free(pFile->lockingContext); | |
3065 rc = closeUnixFile(id); | |
3066 unixLeaveMutex(); | |
3067 } | 3003 } |
| 3004 releaseInodeInfo(pFile); |
| 3005 sqlite3_free(pFile->lockingContext); |
| 3006 rc = closeUnixFile(id); |
| 3007 unixLeaveMutex(); |
3068 return rc; | 3008 return rc; |
3069 } | 3009 } |
3070 | 3010 |
3071 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ | 3011 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ |
3072 /* | 3012 /* |
3073 ** The code above is the AFP lock implementation. The code is specific | 3013 ** The code above is the AFP lock implementation. The code is specific |
3074 ** to MacOSX and does not work on other unix platforms. No alternative | 3014 ** to MacOSX and does not work on other unix platforms. No alternative |
3075 ** is available. If you don't compile for a mac, then the "unix-afp" | 3015 ** is available. If you don't compile for a mac, then the "unix-afp" |
3076 ** VFS is not available. | 3016 ** VFS is not available. |
3077 ** | 3017 ** |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3127 */ | 3067 */ |
3128 static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ | 3068 static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ |
3129 int got; | 3069 int got; |
3130 int prior = 0; | 3070 int prior = 0; |
3131 #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) | 3071 #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
3132 i64 newOffset; | 3072 i64 newOffset; |
3133 #endif | 3073 #endif |
3134 TIMER_START; | 3074 TIMER_START; |
3135 assert( cnt==(cnt&0x1ffff) ); | 3075 assert( cnt==(cnt&0x1ffff) ); |
3136 assert( id->h>2 ); | 3076 assert( id->h>2 ); |
3137 cnt &= 0x1ffff; | |
3138 do{ | 3077 do{ |
3139 #if defined(USE_PREAD) | 3078 #if defined(USE_PREAD) |
3140 got = osPread(id->h, pBuf, cnt, offset); | 3079 got = osPread(id->h, pBuf, cnt, offset); |
3141 SimulateIOError( got = -1 ); | 3080 SimulateIOError( got = -1 ); |
3142 #elif defined(USE_PREAD64) | 3081 #elif defined(USE_PREAD64) |
3143 got = osPread64(id->h, pBuf, cnt, offset); | 3082 got = osPread64(id->h, pBuf, cnt, offset); |
3144 SimulateIOError( got = -1 ); | 3083 SimulateIOError( got = -1 ); |
3145 #else | 3084 #else |
3146 newOffset = lseek(id->h, offset, SEEK_SET); | 3085 newOffset = lseek(id->h, offset, SEEK_SET); |
3147 SimulateIOError( newOffset-- ); | 3086 SimulateIOError( newOffset = -1 ); |
3148 if( newOffset!=offset ){ | 3087 if( newOffset<0 ){ |
3149 if( newOffset == -1 ){ | 3088 storeLastErrno((unixFile*)id, errno); |
3150 ((unixFile*)id)->lastErrno = errno; | |
3151 }else{ | |
3152 ((unixFile*)id)->lastErrno = 0; | |
3153 } | |
3154 return -1; | 3089 return -1; |
3155 } | 3090 } |
3156 got = osRead(id->h, pBuf, cnt); | 3091 got = osRead(id->h, pBuf, cnt); |
3157 #endif | 3092 #endif |
3158 if( got==cnt ) break; | 3093 if( got==cnt ) break; |
3159 if( got<0 ){ | 3094 if( got<0 ){ |
3160 if( errno==EINTR ){ got = 1; continue; } | 3095 if( errno==EINTR ){ got = 1; continue; } |
3161 prior = 0; | 3096 prior = 0; |
3162 ((unixFile*)id)->lastErrno = errno; | 3097 storeLastErrno((unixFile*)id, errno); |
3163 break; | 3098 break; |
3164 }else if( got>0 ){ | 3099 }else if( got>0 ){ |
3165 cnt -= got; | 3100 cnt -= got; |
3166 offset += got; | 3101 offset += got; |
3167 prior += got; | 3102 prior += got; |
3168 pBuf = (void*)(got + (char*)pBuf); | 3103 pBuf = (void*)(got + (char*)pBuf); |
3169 } | 3104 } |
3170 }while( got>0 ); | 3105 }while( got>0 ); |
3171 TIMER_END; | 3106 TIMER_END; |
3172 OSTRACE(("READ %-3d %5d %7lld %llu\n", | 3107 OSTRACE(("READ %-3d %5d %7lld %llu\n", |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3217 } | 3152 } |
3218 #endif | 3153 #endif |
3219 | 3154 |
3220 got = seekAndRead(pFile, offset, pBuf, amt); | 3155 got = seekAndRead(pFile, offset, pBuf, amt); |
3221 if( got==amt ){ | 3156 if( got==amt ){ |
3222 return SQLITE_OK; | 3157 return SQLITE_OK; |
3223 }else if( got<0 ){ | 3158 }else if( got<0 ){ |
3224 /* lastErrno set by seekAndRead */ | 3159 /* lastErrno set by seekAndRead */ |
3225 return SQLITE_IOERR_READ; | 3160 return SQLITE_IOERR_READ; |
3226 }else{ | 3161 }else{ |
3227 pFile->lastErrno = 0; /* not a system error */ | 3162 storeLastErrno(pFile, 0); /* not a system error */ |
3228 /* Unread parts of the buffer must be zero-filled */ | 3163 /* Unread parts of the buffer must be zero-filled */ |
3229 memset(&((char*)pBuf)[got], 0, amt-got); | 3164 memset(&((char*)pBuf)[got], 0, amt-got); |
3230 return SQLITE_IOERR_SHORT_READ; | 3165 return SQLITE_IOERR_SHORT_READ; |
3231 } | 3166 } |
3232 } | 3167 } |
3233 | 3168 |
3234 /* | 3169 /* |
3235 ** Attempt to seek the file-descriptor passed as the first argument to | 3170 ** Attempt to seek the file-descriptor passed as the first argument to |
3236 ** absolute offset iOff, then attempt to write nBuf bytes of data from | 3171 ** absolute offset iOff, then attempt to write nBuf bytes of data from |
3237 ** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, | 3172 ** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, |
3238 ** return the actual number of bytes written (which may be less than | 3173 ** return the actual number of bytes written (which may be less than |
3239 ** nBuf). | 3174 ** nBuf). |
3240 */ | 3175 */ |
3241 static int seekAndWriteFd( | 3176 static int seekAndWriteFd( |
3242 int fd, /* File descriptor to write to */ | 3177 int fd, /* File descriptor to write to */ |
3243 i64 iOff, /* File offset to begin writing at */ | 3178 i64 iOff, /* File offset to begin writing at */ |
3244 const void *pBuf, /* Copy data from this buffer to the file */ | 3179 const void *pBuf, /* Copy data from this buffer to the file */ |
3245 int nBuf, /* Size of buffer pBuf in bytes */ | 3180 int nBuf, /* Size of buffer pBuf in bytes */ |
3246 int *piErrno /* OUT: Error number if error occurs */ | 3181 int *piErrno /* OUT: Error number if error occurs */ |
3247 ){ | 3182 ){ |
3248 int rc = 0; /* Value returned by system call */ | 3183 int rc = 0; /* Value returned by system call */ |
3249 | 3184 |
3250 assert( nBuf==(nBuf&0x1ffff) ); | 3185 assert( nBuf==(nBuf&0x1ffff) ); |
3251 assert( fd>2 ); | 3186 assert( fd>2 ); |
| 3187 assert( piErrno!=0 ); |
3252 nBuf &= 0x1ffff; | 3188 nBuf &= 0x1ffff; |
3253 TIMER_START; | 3189 TIMER_START; |
3254 | 3190 |
3255 #if defined(USE_PREAD) | 3191 #if defined(USE_PREAD) |
3256 do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); | 3192 do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); |
3257 #elif defined(USE_PREAD64) | 3193 #elif defined(USE_PREAD64) |
3258 do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); | 3194 do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); |
3259 #else | 3195 #else |
3260 do{ | 3196 do{ |
3261 i64 iSeek = lseek(fd, iOff, SEEK_SET); | 3197 i64 iSeek = lseek(fd, iOff, SEEK_SET); |
3262 SimulateIOError( iSeek-- ); | 3198 SimulateIOError( iSeek = -1 ); |
3263 | 3199 if( iSeek<0 ){ |
3264 if( iSeek!=iOff ){ | 3200 rc = -1; |
3265 if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0); | 3201 break; |
3266 return -1; | |
3267 } | 3202 } |
3268 rc = osWrite(fd, pBuf, nBuf); | 3203 rc = osWrite(fd, pBuf, nBuf); |
3269 }while( rc<0 && errno==EINTR ); | 3204 }while( rc<0 && errno==EINTR ); |
3270 #endif | 3205 #endif |
3271 | 3206 |
3272 TIMER_END; | 3207 TIMER_END; |
3273 OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED)); | 3208 OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED)); |
3274 | 3209 |
3275 if( rc<0 && piErrno ) *piErrno = errno; | 3210 if( rc<0 ) *piErrno = errno; |
3276 return rc; | 3211 return rc; |
3277 } | 3212 } |
3278 | 3213 |
3279 | 3214 |
3280 /* | 3215 /* |
3281 ** Seek to the offset in id->offset then read cnt bytes into pBuf. | 3216 ** Seek to the offset in id->offset then read cnt bytes into pBuf. |
3282 ** Return the number of bytes actually read. Update the offset. | 3217 ** Return the number of bytes actually read. Update the offset. |
3283 ** | 3218 ** |
3284 ** To avoid stomping the errno value on a failed write the lastErrno value | 3219 ** To avoid stomping the errno value on a failed write the lastErrno value |
3285 ** is set before returning. | 3220 ** is set before returning. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3328 SimulateIOErrorBenign(1); | 3263 SimulateIOErrorBenign(1); |
3329 rc = seekAndRead(pFile, 24, oldCntr, 4); | 3264 rc = seekAndRead(pFile, 24, oldCntr, 4); |
3330 SimulateIOErrorBenign(0); | 3265 SimulateIOErrorBenign(0); |
3331 if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ | 3266 if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ |
3332 pFile->transCntrChng = 1; /* The transaction counter has changed */ | 3267 pFile->transCntrChng = 1; /* The transaction counter has changed */ |
3333 } | 3268 } |
3334 } | 3269 } |
3335 } | 3270 } |
3336 #endif | 3271 #endif |
3337 | 3272 |
3338 #if SQLITE_MAX_MMAP_SIZE>0 | 3273 #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 |
3339 /* Deal with as much of this write request as possible by transfering | 3274 /* Deal with as much of this write request as possible by transfering |
3340 ** data from the memory mapping using memcpy(). */ | 3275 ** data from the memory mapping using memcpy(). */ |
3341 if( offset<pFile->mmapSize ){ | 3276 if( offset<pFile->mmapSize ){ |
3342 if( offset+amt <= pFile->mmapSize ){ | 3277 if( offset+amt <= pFile->mmapSize ){ |
3343 memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); | 3278 memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); |
3344 return SQLITE_OK; | 3279 return SQLITE_OK; |
3345 }else{ | 3280 }else{ |
3346 int nCopy = pFile->mmapSize - offset; | 3281 int nCopy = pFile->mmapSize - offset; |
3347 memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); | 3282 memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); |
3348 pBuf = &((u8 *)pBuf)[nCopy]; | 3283 pBuf = &((u8 *)pBuf)[nCopy]; |
3349 amt -= nCopy; | 3284 amt -= nCopy; |
3350 offset += nCopy; | 3285 offset += nCopy; |
3351 } | 3286 } |
3352 } | 3287 } |
3353 #endif | 3288 #endif |
3354 | 3289 |
3355 while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){ | 3290 while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){ |
3356 amt -= wrote; | 3291 amt -= wrote; |
3357 offset += wrote; | 3292 offset += wrote; |
3358 pBuf = &((char*)pBuf)[wrote]; | 3293 pBuf = &((char*)pBuf)[wrote]; |
3359 } | 3294 } |
3360 SimulateIOError(( wrote=(-1), amt=1 )); | 3295 SimulateIOError(( wrote=(-1), amt=1 )); |
3361 SimulateDiskfullError(( wrote=0, amt=1 )); | 3296 SimulateDiskfullError(( wrote=0, amt=1 )); |
3362 | 3297 |
3363 if( amt>0 ){ | 3298 if( amt>wrote ){ |
3364 if( wrote<0 && pFile->lastErrno!=ENOSPC ){ | 3299 if( wrote<0 && pFile->lastErrno!=ENOSPC ){ |
3365 /* lastErrno set by seekAndWrite */ | 3300 /* lastErrno set by seekAndWrite */ |
3366 return SQLITE_IOERR_WRITE; | 3301 return SQLITE_IOERR_WRITE; |
3367 }else{ | 3302 }else{ |
3368 pFile->lastErrno = 0; /* not a system error */ | 3303 storeLastErrno(pFile, 0); /* not a system error */ |
3369 return SQLITE_FULL; | 3304 return SQLITE_FULL; |
3370 } | 3305 } |
3371 } | 3306 } |
3372 | 3307 |
3373 return SQLITE_OK; | 3308 return SQLITE_OK; |
3374 } | 3309 } |
3375 | 3310 |
3376 #ifdef SQLITE_TEST | 3311 #ifdef SQLITE_TEST |
3377 /* | 3312 /* |
3378 ** Count the number of fullsyncs and normal syncs. This is used to test | 3313 ** Count the number of fullsyncs and normal syncs. This is used to test |
3379 ** that syncs and fullsyncs are occurring at the right times. | 3314 ** that syncs and fullsyncs are occurring at the right times. |
3380 */ | 3315 */ |
3381 int sqlite3_sync_count = 0; | 3316 int sqlite3_sync_count = 0; |
3382 int sqlite3_fullsync_count = 0; | 3317 int sqlite3_fullsync_count = 0; |
3383 #endif | 3318 #endif |
3384 | 3319 |
3385 /* | 3320 /* |
3386 ** We do not trust systems to provide a working fdatasync(). Some do. | 3321 ** We do not trust systems to provide a working fdatasync(). Some do. |
3387 ** Others do no. To be safe, we will stick with the (slightly slower) | 3322 ** Others do no. To be safe, we will stick with the (slightly slower) |
3388 ** fsync(). If you know that your system does support fdatasync() correctly, | 3323 ** fsync(). If you know that your system does support fdatasync() correctly, |
3389 ** then simply compile with -Dfdatasync=fdatasync | 3324 ** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC |
3390 */ | 3325 */ |
3391 #if !defined(fdatasync) | 3326 #if !defined(fdatasync) && !HAVE_FDATASYNC |
3392 # define fdatasync fsync | 3327 # define fdatasync fsync |
3393 #endif | 3328 #endif |
3394 | 3329 |
3395 /* | 3330 /* |
3396 ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not | 3331 ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
3397 ** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently | 3332 ** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently |
3398 ** only available on Mac OS X. But that could change. | 3333 ** only available on Mac OS X. But that could change. |
3399 */ | 3334 */ |
3400 #ifdef F_FULLFSYNC | 3335 #ifdef F_FULLFSYNC |
3401 # define HAVE_FULLFSYNC 1 | 3336 # define HAVE_FULLFSYNC 1 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3449 /* Record the number of times that we do a normal fsync() and | 3384 /* Record the number of times that we do a normal fsync() and |
3450 ** FULLSYNC. This is used during testing to verify that this procedure | 3385 ** FULLSYNC. This is used during testing to verify that this procedure |
3451 ** gets called with the correct arguments. | 3386 ** gets called with the correct arguments. |
3452 */ | 3387 */ |
3453 #ifdef SQLITE_TEST | 3388 #ifdef SQLITE_TEST |
3454 if( fullSync ) sqlite3_fullsync_count++; | 3389 if( fullSync ) sqlite3_fullsync_count++; |
3455 sqlite3_sync_count++; | 3390 sqlite3_sync_count++; |
3456 #endif | 3391 #endif |
3457 | 3392 |
3458 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a | 3393 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
3459 ** no-op | 3394 ** no-op. But go ahead and call fstat() to validate the file |
| 3395 ** descriptor as we need a method to provoke a failure during |
| 3396 ** coverate testing. |
3460 */ | 3397 */ |
3461 #ifdef SQLITE_NO_SYNC | 3398 #ifdef SQLITE_NO_SYNC |
3462 rc = SQLITE_OK; | 3399 { |
| 3400 struct stat buf; |
| 3401 rc = osFstat(fd, &buf); |
| 3402 } |
3463 #elif HAVE_FULLFSYNC | 3403 #elif HAVE_FULLFSYNC |
3464 if( fullSync ){ | 3404 if( fullSync ){ |
3465 rc = osFcntl(fd, F_FULLFSYNC, 0); | 3405 rc = osFcntl(fd, F_FULLFSYNC, 0); |
3466 }else{ | 3406 }else{ |
3467 rc = 1; | 3407 rc = 1; |
3468 } | 3408 } |
3469 /* If the FULLFSYNC failed, fall back to attempting an fsync(). | 3409 /* If the FULLFSYNC failed, fall back to attempting an fsync(). |
3470 ** It shouldn't be possible for fullfsync to fail on the local | 3410 ** It shouldn't be possible for fullfsync to fail on the local |
3471 ** file system (on OSX), so failure indicates that FULLFSYNC | 3411 ** file system (on OSX), so failure indicates that FULLFSYNC |
3472 ** isn't supported for this file system. So, attempt an fsync | 3412 ** isn't supported for this file system. So, attempt an fsync |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3518 ** | 3458 ** |
3519 ** If SQLITE_OK is returned, the caller is responsible for closing | 3459 ** If SQLITE_OK is returned, the caller is responsible for closing |
3520 ** the file descriptor *pFd using close(). | 3460 ** the file descriptor *pFd using close(). |
3521 */ | 3461 */ |
3522 static int openDirectory(const char *zFilename, int *pFd){ | 3462 static int openDirectory(const char *zFilename, int *pFd){ |
3523 int ii; | 3463 int ii; |
3524 int fd = -1; | 3464 int fd = -1; |
3525 char zDirname[MAX_PATHNAME+1]; | 3465 char zDirname[MAX_PATHNAME+1]; |
3526 | 3466 |
3527 sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); | 3467 sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); |
3528 for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); | 3468 for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--); |
3529 if( ii>0 ){ | 3469 if( ii>0 ){ |
3530 zDirname[ii] = '\0'; | 3470 zDirname[ii] = '\0'; |
3531 fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); | 3471 }else{ |
3532 if( fd>=0 ){ | 3472 if( zDirname[0]!='/' ) zDirname[0] = '.'; |
3533 OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); | 3473 zDirname[1] = 0; |
3534 } | 3474 } |
| 3475 fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); |
| 3476 if( fd>=0 ){ |
| 3477 OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); |
3535 } | 3478 } |
3536 *pFd = fd; | 3479 *pFd = fd; |
3537 return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); | 3480 if( fd>=0 ) return SQLITE_OK; |
| 3481 return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname); |
3538 } | 3482 } |
3539 | 3483 |
3540 /* | 3484 /* |
3541 ** Make sure all writes to a particular file are committed to disk. | 3485 ** Make sure all writes to a particular file are committed to disk. |
3542 ** | 3486 ** |
3543 ** If dataOnly==0 then both the file itself and its metadata (file | 3487 ** If dataOnly==0 then both the file itself and its metadata (file |
3544 ** size, access time, etc) are synced. If dataOnly!=0 then only the | 3488 ** size, access time, etc) are synced. If dataOnly!=0 then only the |
3545 ** file data is synced. | 3489 ** file data is synced. |
3546 ** | 3490 ** |
3547 ** Under Unix, also make sure that the directory entry for the file | 3491 ** Under Unix, also make sure that the directory entry for the file |
(...skipping 19 matching lines...) Expand all Loading... |
3567 /* Unix cannot, but some systems may return SQLITE_FULL from here. This | 3511 /* Unix cannot, but some systems may return SQLITE_FULL from here. This |
3568 ** line is to test that doing so does not cause any problems. | 3512 ** line is to test that doing so does not cause any problems. |
3569 */ | 3513 */ |
3570 SimulateDiskfullError( return SQLITE_FULL ); | 3514 SimulateDiskfullError( return SQLITE_FULL ); |
3571 | 3515 |
3572 assert( pFile ); | 3516 assert( pFile ); |
3573 OSTRACE(("SYNC %-3d\n", pFile->h)); | 3517 OSTRACE(("SYNC %-3d\n", pFile->h)); |
3574 rc = full_fsync(pFile->h, isFullsync, isDataOnly); | 3518 rc = full_fsync(pFile->h, isFullsync, isDataOnly); |
3575 SimulateIOError( rc=1 ); | 3519 SimulateIOError( rc=1 ); |
3576 if( rc ){ | 3520 if( rc ){ |
3577 pFile->lastErrno = errno; | 3521 storeLastErrno(pFile, errno); |
3578 return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); | 3522 return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); |
3579 } | 3523 } |
3580 | 3524 |
3581 /* Also fsync the directory containing the file if the DIRSYNC flag | 3525 /* Also fsync the directory containing the file if the DIRSYNC flag |
3582 ** is set. This is a one-time occurrence. Many systems (examples: AIX) | 3526 ** is set. This is a one-time occurrence. Many systems (examples: AIX) |
3583 ** are unable to fsync a directory, so ignore errors on the fsync. | 3527 ** are unable to fsync a directory, so ignore errors on the fsync. |
3584 */ | 3528 */ |
3585 if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ | 3529 if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ |
3586 int dirfd; | 3530 int dirfd; |
3587 OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, | 3531 OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, |
3588 HAVE_FULLFSYNC, isFullsync)); | 3532 HAVE_FULLFSYNC, isFullsync)); |
3589 rc = osOpenDirectory(pFile->zPath, &dirfd); | 3533 rc = osOpenDirectory(pFile->zPath, &dirfd); |
3590 if( rc==SQLITE_OK && dirfd>=0 ){ | 3534 if( rc==SQLITE_OK ){ |
3591 full_fsync(dirfd, 0, 0); | 3535 full_fsync(dirfd, 0, 0); |
3592 robust_close(pFile, dirfd, __LINE__); | 3536 robust_close(pFile, dirfd, __LINE__); |
3593 }else if( rc==SQLITE_CANTOPEN ){ | 3537 }else{ |
| 3538 assert( rc==SQLITE_CANTOPEN ); |
3594 rc = SQLITE_OK; | 3539 rc = SQLITE_OK; |
3595 } | 3540 } |
3596 pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; | 3541 pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; |
3597 } | 3542 } |
3598 return rc; | 3543 return rc; |
3599 } | 3544 } |
3600 | 3545 |
3601 /* | 3546 /* |
3602 ** Truncate an open file to a specified size | 3547 ** Truncate an open file to a specified size |
3603 */ | 3548 */ |
3604 static int unixTruncate(sqlite3_file *id, i64 nByte){ | 3549 static int unixTruncate(sqlite3_file *id, i64 nByte){ |
3605 unixFile *pFile = (unixFile *)id; | 3550 unixFile *pFile = (unixFile *)id; |
3606 int rc; | 3551 int rc; |
3607 assert( pFile ); | 3552 assert( pFile ); |
3608 SimulateIOError( return SQLITE_IOERR_TRUNCATE ); | 3553 SimulateIOError( return SQLITE_IOERR_TRUNCATE ); |
3609 | 3554 |
3610 /* If the user has configured a chunk-size for this file, truncate the | 3555 /* If the user has configured a chunk-size for this file, truncate the |
3611 ** file so that it consists of an integer number of chunks (i.e. the | 3556 ** file so that it consists of an integer number of chunks (i.e. the |
3612 ** actual file size after the operation may be larger than the requested | 3557 ** actual file size after the operation may be larger than the requested |
3613 ** size). | 3558 ** size). |
3614 */ | 3559 */ |
3615 if( pFile->szChunk>0 ){ | 3560 if( pFile->szChunk>0 ){ |
3616 nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; | 3561 nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
3617 } | 3562 } |
3618 | 3563 |
3619 rc = robust_ftruncate(pFile->h, nByte); | 3564 rc = robust_ftruncate(pFile->h, nByte); |
3620 if( rc ){ | 3565 if( rc ){ |
3621 pFile->lastErrno = errno; | 3566 storeLastErrno(pFile, errno); |
3622 return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); | 3567 return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); |
3623 }else{ | 3568 }else{ |
3624 #ifdef SQLITE_DEBUG | 3569 #ifdef SQLITE_DEBUG |
3625 /* If we are doing a normal write to a database file (as opposed to | 3570 /* If we are doing a normal write to a database file (as opposed to |
3626 ** doing a hot-journal rollback or a write to some file other than a | 3571 ** doing a hot-journal rollback or a write to some file other than a |
3627 ** normal database file) and we truncate the file to zero length, | 3572 ** normal database file) and we truncate the file to zero length, |
3628 ** that effectively updates the change counter. This might happen | 3573 ** that effectively updates the change counter. This might happen |
3629 ** when restoring a database using the backup API from a zero-length | 3574 ** when restoring a database using the backup API from a zero-length |
3630 ** source. | 3575 ** source. |
3631 */ | 3576 */ |
(...skipping 19 matching lines...) Expand all Loading... |
3651 /* | 3596 /* |
3652 ** Determine the current size of a file in bytes | 3597 ** Determine the current size of a file in bytes |
3653 */ | 3598 */ |
3654 static int unixFileSize(sqlite3_file *id, i64 *pSize){ | 3599 static int unixFileSize(sqlite3_file *id, i64 *pSize){ |
3655 int rc; | 3600 int rc; |
3656 struct stat buf; | 3601 struct stat buf; |
3657 assert( id ); | 3602 assert( id ); |
3658 rc = osFstat(((unixFile*)id)->h, &buf); | 3603 rc = osFstat(((unixFile*)id)->h, &buf); |
3659 SimulateIOError( rc=1 ); | 3604 SimulateIOError( rc=1 ); |
3660 if( rc!=0 ){ | 3605 if( rc!=0 ){ |
3661 ((unixFile*)id)->lastErrno = errno; | 3606 storeLastErrno((unixFile*)id, errno); |
3662 return SQLITE_IOERR_FSTAT; | 3607 return SQLITE_IOERR_FSTAT; |
3663 } | 3608 } |
3664 *pSize = buf.st_size; | 3609 *pSize = buf.st_size; |
3665 | 3610 |
3666 /* When opening a zero-size database, the findInodeInfo() procedure | 3611 /* When opening a zero-size database, the findInodeInfo() procedure |
3667 ** writes a single byte into that file in order to work around a bug | 3612 ** writes a single byte into that file in order to work around a bug |
3668 ** in the OS-X msdos filesystem. In order to avoid problems with upper | 3613 ** in the OS-X msdos filesystem. In order to avoid problems with upper |
3669 ** layers, we need to report this file size as zero even though it is | 3614 ** layers, we need to report this file size as zero even though it is |
3670 ** really 1. Ticket #3260. | 3615 ** really 1. Ticket #3260. |
3671 */ | 3616 */ |
(...skipping 15 matching lines...) Expand all Loading... |
3687 ** This function is called to handle the SQLITE_FCNTL_SIZE_HINT | 3632 ** This function is called to handle the SQLITE_FCNTL_SIZE_HINT |
3688 ** file-control operation. Enlarge the database to nBytes in size | 3633 ** file-control operation. Enlarge the database to nBytes in size |
3689 ** (rounded up to the next chunk-size). If the database is already | 3634 ** (rounded up to the next chunk-size). If the database is already |
3690 ** nBytes or larger, this routine is a no-op. | 3635 ** nBytes or larger, this routine is a no-op. |
3691 */ | 3636 */ |
3692 static int fcntlSizeHint(unixFile *pFile, i64 nByte){ | 3637 static int fcntlSizeHint(unixFile *pFile, i64 nByte){ |
3693 if( pFile->szChunk>0 ){ | 3638 if( pFile->szChunk>0 ){ |
3694 i64 nSize; /* Required file size */ | 3639 i64 nSize; /* Required file size */ |
3695 struct stat buf; /* Used to hold return values of fstat() */ | 3640 struct stat buf; /* Used to hold return values of fstat() */ |
3696 | 3641 |
3697 if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; | 3642 if( osFstat(pFile->h, &buf) ){ |
| 3643 return SQLITE_IOERR_FSTAT; |
| 3644 } |
3698 | 3645 |
3699 nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; | 3646 nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; |
3700 if( nSize>(i64)buf.st_size ){ | 3647 if( nSize>(i64)buf.st_size ){ |
3701 | 3648 |
3702 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE | 3649 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE |
3703 /* The code below is handling the return value of osFallocate() | 3650 /* The code below is handling the return value of osFallocate() |
3704 ** correctly. posix_fallocate() is defined to "returns zero on success, | 3651 ** correctly. posix_fallocate() is defined to "returns zero on success, |
3705 ** or an error number on failure". See the manpage for details. */ | 3652 ** or an error number on failure". See the manpage for details. */ |
3706 int err; | 3653 int err; |
3707 do{ | 3654 do{ |
3708 err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); | 3655 err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); |
3709 }while( err==EINTR ); | 3656 }while( err==EINTR ); |
3710 if( err ) return SQLITE_IOERR_WRITE; | 3657 if( err ) return SQLITE_IOERR_WRITE; |
3711 #else | 3658 #else |
3712 /* If the OS does not have posix_fallocate(), fake it. First use | 3659 /* If the OS does not have posix_fallocate(), fake it. Write a |
3713 ** ftruncate() to set the file size, then write a single byte to | 3660 ** single byte to the last byte in each block that falls entirely |
3714 ** the last byte in each block within the extended region. This | 3661 ** within the extended region. Then, if required, a single byte |
3715 ** is the same technique used by glibc to implement posix_fallocate() | 3662 ** at offset (nSize-1), to set the size of the file correctly. |
3716 ** on systems that do not have a real fallocate() system call. | 3663 ** This is a similar technique to that used by glibc on systems |
| 3664 ** that do not have a real fallocate() call. |
3717 */ | 3665 */ |
3718 int nBlk = buf.st_blksize; /* File-system block size */ | 3666 int nBlk = buf.st_blksize; /* File-system block size */ |
| 3667 int nWrite = 0; /* Number of bytes written by seekAndWrite */ |
3719 i64 iWrite; /* Next offset to write to */ | 3668 i64 iWrite; /* Next offset to write to */ |
3720 | 3669 |
3721 if( robust_ftruncate(pFile->h, nSize) ){ | 3670 iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1; |
3722 pFile->lastErrno = errno; | 3671 assert( iWrite>=buf.st_size ); |
3723 return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); | 3672 assert( ((iWrite+1)%nBlk)==0 ); |
3724 } | 3673 for(/*no-op*/; iWrite<nSize+nBlk-1; iWrite+=nBlk ){ |
3725 iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; | 3674 if( iWrite>=nSize ) iWrite = nSize - 1; |
3726 while( iWrite<nSize ){ | 3675 nWrite = seekAndWrite(pFile, iWrite, "", 1); |
3727 int nWrite = seekAndWrite(pFile, iWrite, "", 1); | |
3728 if( nWrite!=1 ) return SQLITE_IOERR_WRITE; | 3676 if( nWrite!=1 ) return SQLITE_IOERR_WRITE; |
3729 iWrite += nBlk; | |
3730 } | 3677 } |
3731 #endif | 3678 #endif |
3732 } | 3679 } |
3733 } | 3680 } |
3734 | 3681 |
3735 #if SQLITE_MAX_MMAP_SIZE>0 | 3682 #if SQLITE_MAX_MMAP_SIZE>0 |
3736 if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ | 3683 if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ |
3737 int rc; | 3684 int rc; |
3738 if( pFile->szChunk<=0 ){ | 3685 if( pFile->szChunk<=0 ){ |
3739 if( robust_ftruncate(pFile->h, nByte) ){ | 3686 if( robust_ftruncate(pFile->h, nByte) ){ |
3740 pFile->lastErrno = errno; | 3687 storeLastErrno(pFile, errno); |
3741 return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); | 3688 return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); |
3742 } | 3689 } |
3743 } | 3690 } |
3744 | 3691 |
3745 rc = unixMapfile(pFile, nByte); | 3692 rc = unixMapfile(pFile, nByte); |
3746 return rc; | 3693 return rc; |
3747 } | 3694 } |
3748 #endif | 3695 #endif |
3749 | 3696 |
3750 return SQLITE_OK; | 3697 return SQLITE_OK; |
(...skipping 21 matching lines...) Expand all Loading... |
3772 /* | 3719 /* |
3773 ** Information and control of an open file handle. | 3720 ** Information and control of an open file handle. |
3774 */ | 3721 */ |
3775 static int unixFileControl(sqlite3_file *id, int op, void *pArg){ | 3722 static int unixFileControl(sqlite3_file *id, int op, void *pArg){ |
3776 unixFile *pFile = (unixFile*)id; | 3723 unixFile *pFile = (unixFile*)id; |
3777 switch( op ){ | 3724 switch( op ){ |
3778 case SQLITE_FCNTL_LOCKSTATE: { | 3725 case SQLITE_FCNTL_LOCKSTATE: { |
3779 *(int*)pArg = pFile->eFileLock; | 3726 *(int*)pArg = pFile->eFileLock; |
3780 return SQLITE_OK; | 3727 return SQLITE_OK; |
3781 } | 3728 } |
3782 case SQLITE_LAST_ERRNO: { | 3729 case SQLITE_FCNTL_LAST_ERRNO: { |
3783 *(int*)pArg = pFile->lastErrno; | 3730 *(int*)pArg = pFile->lastErrno; |
3784 return SQLITE_OK; | 3731 return SQLITE_OK; |
3785 } | 3732 } |
3786 case SQLITE_FCNTL_CHUNK_SIZE: { | 3733 case SQLITE_FCNTL_CHUNK_SIZE: { |
3787 pFile->szChunk = *(int *)pArg; | 3734 pFile->szChunk = *(int *)pArg; |
3788 return SQLITE_OK; | 3735 return SQLITE_OK; |
3789 } | 3736 } |
3790 case SQLITE_FCNTL_SIZE_HINT: { | 3737 case SQLITE_FCNTL_SIZE_HINT: { |
3791 int rc; | 3738 int rc; |
3792 SimulateIOErrorBenign(1); | 3739 SimulateIOErrorBenign(1); |
3793 rc = fcntlSizeHint(pFile, *(i64 *)pArg); | 3740 rc = fcntlSizeHint(pFile, *(i64 *)pArg); |
3794 SimulateIOErrorBenign(0); | 3741 SimulateIOErrorBenign(0); |
3795 return rc; | 3742 return rc; |
3796 } | 3743 } |
3797 case SQLITE_FCNTL_PERSIST_WAL: { | 3744 case SQLITE_FCNTL_PERSIST_WAL: { |
3798 unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); | 3745 unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); |
3799 return SQLITE_OK; | 3746 return SQLITE_OK; |
3800 } | 3747 } |
3801 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { | 3748 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { |
3802 unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); | 3749 unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); |
3803 return SQLITE_OK; | 3750 return SQLITE_OK; |
3804 } | 3751 } |
3805 case SQLITE_FCNTL_VFSNAME: { | 3752 case SQLITE_FCNTL_VFSNAME: { |
3806 *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); | 3753 *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); |
3807 return SQLITE_OK; | 3754 return SQLITE_OK; |
3808 } | 3755 } |
3809 case SQLITE_FCNTL_TEMPFILENAME: { | 3756 case SQLITE_FCNTL_TEMPFILENAME: { |
3810 char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname ); | 3757 char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname ); |
3811 if( zTFile ){ | 3758 if( zTFile ){ |
3812 unixGetTempname(pFile->pVfs->mxPathname, zTFile); | 3759 unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
3813 *(char**)pArg = zTFile; | 3760 *(char**)pArg = zTFile; |
3814 } | 3761 } |
3815 return SQLITE_OK; | 3762 return SQLITE_OK; |
3816 } | 3763 } |
3817 case SQLITE_FCNTL_HAS_MOVED: { | 3764 case SQLITE_FCNTL_HAS_MOVED: { |
3818 *(int*)pArg = fileHasMoved(pFile); | 3765 *(int*)pArg = fileHasMoved(pFile); |
3819 return SQLITE_OK; | 3766 return SQLITE_OK; |
3820 } | 3767 } |
(...skipping 20 matching lines...) Expand all Loading... |
3841 ** a rollback and that the database is therefore unchanged and | 3788 ** a rollback and that the database is therefore unchanged and |
3842 ** it hence it is OK for the transaction change counter to be | 3789 ** it hence it is OK for the transaction change counter to be |
3843 ** unchanged. | 3790 ** unchanged. |
3844 */ | 3791 */ |
3845 case SQLITE_FCNTL_DB_UNCHANGED: { | 3792 case SQLITE_FCNTL_DB_UNCHANGED: { |
3846 ((unixFile*)id)->dbUpdate = 0; | 3793 ((unixFile*)id)->dbUpdate = 0; |
3847 return SQLITE_OK; | 3794 return SQLITE_OK; |
3848 } | 3795 } |
3849 #endif | 3796 #endif |
3850 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) | 3797 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) |
3851 case SQLITE_SET_LOCKPROXYFILE: | 3798 case SQLITE_FCNTL_SET_LOCKPROXYFILE: |
3852 case SQLITE_GET_LOCKPROXYFILE: { | 3799 case SQLITE_FCNTL_GET_LOCKPROXYFILE: { |
3853 return proxyFileControl(id,op,pArg); | 3800 return proxyFileControl(id,op,pArg); |
3854 } | 3801 } |
3855 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ | 3802 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ |
3856 } | 3803 } |
3857 return SQLITE_NOTFOUND; | 3804 return SQLITE_NOTFOUND; |
3858 } | 3805 } |
3859 | 3806 |
3860 /* | 3807 /* |
3861 ** Return the sector size in bytes of the underlying block device for | 3808 ** Return the sector size in bytes of the underlying block device for |
3862 ** the specified file. This is almost always 512 bytes, but may be | 3809 ** the specified file. This is almost always 512 bytes, but may be |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3982 | 3929 |
3983 #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 | 3930 #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
3984 | 3931 |
3985 /* | 3932 /* |
3986 ** Return the system page size. | 3933 ** Return the system page size. |
3987 ** | 3934 ** |
3988 ** This function should not be called directly by other code in this file. | 3935 ** This function should not be called directly by other code in this file. |
3989 ** Instead, it should be called via macro osGetpagesize(). | 3936 ** Instead, it should be called via macro osGetpagesize(). |
3990 */ | 3937 */ |
3991 static int unixGetpagesize(void){ | 3938 static int unixGetpagesize(void){ |
3992 #if defined(_BSD_SOURCE) | 3939 #if OS_VXWORKS |
| 3940 return 1024; |
| 3941 #elif defined(_BSD_SOURCE) |
3993 return getpagesize(); | 3942 return getpagesize(); |
3994 #else | 3943 #else |
3995 return (int)sysconf(_SC_PAGESIZE); | 3944 return (int)sysconf(_SC_PAGESIZE); |
3996 #endif | 3945 #endif |
3997 } | 3946 } |
3998 | 3947 |
3999 #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ | 3948 #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ |
4000 | 3949 |
4001 #ifndef SQLITE_OMIT_WAL | 3950 #ifndef SQLITE_OMIT_WAL |
4002 | 3951 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4075 #define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ | 4024 #define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ |
4076 #define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ | 4025 #define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ |
4077 | 4026 |
4078 /* | 4027 /* |
4079 ** Apply posix advisory locks for all bytes from ofst through ofst+n-1. | 4028 ** Apply posix advisory locks for all bytes from ofst through ofst+n-1. |
4080 ** | 4029 ** |
4081 ** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking | 4030 ** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking |
4082 ** otherwise. | 4031 ** otherwise. |
4083 */ | 4032 */ |
4084 static int unixShmSystemLock( | 4033 static int unixShmSystemLock( |
4085 unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */ | 4034 unixFile *pFile, /* Open connection to the WAL file */ |
4086 int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ | 4035 int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ |
4087 int ofst, /* First byte of the locking range */ | 4036 int ofst, /* First byte of the locking range */ |
4088 int n /* Number of bytes to lock */ | 4037 int n /* Number of bytes to lock */ |
4089 ){ | 4038 ){ |
4090 struct flock f; /* The posix advisory locking structure */ | 4039 unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */ |
4091 int rc = SQLITE_OK; /* Result code form fcntl() */ | 4040 struct flock f; /* The posix advisory locking structure */ |
| 4041 int rc = SQLITE_OK; /* Result code form fcntl() */ |
4092 | 4042 |
4093 /* Access to the unixShmNode object is serialized by the caller */ | 4043 /* Access to the unixShmNode object is serialized by the caller */ |
| 4044 pShmNode = pFile->pInode->pShmNode; |
4094 assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); | 4045 assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); |
4095 | 4046 |
4096 /* Shared locks never span more than one byte */ | 4047 /* Shared locks never span more than one byte */ |
4097 assert( n==1 || lockType!=F_RDLCK ); | 4048 assert( n==1 || lockType!=F_RDLCK ); |
4098 | 4049 |
4099 /* Locks are within range */ | 4050 /* Locks are within range */ |
4100 assert( n>=1 && n<SQLITE_SHM_NLOCK ); | 4051 assert( n>=1 && n<=SQLITE_SHM_NLOCK ); |
4101 | 4052 |
4102 if( pShmNode->h>=0 ){ | 4053 if( pShmNode->h>=0 ){ |
4103 /* Initialize the locking parameters */ | 4054 /* Initialize the locking parameters */ |
4104 memset(&f, 0, sizeof(f)); | 4055 memset(&f, 0, sizeof(f)); |
4105 f.l_type = lockType; | 4056 f.l_type = lockType; |
4106 f.l_whence = SEEK_SET; | 4057 f.l_whence = SEEK_SET; |
4107 f.l_start = ofst; | 4058 f.l_start = ofst; |
4108 f.l_len = n; | 4059 f.l_len = n; |
4109 | 4060 |
4110 rc = osFcntl(pShmNode->h, F_SETLK, &f); | 4061 rc = osFcntl(pShmNode->h, F_SETLK, &f); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4168 | 4119 |
4169 /* | 4120 /* |
4170 ** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0. | 4121 ** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0. |
4171 ** | 4122 ** |
4172 ** This is not a VFS shared-memory method; it is a utility function called | 4123 ** This is not a VFS shared-memory method; it is a utility function called |
4173 ** by VFS shared-memory methods. | 4124 ** by VFS shared-memory methods. |
4174 */ | 4125 */ |
4175 static void unixShmPurge(unixFile *pFd){ | 4126 static void unixShmPurge(unixFile *pFd){ |
4176 unixShmNode *p = pFd->pInode->pShmNode; | 4127 unixShmNode *p = pFd->pInode->pShmNode; |
4177 assert( unixMutexHeld() ); | 4128 assert( unixMutexHeld() ); |
4178 if( p && p->nRef==0 ){ | 4129 if( p && ALWAYS(p->nRef==0) ){ |
4179 int nShmPerMap = unixShmRegionPerMap(); | 4130 int nShmPerMap = unixShmRegionPerMap(); |
4180 int i; | 4131 int i; |
4181 assert( p->pInode==pFd->pInode ); | 4132 assert( p->pInode==pFd->pInode ); |
4182 sqlite3_mutex_free(p->mutex); | 4133 sqlite3_mutex_free(p->mutex); |
4183 for(i=0; i<p->nRegion; i+=nShmPerMap){ | 4134 for(i=0; i<p->nRegion; i+=nShmPerMap){ |
4184 if( p->h>=0 ){ | 4135 if( p->h>=0 ){ |
4185 osMunmap(p->apRegion[i], p->szRegion); | 4136 osMunmap(p->apRegion[i], p->szRegion); |
4186 }else{ | 4137 }else{ |
4187 sqlite3_free(p->apRegion[i]); | 4138 sqlite3_free(p->apRegion[i]); |
4188 } | 4139 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4234 */ | 4185 */ |
4235 static int unixOpenSharedMemory(unixFile *pDbFd){ | 4186 static int unixOpenSharedMemory(unixFile *pDbFd){ |
4236 struct unixShm *p = 0; /* The connection to be opened */ | 4187 struct unixShm *p = 0; /* The connection to be opened */ |
4237 struct unixShmNode *pShmNode; /* The underlying mmapped file */ | 4188 struct unixShmNode *pShmNode; /* The underlying mmapped file */ |
4238 int rc; /* Result code */ | 4189 int rc; /* Result code */ |
4239 unixInodeInfo *pInode; /* The inode of fd */ | 4190 unixInodeInfo *pInode; /* The inode of fd */ |
4240 char *zShmFilename; /* Name of the file used for SHM */ | 4191 char *zShmFilename; /* Name of the file used for SHM */ |
4241 int nShmFilename; /* Size of the SHM filename in bytes */ | 4192 int nShmFilename; /* Size of the SHM filename in bytes */ |
4242 | 4193 |
4243 /* Allocate space for the new unixShm object. */ | 4194 /* Allocate space for the new unixShm object. */ |
4244 p = sqlite3_malloc( sizeof(*p) ); | 4195 p = sqlite3_malloc64( sizeof(*p) ); |
4245 if( p==0 ) return SQLITE_NOMEM; | 4196 if( p==0 ) return SQLITE_NOMEM; |
4246 memset(p, 0, sizeof(*p)); | 4197 memset(p, 0, sizeof(*p)); |
4247 assert( pDbFd->pShm==0 ); | 4198 assert( pDbFd->pShm==0 ); |
4248 | 4199 |
4249 /* Check to see if a unixShmNode object already exists. Reuse an existing | 4200 /* Check to see if a unixShmNode object already exists. Reuse an existing |
4250 ** one if present. Create a new one if necessary. | 4201 ** one if present. Create a new one if necessary. |
4251 */ | 4202 */ |
4252 unixEnterMutex(); | 4203 unixEnterMutex(); |
4253 pInode = pDbFd->pInode; | 4204 pInode = pDbFd->pInode; |
4254 pShmNode = pInode->pShmNode; | 4205 pShmNode = pInode->pShmNode; |
4255 if( pShmNode==0 ){ | 4206 if( pShmNode==0 ){ |
4256 struct stat sStat; /* fstat() info for database file */ | 4207 struct stat sStat; /* fstat() info for database file */ |
| 4208 #ifndef SQLITE_SHM_DIRECTORY |
| 4209 const char *zBasePath = pDbFd->zPath; |
| 4210 #endif |
4257 | 4211 |
4258 /* Call fstat() to figure out the permissions on the database file. If | 4212 /* Call fstat() to figure out the permissions on the database file. If |
4259 ** a new *-shm file is created, an attempt will be made to create it | 4213 ** a new *-shm file is created, an attempt will be made to create it |
4260 ** with the same permissions. | 4214 ** with the same permissions. |
4261 */ | 4215 */ |
4262 if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ | 4216 if( osFstat(pDbFd->h, &sStat) ){ |
4263 rc = SQLITE_IOERR_FSTAT; | 4217 rc = SQLITE_IOERR_FSTAT; |
4264 goto shm_open_err; | 4218 goto shm_open_err; |
4265 } | 4219 } |
4266 | 4220 |
4267 #ifdef SQLITE_SHM_DIRECTORY | 4221 #ifdef SQLITE_SHM_DIRECTORY |
4268 nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; | 4222 nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; |
4269 #else | 4223 #else |
4270 nShmFilename = 6 + (int)strlen(pDbFd->zPath); | 4224 nShmFilename = 6 + (int)strlen(zBasePath); |
4271 #endif | 4225 #endif |
4272 pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename ); | 4226 pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); |
4273 if( pShmNode==0 ){ | 4227 if( pShmNode==0 ){ |
4274 rc = SQLITE_NOMEM; | 4228 rc = SQLITE_NOMEM; |
4275 goto shm_open_err; | 4229 goto shm_open_err; |
4276 } | 4230 } |
4277 memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); | 4231 memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); |
4278 zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; | 4232 zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; |
4279 #ifdef SQLITE_SHM_DIRECTORY | 4233 #ifdef SQLITE_SHM_DIRECTORY |
4280 sqlite3_snprintf(nShmFilename, zShmFilename, | 4234 sqlite3_snprintf(nShmFilename, zShmFilename, |
4281 SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", | 4235 SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", |
4282 (u32)sStat.st_ino, (u32)sStat.st_dev); | 4236 (u32)sStat.st_ino, (u32)sStat.st_dev); |
4283 #else | 4237 #else |
4284 sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath); | 4238 sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); |
4285 sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); | 4239 sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); |
4286 #endif | 4240 #endif |
4287 pShmNode->h = -1; | 4241 pShmNode->h = -1; |
4288 pDbFd->pInode->pShmNode = pShmNode; | 4242 pDbFd->pInode->pShmNode = pShmNode; |
4289 pShmNode->pInode = pDbFd->pInode; | 4243 pShmNode->pInode = pDbFd->pInode; |
4290 pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); | 4244 pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); |
4291 if( pShmNode->mutex==0 ){ | 4245 if( pShmNode->mutex==0 ){ |
4292 rc = SQLITE_NOMEM; | 4246 rc = SQLITE_NOMEM; |
4293 goto shm_open_err; | 4247 goto shm_open_err; |
4294 } | 4248 } |
4295 | 4249 |
4296 if( pInode->bProcessLock==0 ){ | 4250 if( pInode->bProcessLock==0 ){ |
4297 int openFlags = O_RDWR | O_CREAT; | 4251 int openFlags = O_RDWR | O_CREAT; |
4298 if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ | 4252 if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ |
4299 openFlags = O_RDONLY; | 4253 openFlags = O_RDONLY; |
4300 pShmNode->isReadonly = 1; | 4254 pShmNode->isReadonly = 1; |
4301 } | 4255 } |
4302 pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); | 4256 pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); |
4303 if( pShmNode->h<0 ){ | 4257 if( pShmNode->h<0 ){ |
4304 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); | 4258 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
4305 goto shm_open_err; | 4259 goto shm_open_err; |
4306 } | 4260 } |
4307 | 4261 |
4308 /* If this process is running as root, make sure that the SHM file | 4262 /* If this process is running as root, make sure that the SHM file |
4309 ** is owned by the same user that owns the original database. Otherwise, | 4263 ** is owned by the same user that owns the original database. Otherwise, |
4310 ** the original owner will not be able to connect. | 4264 ** the original owner will not be able to connect. |
4311 */ | 4265 */ |
4312 osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); | 4266 robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); |
4313 | 4267 |
4314 /* Check to see if another process is holding the dead-man switch. | 4268 /* Check to see if another process is holding the dead-man switch. |
4315 ** If not, truncate the file to zero length. | 4269 ** If not, truncate the file to zero length. |
4316 */ | 4270 */ |
4317 rc = SQLITE_OK; | 4271 rc = SQLITE_OK; |
4318 if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ | 4272 if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ |
4319 if( robust_ftruncate(pShmNode->h, 0) ){ | 4273 if( robust_ftruncate(pShmNode->h, 0) ){ |
4320 rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); | 4274 rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); |
4321 } | 4275 } |
4322 } | 4276 } |
4323 if( rc==SQLITE_OK ){ | 4277 if( rc==SQLITE_OK ){ |
4324 rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); | 4278 rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); |
4325 } | 4279 } |
4326 if( rc ) goto shm_open_err; | 4280 if( rc ) goto shm_open_err; |
4327 } | 4281 } |
4328 } | 4282 } |
4329 | 4283 |
4330 /* Make the new connection a child of the unixShmNode */ | 4284 /* Make the new connection a child of the unixShmNode */ |
4331 p->pShmNode = pShmNode; | 4285 p->pShmNode = pShmNode; |
4332 #ifdef SQLITE_DEBUG | 4286 #ifdef SQLITE_DEBUG |
4333 p->id = pShmNode->nextShmId++; | 4287 p->id = pShmNode->nextShmId++; |
4334 #endif | 4288 #endif |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4439 ** pages forces the OS to allocate them immediately, which reduces | 4393 ** pages forces the OS to allocate them immediately, which reduces |
4440 ** the chances of SIGBUS while accessing the mapped region later on. | 4394 ** the chances of SIGBUS while accessing the mapped region later on. |
4441 */ | 4395 */ |
4442 else{ | 4396 else{ |
4443 static const int pgsz = 4096; | 4397 static const int pgsz = 4096; |
4444 int iPg; | 4398 int iPg; |
4445 | 4399 |
4446 /* Write to the last byte of each newly allocated or extended page */ | 4400 /* Write to the last byte of each newly allocated or extended page */ |
4447 assert( (nByte % pgsz)==0 ); | 4401 assert( (nByte % pgsz)==0 ); |
4448 for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){ | 4402 for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){ |
4449 if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){ | 4403 int x = 0; |
| 4404 if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){ |
4450 const char *zFile = pShmNode->zFilename; | 4405 const char *zFile = pShmNode->zFilename; |
4451 rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); | 4406 rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); |
4452 goto shmpage_out; | 4407 goto shmpage_out; |
4453 } | 4408 } |
4454 } | 4409 } |
4455 } | 4410 } |
4456 } | 4411 } |
4457 } | 4412 } |
4458 | 4413 |
4459 /* Map the requested memory region into this processes address space. */ | 4414 /* Map the requested memory region into this processes address space. */ |
(...skipping 12 matching lines...) Expand all Loading... |
4472 if( pShmNode->h>=0 ){ | 4427 if( pShmNode->h>=0 ){ |
4473 pMem = osMmap(0, nMap, | 4428 pMem = osMmap(0, nMap, |
4474 pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, | 4429 pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
4475 MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion | 4430 MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion |
4476 ); | 4431 ); |
4477 if( pMem==MAP_FAILED ){ | 4432 if( pMem==MAP_FAILED ){ |
4478 rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); | 4433 rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
4479 goto shmpage_out; | 4434 goto shmpage_out; |
4480 } | 4435 } |
4481 }else{ | 4436 }else{ |
4482 pMem = sqlite3_malloc(szRegion); | 4437 pMem = sqlite3_malloc64(szRegion); |
4483 if( pMem==0 ){ | 4438 if( pMem==0 ){ |
4484 rc = SQLITE_NOMEM; | 4439 rc = SQLITE_NOMEM; |
4485 goto shmpage_out; | 4440 goto shmpage_out; |
4486 } | 4441 } |
4487 memset(pMem, 0, szRegion); | 4442 memset(pMem, 0, szRegion); |
4488 } | 4443 } |
4489 | 4444 |
4490 for(i=0; i<nShmPerMap; i++){ | 4445 for(i=0; i<nShmPerMap; i++){ |
4491 pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; | 4446 pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; |
4492 } | 4447 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4546 | 4501 |
4547 /* See if any siblings hold this same lock */ | 4502 /* See if any siblings hold this same lock */ |
4548 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ | 4503 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ |
4549 if( pX==p ) continue; | 4504 if( pX==p ) continue; |
4550 assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); | 4505 assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); |
4551 allMask |= pX->sharedMask; | 4506 allMask |= pX->sharedMask; |
4552 } | 4507 } |
4553 | 4508 |
4554 /* Unlock the system-level locks */ | 4509 /* Unlock the system-level locks */ |
4555 if( (mask & allMask)==0 ){ | 4510 if( (mask & allMask)==0 ){ |
4556 rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n); | 4511 rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); |
4557 }else{ | 4512 }else{ |
4558 rc = SQLITE_OK; | 4513 rc = SQLITE_OK; |
4559 } | 4514 } |
4560 | 4515 |
4561 /* Undo the local locks */ | 4516 /* Undo the local locks */ |
4562 if( rc==SQLITE_OK ){ | 4517 if( rc==SQLITE_OK ){ |
4563 p->exclMask &= ~mask; | 4518 p->exclMask &= ~mask; |
4564 p->sharedMask &= ~mask; | 4519 p->sharedMask &= ~mask; |
4565 } | 4520 } |
4566 }else if( flags & SQLITE_SHM_SHARED ){ | 4521 }else if( flags & SQLITE_SHM_SHARED ){ |
4567 u16 allShared = 0; /* Union of locks held by connections other than "p" */ | 4522 u16 allShared = 0; /* Union of locks held by connections other than "p" */ |
4568 | 4523 |
4569 /* Find out which shared locks are already held by sibling connections. | 4524 /* Find out which shared locks are already held by sibling connections. |
4570 ** If any sibling already holds an exclusive lock, go ahead and return | 4525 ** If any sibling already holds an exclusive lock, go ahead and return |
4571 ** SQLITE_BUSY. | 4526 ** SQLITE_BUSY. |
4572 */ | 4527 */ |
4573 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ | 4528 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ |
4574 if( (pX->exclMask & mask)!=0 ){ | 4529 if( (pX->exclMask & mask)!=0 ){ |
4575 rc = SQLITE_BUSY; | 4530 rc = SQLITE_BUSY; |
4576 break; | 4531 break; |
4577 } | 4532 } |
4578 allShared |= pX->sharedMask; | 4533 allShared |= pX->sharedMask; |
4579 } | 4534 } |
4580 | 4535 |
4581 /* Get shared locks at the system level, if necessary */ | 4536 /* Get shared locks at the system level, if necessary */ |
4582 if( rc==SQLITE_OK ){ | 4537 if( rc==SQLITE_OK ){ |
4583 if( (allShared & mask)==0 ){ | 4538 if( (allShared & mask)==0 ){ |
4584 rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n); | 4539 rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); |
4585 }else{ | 4540 }else{ |
4586 rc = SQLITE_OK; | 4541 rc = SQLITE_OK; |
4587 } | 4542 } |
4588 } | 4543 } |
4589 | 4544 |
4590 /* Get the local shared locks */ | 4545 /* Get the local shared locks */ |
4591 if( rc==SQLITE_OK ){ | 4546 if( rc==SQLITE_OK ){ |
4592 p->sharedMask |= mask; | 4547 p->sharedMask |= mask; |
4593 } | 4548 } |
4594 }else{ | 4549 }else{ |
4595 /* Make sure no sibling connections hold locks that will block this | 4550 /* Make sure no sibling connections hold locks that will block this |
4596 ** lock. If any do, return SQLITE_BUSY right away. | 4551 ** lock. If any do, return SQLITE_BUSY right away. |
4597 */ | 4552 */ |
4598 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ | 4553 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ |
4599 if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ | 4554 if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ |
4600 rc = SQLITE_BUSY; | 4555 rc = SQLITE_BUSY; |
4601 break; | 4556 break; |
4602 } | 4557 } |
4603 } | 4558 } |
4604 | 4559 |
4605 /* Get the exclusive locks at the system level. Then if successful | 4560 /* Get the exclusive locks at the system level. Then if successful |
4606 ** also mark the local connection as being locked. | 4561 ** also mark the local connection as being locked. |
4607 */ | 4562 */ |
4608 if( rc==SQLITE_OK ){ | 4563 if( rc==SQLITE_OK ){ |
4609 rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n); | 4564 rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); |
4610 if( rc==SQLITE_OK ){ | 4565 if( rc==SQLITE_OK ){ |
4611 assert( (p->sharedMask & mask)==0 ); | 4566 assert( (p->sharedMask & mask)==0 ); |
4612 p->exclMask |= mask; | 4567 p->exclMask |= mask; |
4613 } | 4568 } |
4614 } | 4569 } |
4615 } | 4570 } |
4616 sqlite3_mutex_leave(pShmNode->mutex); | 4571 sqlite3_mutex_leave(pShmNode->mutex); |
4617 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", | 4572 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", |
4618 p->id, getpid(), p->sharedMask, p->exclMask)); | 4573 p->id, osGetpid(0), p->sharedMask, p->exclMask)); |
4619 return rc; | 4574 return rc; |
4620 } | 4575 } |
4621 | 4576 |
4622 /* | 4577 /* |
4623 ** Implement a memory barrier or memory fence on shared memory. | 4578 ** Implement a memory barrier or memory fence on shared memory. |
4624 ** | 4579 ** |
4625 ** All loads and stores begun before the barrier must complete before | 4580 ** All loads and stores begun before the barrier must complete before |
4626 ** any load or store begun after the barrier. | 4581 ** any load or store begun after the barrier. |
4627 */ | 4582 */ |
4628 static void unixShmBarrier( | 4583 static void unixShmBarrier( |
4629 sqlite3_file *fd /* Database file holding the shared memory */ | 4584 sqlite3_file *fd /* Database file holding the shared memory */ |
4630 ){ | 4585 ){ |
4631 UNUSED_PARAMETER(fd); | 4586 UNUSED_PARAMETER(fd); |
4632 unixEnterMutex(); | 4587 sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ |
| 4588 unixEnterMutex(); /* Also mutex, for redundancy */ |
4633 unixLeaveMutex(); | 4589 unixLeaveMutex(); |
4634 } | 4590 } |
4635 | 4591 |
4636 /* | 4592 /* |
4637 ** Close a connection to shared-memory. Delete the underlying | 4593 ** Close a connection to shared-memory. Delete the underlying |
4638 ** storage if deleteFlag is true. | 4594 ** storage if deleteFlag is true. |
4639 ** | 4595 ** |
4640 ** If there is no shared memory associated with the connection then this | 4596 ** If there is no shared memory associated with the connection then this |
4641 ** routine is a harmless no-op. | 4597 ** routine is a harmless no-op. |
4642 */ | 4598 */ |
(...skipping 24 matching lines...) Expand all Loading... |
4667 sqlite3_free(p); | 4623 sqlite3_free(p); |
4668 pDbFd->pShm = 0; | 4624 pDbFd->pShm = 0; |
4669 sqlite3_mutex_leave(pShmNode->mutex); | 4625 sqlite3_mutex_leave(pShmNode->mutex); |
4670 | 4626 |
4671 /* If pShmNode->nRef has reached 0, then close the underlying | 4627 /* If pShmNode->nRef has reached 0, then close the underlying |
4672 ** shared-memory file, too */ | 4628 ** shared-memory file, too */ |
4673 unixEnterMutex(); | 4629 unixEnterMutex(); |
4674 assert( pShmNode->nRef>0 ); | 4630 assert( pShmNode->nRef>0 ); |
4675 pShmNode->nRef--; | 4631 pShmNode->nRef--; |
4676 if( pShmNode->nRef==0 ){ | 4632 if( pShmNode->nRef==0 ){ |
4677 if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename); | 4633 if( deleteFlag && pShmNode->h>=0 ){ |
| 4634 osUnlink(pShmNode->zFilename); |
| 4635 } |
4678 unixShmPurge(pDbFd); | 4636 unixShmPurge(pDbFd); |
4679 } | 4637 } |
4680 unixLeaveMutex(); | 4638 unixLeaveMutex(); |
4681 | 4639 |
4682 return SQLITE_OK; | 4640 return SQLITE_OK; |
4683 } | 4641 } |
4684 | 4642 |
4685 | 4643 |
4686 #else | 4644 #else |
4687 # define unixShmMap 0 | 4645 # define unixShmMap 0 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4730 u8 *pNew = 0; /* Location of new mapping */ | 4688 u8 *pNew = 0; /* Location of new mapping */ |
4731 int flags = PROT_READ; /* Flags to pass to mmap() */ | 4689 int flags = PROT_READ; /* Flags to pass to mmap() */ |
4732 | 4690 |
4733 assert( pFd->nFetchOut==0 ); | 4691 assert( pFd->nFetchOut==0 ); |
4734 assert( nNew>pFd->mmapSize ); | 4692 assert( nNew>pFd->mmapSize ); |
4735 assert( nNew<=pFd->mmapSizeMax ); | 4693 assert( nNew<=pFd->mmapSizeMax ); |
4736 assert( nNew>0 ); | 4694 assert( nNew>0 ); |
4737 assert( pFd->mmapSizeActual>=pFd->mmapSize ); | 4695 assert( pFd->mmapSizeActual>=pFd->mmapSize ); |
4738 assert( MAP_FAILED!=0 ); | 4696 assert( MAP_FAILED!=0 ); |
4739 | 4697 |
| 4698 #ifdef SQLITE_MMAP_READWRITE |
4740 if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; | 4699 if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; |
| 4700 #endif |
4741 | 4701 |
4742 if( pOrig ){ | 4702 if( pOrig ){ |
4743 #if HAVE_MREMAP | 4703 #if HAVE_MREMAP |
4744 i64 nReuse = pFd->mmapSize; | 4704 i64 nReuse = pFd->mmapSize; |
4745 #else | 4705 #else |
4746 const int szSyspage = osGetpagesize(); | 4706 const int szSyspage = osGetpagesize(); |
4747 i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); | 4707 i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); |
4748 #endif | 4708 #endif |
4749 u8 *pReq = &pOrig[nReuse]; | 4709 u8 *pReq = &pOrig[nReuse]; |
4750 | 4710 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4802 ** If parameter nByte is non-negative, then it is the requested size of | 4762 ** If parameter nByte is non-negative, then it is the requested size of |
4803 ** the mapping to create. Otherwise, if nByte is less than zero, then the | 4763 ** the mapping to create. Otherwise, if nByte is less than zero, then the |
4804 ** requested size is the size of the file on disk. The actual size of the | 4764 ** requested size is the size of the file on disk. The actual size of the |
4805 ** created mapping is either the requested size or the value configured | 4765 ** created mapping is either the requested size or the value configured |
4806 ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. | 4766 ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. |
4807 ** | 4767 ** |
4808 ** SQLITE_OK is returned if no error occurs (even if the mapping is not | 4768 ** SQLITE_OK is returned if no error occurs (even if the mapping is not |
4809 ** recreated as a result of outstanding references) or an SQLite error | 4769 ** recreated as a result of outstanding references) or an SQLite error |
4810 ** code otherwise. | 4770 ** code otherwise. |
4811 */ | 4771 */ |
4812 static int unixMapfile(unixFile *pFd, i64 nByte){ | 4772 static int unixMapfile(unixFile *pFd, i64 nMap){ |
4813 i64 nMap = nByte; | |
4814 int rc; | |
4815 | |
4816 assert( nMap>=0 || pFd->nFetchOut==0 ); | 4773 assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 4774 assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); |
4817 if( pFd->nFetchOut>0 ) return SQLITE_OK; | 4775 if( pFd->nFetchOut>0 ) return SQLITE_OK; |
4818 | 4776 |
4819 if( nMap<0 ){ | 4777 if( nMap<0 ){ |
4820 struct stat statbuf; /* Low-level file information */ | 4778 struct stat statbuf; /* Low-level file information */ |
4821 rc = osFstat(pFd->h, &statbuf); | 4779 if( osFstat(pFd->h, &statbuf) ){ |
4822 if( rc!=SQLITE_OK ){ | |
4823 return SQLITE_IOERR_FSTAT; | 4780 return SQLITE_IOERR_FSTAT; |
4824 } | 4781 } |
4825 nMap = statbuf.st_size; | 4782 nMap = statbuf.st_size; |
4826 } | 4783 } |
4827 if( nMap>pFd->mmapSizeMax ){ | 4784 if( nMap>pFd->mmapSizeMax ){ |
4828 nMap = pFd->mmapSizeMax; | 4785 nMap = pFd->mmapSizeMax; |
4829 } | 4786 } |
4830 | 4787 |
| 4788 assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); |
4831 if( nMap!=pFd->mmapSize ){ | 4789 if( nMap!=pFd->mmapSize ){ |
4832 if( nMap>0 ){ | 4790 unixRemapfile(pFd, nMap); |
4833 unixRemapfile(pFd, nMap); | |
4834 }else{ | |
4835 unixUnmapfile(pFd); | |
4836 } | |
4837 } | 4791 } |
4838 | 4792 |
4839 return SQLITE_OK; | 4793 return SQLITE_OK; |
4840 } | 4794 } |
4841 #endif /* SQLITE_MAX_MMAP_SIZE>0 */ | 4795 #endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
4842 | 4796 |
4843 /* | 4797 /* |
4844 ** If possible, return a pointer to a mapping of file fd starting at offset | 4798 ** If possible, return a pointer to a mapping of file fd starting at offset |
4845 ** iOff. The mapping must be valid for at least nAmt bytes. | 4799 ** iOff. The mapping must be valid for at least nAmt bytes. |
4846 ** | 4800 ** |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4944 ** | 4898 ** |
4945 ** | 4899 ** |
4946 ** Each instance of this macro generates two objects: | 4900 ** Each instance of this macro generates two objects: |
4947 ** | 4901 ** |
4948 ** * A constant sqlite3_io_methods object call METHOD that has locking | 4902 ** * A constant sqlite3_io_methods object call METHOD that has locking |
4949 ** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. | 4903 ** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. |
4950 ** | 4904 ** |
4951 ** * An I/O method finder function called FINDER that returns a pointer | 4905 ** * An I/O method finder function called FINDER that returns a pointer |
4952 ** to the METHOD object in the previous bullet. | 4906 ** to the METHOD object in the previous bullet. |
4953 */ | 4907 */ |
4954 #define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP)
\ | 4908 #define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \ |
4955 static const sqlite3_io_methods METHOD = { \ | 4909 static const sqlite3_io_methods METHOD = { \ |
4956 VERSION, /* iVersion */ \ | 4910 VERSION, /* iVersion */ \ |
4957 CLOSE, /* xClose */ \ | 4911 CLOSE, /* xClose */ \ |
4958 unixRead, /* xRead */ \ | 4912 unixRead, /* xRead */ \ |
4959 unixWrite, /* xWrite */ \ | 4913 unixWrite, /* xWrite */ \ |
4960 unixTruncate, /* xTruncate */ \ | 4914 unixTruncate, /* xTruncate */ \ |
4961 unixSync, /* xSync */ \ | 4915 unixSync, /* xSync */ \ |
4962 unixFileSize, /* xFileSize */ \ | 4916 unixFileSize, /* xFileSize */ \ |
4963 LOCK, /* xLock */ \ | 4917 LOCK, /* xLock */ \ |
4964 UNLOCK, /* xUnlock */ \ | 4918 UNLOCK, /* xUnlock */ \ |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5009 dotlockIoFinder, /* Finder function name */ | 4963 dotlockIoFinder, /* Finder function name */ |
5010 dotlockIoMethods, /* sqlite3_io_methods object name */ | 4964 dotlockIoMethods, /* sqlite3_io_methods object name */ |
5011 1, /* shared memory is disabled */ | 4965 1, /* shared memory is disabled */ |
5012 dotlockClose, /* xClose method */ | 4966 dotlockClose, /* xClose method */ |
5013 dotlockLock, /* xLock method */ | 4967 dotlockLock, /* xLock method */ |
5014 dotlockUnlock, /* xUnlock method */ | 4968 dotlockUnlock, /* xUnlock method */ |
5015 dotlockCheckReservedLock, /* xCheckReservedLock method */ | 4969 dotlockCheckReservedLock, /* xCheckReservedLock method */ |
5016 0 /* xShmMap method */ | 4970 0 /* xShmMap method */ |
5017 ) | 4971 ) |
5018 | 4972 |
5019 #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS | 4973 #if SQLITE_ENABLE_LOCKING_STYLE |
5020 IOMETHODS( | 4974 IOMETHODS( |
5021 flockIoFinder, /* Finder function name */ | 4975 flockIoFinder, /* Finder function name */ |
5022 flockIoMethods, /* sqlite3_io_methods object name */ | 4976 flockIoMethods, /* sqlite3_io_methods object name */ |
5023 1, /* shared memory is disabled */ | 4977 1, /* shared memory is disabled */ |
5024 flockClose, /* xClose method */ | 4978 flockClose, /* xClose method */ |
5025 flockLock, /* xLock method */ | 4979 flockLock, /* xLock method */ |
5026 flockUnlock, /* xUnlock method */ | 4980 flockUnlock, /* xUnlock method */ |
5027 flockCheckReservedLock, /* xCheckReservedLock method */ | 4981 flockCheckReservedLock, /* xCheckReservedLock method */ |
5028 0 /* xShmMap method */ | 4982 0 /* xShmMap method */ |
5029 ) | 4983 ) |
5030 #endif | 4984 #endif |
5031 | 4985 |
5032 #if OS_VXWORKS | 4986 #if OS_VXWORKS |
5033 IOMETHODS( | 4987 IOMETHODS( |
5034 semIoFinder, /* Finder function name */ | 4988 semIoFinder, /* Finder function name */ |
5035 semIoMethods, /* sqlite3_io_methods object name */ | 4989 semIoMethods, /* sqlite3_io_methods object name */ |
5036 1, /* shared memory is disabled */ | 4990 1, /* shared memory is disabled */ |
5037 semClose, /* xClose method */ | 4991 semXClose, /* xClose method */ |
5038 semLock, /* xLock method */ | 4992 semXLock, /* xLock method */ |
5039 semUnlock, /* xUnlock method */ | 4993 semXUnlock, /* xUnlock method */ |
5040 semCheckReservedLock, /* xCheckReservedLock method */ | 4994 semXCheckReservedLock, /* xCheckReservedLock method */ |
5041 0 /* xShmMap method */ | 4995 0 /* xShmMap method */ |
5042 ) | 4996 ) |
5043 #endif | 4997 #endif |
5044 | 4998 |
5045 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE | 4999 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
5046 IOMETHODS( | 5000 IOMETHODS( |
5047 afpIoFinder, /* Finder function name */ | 5001 afpIoFinder, /* Finder function name */ |
5048 afpIoMethods, /* sqlite3_io_methods object name */ | 5002 afpIoMethods, /* sqlite3_io_methods object name */ |
5049 1, /* shared memory is disabled */ | 5003 1, /* shared memory is disabled */ |
5050 afpClose, /* xClose method */ | 5004 afpClose, /* xClose method */ |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5154 } | 5108 } |
5155 }else{ | 5109 }else{ |
5156 return &dotlockIoMethods; | 5110 return &dotlockIoMethods; |
5157 } | 5111 } |
5158 } | 5112 } |
5159 static const sqlite3_io_methods | 5113 static const sqlite3_io_methods |
5160 *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; | 5114 *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; |
5161 | 5115 |
5162 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ | 5116 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ |
5163 | 5117 |
5164 #if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE | 5118 #if OS_VXWORKS |
5165 /* | 5119 /* |
5166 ** This "finder" function attempts to determine the best locking strategy | 5120 ** This "finder" function for VxWorks checks to see if posix advisory |
5167 ** for the database file "filePath". It then returns the sqlite3_io_methods | 5121 ** locking works. If it does, then that is what is used. If it does not |
5168 ** object that implements that strategy. | 5122 ** work, then fallback to named semaphore locking. |
5169 ** | |
5170 ** This is for VXWorks only. | |
5171 */ | 5123 */ |
5172 static const sqlite3_io_methods *autolockIoFinderImpl( | 5124 static const sqlite3_io_methods *vxworksIoFinderImpl( |
5173 const char *filePath, /* name of the database file */ | 5125 const char *filePath, /* name of the database file */ |
5174 unixFile *pNew /* the open file object */ | 5126 unixFile *pNew /* the open file object */ |
5175 ){ | 5127 ){ |
5176 struct flock lockInfo; | 5128 struct flock lockInfo; |
5177 | 5129 |
5178 if( !filePath ){ | 5130 if( !filePath ){ |
5179 /* If filePath==NULL that means we are dealing with a transient file | 5131 /* If filePath==NULL that means we are dealing with a transient file |
5180 ** that does not need to be locked. */ | 5132 ** that does not need to be locked. */ |
5181 return &nolockIoMethods; | 5133 return &nolockIoMethods; |
5182 } | 5134 } |
5183 | 5135 |
5184 /* Test if fcntl() is supported and use POSIX style locks. | 5136 /* Test if fcntl() is supported and use POSIX style locks. |
5185 ** Otherwise fall back to the named semaphore method. | 5137 ** Otherwise fall back to the named semaphore method. |
5186 */ | 5138 */ |
5187 lockInfo.l_len = 1; | 5139 lockInfo.l_len = 1; |
5188 lockInfo.l_start = 0; | 5140 lockInfo.l_start = 0; |
5189 lockInfo.l_whence = SEEK_SET; | 5141 lockInfo.l_whence = SEEK_SET; |
5190 lockInfo.l_type = F_RDLCK; | 5142 lockInfo.l_type = F_RDLCK; |
5191 if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { | 5143 if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { |
5192 return &posixIoMethods; | 5144 return &posixIoMethods; |
5193 }else{ | 5145 }else{ |
5194 return &semIoMethods; | 5146 return &semIoMethods; |
5195 } | 5147 } |
5196 } | 5148 } |
5197 static const sqlite3_io_methods | 5149 static const sqlite3_io_methods |
5198 *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; | 5150 *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; |
5199 | 5151 |
5200 #endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ | 5152 #endif /* OS_VXWORKS */ |
5201 | 5153 |
5202 /* | 5154 /* |
5203 ** An abstract type for a pointer to an IO method finder function: | 5155 ** An abstract type for a pointer to an IO method finder function: |
5204 */ | 5156 */ |
5205 typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); | 5157 typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); |
5206 | 5158 |
5207 | 5159 |
5208 /**************************************************************************** | 5160 /**************************************************************************** |
5209 **************************** sqlite3_vfs methods **************************** | 5161 **************************** sqlite3_vfs methods **************************** |
5210 ** | 5162 ** |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5309 } | 5261 } |
5310 unixLeaveMutex(); | 5262 unixLeaveMutex(); |
5311 } | 5263 } |
5312 | 5264 |
5313 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) | 5265 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) |
5314 else if( pLockingStyle == &afpIoMethods ){ | 5266 else if( pLockingStyle == &afpIoMethods ){ |
5315 /* AFP locking uses the file path so it needs to be included in | 5267 /* AFP locking uses the file path so it needs to be included in |
5316 ** the afpLockingContext. | 5268 ** the afpLockingContext. |
5317 */ | 5269 */ |
5318 afpLockingContext *pCtx; | 5270 afpLockingContext *pCtx; |
5319 pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) ); | 5271 pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) ); |
5320 if( pCtx==0 ){ | 5272 if( pCtx==0 ){ |
5321 rc = SQLITE_NOMEM; | 5273 rc = SQLITE_NOMEM; |
5322 }else{ | 5274 }else{ |
5323 /* NB: zFilename exists and remains valid until the file is closed | 5275 /* NB: zFilename exists and remains valid until the file is closed |
5324 ** according to requirement F11141. So we do not need to make a | 5276 ** according to requirement F11141. So we do not need to make a |
5325 ** copy of the filename. */ | 5277 ** copy of the filename. */ |
5326 pCtx->dbPath = zFilename; | 5278 pCtx->dbPath = zFilename; |
5327 pCtx->reserved = 0; | 5279 pCtx->reserved = 0; |
5328 srandomdev(); | 5280 srandomdev(); |
5329 unixEnterMutex(); | 5281 unixEnterMutex(); |
5330 rc = findInodeInfo(pNew, &pNew->pInode); | 5282 rc = findInodeInfo(pNew, &pNew->pInode); |
5331 if( rc!=SQLITE_OK ){ | 5283 if( rc!=SQLITE_OK ){ |
5332 sqlite3_free(pNew->lockingContext); | 5284 sqlite3_free(pNew->lockingContext); |
5333 robust_close(pNew, h, __LINE__); | 5285 robust_close(pNew, h, __LINE__); |
5334 h = -1; | 5286 h = -1; |
5335 } | 5287 } |
5336 unixLeaveMutex(); | 5288 unixLeaveMutex(); |
5337 } | 5289 } |
5338 } | 5290 } |
5339 #endif | 5291 #endif |
5340 | 5292 |
5341 else if( pLockingStyle == &dotlockIoMethods ){ | 5293 else if( pLockingStyle == &dotlockIoMethods ){ |
5342 /* Dotfile locking uses the file path so it needs to be included in | 5294 /* Dotfile locking uses the file path so it needs to be included in |
5343 ** the dotlockLockingContext | 5295 ** the dotlockLockingContext |
5344 */ | 5296 */ |
5345 char *zLockFile; | 5297 char *zLockFile; |
5346 int nFilename; | 5298 int nFilename; |
5347 assert( zFilename!=0 ); | 5299 assert( zFilename!=0 ); |
5348 nFilename = (int)strlen(zFilename) + 6; | 5300 nFilename = (int)strlen(zFilename) + 6; |
5349 zLockFile = (char *)sqlite3_malloc(nFilename); | 5301 zLockFile = (char *)sqlite3_malloc64(nFilename); |
5350 if( zLockFile==0 ){ | 5302 if( zLockFile==0 ){ |
5351 rc = SQLITE_NOMEM; | 5303 rc = SQLITE_NOMEM; |
5352 }else{ | 5304 }else{ |
5353 sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); | 5305 sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); |
5354 } | 5306 } |
5355 pNew->lockingContext = zLockFile; | 5307 pNew->lockingContext = zLockFile; |
5356 } | 5308 } |
5357 | 5309 |
5358 #if OS_VXWORKS | 5310 #if OS_VXWORKS |
5359 else if( pLockingStyle == &semIoMethods ){ | 5311 else if( pLockingStyle == &semIoMethods ){ |
(...skipping 12 matching lines...) Expand all Loading... |
5372 pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); | 5324 pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); |
5373 if( pNew->pInode->pSem == SEM_FAILED ){ | 5325 if( pNew->pInode->pSem == SEM_FAILED ){ |
5374 rc = SQLITE_NOMEM; | 5326 rc = SQLITE_NOMEM; |
5375 pNew->pInode->aSemName[0] = '\0'; | 5327 pNew->pInode->aSemName[0] = '\0'; |
5376 } | 5328 } |
5377 } | 5329 } |
5378 unixLeaveMutex(); | 5330 unixLeaveMutex(); |
5379 } | 5331 } |
5380 #endif | 5332 #endif |
5381 | 5333 |
5382 pNew->lastErrno = 0; | 5334 storeLastErrno(pNew, 0); |
5383 #if OS_VXWORKS | 5335 #if OS_VXWORKS |
5384 if( rc!=SQLITE_OK ){ | 5336 if( rc!=SQLITE_OK ){ |
5385 if( h>=0 ) robust_close(pNew, h, __LINE__); | 5337 if( h>=0 ) robust_close(pNew, h, __LINE__); |
5386 h = -1; | 5338 h = -1; |
5387 osUnlink(zFilename); | 5339 osUnlink(zFilename); |
5388 pNew->ctrlFlags |= UNIXFILE_DELETE; | 5340 pNew->ctrlFlags |= UNIXFILE_DELETE; |
5389 } | 5341 } |
5390 #endif | 5342 #endif |
5391 if( rc!=SQLITE_OK ){ | 5343 if( rc!=SQLITE_OK ){ |
5392 if( h>=0 ) robust_close(pNew, h, __LINE__); | 5344 if( h>=0 ) robust_close(pNew, h, __LINE__); |
5393 }else{ | 5345 }else{ |
5394 pNew->pMethod = pLockingStyle; | 5346 pNew->pMethod = pLockingStyle; |
5395 OpenCounter(+1); | 5347 OpenCounter(+1); |
5396 verifyDbFile(pNew); | 5348 verifyDbFile(pNew); |
5397 } | 5349 } |
5398 return rc; | 5350 return rc; |
5399 } | 5351 } |
5400 | 5352 |
5401 /* | 5353 /* |
5402 ** Return the name of a directory in which to put temporary files. | 5354 ** Return the name of a directory in which to put temporary files. |
5403 ** If no suitable temporary file directory can be found, return NULL. | 5355 ** If no suitable temporary file directory can be found, return NULL. |
5404 */ | 5356 */ |
5405 static const char *unixTempFileDir(void){ | 5357 static const char *unixTempFileDir(void){ |
5406 static const char *azDirs[] = { | 5358 static const char *azDirs[] = { |
5407 0, | 5359 0, |
5408 0, | 5360 0, |
5409 0, | |
5410 "/var/tmp", | 5361 "/var/tmp", |
5411 "/usr/tmp", | 5362 "/usr/tmp", |
5412 "/tmp", | 5363 "/tmp", |
5413 0 /* List terminator */ | 5364 "." |
5414 }; | 5365 }; |
5415 unsigned int i; | 5366 unsigned int i; |
5416 struct stat buf; | 5367 struct stat buf; |
5417 const char *zDir = 0; | 5368 const char *zDir = sqlite3_temp_directory; |
5418 | 5369 |
5419 azDirs[0] = sqlite3_temp_directory; | 5370 if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); |
5420 if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR"); | 5371 if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); |
5421 if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR"); | |
5422 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ | 5372 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
5423 if( zDir==0 ) continue; | 5373 if( zDir==0 ) continue; |
5424 if( osStat(zDir, &buf) ) continue; | 5374 if( osStat(zDir, &buf) ) continue; |
5425 if( !S_ISDIR(buf.st_mode) ) continue; | 5375 if( !S_ISDIR(buf.st_mode) ) continue; |
5426 if( osAccess(zDir, 07) ) continue; | 5376 if( osAccess(zDir, 07) ) continue; |
5427 break; | 5377 break; |
5428 } | 5378 } |
5429 return zDir; | 5379 return zDir; |
5430 } | 5380 } |
5431 | 5381 |
5432 /* | 5382 /* |
5433 ** Create a temporary file name in zBuf. zBuf must be allocated | 5383 ** Create a temporary file name in zBuf. zBuf must be allocated |
5434 ** by the calling process and must be big enough to hold at least | 5384 ** by the calling process and must be big enough to hold at least |
5435 ** pVfs->mxPathname bytes. | 5385 ** pVfs->mxPathname bytes. |
5436 */ | 5386 */ |
5437 static int unixGetTempname(int nBuf, char *zBuf){ | 5387 static int unixGetTempname(int nBuf, char *zBuf){ |
5438 static const unsigned char zChars[] = | |
5439 "abcdefghijklmnopqrstuvwxyz" | |
5440 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
5441 "0123456789"; | |
5442 unsigned int i, j; | |
5443 const char *zDir; | 5388 const char *zDir; |
| 5389 int iLimit = 0; |
5444 | 5390 |
5445 /* It's odd to simulate an io-error here, but really this is just | 5391 /* It's odd to simulate an io-error here, but really this is just |
5446 ** using the io-error infrastructure to test that SQLite handles this | 5392 ** using the io-error infrastructure to test that SQLite handles this |
5447 ** function failing. | 5393 ** function failing. |
5448 */ | 5394 */ |
5449 SimulateIOError( return SQLITE_IOERR ); | 5395 SimulateIOError( return SQLITE_IOERR ); |
5450 | 5396 |
5451 zDir = unixTempFileDir(); | 5397 zDir = unixTempFileDir(); |
5452 if( zDir==0 ) zDir = "."; | |
5453 | |
5454 /* Check that the output buffer is large enough for the temporary file | |
5455 ** name. If it is not, return SQLITE_ERROR. | |
5456 */ | |
5457 if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){ | |
5458 return SQLITE_ERROR; | |
5459 } | |
5460 | |
5461 do{ | 5398 do{ |
5462 sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); | 5399 u64 r; |
5463 j = (int)strlen(zBuf); | 5400 sqlite3_randomness(sizeof(r), &r); |
5464 sqlite3_randomness(15, &zBuf[j]); | 5401 assert( nBuf>2 ); |
5465 for(i=0; i<15; i++, j++){ | 5402 zBuf[nBuf-2] = 0; |
5466 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; | 5403 sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", |
5467 } | 5404 zDir, r, 0); |
5468 zBuf[j] = 0; | 5405 if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR; |
5469 zBuf[j+1] = 0; | |
5470 }while( osAccess(zBuf,0)==0 ); | 5406 }while( osAccess(zBuf,0)==0 ); |
5471 return SQLITE_OK; | 5407 return SQLITE_OK; |
5472 } | 5408 } |
5473 | 5409 |
5474 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) | 5410 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) |
5475 /* | 5411 /* |
5476 ** Routine to transform a unixFile into a proxy-locking unixFile. | 5412 ** Routine to transform a unixFile into a proxy-locking unixFile. |
5477 ** Implementation in the proxy-lock division, but used by unixOpen() | 5413 ** Implementation in the proxy-lock division, but used by unixOpen() |
5478 ** if SQLITE_PREFER_PROXY_LOCKING is defined. | 5414 ** if SQLITE_PREFER_PROXY_LOCKING is defined. |
5479 */ | 5415 */ |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5581 ** | 5517 ** |
5582 ** "<path to db>-journal" | 5518 ** "<path to db>-journal" |
5583 ** "<path to db>-wal" | 5519 ** "<path to db>-wal" |
5584 ** "<path to db>-journalNN" | 5520 ** "<path to db>-journalNN" |
5585 ** "<path to db>-walNN" | 5521 ** "<path to db>-walNN" |
5586 ** | 5522 ** |
5587 ** where NN is a decimal number. The NN naming schemes are | 5523 ** where NN is a decimal number. The NN naming schemes are |
5588 ** used by the test_multiplex.c module. | 5524 ** used by the test_multiplex.c module. |
5589 */ | 5525 */ |
5590 nDb = sqlite3Strlen30(zPath) - 1; | 5526 nDb = sqlite3Strlen30(zPath) - 1; |
5591 #ifdef SQLITE_ENABLE_8_3_NAMES | 5527 while( zPath[nDb]!='-' ){ |
5592 while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--; | 5528 #ifndef SQLITE_ENABLE_8_3_NAMES |
5593 if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK; | 5529 /* In the normal case (8+3 filenames disabled) the journal filename |
| 5530 ** is guaranteed to contain a '-' character. */ |
| 5531 assert( nDb>0 ); |
| 5532 assert( sqlite3Isalnum(zPath[nDb]) ); |
5594 #else | 5533 #else |
5595 while( zPath[nDb]!='-' ){ | 5534 /* If 8+3 names are possible, then the journal file might not contain |
5596 assert( nDb>0 ); | 5535 ** a '-' character. So check for that case and return early. */ |
5597 assert( zPath[nDb]!='\n' ); | 5536 if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK; |
| 5537 #endif |
5598 nDb--; | 5538 nDb--; |
5599 } | 5539 } |
5600 #endif | |
5601 memcpy(zDb, zPath, nDb); | 5540 memcpy(zDb, zPath, nDb); |
5602 zDb[nDb] = '\0'; | 5541 zDb[nDb] = '\0'; |
5603 | 5542 |
5604 if( 0==osStat(zDb, &sStat) ){ | 5543 if( 0==osStat(zDb, &sStat) ){ |
5605 *pMode = sStat.st_mode & 0777; | 5544 *pMode = sStat.st_mode & 0777; |
5606 *pUid = sStat.st_uid; | 5545 *pUid = sStat.st_uid; |
5607 *pGid = sStat.st_gid; | 5546 *pGid = sStat.st_gid; |
5608 }else{ | 5547 }else{ |
5609 rc = SQLITE_IOERR_FSTAT; | 5548 rc = SQLITE_IOERR_FSTAT; |
5610 } | 5549 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5703 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL | 5642 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL |
5704 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL | 5643 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL |
5705 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL | 5644 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL |
5706 ); | 5645 ); |
5707 | 5646 |
5708 /* Detect a pid change and reset the PRNG. There is a race condition | 5647 /* Detect a pid change and reset the PRNG. There is a race condition |
5709 ** here such that two or more threads all trying to open databases at | 5648 ** here such that two or more threads all trying to open databases at |
5710 ** the same instant might all reset the PRNG. But multiple resets | 5649 ** the same instant might all reset the PRNG. But multiple resets |
5711 ** are harmless. | 5650 ** are harmless. |
5712 */ | 5651 */ |
5713 if( randomnessPid!=getpid() ){ | 5652 if( randomnessPid!=osGetpid(0) ){ |
5714 randomnessPid = getpid(); | 5653 randomnessPid = osGetpid(0); |
5715 sqlite3_randomness(0,0); | 5654 sqlite3_randomness(0,0); |
5716 } | 5655 } |
5717 | 5656 |
5718 memset(p, 0, sizeof(unixFile)); | 5657 memset(p, 0, sizeof(unixFile)); |
5719 | 5658 |
5720 if( eType==SQLITE_OPEN_MAIN_DB ){ | 5659 if( eType==SQLITE_OPEN_MAIN_DB ){ |
5721 UnixUnusedFd *pUnused; | 5660 UnixUnusedFd *pUnused; |
5722 pUnused = findReusableFd(zName, flags); | 5661 pUnused = findReusableFd(zName, flags); |
5723 if( pUnused ){ | 5662 if( pUnused ){ |
5724 fd = pUnused->fd; | 5663 fd = pUnused->fd; |
5725 }else{ | 5664 }else{ |
5726 pUnused = sqlite3_malloc(sizeof(*pUnused)); | 5665 pUnused = sqlite3_malloc64(sizeof(*pUnused)); |
5727 if( !pUnused ){ | 5666 if( !pUnused ){ |
5728 return SQLITE_NOMEM; | 5667 return SQLITE_NOMEM; |
5729 } | 5668 } |
5730 } | 5669 } |
5731 p->pUnused = pUnused; | 5670 p->pUnused = pUnused; |
5732 | 5671 |
5733 /* Database filenames are double-zero terminated if they are not | 5672 /* Database filenames are double-zero terminated if they are not |
5734 ** URIs with parameters. Hence, they can always be passed into | 5673 ** URIs with parameters. Hence, they can always be passed into |
5735 ** sqlite3_uri_parameter(). */ | 5674 ** sqlite3_uri_parameter(). */ |
5736 assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); | 5675 assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); |
5737 | 5676 |
5738 }else if( !zName ){ | 5677 }else if( !zName ){ |
5739 /* If zName is NULL, the upper layer is requesting a temp file. */ | 5678 /* If zName is NULL, the upper layer is requesting a temp file. */ |
5740 assert(isDelete && !syncDir); | 5679 assert(isDelete && !syncDir); |
5741 rc = unixGetTempname(MAX_PATHNAME+2, zTmpname); | 5680 rc = unixGetTempname(pVfs->mxPathname, zTmpname); |
5742 if( rc!=SQLITE_OK ){ | 5681 if( rc!=SQLITE_OK ){ |
5743 return rc; | 5682 return rc; |
5744 } | 5683 } |
5745 zName = zTmpname; | 5684 zName = zTmpname; |
5746 | 5685 |
5747 /* Generated temporary filenames are always double-zero terminated | 5686 /* Generated temporary filenames are always double-zero terminated |
5748 ** for use by sqlite3_uri_parameter(). */ | 5687 ** for use by sqlite3_uri_parameter(). */ |
5749 assert( zName[strlen(zName)+1]==0 ); | 5688 assert( zName[strlen(zName)+1]==0 ); |
5750 } | 5689 } |
5751 | 5690 |
(...skipping 12 matching lines...) Expand all Loading... |
5764 uid_t uid; /* Userid for the file */ | 5703 uid_t uid; /* Userid for the file */ |
5765 gid_t gid; /* Groupid for the file */ | 5704 gid_t gid; /* Groupid for the file */ |
5766 rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); | 5705 rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); |
5767 if( rc!=SQLITE_OK ){ | 5706 if( rc!=SQLITE_OK ){ |
5768 assert( !p->pUnused ); | 5707 assert( !p->pUnused ); |
5769 assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); | 5708 assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); |
5770 return rc; | 5709 return rc; |
5771 } | 5710 } |
5772 fd = robust_open(zName, openFlags, openMode); | 5711 fd = robust_open(zName, openFlags, openMode); |
5773 OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); | 5712 OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); |
5774 if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ | 5713 assert( !isExclusive || (openFlags & O_CREAT)!=0 ); |
| 5714 if( fd<0 && errno!=EISDIR && isReadWrite ){ |
5775 /* Failed to open the file for read/write access. Try read-only. */ | 5715 /* Failed to open the file for read/write access. Try read-only. */ |
5776 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | 5716 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
5777 openFlags &= ~(O_RDWR|O_CREAT); | 5717 openFlags &= ~(O_RDWR|O_CREAT); |
5778 flags |= SQLITE_OPEN_READONLY; | 5718 flags |= SQLITE_OPEN_READONLY; |
5779 openFlags |= O_RDONLY; | 5719 openFlags |= O_RDONLY; |
5780 isReadonly = 1; | 5720 isReadonly = 1; |
5781 fd = robust_open(zName, openFlags, openMode); | 5721 fd = robust_open(zName, openFlags, openMode); |
5782 } | 5722 } |
5783 if( fd<0 ){ | 5723 if( fd<0 ){ |
5784 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); | 5724 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); |
5785 goto open_finished; | 5725 goto open_finished; |
5786 } | 5726 } |
5787 | 5727 |
5788 /* If this process is running as root and if creating a new rollback | 5728 /* If this process is running as root and if creating a new rollback |
5789 ** journal or WAL file, set the ownership of the journal or WAL to be | 5729 ** journal or WAL file, set the ownership of the journal or WAL to be |
5790 ** the same as the original database. | 5730 ** the same as the original database. |
5791 */ | 5731 */ |
5792 if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ | 5732 if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ |
5793 osFchown(fd, uid, gid); | 5733 robustFchown(fd, uid, gid); |
5794 } | 5734 } |
5795 } | 5735 } |
5796 assert( fd>=0 ); | 5736 assert( fd>=0 ); |
5797 if( pOutFlags ){ | 5737 if( pOutFlags ){ |
5798 *pOutFlags = flags; | 5738 *pOutFlags = flags; |
5799 } | 5739 } |
5800 | 5740 |
5801 if( p->pUnused ){ | 5741 if( p->pUnused ){ |
5802 p->pUnused->fd = fd; | 5742 p->pUnused->fd = fd; |
5803 p->pUnused->flags = flags; | 5743 p->pUnused->flags = flags; |
(...skipping 16 matching lines...) Expand all Loading... |
5820 else{ | 5760 else{ |
5821 p->openFlags = openFlags; | 5761 p->openFlags = openFlags; |
5822 } | 5762 } |
5823 #endif | 5763 #endif |
5824 | 5764 |
5825 noLock = eType!=SQLITE_OPEN_MAIN_DB; | 5765 noLock = eType!=SQLITE_OPEN_MAIN_DB; |
5826 | 5766 |
5827 | 5767 |
5828 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE | 5768 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE |
5829 if( fstatfs(fd, &fsInfo) == -1 ){ | 5769 if( fstatfs(fd, &fsInfo) == -1 ){ |
5830 ((unixFile*)pFile)->lastErrno = errno; | 5770 storeLastErrno(p, errno); |
5831 robust_close(p, fd, __LINE__); | 5771 robust_close(p, fd, __LINE__); |
5832 return SQLITE_IOERR_ACCESS; | 5772 return SQLITE_IOERR_ACCESS; |
5833 } | 5773 } |
5834 if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { | 5774 if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { |
5835 ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; | 5775 ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; |
5836 } | 5776 } |
| 5777 if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) { |
| 5778 ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; |
| 5779 } |
5837 #endif | 5780 #endif |
5838 | 5781 |
5839 /* Set up appropriate ctrlFlags */ | 5782 /* Set up appropriate ctrlFlags */ |
5840 if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; | 5783 if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; |
5841 if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; | 5784 if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; |
5842 if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; | 5785 if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; |
5843 if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; | 5786 if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; |
5844 if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; | 5787 if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; |
5845 | 5788 |
5846 #if SQLITE_ENABLE_LOCKING_STYLE | 5789 #if SQLITE_ENABLE_LOCKING_STYLE |
5847 #if SQLITE_PREFER_PROXY_LOCKING | 5790 #if SQLITE_PREFER_PROXY_LOCKING |
5848 isAutoProxy = 1; | 5791 isAutoProxy = 1; |
5849 #endif | 5792 #endif |
5850 if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){ | 5793 if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){ |
5851 char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); | 5794 char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); |
5852 int useProxy = 0; | 5795 int useProxy = 0; |
5853 | 5796 |
5854 /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means | 5797 /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means |
5855 ** never use proxy, NULL means use proxy for non-local files only. */ | 5798 ** never use proxy, NULL means use proxy for non-local files only. */ |
5856 if( envforce!=NULL ){ | 5799 if( envforce!=NULL ){ |
5857 useProxy = atoi(envforce)>0; | 5800 useProxy = atoi(envforce)>0; |
5858 }else{ | 5801 }else{ |
5859 if( statfs(zPath, &fsInfo) == -1 ){ | |
5860 /* In theory, the close(fd) call is sub-optimal. If the file opened | |
5861 ** with fd is a database file, and there are other connections open | |
5862 ** on that file that are currently holding advisory locks on it, | |
5863 ** then the call to close() will cancel those locks. In practice, | |
5864 ** we're assuming that statfs() doesn't fail very often. At least | |
5865 ** not while other file descriptors opened by the same process on | |
5866 ** the same file are working. */ | |
5867 p->lastErrno = errno; | |
5868 robust_close(p, fd, __LINE__); | |
5869 rc = SQLITE_IOERR_ACCESS; | |
5870 goto open_finished; | |
5871 } | |
5872 useProxy = !(fsInfo.f_flags&MNT_LOCAL); | 5802 useProxy = !(fsInfo.f_flags&MNT_LOCAL); |
5873 } | 5803 } |
5874 if( useProxy ){ | 5804 if( useProxy ){ |
5875 rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); | 5805 rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); |
5876 if( rc==SQLITE_OK ){ | 5806 if( rc==SQLITE_OK ){ |
5877 rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); | 5807 rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); |
5878 if( rc!=SQLITE_OK ){ | 5808 if( rc!=SQLITE_OK ){ |
5879 /* Use unixClose to clean up the resources added in fillInUnixFile | 5809 /* Use unixClose to clean up the resources added in fillInUnixFile |
5880 ** and clear all the structure's references. Specifically, | 5810 ** and clear all the structure's references. Specifically, |
5881 ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op | 5811 ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5930 if( rc==SQLITE_OK ){ | 5860 if( rc==SQLITE_OK ){ |
5931 #if OS_VXWORKS | 5861 #if OS_VXWORKS |
5932 if( fsync(fd)==-1 ) | 5862 if( fsync(fd)==-1 ) |
5933 #else | 5863 #else |
5934 if( fsync(fd) ) | 5864 if( fsync(fd) ) |
5935 #endif | 5865 #endif |
5936 { | 5866 { |
5937 rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); | 5867 rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); |
5938 } | 5868 } |
5939 robust_close(0, fd, __LINE__); | 5869 robust_close(0, fd, __LINE__); |
5940 }else if( rc==SQLITE_CANTOPEN ){ | 5870 }else{ |
| 5871 assert( rc==SQLITE_CANTOPEN ); |
5941 rc = SQLITE_OK; | 5872 rc = SQLITE_OK; |
5942 } | 5873 } |
5943 } | 5874 } |
5944 #endif | 5875 #endif |
5945 return rc; | 5876 return rc; |
5946 } | 5877 } |
5947 | 5878 |
5948 /* | 5879 /* |
5949 ** Test the existence of or access permissions of file zPath. The | 5880 ** Test the existence of or access permissions of file zPath. The |
5950 ** test performed depends on the value of flags: | 5881 ** test performed depends on the value of flags: |
5951 ** | 5882 ** |
5952 ** SQLITE_ACCESS_EXISTS: Return 1 if the file exists | 5883 ** SQLITE_ACCESS_EXISTS: Return 1 if the file exists |
5953 ** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. | 5884 ** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. |
5954 ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. | 5885 ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. |
5955 ** | 5886 ** |
5956 ** Otherwise return 0. | 5887 ** Otherwise return 0. |
5957 */ | 5888 */ |
5958 static int unixAccess( | 5889 static int unixAccess( |
5959 sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ | 5890 sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ |
5960 const char *zPath, /* Path of the file to examine */ | 5891 const char *zPath, /* Path of the file to examine */ |
5961 int flags, /* What do we want to learn about the zPath file? */ | 5892 int flags, /* What do we want to learn about the zPath file? */ |
5962 int *pResOut /* Write result boolean here */ | 5893 int *pResOut /* Write result boolean here */ |
5963 ){ | 5894 ){ |
5964 int amode = 0; | |
5965 UNUSED_PARAMETER(NotUsed); | 5895 UNUSED_PARAMETER(NotUsed); |
5966 SimulateIOError( return SQLITE_IOERR_ACCESS; ); | 5896 SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
5967 switch( flags ){ | 5897 assert( pResOut!=0 ); |
5968 case SQLITE_ACCESS_EXISTS: | |
5969 amode = F_OK; | |
5970 break; | |
5971 case SQLITE_ACCESS_READWRITE: | |
5972 amode = W_OK|R_OK; | |
5973 break; | |
5974 case SQLITE_ACCESS_READ: | |
5975 amode = R_OK; | |
5976 break; | |
5977 | 5898 |
5978 default: | 5899 /* The spec says there are three possible values for flags. But only |
5979 assert(!"Invalid flags argument"); | 5900 ** two of them are actually used */ |
5980 } | 5901 assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); |
5981 *pResOut = (osAccess(zPath, amode)==0); | 5902 |
5982 if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ | 5903 if( flags==SQLITE_ACCESS_EXISTS ){ |
5983 struct stat buf; | 5904 struct stat buf; |
5984 if( 0==osStat(zPath, &buf) && buf.st_size==0 ){ | 5905 *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0); |
5985 *pResOut = 0; | 5906 }else{ |
5986 } | 5907 *pResOut = osAccess(zPath, W_OK|R_OK)==0; |
5987 } | 5908 } |
5988 return SQLITE_OK; | 5909 return SQLITE_OK; |
5989 } | 5910 } |
5990 | 5911 |
5991 | 5912 |
5992 /* | 5913 /* |
5993 ** Turn a relative pathname into a full pathname. The relative path | 5914 ** Turn a relative pathname into a full pathname. The relative path |
5994 ** is stored as a nul-terminated string in the buffer pointed to by | 5915 ** is stored as a nul-terminated string in the buffer pointed to by |
5995 ** zPath. | 5916 ** zPath. |
5996 ** | 5917 ** |
5997 ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes | 5918 ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes |
5998 ** (in this case, MAX_PATHNAME bytes). The full-path is written to | 5919 ** (in this case, MAX_PATHNAME bytes). The full-path is written to |
5999 ** this buffer before returning. | 5920 ** this buffer before returning. |
6000 */ | 5921 */ |
6001 static int unixFullPathname( | 5922 static int unixFullPathname( |
6002 sqlite3_vfs *pVfs, /* Pointer to vfs object */ | 5923 sqlite3_vfs *pVfs, /* Pointer to vfs object */ |
6003 const char *zPath, /* Possibly relative input path */ | 5924 const char *zPath, /* Possibly relative input path */ |
6004 int nOut, /* Size of output buffer in bytes */ | 5925 int nOut, /* Size of output buffer in bytes */ |
6005 char *zOut /* Output buffer */ | 5926 char *zOut /* Output buffer */ |
6006 ){ | 5927 ){ |
| 5928 int nByte; |
6007 | 5929 |
6008 /* It's odd to simulate an io-error here, but really this is just | 5930 /* It's odd to simulate an io-error here, but really this is just |
6009 ** using the io-error infrastructure to test that SQLite handles this | 5931 ** using the io-error infrastructure to test that SQLite handles this |
6010 ** function failing. This function could fail if, for example, the | 5932 ** function failing. This function could fail if, for example, the |
6011 ** current working directory has been unlinked. | 5933 ** current working directory has been unlinked. |
6012 */ | 5934 */ |
6013 SimulateIOError( return SQLITE_ERROR ); | 5935 SimulateIOError( return SQLITE_ERROR ); |
6014 | 5936 |
6015 assert( pVfs->mxPathname==MAX_PATHNAME ); | 5937 assert( pVfs->mxPathname==MAX_PATHNAME ); |
6016 UNUSED_PARAMETER(pVfs); | 5938 UNUSED_PARAMETER(pVfs); |
6017 | 5939 |
6018 zOut[nOut-1] = '\0'; | 5940 /* Attempt to resolve the path as if it were a symbolic link. If it is |
6019 if( zPath[0]=='/' ){ | 5941 ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if |
| 5942 ** the identified file is not a symbolic link or does not exist, then |
| 5943 ** zPath is copied directly into zOut. Either way, nByte is left set to |
| 5944 ** the size of the string copied into zOut[] in bytes. */ |
| 5945 nByte = osReadlink(zPath, zOut, nOut-1); |
| 5946 if( nByte<0 ){ |
| 5947 if( errno!=EINVAL && errno!=ENOENT ){ |
| 5948 return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath); |
| 5949 } |
6020 sqlite3_snprintf(nOut, zOut, "%s", zPath); | 5950 sqlite3_snprintf(nOut, zOut, "%s", zPath); |
| 5951 nByte = sqlite3Strlen30(zOut); |
6021 }else{ | 5952 }else{ |
| 5953 zOut[nByte] = '\0'; |
| 5954 } |
| 5955 |
| 5956 /* If buffer zOut[] now contains an absolute path there is nothing more |
| 5957 ** to do. If it contains a relative path, do the following: |
| 5958 ** |
| 5959 ** * move the relative path string so that it is at the end of th |
| 5960 ** zOut[] buffer. |
| 5961 ** * Call getcwd() to read the path of the current working directory |
| 5962 ** into the start of the zOut[] buffer. |
| 5963 ** * Append a '/' character to the cwd string and move the |
| 5964 ** relative path back within the buffer so that it immediately |
| 5965 ** follows the '/'. |
| 5966 ** |
| 5967 ** This code is written so that if the combination of the CWD and relative |
| 5968 ** path are larger than the allocated size of zOut[] the CWD is silently |
| 5969 ** truncated to make it fit. This is Ok, as SQLite refuses to open any |
| 5970 ** file for which this function returns a full path larger than (nOut-8) |
| 5971 ** bytes in size. */ |
| 5972 testcase( nByte==nOut-5 ); |
| 5973 testcase( nByte==nOut-4 ); |
| 5974 if( zOut[0]!='/' && nByte<nOut-4 ){ |
6022 int nCwd; | 5975 int nCwd; |
6023 if( osGetcwd(zOut, nOut-1)==0 ){ | 5976 int nRem = nOut-nByte-1; |
| 5977 memmove(&zOut[nRem], zOut, nByte+1); |
| 5978 zOut[nRem-1] = '\0'; |
| 5979 if( osGetcwd(zOut, nRem-1)==0 ){ |
6024 return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); | 5980 return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); |
6025 } | 5981 } |
6026 nCwd = (int)strlen(zOut); | 5982 nCwd = sqlite3Strlen30(zOut); |
6027 sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath); | 5983 assert( nCwd<=nRem-1 ); |
| 5984 zOut[nCwd] = '/'; |
| 5985 memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1); |
6028 } | 5986 } |
| 5987 |
6029 return SQLITE_OK; | 5988 return SQLITE_OK; |
6030 } | 5989 } |
6031 | 5990 |
6032 | 5991 |
6033 #ifndef SQLITE_OMIT_LOAD_EXTENSION | 5992 #ifndef SQLITE_OMIT_LOAD_EXTENSION |
6034 /* | 5993 /* |
6035 ** Interfaces for opening a shared library, finding entry points | 5994 ** Interfaces for opening a shared library, finding entry points |
6036 ** within the shared library, and closing the shared library. | 5995 ** within the shared library, and closing the shared library. |
6037 */ | 5996 */ |
6038 #include <dlfcn.h> | 5997 #include <dlfcn.h> |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6105 ** uninitialized space in zBuf - but valgrind errors tend to worry | 6064 ** uninitialized space in zBuf - but valgrind errors tend to worry |
6106 ** some users. Rather than argue, it seems easier just to initialize | 6065 ** some users. Rather than argue, it seems easier just to initialize |
6107 ** the whole array and silence valgrind, even if that means less randomness | 6066 ** the whole array and silence valgrind, even if that means less randomness |
6108 ** in the random seed. | 6067 ** in the random seed. |
6109 ** | 6068 ** |
6110 ** When testing, initializing zBuf[] to zero is all we do. That means | 6069 ** When testing, initializing zBuf[] to zero is all we do. That means |
6111 ** that we always use the same random number sequence. This makes the | 6070 ** that we always use the same random number sequence. This makes the |
6112 ** tests repeatable. | 6071 ** tests repeatable. |
6113 */ | 6072 */ |
6114 memset(zBuf, 0, nBuf); | 6073 memset(zBuf, 0, nBuf); |
6115 randomnessPid = getpid(); | 6074 randomnessPid = osGetpid(0); |
6116 #if !defined(SQLITE_TEST) | 6075 #if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) |
6117 { | 6076 { |
6118 int fd, got; | 6077 int fd, got; |
6119 fd = robust_open("/dev/urandom", O_RDONLY, 0); | 6078 fd = robust_open("/dev/urandom", O_RDONLY, 0); |
6120 if( fd<0 ){ | 6079 if( fd<0 ){ |
6121 time_t t; | 6080 time_t t; |
6122 time(&t); | 6081 time(&t); |
6123 memcpy(zBuf, &t, sizeof(t)); | 6082 memcpy(zBuf, &t, sizeof(t)); |
6124 memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid)); | 6083 memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid)); |
6125 assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf ); | 6084 assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf ); |
6126 nBuf = sizeof(t) + sizeof(randomnessPid); | 6085 nBuf = sizeof(t) + sizeof(randomnessPid); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6188 #if defined(NO_GETTOD) | 6147 #if defined(NO_GETTOD) |
6189 time_t t; | 6148 time_t t; |
6190 time(&t); | 6149 time(&t); |
6191 *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; | 6150 *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; |
6192 #elif OS_VXWORKS | 6151 #elif OS_VXWORKS |
6193 struct timespec sNow; | 6152 struct timespec sNow; |
6194 clock_gettime(CLOCK_REALTIME, &sNow); | 6153 clock_gettime(CLOCK_REALTIME, &sNow); |
6195 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; | 6154 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; |
6196 #else | 6155 #else |
6197 struct timeval sNow; | 6156 struct timeval sNow; |
6198 if( gettimeofday(&sNow, 0)==0 ){ | 6157 (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ |
6199 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; | 6158 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; |
6200 }else{ | |
6201 rc = SQLITE_ERROR; | |
6202 } | |
6203 #endif | 6159 #endif |
6204 | 6160 |
6205 #ifdef SQLITE_TEST | 6161 #ifdef SQLITE_TEST |
6206 if( sqlite3_current_time ){ | 6162 if( sqlite3_current_time ){ |
6207 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; | 6163 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; |
6208 } | 6164 } |
6209 #endif | 6165 #endif |
6210 UNUSED_PARAMETER(NotUsed); | 6166 UNUSED_PARAMETER(NotUsed); |
6211 return rc; | 6167 return rc; |
6212 } | 6168 } |
6213 | 6169 |
| 6170 #if 0 /* Not used */ |
6214 /* | 6171 /* |
6215 ** Find the current time (in Universal Coordinated Time). Write the | 6172 ** Find the current time (in Universal Coordinated Time). Write the |
6216 ** current time and date as a Julian Day number into *prNow and | 6173 ** current time and date as a Julian Day number into *prNow and |
6217 ** return 0. Return 1 if the time and date cannot be found. | 6174 ** return 0. Return 1 if the time and date cannot be found. |
6218 */ | 6175 */ |
6219 static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ | 6176 static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ |
6220 sqlite3_int64 i = 0; | 6177 sqlite3_int64 i = 0; |
6221 int rc; | 6178 int rc; |
6222 UNUSED_PARAMETER(NotUsed); | 6179 UNUSED_PARAMETER(NotUsed); |
6223 rc = unixCurrentTimeInt64(0, &i); | 6180 rc = unixCurrentTimeInt64(0, &i); |
6224 *prNow = i/86400000.0; | 6181 *prNow = i/86400000.0; |
6225 return rc; | 6182 return rc; |
6226 } | 6183 } |
| 6184 #else |
| 6185 # define unixCurrentTime 0 |
| 6186 #endif |
6227 | 6187 |
| 6188 #if 0 /* Not used */ |
6228 /* | 6189 /* |
6229 ** We added the xGetLastError() method with the intention of providing | 6190 ** We added the xGetLastError() method with the intention of providing |
6230 ** better low-level error messages when operating-system problems come up | 6191 ** better low-level error messages when operating-system problems come up |
6231 ** during SQLite operation. But so far, none of that has been implemented | 6192 ** during SQLite operation. But so far, none of that has been implemented |
6232 ** in the core. So this routine is never called. For now, it is merely | 6193 ** in the core. So this routine is never called. For now, it is merely |
6233 ** a place-holder. | 6194 ** a place-holder. |
6234 */ | 6195 */ |
6235 static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ | 6196 static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ |
6236 UNUSED_PARAMETER(NotUsed); | 6197 UNUSED_PARAMETER(NotUsed); |
6237 UNUSED_PARAMETER(NotUsed2); | 6198 UNUSED_PARAMETER(NotUsed2); |
6238 UNUSED_PARAMETER(NotUsed3); | 6199 UNUSED_PARAMETER(NotUsed3); |
6239 return 0; | 6200 return 0; |
6240 } | 6201 } |
| 6202 #else |
| 6203 # define unixGetLastError 0 |
| 6204 #endif |
6241 | 6205 |
6242 | 6206 |
6243 /* | 6207 /* |
6244 ************************ End of sqlite3_vfs methods *************************** | 6208 ************************ End of sqlite3_vfs methods *************************** |
6245 ******************************************************************************/ | 6209 ******************************************************************************/ |
6246 | 6210 |
6247 /****************************************************************************** | 6211 /****************************************************************************** |
6248 ************************** Begin Proxy Locking ******************************** | 6212 ************************** Begin Proxy Locking ******************************** |
6249 ** | 6213 ** |
6250 ** Proxy locking is a "uber-locking-method" in this sense: It uses the | 6214 ** Proxy locking is a "uber-locking-method" in this sense: It uses the |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6287 ** changes the way database access is controlled by limiting access to a | 6251 ** changes the way database access is controlled by limiting access to a |
6288 ** single host at a time and moving file locks off of the database file | 6252 ** single host at a time and moving file locks off of the database file |
6289 ** and onto a proxy file on the local file system. | 6253 ** and onto a proxy file on the local file system. |
6290 ** | 6254 ** |
6291 ** | 6255 ** |
6292 ** Using proxy locks | 6256 ** Using proxy locks |
6293 ** ----------------- | 6257 ** ----------------- |
6294 ** | 6258 ** |
6295 ** C APIs | 6259 ** C APIs |
6296 ** | 6260 ** |
6297 ** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE, | 6261 ** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, |
6298 ** <proxy_path> | ":auto:"); | 6262 ** <proxy_path> | ":auto:"); |
6299 ** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>); | 6263 ** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, |
| 6264 ** &<proxy_path>); |
6300 ** | 6265 ** |
6301 ** | 6266 ** |
6302 ** SQL pragmas | 6267 ** SQL pragmas |
6303 ** | 6268 ** |
6304 ** PRAGMA [database.]lock_proxy_file=<proxy_path> | :auto: | 6269 ** PRAGMA [database.]lock_proxy_file=<proxy_path> | :auto: |
6305 ** PRAGMA [database.]lock_proxy_file | 6270 ** PRAGMA [database.]lock_proxy_file |
6306 ** | 6271 ** |
6307 ** Specifying ":auto:" means that if there is a conch file with a matching | 6272 ** Specifying ":auto:" means that if there is a conch file with a matching |
6308 ** host ID in it, the proxy path in the conch file will be used, otherwise | 6273 ** host ID in it, the proxy path in the conch file will be used, otherwise |
6309 ** a proxy path based on the user's temp dir | 6274 ** a proxy path based on the user's temp dir |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6382 ** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS | 6347 ** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS |
6383 ** | 6348 ** |
6384 ** Permissions to use when creating a directory for storing the | 6349 ** Permissions to use when creating a directory for storing the |
6385 ** lock proxy files, only used when LOCKPROXYDIR is not set. | 6350 ** lock proxy files, only used when LOCKPROXYDIR is not set. |
6386 ** | 6351 ** |
6387 ** | 6352 ** |
6388 ** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, | 6353 ** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, |
6389 ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will | 6354 ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will |
6390 ** force proxy locking to be used for every database file opened, and 0 | 6355 ** force proxy locking to be used for every database file opened, and 0 |
6391 ** will force automatic proxy locking to be disabled for all database | 6356 ** will force automatic proxy locking to be disabled for all database |
6392 ** files (explicitly calling the SQLITE_SET_LOCKPROXYFILE pragma or | 6357 ** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or |
6393 ** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). | 6358 ** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). |
6394 */ | 6359 */ |
6395 | 6360 |
6396 /* | 6361 /* |
6397 ** Proxy locking is only available on MacOSX | 6362 ** Proxy locking is only available on MacOSX |
6398 */ | 6363 */ |
6399 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE | 6364 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
6400 | 6365 |
6401 /* | 6366 /* |
6402 ** The proxyLockingContext has the path and file structures for the remote | 6367 ** The proxyLockingContext has the path and file structures for the remote |
6403 ** and local proxy files in it | 6368 ** and local proxy files in it |
6404 */ | 6369 */ |
6405 typedef struct proxyLockingContext proxyLockingContext; | 6370 typedef struct proxyLockingContext proxyLockingContext; |
6406 struct proxyLockingContext { | 6371 struct proxyLockingContext { |
6407 unixFile *conchFile; /* Open conch file */ | 6372 unixFile *conchFile; /* Open conch file */ |
6408 char *conchFilePath; /* Name of the conch file */ | 6373 char *conchFilePath; /* Name of the conch file */ |
6409 unixFile *lockProxy; /* Open proxy lock file */ | 6374 unixFile *lockProxy; /* Open proxy lock file */ |
6410 char *lockProxyPath; /* Name of the proxy lock file */ | 6375 char *lockProxyPath; /* Name of the proxy lock file */ |
6411 char *dbPath; /* Name of the open file */ | 6376 char *dbPath; /* Name of the open file */ |
6412 int conchHeld; /* 1 if the conch is held, -1 if lockless */ | 6377 int conchHeld; /* 1 if the conch is held, -1 if lockless */ |
| 6378 int nFails; /* Number of conch taking failures */ |
6413 void *oldLockingContext; /* Original lockingcontext to restore on close */ | 6379 void *oldLockingContext; /* Original lockingcontext to restore on close */ |
6414 sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ | 6380 sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ |
6415 }; | 6381 }; |
6416 | 6382 |
6417 /* | 6383 /* |
6418 ** The proxy lock file path for the database at dbPath is written into lPath, | 6384 ** The proxy lock file path for the database at dbPath is written into lPath, |
6419 ** which must point to valid, writable memory large enough for a maxLen length | 6385 ** which must point to valid, writable memory large enough for a maxLen length |
6420 ** file path. | 6386 ** file path. |
6421 */ | 6387 */ |
6422 static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ | 6388 static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ |
6423 int len; | 6389 int len; |
6424 int dbLen; | 6390 int dbLen; |
6425 int i; | 6391 int i; |
6426 | 6392 |
6427 #ifdef LOCKPROXYDIR | 6393 #ifdef LOCKPROXYDIR |
6428 len = strlcpy(lPath, LOCKPROXYDIR, maxLen); | 6394 len = strlcpy(lPath, LOCKPROXYDIR, maxLen); |
6429 #else | 6395 #else |
6430 # ifdef _CS_DARWIN_USER_TEMP_DIR | 6396 # ifdef _CS_DARWIN_USER_TEMP_DIR |
6431 { | 6397 { |
6432 if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ | 6398 if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ |
6433 OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", | 6399 OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", |
6434 lPath, errno, getpid())); | 6400 lPath, errno, osGetpid(0))); |
6435 return SQLITE_IOERR_LOCK; | 6401 return SQLITE_IOERR_LOCK; |
6436 } | 6402 } |
6437 len = strlcat(lPath, "sqliteplocks", maxLen); | 6403 len = strlcat(lPath, "sqliteplocks", maxLen); |
6438 } | 6404 } |
6439 # else | 6405 # else |
6440 len = strlcpy(lPath, "/tmp/", maxLen); | 6406 len = strlcpy(lPath, "/tmp/", maxLen); |
6441 # endif | 6407 # endif |
6442 #endif | 6408 #endif |
6443 | 6409 |
6444 if( lPath[len-1]!='/' ){ | 6410 if( lPath[len-1]!='/' ){ |
6445 len = strlcat(lPath, "/", maxLen); | 6411 len = strlcat(lPath, "/", maxLen); |
6446 } | 6412 } |
6447 | 6413 |
6448 /* transform the db path to a unique cache name */ | 6414 /* transform the db path to a unique cache name */ |
6449 dbLen = (int)strlen(dbPath); | 6415 dbLen = (int)strlen(dbPath); |
6450 for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){ | 6416 for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){ |
6451 char c = dbPath[i]; | 6417 char c = dbPath[i]; |
6452 lPath[i+len] = (c=='/')?'_':c; | 6418 lPath[i+len] = (c=='/')?'_':c; |
6453 } | 6419 } |
6454 lPath[i+len]='\0'; | 6420 lPath[i+len]='\0'; |
6455 strlcat(lPath, ":auto:", maxLen); | 6421 strlcat(lPath, ":auto:", maxLen); |
6456 OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid())); | 6422 OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, osGetpid(0))); |
6457 return SQLITE_OK; | 6423 return SQLITE_OK; |
6458 } | 6424 } |
6459 | 6425 |
6460 /* | 6426 /* |
6461 ** Creates the lock file and any missing directories in lockPath | 6427 ** Creates the lock file and any missing directories in lockPath |
6462 */ | 6428 */ |
6463 static int proxyCreateLockPath(const char *lockPath){ | 6429 static int proxyCreateLockPath(const char *lockPath){ |
6464 int i, len; | 6430 int i, len; |
6465 char buf[MAXPATHLEN]; | 6431 char buf[MAXPATHLEN]; |
6466 int start = 0; | 6432 int start = 0; |
6467 | 6433 |
6468 assert(lockPath!=NULL); | 6434 assert(lockPath!=NULL); |
6469 /* try to create all the intermediate directories */ | 6435 /* try to create all the intermediate directories */ |
6470 len = (int)strlen(lockPath); | 6436 len = (int)strlen(lockPath); |
6471 buf[0] = lockPath[0]; | 6437 buf[0] = lockPath[0]; |
6472 for( i=1; i<len; i++ ){ | 6438 for( i=1; i<len; i++ ){ |
6473 if( lockPath[i] == '/' && (i - start > 0) ){ | 6439 if( lockPath[i] == '/' && (i - start > 0) ){ |
6474 /* only mkdir if leaf dir != "." or "/" or ".." */ | 6440 /* only mkdir if leaf dir != "." or "/" or ".." */ |
6475 if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') | 6441 if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') |
6476 || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ | 6442 || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ |
6477 buf[i]='\0'; | 6443 buf[i]='\0'; |
6478 if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ | 6444 if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ |
6479 int err=errno; | 6445 int err=errno; |
6480 if( err!=EEXIST ) { | 6446 if( err!=EEXIST ) { |
6481 OSTRACE(("CREATELOCKPATH FAILED creating %s, " | 6447 OSTRACE(("CREATELOCKPATH FAILED creating %s, " |
6482 "'%s' proxy lock path=%s pid=%d\n", | 6448 "'%s' proxy lock path=%s pid=%d\n", |
6483 buf, strerror(err), lockPath, getpid())); | 6449 buf, strerror(err), lockPath, osGetpid(0))); |
6484 return err; | 6450 return err; |
6485 } | 6451 } |
6486 } | 6452 } |
6487 } | 6453 } |
6488 start=i+1; | 6454 start=i+1; |
6489 } | 6455 } |
6490 buf[i] = lockPath[i]; | 6456 buf[i] = lockPath[i]; |
6491 } | 6457 } |
6492 OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid())); | 6458 OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0))); |
6493 return 0; | 6459 return 0; |
6494 } | 6460 } |
6495 | 6461 |
6496 /* | 6462 /* |
6497 ** Create a new VFS file descriptor (stored in memory obtained from | 6463 ** Create a new VFS file descriptor (stored in memory obtained from |
6498 ** sqlite3_malloc) and open the file named "path" in the file descriptor. | 6464 ** sqlite3_malloc) and open the file named "path" in the file descriptor. |
6499 ** | 6465 ** |
6500 ** The caller is responsible not only for closing the file descriptor | 6466 ** The caller is responsible not only for closing the file descriptor |
6501 ** but also for freeing the memory associated with the file descriptor. | 6467 ** but also for freeing the memory associated with the file descriptor. |
6502 */ | 6468 */ |
(...skipping 13 matching lines...) Expand all Loading... |
6516 /* 1. first try to open/create the file | 6482 /* 1. first try to open/create the file |
6517 ** 2. if that fails, and this is a lock file (not-conch), try creating | 6483 ** 2. if that fails, and this is a lock file (not-conch), try creating |
6518 ** the parent directories and then try again. | 6484 ** the parent directories and then try again. |
6519 ** 3. if that fails, try to open the file read-only | 6485 ** 3. if that fails, try to open the file read-only |
6520 ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file | 6486 ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file |
6521 */ | 6487 */ |
6522 pUnused = findReusableFd(path, openFlags); | 6488 pUnused = findReusableFd(path, openFlags); |
6523 if( pUnused ){ | 6489 if( pUnused ){ |
6524 fd = pUnused->fd; | 6490 fd = pUnused->fd; |
6525 }else{ | 6491 }else{ |
6526 pUnused = sqlite3_malloc(sizeof(*pUnused)); | 6492 pUnused = sqlite3_malloc64(sizeof(*pUnused)); |
6527 if( !pUnused ){ | 6493 if( !pUnused ){ |
6528 return SQLITE_NOMEM; | 6494 return SQLITE_NOMEM; |
6529 } | 6495 } |
6530 } | 6496 } |
6531 if( fd<0 ){ | 6497 if( fd<0 ){ |
6532 fd = robust_open(path, openFlags, 0); | 6498 fd = robust_open(path, openFlags, 0); |
6533 terrno = errno; | 6499 terrno = errno; |
6534 if( fd<0 && errno==ENOENT && islockfile ){ | 6500 if( fd<0 && errno==ENOENT && islockfile ){ |
6535 if( proxyCreateLockPath(path) == SQLITE_OK ){ | 6501 if( proxyCreateLockPath(path) == SQLITE_OK ){ |
6536 fd = robust_open(path, openFlags, 0); | 6502 fd = robust_open(path, openFlags, 0); |
(...skipping 12 matching lines...) Expand all Loading... |
6549 switch (terrno) { | 6515 switch (terrno) { |
6550 case EACCES: | 6516 case EACCES: |
6551 return SQLITE_PERM; | 6517 return SQLITE_PERM; |
6552 case EIO: | 6518 case EIO: |
6553 return SQLITE_IOERR_LOCK; /* even though it is the conch */ | 6519 return SQLITE_IOERR_LOCK; /* even though it is the conch */ |
6554 default: | 6520 default: |
6555 return SQLITE_CANTOPEN_BKPT; | 6521 return SQLITE_CANTOPEN_BKPT; |
6556 } | 6522 } |
6557 } | 6523 } |
6558 | 6524 |
6559 pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew)); | 6525 pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); |
6560 if( pNew==NULL ){ | 6526 if( pNew==NULL ){ |
6561 rc = SQLITE_NOMEM; | 6527 rc = SQLITE_NOMEM; |
6562 goto end_create_proxy; | 6528 goto end_create_proxy; |
6563 } | 6529 } |
6564 memset(pNew, 0, sizeof(unixFile)); | 6530 memset(pNew, 0, sizeof(unixFile)); |
6565 pNew->openFlags = openFlags; | 6531 pNew->openFlags = openFlags; |
6566 memset(&dummyVfs, 0, sizeof(dummyVfs)); | 6532 memset(&dummyVfs, 0, sizeof(dummyVfs)); |
6567 dummyVfs.pAppData = (void*)&autolockIoFinder; | 6533 dummyVfs.pAppData = (void*)&autolockIoFinder; |
6568 dummyVfs.zName = "dummy"; | 6534 dummyVfs.zName = "dummy"; |
6569 pUnused->fd = fd; | 6535 pUnused->fd = fd; |
(...skipping 12 matching lines...) Expand all Loading... |
6582 return rc; | 6548 return rc; |
6583 } | 6549 } |
6584 | 6550 |
6585 #ifdef SQLITE_TEST | 6551 #ifdef SQLITE_TEST |
6586 /* simulate multiple hosts by creating unique hostid file paths */ | 6552 /* simulate multiple hosts by creating unique hostid file paths */ |
6587 int sqlite3_hostid_num = 0; | 6553 int sqlite3_hostid_num = 0; |
6588 #endif | 6554 #endif |
6589 | 6555 |
6590 #define PROXY_HOSTIDLEN 16 /* conch file host id length */ | 6556 #define PROXY_HOSTIDLEN 16 /* conch file host id length */ |
6591 | 6557 |
| 6558 #ifdef HAVE_GETHOSTUUID |
6592 /* Not always defined in the headers as it ought to be */ | 6559 /* Not always defined in the headers as it ought to be */ |
6593 extern int gethostuuid(uuid_t id, const struct timespec *wait); | 6560 extern int gethostuuid(uuid_t id, const struct timespec *wait); |
| 6561 #endif |
6594 | 6562 |
6595 /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN | 6563 /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN |
6596 ** bytes of writable memory. | 6564 ** bytes of writable memory. |
6597 */ | 6565 */ |
6598 static int proxyGetHostID(unsigned char *pHostID, int *pError){ | 6566 static int proxyGetHostID(unsigned char *pHostID, int *pError){ |
6599 assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); | 6567 assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); |
6600 memset(pHostID, 0, PROXY_HOSTIDLEN); | 6568 memset(pHostID, 0, PROXY_HOSTIDLEN); |
6601 #if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\ | 6569 #ifdef HAVE_GETHOSTUUID |
6602 && __MAC_OS_X_VERSION_MIN_REQUIRED<1050 | |
6603 { | 6570 { |
6604 static const struct timespec timeout = {1, 0}; /* 1 sec timeout */ | 6571 struct timespec timeout = {1, 0}; /* 1 sec timeout */ |
6605 if( gethostuuid(pHostID, &timeout) ){ | 6572 if( gethostuuid(pHostID, &timeout) ){ |
6606 int err = errno; | 6573 int err = errno; |
6607 if( pError ){ | 6574 if( pError ){ |
6608 *pError = err; | 6575 *pError = err; |
6609 } | 6576 } |
6610 return SQLITE_IOERR; | 6577 return SQLITE_IOERR; |
6611 } | 6578 } |
6612 } | 6579 } |
6613 #else | 6580 #else |
6614 UNUSED_PARAMETER(pError); | 6581 UNUSED_PARAMETER(pError); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6709 nTries ++; | 6676 nTries ++; |
6710 if( rc==SQLITE_BUSY ){ | 6677 if( rc==SQLITE_BUSY ){ |
6711 /* If the lock failed (busy): | 6678 /* If the lock failed (busy): |
6712 * 1st try: get the mod time of the conch, wait 0.5s and try again. | 6679 * 1st try: get the mod time of the conch, wait 0.5s and try again. |
6713 * 2nd try: fail if the mod time changed or host id is different, wait | 6680 * 2nd try: fail if the mod time changed or host id is different, wait |
6714 * 10 sec and try again | 6681 * 10 sec and try again |
6715 * 3rd try: break the lock unless the mod time has changed. | 6682 * 3rd try: break the lock unless the mod time has changed. |
6716 */ | 6683 */ |
6717 struct stat buf; | 6684 struct stat buf; |
6718 if( osFstat(conchFile->h, &buf) ){ | 6685 if( osFstat(conchFile->h, &buf) ){ |
6719 pFile->lastErrno = errno; | 6686 storeLastErrno(pFile, errno); |
6720 return SQLITE_IOERR_LOCK; | 6687 return SQLITE_IOERR_LOCK; |
6721 } | 6688 } |
6722 | 6689 |
6723 if( nTries==1 ){ | 6690 if( nTries==1 ){ |
6724 conchModTime = buf.st_mtimespec; | 6691 conchModTime = buf.st_mtimespec; |
6725 usleep(500000); /* wait 0.5 sec and try the lock again*/ | 6692 usleep(500000); /* wait 0.5 sec and try the lock again*/ |
6726 continue; | 6693 continue; |
6727 } | 6694 } |
6728 | 6695 |
6729 assert( nTries>1 ); | 6696 assert( nTries>1 ); |
6730 if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || | 6697 if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || |
6731 conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ | 6698 conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ |
6732 return SQLITE_BUSY; | 6699 return SQLITE_BUSY; |
6733 } | 6700 } |
6734 | 6701 |
6735 if( nTries==2 ){ | 6702 if( nTries==2 ){ |
6736 char tBuf[PROXY_MAXCONCHLEN]; | 6703 char tBuf[PROXY_MAXCONCHLEN]; |
6737 int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); | 6704 int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); |
6738 if( len<0 ){ | 6705 if( len<0 ){ |
6739 pFile->lastErrno = errno; | 6706 storeLastErrno(pFile, errno); |
6740 return SQLITE_IOERR_LOCK; | 6707 return SQLITE_IOERR_LOCK; |
6741 } | 6708 } |
6742 if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ | 6709 if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ |
6743 /* don't break the lock if the host id doesn't match */ | 6710 /* don't break the lock if the host id doesn't match */ |
6744 if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ | 6711 if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ |
6745 return SQLITE_BUSY; | 6712 return SQLITE_BUSY; |
6746 } | 6713 } |
6747 }else{ | 6714 }else{ |
6748 /* don't break the lock on short read or a version mismatch */ | 6715 /* don't break the lock on short read or a version mismatch */ |
6749 return SQLITE_BUSY; | 6716 return SQLITE_BUSY; |
6750 } | 6717 } |
6751 usleep(10000000); /* wait 10 sec and try the lock again */ | 6718 usleep(10000000); /* wait 10 sec and try the lock again */ |
6752 continue; | 6719 continue; |
6753 } | 6720 } |
6754 | 6721 |
6755 assert( nTries==3 ); | 6722 assert( nTries==3 ); |
6756 if( 0==proxyBreakConchLock(pFile, myHostID) ){ | 6723 if( 0==proxyBreakConchLock(pFile, myHostID) ){ |
6757 rc = SQLITE_OK; | 6724 rc = SQLITE_OK; |
6758 if( lockType==EXCLUSIVE_LOCK ){ | 6725 if( lockType==EXCLUSIVE_LOCK ){ |
6759 rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
| 6726 rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); |
6760 } | 6727 } |
6761 if( !rc ){ | 6728 if( !rc ){ |
6762 rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); | 6729 rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); |
6763 } | 6730 } |
6764 } | 6731 } |
6765 } | 6732 } |
6766 } while( rc==SQLITE_BUSY && nTries<3 ); | 6733 } while( rc==SQLITE_BUSY && nTries<3 ); |
6767 | 6734 |
6768 return rc; | 6735 return rc; |
6769 } | 6736 } |
(...skipping 17 matching lines...) Expand all Loading... |
6787 char lockPath[MAXPATHLEN]; | 6754 char lockPath[MAXPATHLEN]; |
6788 char *tempLockPath = NULL; | 6755 char *tempLockPath = NULL; |
6789 int rc = SQLITE_OK; | 6756 int rc = SQLITE_OK; |
6790 int createConch = 0; | 6757 int createConch = 0; |
6791 int hostIdMatch = 0; | 6758 int hostIdMatch = 0; |
6792 int readLen = 0; | 6759 int readLen = 0; |
6793 int tryOldLockPath = 0; | 6760 int tryOldLockPath = 0; |
6794 int forceNewLockPath = 0; | 6761 int forceNewLockPath = 0; |
6795 | 6762 |
6796 OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, | 6763 OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, |
6797 (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid())); | 6764 (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), |
| 6765 osGetpid(0))); |
6798 | 6766 |
6799 rc = proxyGetHostID(myHostID, &pError); | 6767 rc = proxyGetHostID(myHostID, &pError); |
6800 if( (rc&0xff)==SQLITE_IOERR ){ | 6768 if( (rc&0xff)==SQLITE_IOERR ){ |
6801 pFile->lastErrno = pError; | 6769 storeLastErrno(pFile, pError); |
6802 goto end_takeconch; | 6770 goto end_takeconch; |
6803 } | 6771 } |
6804 rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); | 6772 rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); |
6805 if( rc!=SQLITE_OK ){ | 6773 if( rc!=SQLITE_OK ){ |
6806 goto end_takeconch; | 6774 goto end_takeconch; |
6807 } | 6775 } |
6808 /* read the existing conch file */ | 6776 /* read the existing conch file */ |
6809 readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); | 6777 readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); |
6810 if( readLen<0 ){ | 6778 if( readLen<0 ){ |
6811 /* I/O error: lastErrno set by seekAndRead */ | 6779 /* I/O error: lastErrno set by seekAndRead */ |
6812 pFile->lastErrno = conchFile->lastErrno; | 6780 storeLastErrno(pFile, conchFile->lastErrno); |
6813 rc = SQLITE_IOERR_READ; | 6781 rc = SQLITE_IOERR_READ; |
6814 goto end_takeconch; | 6782 goto end_takeconch; |
6815 }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || | 6783 }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || |
6816 readBuf[0]!=(char)PROXY_CONCHVERSION ){ | 6784 readBuf[0]!=(char)PROXY_CONCHVERSION ){ |
6817 /* a short read or version format mismatch means we need to create a new | 6785 /* a short read or version format mismatch means we need to create a new |
6818 ** conch file. | 6786 ** conch file. |
6819 */ | 6787 */ |
6820 createConch = 1; | 6788 createConch = 1; |
6821 } | 6789 } |
6822 /* if the host id matches and the lock path already exists in the conch | 6790 /* if the host id matches and the lock path already exists in the conch |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6875 futimes(conchFile->h, NULL); | 6843 futimes(conchFile->h, NULL); |
6876 if( hostIdMatch && !createConch ){ | 6844 if( hostIdMatch && !createConch ){ |
6877 if( conchFile->pInode && conchFile->pInode->nShared>1 ){ | 6845 if( conchFile->pInode && conchFile->pInode->nShared>1 ){ |
6878 /* We are trying for an exclusive lock but another thread in this | 6846 /* We are trying for an exclusive lock but another thread in this |
6879 ** same process is still holding a shared lock. */ | 6847 ** same process is still holding a shared lock. */ |
6880 rc = SQLITE_BUSY; | 6848 rc = SQLITE_BUSY; |
6881 } else { | 6849 } else { |
6882 rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); | 6850 rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); |
6883 } | 6851 } |
6884 }else{ | 6852 }else{ |
6885 rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK)
; | 6853 rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); |
6886 } | 6854 } |
6887 if( rc==SQLITE_OK ){ | 6855 if( rc==SQLITE_OK ){ |
6888 char writeBuffer[PROXY_MAXCONCHLEN]; | 6856 char writeBuffer[PROXY_MAXCONCHLEN]; |
6889 int writeSize = 0; | 6857 int writeSize = 0; |
6890 | 6858 |
6891 writeBuffer[0] = (char)PROXY_CONCHVERSION; | 6859 writeBuffer[0] = (char)PROXY_CONCHVERSION; |
6892 memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); | 6860 memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); |
6893 if( pCtx->lockProxyPath!=NULL ){ | 6861 if( pCtx->lockProxyPath!=NULL ){ |
6894 strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN
); | 6862 strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, |
| 6863 MAXPATHLEN); |
6895 }else{ | 6864 }else{ |
6896 strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); | 6865 strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); |
6897 } | 6866 } |
6898 writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); | 6867 writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); |
6899 robust_ftruncate(conchFile->h, writeSize); | 6868 robust_ftruncate(conchFile->h, writeSize); |
6900 rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); | 6869 rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); |
6901 fsync(conchFile->h); | 6870 fsync(conchFile->h); |
6902 /* If we created a new conch file (not just updated the contents of a | 6871 /* If we created a new conch file (not just updated the contents of a |
6903 ** valid conch file), try to match the permissions of the database | 6872 ** valid conch file), try to match the permissions of the database |
6904 */ | 6873 */ |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6996 */ | 6965 */ |
6997 static int proxyReleaseConch(unixFile *pFile){ | 6966 static int proxyReleaseConch(unixFile *pFile){ |
6998 int rc = SQLITE_OK; /* Subroutine return code */ | 6967 int rc = SQLITE_OK; /* Subroutine return code */ |
6999 proxyLockingContext *pCtx; /* The locking context for the proxy lock */ | 6968 proxyLockingContext *pCtx; /* The locking context for the proxy lock */ |
7000 unixFile *conchFile; /* Name of the conch file */ | 6969 unixFile *conchFile; /* Name of the conch file */ |
7001 | 6970 |
7002 pCtx = (proxyLockingContext *)pFile->lockingContext; | 6971 pCtx = (proxyLockingContext *)pFile->lockingContext; |
7003 conchFile = pCtx->conchFile; | 6972 conchFile = pCtx->conchFile; |
7004 OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, | 6973 OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, |
7005 (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), | 6974 (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), |
7006 getpid())); | 6975 osGetpid(0))); |
7007 if( pCtx->conchHeld>0 ){ | 6976 if( pCtx->conchHeld>0 ){ |
7008 rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); | 6977 rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); |
7009 } | 6978 } |
7010 pCtx->conchHeld = 0; | 6979 pCtx->conchHeld = 0; |
7011 OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, | 6980 OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, |
7012 (rc==SQLITE_OK ? "ok" : "failed"))); | 6981 (rc==SQLITE_OK ? "ok" : "failed"))); |
7013 return rc; | 6982 return rc; |
7014 } | 6983 } |
7015 | 6984 |
7016 /* | 6985 /* |
7017 ** Given the name of a database file, compute the name of its conch file. | 6986 ** Given the name of a database file, compute the name of its conch file. |
7018 ** Store the conch filename in memory obtained from sqlite3_malloc(). | 6987 ** Store the conch filename in memory obtained from sqlite3_malloc64(). |
7019 ** Make *pConchPath point to the new name. Return SQLITE_OK on success | 6988 ** Make *pConchPath point to the new name. Return SQLITE_OK on success |
7020 ** or SQLITE_NOMEM if unable to obtain memory. | 6989 ** or SQLITE_NOMEM if unable to obtain memory. |
7021 ** | 6990 ** |
7022 ** The caller is responsible for ensuring that the allocated memory | 6991 ** The caller is responsible for ensuring that the allocated memory |
7023 ** space is eventually freed. | 6992 ** space is eventually freed. |
7024 ** | 6993 ** |
7025 ** *pConchPath is set to NULL if a memory allocation error occurs. | 6994 ** *pConchPath is set to NULL if a memory allocation error occurs. |
7026 */ | 6995 */ |
7027 static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ | 6996 static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ |
7028 int i; /* Loop counter */ | 6997 int i; /* Loop counter */ |
7029 int len = (int)strlen(dbPath); /* Length of database filename - dbPath */ | 6998 int len = (int)strlen(dbPath); /* Length of database filename - dbPath */ |
7030 char *conchPath; /* buffer in which to construct conch name */ | 6999 char *conchPath; /* buffer in which to construct conch name */ |
7031 | 7000 |
7032 /* Allocate space for the conch filename and initialize the name to | 7001 /* Allocate space for the conch filename and initialize the name to |
7033 ** the name of the original database file. */ | 7002 ** the name of the original database file. */ |
7034 *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8); | 7003 *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); |
7035 if( conchPath==0 ){ | 7004 if( conchPath==0 ){ |
7036 return SQLITE_NOMEM; | 7005 return SQLITE_NOMEM; |
7037 } | 7006 } |
7038 memcpy(conchPath, dbPath, len+1); | 7007 memcpy(conchPath, dbPath, len+1); |
7039 | 7008 |
7040 /* now insert a "." before the last / character */ | 7009 /* now insert a "." before the last / character */ |
7041 for( i=(len-1); i>=0; i-- ){ | 7010 for( i=(len-1); i>=0; i-- ){ |
7042 if( conchPath[i]=='/' ){ | 7011 if( conchPath[i]=='/' ){ |
7043 i++; | 7012 i++; |
7044 break; | 7013 break; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7096 ** | 7065 ** |
7097 ** This routine find the filename associated with pFile and writes it | 7066 ** This routine find the filename associated with pFile and writes it |
7098 ** int dbPath. | 7067 ** int dbPath. |
7099 */ | 7068 */ |
7100 static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ | 7069 static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ |
7101 #if defined(__APPLE__) | 7070 #if defined(__APPLE__) |
7102 if( pFile->pMethod == &afpIoMethods ){ | 7071 if( pFile->pMethod == &afpIoMethods ){ |
7103 /* afp style keeps a reference to the db path in the filePath field | 7072 /* afp style keeps a reference to the db path in the filePath field |
7104 ** of the struct */ | 7073 ** of the struct */ |
7105 assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); | 7074 assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); |
7106 strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPAT
HLEN); | 7075 strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, |
| 7076 MAXPATHLEN); |
7107 } else | 7077 } else |
7108 #endif | 7078 #endif |
7109 if( pFile->pMethod == &dotlockIoMethods ){ | 7079 if( pFile->pMethod == &dotlockIoMethods ){ |
7110 /* dot lock style uses the locking context to store the dot lock | 7080 /* dot lock style uses the locking context to store the dot lock |
7111 ** file path */ | 7081 ** file path */ |
7112 int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); | 7082 int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); |
7113 memcpy(dbPath, (char *)pFile->lockingContext, len + 1); | 7083 memcpy(dbPath, (char *)pFile->lockingContext, len + 1); |
7114 }else{ | 7084 }else{ |
7115 /* all other styles use the locking context to store the db file path */ | 7085 /* all other styles use the locking context to store the db file path */ |
7116 assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); | 7086 assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); |
(...skipping 20 matching lines...) Expand all Loading... |
7137 return SQLITE_BUSY; | 7107 return SQLITE_BUSY; |
7138 } | 7108 } |
7139 proxyGetDbPathForUnixFile(pFile, dbPath); | 7109 proxyGetDbPathForUnixFile(pFile, dbPath); |
7140 if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){ | 7110 if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){ |
7141 lockPath=NULL; | 7111 lockPath=NULL; |
7142 }else{ | 7112 }else{ |
7143 lockPath=(char *)path; | 7113 lockPath=(char *)path; |
7144 } | 7114 } |
7145 | 7115 |
7146 OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, | 7116 OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, |
7147 (lockPath ? lockPath : ":auto:"), getpid())); | 7117 (lockPath ? lockPath : ":auto:"), osGetpid(0))); |
7148 | 7118 |
7149 pCtx = sqlite3_malloc( sizeof(*pCtx) ); | 7119 pCtx = sqlite3_malloc64( sizeof(*pCtx) ); |
7150 if( pCtx==0 ){ | 7120 if( pCtx==0 ){ |
7151 return SQLITE_NOMEM; | 7121 return SQLITE_NOMEM; |
7152 } | 7122 } |
7153 memset(pCtx, 0, sizeof(*pCtx)); | 7123 memset(pCtx, 0, sizeof(*pCtx)); |
7154 | 7124 |
7155 rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath); | 7125 rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath); |
7156 if( rc==SQLITE_OK ){ | 7126 if( rc==SQLITE_OK ){ |
7157 rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0); | 7127 rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0); |
7158 if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){ | 7128 if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){ |
7159 /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and | 7129 /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7209 return rc; | 7179 return rc; |
7210 } | 7180 } |
7211 | 7181 |
7212 | 7182 |
7213 /* | 7183 /* |
7214 ** This routine handles sqlite3_file_control() calls that are specific | 7184 ** This routine handles sqlite3_file_control() calls that are specific |
7215 ** to proxy locking. | 7185 ** to proxy locking. |
7216 */ | 7186 */ |
7217 static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ | 7187 static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ |
7218 switch( op ){ | 7188 switch( op ){ |
7219 case SQLITE_GET_LOCKPROXYFILE: { | 7189 case SQLITE_FCNTL_GET_LOCKPROXYFILE: { |
7220 unixFile *pFile = (unixFile*)id; | 7190 unixFile *pFile = (unixFile*)id; |
7221 if( pFile->pMethod == &proxyIoMethods ){ | 7191 if( pFile->pMethod == &proxyIoMethods ){ |
7222 proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; | 7192 proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; |
7223 proxyTakeConch(pFile); | 7193 proxyTakeConch(pFile); |
7224 if( pCtx->lockProxyPath ){ | 7194 if( pCtx->lockProxyPath ){ |
7225 *(const char **)pArg = pCtx->lockProxyPath; | 7195 *(const char **)pArg = pCtx->lockProxyPath; |
7226 }else{ | 7196 }else{ |
7227 *(const char **)pArg = ":auto: (not held)"; | 7197 *(const char **)pArg = ":auto: (not held)"; |
7228 } | 7198 } |
7229 } else { | 7199 } else { |
7230 *(const char **)pArg = NULL; | 7200 *(const char **)pArg = NULL; |
7231 } | 7201 } |
7232 return SQLITE_OK; | 7202 return SQLITE_OK; |
7233 } | 7203 } |
7234 case SQLITE_SET_LOCKPROXYFILE: { | 7204 case SQLITE_FCNTL_SET_LOCKPROXYFILE: { |
7235 unixFile *pFile = (unixFile*)id; | 7205 unixFile *pFile = (unixFile*)id; |
7236 int rc = SQLITE_OK; | 7206 int rc = SQLITE_OK; |
7237 int isProxyStyle = (pFile->pMethod == &proxyIoMethods); | 7207 int isProxyStyle = (pFile->pMethod == &proxyIoMethods); |
7238 if( pArg==NULL || (const char *)pArg==0 ){ | 7208 if( pArg==NULL || (const char *)pArg==0 ){ |
7239 if( isProxyStyle ){ | 7209 if( isProxyStyle ){ |
7240 /* turn off proxy locking - not supported */ | 7210 /* turn off proxy locking - not supported. If support is added for |
| 7211 ** switching proxy locking mode off then it will need to fail if |
| 7212 ** the journal mode is WAL mode. |
| 7213 */ |
7241 rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; | 7214 rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; |
7242 }else{ | 7215 }else{ |
7243 /* turn off proxy locking - already off - NOOP */ | 7216 /* turn off proxy locking - already off - NOOP */ |
7244 rc = SQLITE_OK; | 7217 rc = SQLITE_OK; |
7245 } | 7218 } |
7246 }else{ | 7219 }else{ |
7247 const char *proxyPath = (const char *)pArg; | 7220 const char *proxyPath = (const char *)pArg; |
7248 if( isProxyStyle ){ | 7221 if( isProxyStyle ){ |
7249 proxyLockingContext *pCtx = | 7222 proxyLockingContext *pCtx = |
7250 (proxyLockingContext*)pFile->lockingContext; | 7223 (proxyLockingContext*)pFile->lockingContext; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7360 /* conchHeld < 0 is lockless */ | 7333 /* conchHeld < 0 is lockless */ |
7361 } | 7334 } |
7362 } | 7335 } |
7363 return rc; | 7336 return rc; |
7364 } | 7337 } |
7365 | 7338 |
7366 /* | 7339 /* |
7367 ** Close a file that uses proxy locks. | 7340 ** Close a file that uses proxy locks. |
7368 */ | 7341 */ |
7369 static int proxyClose(sqlite3_file *id) { | 7342 static int proxyClose(sqlite3_file *id) { |
7370 if( id ){ | 7343 if( ALWAYS(id) ){ |
7371 unixFile *pFile = (unixFile*)id; | 7344 unixFile *pFile = (unixFile*)id; |
7372 proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; | 7345 proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; |
7373 unixFile *lockProxy = pCtx->lockProxy; | 7346 unixFile *lockProxy = pCtx->lockProxy; |
7374 unixFile *conchFile = pCtx->conchFile; | 7347 unixFile *conchFile = pCtx->conchFile; |
7375 int rc = SQLITE_OK; | 7348 int rc = SQLITE_OK; |
7376 | 7349 |
7377 if( lockProxy ){ | 7350 if( lockProxy ){ |
7378 rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); | 7351 rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); |
7379 if( rc ) return rc; | 7352 if( rc ) return rc; |
7380 rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); | 7353 rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7475 } | 7448 } |
7476 | 7449 |
7477 /* | 7450 /* |
7478 ** All default VFSes for unix are contained in the following array. | 7451 ** All default VFSes for unix are contained in the following array. |
7479 ** | 7452 ** |
7480 ** Note that the sqlite3_vfs.pNext field of the VFS object is modified | 7453 ** Note that the sqlite3_vfs.pNext field of the VFS object is modified |
7481 ** by the SQLite core when the VFS is registered. So the following | 7454 ** by the SQLite core when the VFS is registered. So the following |
7482 ** array cannot be const. | 7455 ** array cannot be const. |
7483 */ | 7456 */ |
7484 static sqlite3_vfs aVfs[] = { | 7457 static sqlite3_vfs aVfs[] = { |
7485 #if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__)) | 7458 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) |
7486 UNIXVFS("unix", autolockIoFinder ), | 7459 UNIXVFS("unix", autolockIoFinder ), |
| 7460 #elif OS_VXWORKS |
| 7461 UNIXVFS("unix", vxworksIoFinder ), |
7487 #else | 7462 #else |
7488 UNIXVFS("unix", posixIoFinder ), | 7463 UNIXVFS("unix", posixIoFinder ), |
7489 #endif | 7464 #endif |
7490 UNIXVFS("unix-none", nolockIoFinder ), | 7465 UNIXVFS("unix-none", nolockIoFinder ), |
7491 UNIXVFS("unix-dotfile", dotlockIoFinder ), | 7466 UNIXVFS("unix-dotfile", dotlockIoFinder ), |
7492 UNIXVFS("unix-excl", posixIoFinder ), | 7467 UNIXVFS("unix-excl", posixIoFinder ), |
7493 #if OS_VXWORKS | 7468 #if OS_VXWORKS |
7494 UNIXVFS("unix-namedsem", semIoFinder ), | 7469 UNIXVFS("unix-namedsem", semIoFinder ), |
7495 #endif | 7470 #endif |
| 7471 #if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS |
| 7472 UNIXVFS("unix-posix", posixIoFinder ), |
| 7473 #endif |
7496 #if SQLITE_ENABLE_LOCKING_STYLE | 7474 #if SQLITE_ENABLE_LOCKING_STYLE |
7497 UNIXVFS("unix-posix", posixIoFinder ), | |
7498 #if !OS_VXWORKS | |
7499 UNIXVFS("unix-flock", flockIoFinder ), | 7475 UNIXVFS("unix-flock", flockIoFinder ), |
7500 #endif | 7476 #endif |
7501 #endif | |
7502 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) | 7477 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) |
7503 UNIXVFS("unix-afp", afpIoFinder ), | 7478 UNIXVFS("unix-afp", afpIoFinder ), |
7504 UNIXVFS("unix-nfs", nfsIoFinder ), | 7479 UNIXVFS("unix-nfs", nfsIoFinder ), |
7505 UNIXVFS("unix-proxy", proxyIoFinder ), | 7480 UNIXVFS("unix-proxy", proxyIoFinder ), |
7506 #endif | 7481 #endif |
7507 }; | 7482 }; |
7508 unsigned int i; /* Loop counter */ | 7483 unsigned int i; /* Loop counter */ |
7509 | 7484 |
7510 /* Double-check that the aSyscall[] array has been constructed | 7485 /* Double-check that the aSyscall[] array has been constructed |
7511 ** correctly. See ticket [bb3a86e890c8e96ab] */ | 7486 ** correctly. See ticket [bb3a86e890c8e96ab] */ |
7512 assert( ArraySize(aSyscall)==25 ); | 7487 assert( ArraySize(aSyscall)==27 ); |
7513 | 7488 |
7514 /* Register all VFSes defined in the aVfs[] array */ | 7489 /* Register all VFSes defined in the aVfs[] array */ |
7515 for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ | 7490 for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ |
7516 sqlite3_vfs_register(&aVfs[i], i==0); | 7491 sqlite3_vfs_register(&aVfs[i], i==0); |
7517 } | 7492 } |
7518 return SQLITE_OK; | 7493 return SQLITE_OK; |
7519 } | 7494 } |
7520 | 7495 |
7521 /* | 7496 /* |
7522 ** Shutdown the operating system interface. | 7497 ** Shutdown the operating system interface. |
7523 ** | 7498 ** |
7524 ** Some operating systems might need to do some cleanup in this routine, | 7499 ** Some operating systems might need to do some cleanup in this routine, |
7525 ** to release dynamically allocated objects. But not on unix. | 7500 ** to release dynamically allocated objects. But not on unix. |
7526 ** This routine is a no-op for unix. | 7501 ** This routine is a no-op for unix. |
7527 */ | 7502 */ |
7528 int sqlite3_os_end(void){ | 7503 int sqlite3_os_end(void){ |
7529 return SQLITE_OK; | 7504 return SQLITE_OK; |
7530 } | 7505 } |
7531 | 7506 |
7532 #endif /* SQLITE_OS_UNIX */ | 7507 #endif /* SQLITE_OS_UNIX */ |
OLD | NEW |