Changeset: 8fc6c6bf2c43 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8fc6c6bf2c43 Added Files: sql/test/Tests/alastair_udf_mergetable_bug.py sql/test/Tests/alastair_udf_mergetable_bug.stable.err sql/test/Tests/alastair_udf_mergetable_bug.stable.out Modified Files: clients/mapiclient/mclient.c common/utils/msabaoth.c common/utils/mutils.c gdk/gdk_bbp.c gdk/gdk_heap.c gdk/gdk_storage.c gdk/gdk_utils.c monetdb5/mal/Tests/tst013.stable.out monetdb5/mal/Tests/tst036.stable.out monetdb5/mal/Tests/tst050.stable.out monetdb5/mal/Tests/tst070.stable.out monetdb5/mal/Tests/tst105.stable.out monetdb5/mal/Tests/tst106.stable.out monetdb5/mal/Tests/tst150.stable.out monetdb5/mal/Tests/tst2504.mal monetdb5/mal/Tests/tst2504.stable.out monetdb5/mal/Tests/tst611.stable.out monetdb5/mal/mal_import.c monetdb5/mal/mal_instruction.c monetdb5/mal/mal_readline.c monetdb5/modules/atoms/str.c monetdb5/modules/mal/bbp.c monetdb5/modules/mal/manifold.c monetdb5/optimizer/Tests/inline08.stable.out monetdb5/optimizer/opt_accumulators.c monetdb5/optimizer/opt_aliases.c monetdb5/optimizer/opt_pushselect.c monetdb5/scheduler/srvpool.c monetdb5/tests/BugDay_2005-10-06_4.9.3/Tests/ADT_not_available.SF-850137.stable.out monetdb5/tests/BugReports/Tests/lngssaretruncated.stable.out monetdb5/tests/BugTracker/Tests/parser.SF-2051309.stable.out sql/backends/monet5/sql.c sql/backends/monet5/sql_gencode.c sql/backends/monet5/sql_scenario.c sql/test/BugTracker-2012/Tests/table_function_with_column_subselects.Bug-3172.stable.err testing/process.py tools/merovingian/daemon/argvcmds.c tools/merovingian/daemon/merovingian.c tools/mserver/mserver5.c Branch: default Log Message:
merged diffs (truncated from 1301 to 300 lines): diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c --- a/clients/mapiclient/mclient.c +++ b/clients/mapiclient/mclient.c @@ -1643,7 +1643,7 @@ doRequest(Mapi mid, const char *buf) return 0; } -#define CHECK_RESULT(mid, hdl, buf, break_or_continue) \ +#define CHECK_RESULT(mid, hdl, buf, break_or_continue,freebuf) \ switch (mapi_error(mid)) { \ case MOK: \ /* everything A OK */ \ @@ -1678,7 +1678,7 @@ doRequest(Mapi mid, const char *buf) mapi_explain(mid, stderr); \ errseen = 1; \ timerEnd(); \ - free(buf); \ + if( freebuf) free(freebuf); \ return 1; \ } @@ -1725,7 +1725,7 @@ doFileBulk(Mapi mid, FILE *fp) if (hdl == NULL) { hdl = mapi_query_prep(mid); - CHECK_RESULT(mid, hdl, buf, continue); + CHECK_RESULT(mid, hdl, buf, continue, buf); } if (first && @@ -1739,7 +1739,7 @@ doFileBulk(Mapi mid, FILE *fp) assert(hdl != NULL); mapi_query_part(hdl, buf + skip, length - skip); - CHECK_RESULT(mid, hdl, buf + skip, continue); + CHECK_RESULT(mid, hdl, buf + skip, continue, buf); /* make sure there is a newline in the buffer */ if (strchr(buf + skip, '\n') == NULL) @@ -1758,14 +1758,14 @@ doFileBulk(Mapi mid, FILE *fp) (length > 0 || mapi_query_done(hdl) == MMORE)) continue; /* get more data */ - CHECK_RESULT(mid, hdl, buf + skip, continue); + CHECK_RESULT(mid, hdl, buf + skip, continue, buf); rc = format_result(mid, hdl, 0); if (rc == MMORE && (length > 0 || mapi_query_done(hdl) != MOK)) continue; /* get more data */ - CHECK_RESULT(mid, hdl, buf + skip, continue); + CHECK_RESULT(mid, hdl, buf + skip, continue, buf); mapi_close_handle(hdl); hdl = NULL; @@ -2321,7 +2321,7 @@ doFile(Mapi mid, const char *file, int u "" : "AND system = false")); hdl = mapi_query(mid, q); - CHECK_RESULT(mid, hdl, buf, continue); + CHECK_RESULT(mid, hdl, buf, continue, buf); while (fetch_row(hdl) == 5) { name = mapi_fetch_field(hdl, 0); type = mapi_fetch_field(hdl, 1); @@ -2509,7 +2509,7 @@ doFile(Mapi mid, const char *file, int u if (hdl == NULL) { timerStart(); hdl = mapi_query_prep(mid); - CHECK_RESULT(mid, hdl, buf, continue); + CHECK_RESULT(mid, hdl, buf, continue, buf); } else timerResume(); @@ -2518,7 +2518,7 @@ doFile(Mapi mid, const char *file, int u if (length > 0) { SQLsetSpecial(line); mapi_query_part(hdl, line, length); - CHECK_RESULT(mid, hdl, buf, continue); + CHECK_RESULT(mid, hdl, buf, continue, buf); } /* If the server wants more but we're at the @@ -2536,7 +2536,7 @@ doFile(Mapi mid, const char *file, int u continue; /* done */ } } - CHECK_RESULT(mid, hdl, buf, continue); + CHECK_RESULT(mid, hdl, buf, continue, buf); if (mapi_get_querytype(hdl) == Q_PREPARE) { prepno = mapi_get_tableid(hdl); @@ -2548,7 +2548,7 @@ doFile(Mapi mid, const char *file, int u if (rc == MMORE && (line != NULL || mapi_query_done(hdl) != MOK)) continue; /* get more data */ - CHECK_RESULT(mid, hdl, buf, continue); + CHECK_RESULT(mid, hdl, buf, continue, buf); timerEnd(); mapi_close_handle(hdl); diff --git a/common/utils/msabaoth.c b/common/utils/msabaoth.c --- a/common/utils/msabaoth.c +++ b/common/utils/msabaoth.c @@ -49,6 +49,7 @@ #if defined(_MSC_VER) && _MSC_VER >= 1400 #define close _close #define unlink _unlink +#define fdopen _fdopen #endif #define PATHLENGTH 4096 @@ -674,7 +675,7 @@ msab_getStatus(sabdb** ret, char *dbname } else { /* locking succeed, check for a crash in the uplog */ snprintf(log, sizeof(log), "%s/%s/%s", path, e->d_name, UPLOGFILE); - if ((f = fopen(log, "r")) != NULL) { + if ((f = fdopen(fd, "r+")) != NULL) { (void)fseek(f, -1, SEEK_END); if (fread(data, 1, 1, f) != 1) { /* the log is empty, assume no crash */ @@ -684,11 +685,13 @@ msab_getStatus(sabdb** ret, char *dbname } else { /* should be \t */ sdb->state = SABdbCrashed; } + /* release the lock */ + MT_lockf(buf, F_ULOCK, 4, 1); (void)fclose(f); - } /* cannot happen, we checked it before */ - - /* release the lock */ - close(fd); + } else { + /* shouldn't happen */ + close(fd); + } } snprintf(buf, sizeof(buf), "%s/%s/%s", path, e->d_name, MAINTENANCEFILE); diff --git a/common/utils/mutils.c b/common/utils/mutils.c --- a/common/utils/mutils.c +++ b/common/utils/mutils.c @@ -204,12 +204,16 @@ dirname(char *path) int MT_lockf(char *filename, int mode, off_t off, off_t len) { - int ret = 1, illegalmode = 0, fd = -1; + int ret = 1, fd = -1; OVERLAPPED ov; OSVERSIONINFO os; - HANDLE fh = CreateFile(filename, - GENERIC_READ | GENERIC_WRITE, 0, - NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE fh; + static struct lockedfiles { + struct lockedfiles *next; + char *filename; + int fildes; + } *lockedfiles; + struct lockedfiles **fpp, *fp; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&os); @@ -230,36 +234,59 @@ MT_lockf(char *filename, int mode, off_t #endif #endif - if (fh == NULL) { + if (mode == F_ULOCK) { + for (fpp = &lockedfiles; (fp = *fpp) != NULL; fpp = &fp->next) { + if (strcmp(fp->filename, filename) == 0) { + free(fp->filename); + fd = fp->fildes; + fh = (HANDLE) _get_osfhandle(fd); + fp = *fpp; + *fpp = fp->next; + free(fp); + ret = UnlockFileEx(fh, 0, len, 0, &ov); + return ret ? 0 : -1; + } + } + /* didn't find the locked file, try opening the file + * directly */ + fh = CreateFile(filename, + GENERIC_READ | GENERIC_WRITE, 0, + NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (fh == INVALID_HANDLE_VALUE) + return -2; + ret = UnlockFileEx(fh, 0, len, 0, &ov); + CloseHandle(fh); + return 0; + } + + fd = open(filename, O_CREAT | O_RDWR | O_TEXT, MONETDB_MODE); + if (fd < 0) + return -2; + fh = (HANDLE) _get_osfhandle(fd); + if (fh == INVALID_HANDLE_VALUE) { + close(fd); return -2; } - if (mode == F_ULOCK) { - if (os.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) - ret = UnlockFileEx(fh, 0, 0, len, &ov); - } else if (mode == F_TLOCK) { - if (os.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) - ret = LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, 0, len, &ov); + + if (mode == F_TLOCK) { + ret = LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, len, 0, &ov); } else if (mode == F_LOCK) { - if (os.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) - ret = LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, 0, len, &ov); + ret = LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, len, 0, &ov); } else { - illegalmode = 1; - } - CloseHandle(fh); - if (illegalmode) { + close(fd); SetLastError(ERROR_INVALID_DATA); + return -2; } if (ret != 0) { - fd = open(filename, O_CREAT | O_RDWR, MONETDB_MODE); - if (fd < 0) { - /* this is nasty, but I "trust" windows that it in this case - * also cannot open the file into a filehandle any more, so - * unlocking is in vain. */ - return -2; - } else { - return fd; + if ((fp = malloc(sizeof(*fp))) != NULL && + (fp->filename = strdup(filename)) != NULL) { + fp->fildes = fd; + fp->next = lockedfiles; + lockedfiles = fp; } + return fd; } else { + close(fd); return -1; } } @@ -292,20 +319,25 @@ lockf(int fd, int cmd, off_t len) } #endif +#ifndef O_TEXT +#define O_TEXT 0 +#endif /* returns -1 when locking failed, * returns -2 when the lock file could not be opened/created * returns the (open) file descriptor to the file otherwise */ int MT_lockf(char *filename, int mode, off_t off, off_t len) { - int fd = open(filename, O_CREAT | O_RDWR, MONETDB_MODE); + int fd = open(filename, O_CREAT | O_RDWR | O_TEXT, MONETDB_MODE); if (fd < 0) return -2; - if (lseek(fd, off, SEEK_SET) == off && lockf(fd, mode, len) == 0) { + if (lseek(fd, off, SEEK_SET) >= 0 && + lockf(fd, mode, len) == 0) { /* do not close else we lose the lock we want */ - return fd; + (void) lseek(fd, 0, SEEK_SET); /* move seek pointer back */ + return mode == F_ULOCK ? 0 : fd; } close(fd); return -1; diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c --- a/gdk/gdk_bbp.c +++ b/gdk/gdk_bbp.c @@ -411,8 +411,8 @@ recover_dir(int direxists) { if (direxists) { /* just try; don't care about these non-vital files */ - GDKunlink(BATDIR, "BBP", "bak"); - GDKmove(BATDIR, "BBP", "dir", BATDIR, "BBP", "bak"); + (void) GDKunlink(BATDIR, "BBP", "bak"); + (void) GDKmove(BATDIR, "BBP", "dir", BATDIR, "BBP", "bak"); } return GDKmove(BAKDIR, "BBP", "dir", BATDIR, "BBP", "dir"); } @@ -3142,14 +3142,11 @@ BBPprepare(bit subcommit) ret = (BBPrecover_subdir() < 0); } if (backup_files == 0) { - struct stat st; - backup_dir = 0; - ret = (stat(BAKDIR, &st) == 0 && BBPrecover()); - + ret = BBPrecover(); if (ret == 0) { - /* make a new BAKDIR */ - ret = mkdir(BAKDIR, 0755); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list