File: wvfile.cc

package info (click to toggle)
wvstreams 4.0.2-4
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 6,420 kB
  • ctags: 6,518
  • sloc: cpp: 52,544; sh: 5,770; ansic: 810; makefile: 461; tcl: 114; perl: 18
file content (116 lines) | stat: -rw-r--r-- 2,893 bytes parent folder | download
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;
}