1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/*
* Worldvisions Weaver Software:
* Copyright (C) 1997-2004 Net Integration Technologies, Inc.
*
* A simple class to access filesystem files using WvStreams.
*/
#include "wvfile.h"
#include "wvmoniker.h"
#ifndef _WIN32 // meaningless to do this on win32
/*
* The Win32 runtime library doesn't provide fcntl so we can't
* set readable and writable reliably. Use the other constructor.
*/
WvFile::WvFile(int rwfd) : WvFDStream(rwfd)
{
if (rwfd > -1)
{
/* We have to do it this way since O_RDONLY is defined as 0
in linux. */
mode_t xmode = fcntl(rwfd, F_GETFL);
xmode = xmode & (O_RDONLY | O_WRONLY | O_RDWR);
readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
}
else
readable = writable = false;
skip_select = false;
}
#endif
WvFile::WvFile(WvStringParm filename, int mode, int create_mode)
{
open(filename, mode, create_mode);
}
static IWvStream *increator(WvStringParm s, IObject *, void *)
{
return new WvFile(s, O_RDONLY, 0666);
}
static IWvStream *outcreator(WvStringParm s, IObject *, void *)
{
return new WvFile(s, O_WRONLY|O_CREAT|O_TRUNC, 0666);
}
static IWvStream *creator(WvStringParm s, IObject *, void *)
{
return new WvFile(s, O_RDWR|O_CREAT, 0666);
}
static WvMoniker<IWvStream> reg0("infile", increator);
static WvMoniker<IWvStream> reg1("outfile", outcreator);
static WvMoniker<IWvStream> reg3("file", creator);
bool WvFile::open(WvStringParm filename, int mode, int create_mode)
{
noerr();
/* We have to do it this way since O_RDONLY is defined as 0
in linux. */
int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR));
readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
skip_select = false;
// don't do the default force_select of read if we're not readable!
if (!readable)
undo_force_select(true, false, false);
close();
#ifndef _WIN32
int rwfd = ::open(filename, mode | O_NONBLOCK, create_mode);
#else
int rwfd = ::_open(filename, mode | O_NONBLOCK, create_mode);
#endif
if (rwfd < 0)
{
seterr(errno);
return false;
}
setfd(rwfd);
fcntl(rwfd, F_SETFD, 1);
closed = stop_read = stop_write = false;
return true;
}
// files not open for read are never readable; files not open for write
// are never writable.
bool WvFile::pre_select(SelectInfo &si)
{
bool ret;
SelectRequest oldwant = si.wants;
if (!readable) si.wants.readable = false;
if (!writable) si.wants.writable = false;
ret = WvFDStream::pre_select(si);
si.wants = oldwant;
// Force select() to always return true by causing it to not wait and
// setting our pre_select() return value to true.
if (skip_select)
{
si.msec_timeout = 0;
ret = true;
}
return ret;
}
|