Ticket #108: flintquartz.patch

File flintquartz.patch, 7.5 KB (added by Charlie Hull, 18 years ago)

Patches both Flint and Quartz against Windows delete bug

  • flint_btreebase.cc

     
    2222#include <config.h>
    2323
    2424#include "safeerrno.h"
     25#include "safewindows.h"
    2526
    2627#include "flint_btreebase.h"
    2728#include "flint_io.h"
     
    199200FlintTable_base::read(const string & name, char ch, string &err_msg)
    200201{
    201202    string basename = name + "base" + ch;
     203#ifdef _MSC_VER
     204    /* open file using Windows API, as we may need to delete it while it is still open
     205    - FILE_SHARE_DELETE allows this */
     206    int h = -1;
     207    HANDLE handleWin =
     208        CreateFile(basename.c_str(),
     209                GENERIC_READ,
     210                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     211                NULL,
     212                OPEN_EXISTING,
     213                FILE_ATTRIBUTE_NORMAL,
     214                NULL);
     215    if( handleWin == INVALID_HANDLE_VALUE) {
     216        switch(GetLastError()) {
     217                /* TODO : Incomplete list of possible error codes */
     218                case ERROR_FILE_NOT_FOUND:
     219                case ERROR_PATH_NOT_FOUND:
     220                case ERROR_BAD_PATHNAME:
     221                        _set_errno(ENOENT); break;
     222                case ERROR_ACCESS_DENIED:       
     223                case ERROR_LOCK_VIOLATION:     
     224                case ERROR_NETWORK_ACCESS_DENIED:
     225                case ERROR_DRIVE_LOCKED:
     226                case ERROR_SEEK_ON_DEVICE:
     227                        _set_errno(EACCES); break;
     228                default: _set_errno(EINVAL); break;
     229        }
     230    }
     231    else
     232        /* Now return a standard file descriptor */
     233        h = _open_osfhandle((intptr_t)handleWin, O_RDONLY | O_BINARY);
     234#else   
    202235    int h = open(basename.c_str(), O_RDONLY | O_BINARY);
     236#endif
     237
    203238    if (h == -1) {
    204239        err_msg += "Couldn't open " + basename + ": " + strerror(errno) + "\n";
    205240        return false;
     
    321356    buf.append(reinterpret_cast<const char *>(bit_map), bit_map_size);
    322357    buf += pack_uint(revision);  // REVISION2
    323358
     359#ifdef _MSC_VER
     360    /* open file using Windows API, as we may need to delete it while it is still open
     361    - FILE_SHARE_DELETE allows this*/
     362    int h = -1;
     363    HANDLE handleWin =
     364        CreateFile(filename.c_str(),
     365                GENERIC_WRITE,
     366                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     367                NULL,
     368                CREATE_ALWAYS,
     369                FILE_ATTRIBUTE_NORMAL,
     370                NULL);
     371    if( handleWin == INVALID_HANDLE_VALUE) {
     372        switch(GetLastError()) {
     373                /* TODO : Incomplete list of possible error codes */
     374                case ERROR_ALREADY_EXISTS:
     375                        _set_errno(EEXIST); break;
     376                case ERROR_FILE_NOT_FOUND:
     377                case ERROR_PATH_NOT_FOUND:
     378                case ERROR_BAD_PATHNAME:
     379                        _set_errno(ENOENT); break;
     380                case ERROR_ACCESS_DENIED:       
     381                case ERROR_LOCK_VIOLATION:     
     382                case ERROR_NETWORK_ACCESS_DENIED:
     383                case ERROR_DRIVE_LOCKED:
     384                case ERROR_SEEK_ON_DEVICE:
     385                        _set_errno(EACCES); break;
     386                default: _set_errno(EINVAL); break;
     387        }
     388    }
     389    else
     390        /* Now return a standard file descriptor */
     391        h = _open_osfhandle((intptr_t)handleWin, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
     392#else
    324393    int h = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
     394#endif
    325395    if (h < 0) {
    326396        string message = string("Couldn't open base ")
    327397                + filename + " to write: " + strerror(errno);
  • flint_table.cc

     
    2323#include <config.h>
    2424
    2525#include "safeerrno.h"
    26 
     26#include "safewindows.h"
    2727// Define to use "dangerous" mode - in this mode we write modified btree
    2828// blocks back in place.  This is somewhat faster (especially once we're
    2929// I/O bound) but the database can't be safely searched during indexing
     
    130130
    131131static void sys_unlink(const string &filename)
    132132{
     133#ifdef _MSC_VER
     134    /* We must use DeleteFile as this can delete files that are open */
     135    if(DeleteFile(filename.c_str()) == 0) {
     136        DWORD dwErr = GetLastError();
     137        switch(dwErr) {
     138                case ERROR_FILE_NOT_FOUND: _set_errno(ENOENT); break;
     139                case ERROR_SHARING_VIOLATION:
     140                /* The file should have been opened with FILE_SHARE_DELETE if it is allowed
     141                to be deleted, so if we get a sharing violation something's gone wrong */
     142                case ERROR_ACCESS_DENIED: _set_errno(EACCES); break;
     143        }
     144#else
    133145    if (unlink(filename) == -1) {
     146#endif
    134147        string message = "Failed to unlink ";
    135148        message += filename;
    136149        message += ": ";
  • btree.cc

     
    2323#include <config.h>
    2424
    2525#include "safeerrno.h"
     26#include "safewindows.h"
    2627
    2728// Define to use "dangerous" mode - in this mode we write modified btree
    2829// blocks back in place.  This is somewhat faster (especially once we're
     
    103104
    104105int sys_open_to_read_no_except(const string & name)
    105106{
     107#ifdef _MSC_VER
     108    /* open file using Windows API, as we may need to delete it while it is still open
     109    - FILE_SHARE_DELETE allows this */
     110    int fd = -1;
     111    HANDLE handleWin =
     112        CreateFile(name.c_str(),
     113                GENERIC_READ,
     114                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     115                NULL,
     116                OPEN_EXISTING,
     117                FILE_ATTRIBUTE_NORMAL,
     118                NULL);
     119    if( handleWin == INVALID_HANDLE_VALUE) {
     120        switch(GetLastError()) {
     121                /* TODO : Incomplete list of possible error codes */
     122                case ERROR_FILE_NOT_FOUND:
     123                case ERROR_PATH_NOT_FOUND:
     124                case ERROR_BAD_PATHNAME:
     125                        _set_errno(ENOENT); break;
     126                case ERROR_ACCESS_DENIED:       
     127                case ERROR_LOCK_VIOLATION:     
     128                case ERROR_NETWORK_ACCESS_DENIED:
     129                case ERROR_DRIVE_LOCKED:
     130                case ERROR_SEEK_ON_DEVICE:
     131                        _set_errno(EACCES); break;
     132                default: _set_errno(EINVAL); break;
     133        }
     134    }
     135    else
     136        /* Now return a standard file descriptor */
     137        fd = _open_osfhandle((intptr_t)handleWin, O_RDONLY | O_BINARY);
     138#else   
    106139    int fd = open(name.c_str(), O_RDONLY | O_BINARY);
     140#endif   
    107141    return fd;
    108142}
    109143
     
    120154
    121155static int sys_open_to_write_no_except(const string & name)
    122156{
     157#ifdef _MSC_VER
     158    /* open file using Windows API, as we may need to delete it while it is still open
     159    - FILE_SHARE_DELETE allows this*/
     160    int fd = -1;
     161    HANDLE handleWin =
     162        CreateFile(name.c_str(),
     163                GENERIC_WRITE,
     164                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     165                NULL,
     166                CREATE_ALWAYS,
     167                FILE_ATTRIBUTE_NORMAL,
     168                NULL);
     169    if( handleWin == INVALID_HANDLE_VALUE) {
     170        switch(GetLastError()) {
     171                /* TODO : Incomplete list of possible error codes */
     172                case ERROR_ALREADY_EXISTS:
     173                        _set_errno(EEXIST); break;
     174                case ERROR_FILE_NOT_FOUND:
     175                case ERROR_PATH_NOT_FOUND:
     176                case ERROR_BAD_PATHNAME:
     177                        _set_errno(ENOENT); break;
     178                case ERROR_ACCESS_DENIED:       
     179                case ERROR_LOCK_VIOLATION:     
     180                case ERROR_NETWORK_ACCESS_DENIED:
     181                case ERROR_DRIVE_LOCKED:
     182                case ERROR_SEEK_ON_DEVICE:
     183                        _set_errno(EACCES); break;
     184                default: _set_errno(EINVAL); break;
     185        }
     186    }
     187    else
     188        /* Now return a standard file descriptor */
     189        fd = _open_osfhandle((intptr_t)handleWin, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
     190#else
    123191    int fd = open(name.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
     192#endif   
    124193    return fd;
    125194}
    126195
     
    218287
    219288static void sys_unlink(const string &filename)
    220289{
     290#ifdef _MSC_VER
     291    /* We must use DeleteFile as this can delete files that are open */
     292    if(DeleteFile(filename.c_str()) == 0) {
     293        DWORD dwErr = GetLastError();
     294        switch(dwErr) {
     295                case ERROR_FILE_NOT_FOUND: _set_errno(ENOENT); break;
     296                case ERROR_SHARING_VIOLATION:
     297                /* The file should have been opened with FILE_SHARE_DELETE if it is allowed
     298                to be deleted, so if we get a sharing violation something's gone wrong */
     299                case ERROR_ACCESS_DENIED: _set_errno(EACCES); break;
     300        }
     301#else
    221302    if (unlink(filename) == -1) {
     303#endif
    222304        string message = "Failed to unlink ";
    223305        message += filename;
    224306        message += ": ";