Ticket #108: flint_btreebase.cc.patch

File flint_btreebase.cc.patch, 3.2 KB (added by Charlie Hull, 17 years ago)

Patch to create files that can be deleted while open (Windows only)

  • 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        int h = -1;
     206        HANDLE handleWin = CreateFile(basename.c_str(),
     207                                                        GENERIC_READ,
     208                                                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* FILE_SHARE_DELETE allows it to be deleted while open */
     209                                                        NULL,
     210                                                        OPEN_EXISTING,
     211                                                        FILE_ATTRIBUTE_NORMAL,
     212                                                        NULL);
     213        if( handleWin == INVALID_HANDLE_VALUE)
     214        { /* Failed to open */
     215                switch(GetLastError()){
     216                        /* TODO : Incomplete list of possible error codes */
     217                        case ERROR_FILE_NOT_FOUND:
     218                        case ERROR_PATH_NOT_FOUND:
     219                        case ERROR_BAD_PATHNAME:
     220                                                                        _set_errno(ENOENT); break;
     221                        case ERROR_ACCESS_DENIED:       
     222                        case ERROR_LOCK_VIOLATION:     
     223                        case ERROR_NETWORK_ACCESS_DENIED:
     224                        case ERROR_DRIVE_LOCKED:
     225                        case ERROR_SEEK_ON_DEVICE:
     226                                                                        _set_errno(EACCES); break;
     227                        default: _set_errno(EINVAL); break;
     228                        }
     229                h = -1;                     
     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        int h = -1;
     362        HANDLE handleWin = CreateFile(filename.c_str(),
     363                                                        GENERIC_WRITE,
     364                                                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* FILE_SHARE_DELETE allows it to be deleted while open */
     365                                                        NULL,
     366                                                        CREATE_ALWAYS,
     367                                                        FILE_ATTRIBUTE_NORMAL,
     368                                                        NULL);
     369        if( handleWin == INVALID_HANDLE_VALUE) { /* Failed to open */
     370                switch(GetLastError()) {
     371                        /* TODO : Incomplete list of possible error codes */
     372                        case ERROR_ALREADY_EXISTS:
     373                                                                        _set_errno(EEXIST); break;
     374                        case ERROR_FILE_NOT_FOUND:
     375                        case ERROR_PATH_NOT_FOUND:
     376                        case ERROR_BAD_PATHNAME:
     377                                                                        _set_errno(ENOENT); break;
     378                        case ERROR_ACCESS_DENIED:       
     379                        case ERROR_LOCK_VIOLATION:     
     380                        case ERROR_NETWORK_ACCESS_DENIED:
     381                        case ERROR_DRIVE_LOCKED:
     382                        case ERROR_SEEK_ON_DEVICE:
     383                                                                        _set_errno(EACCES); break;
     384                        default: _set_errno(EINVAL); break;
     385                }
     386                h = -1;                     
     387        }
     388        else
     389                /* Now return a standard file descriptor */
     390                h = _open_osfhandle((intptr_t)handleWin, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
     391#else
    324392    int h = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
     393#endif
    325394    if (h < 0) {
    326395        string message = string("Couldn't open base ")
    327396                + filename + " to write: " + strerror(errno);