WvStreams
wvfile.cc
1 /*
2  * Worldvisions Weaver Software:
3  * Copyright (C) 1997-2004 Net Integration Technologies, Inc.
4  *
5  * A simple class to access filesystem files using WvStreams.
6  */
7 #include "wvfile.h"
8 #include "wvmoniker.h"
9 
11 {
12  readable = writable = false;
13 }
14 
15 #ifndef _WIN32 // meaningless to do this on win32
16 /*
17  * The Win32 runtime library doesn't provide fcntl so we can't
18  * set readable and writable reliably. Use the other constructor.
19  */
20 WvFile::WvFile(int rwfd) : WvFDStream(rwfd)
21 {
22  if (rwfd > -1)
23  {
24  /* We have to do it this way since O_RDONLY is defined as 0
25  in linux. */
26  mode_t xmode = fcntl(rwfd, F_GETFL);
27  xmode = xmode & (O_RDONLY | O_WRONLY | O_RDWR);
28  readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
29  writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
30  }
31  else
32  readable = writable = false;
33 }
34 #endif
35 
36 
37 WvFile::WvFile(WvStringParm filename, int mode, int create_mode)
38 {
39 #ifdef _WIN32
40  mode |= O_BINARY; // WvStreams users aren't expecting crlf mangling
41 #endif
42  open(filename, mode, create_mode);
43 }
44 
45 
46 static IWvStream *increator(WvStringParm s, IObject*)
47 {
48  return new WvFile(s, O_RDONLY, 0666);
49 }
50 
51 static IWvStream *outcreator(WvStringParm s, IObject*)
52 {
53  return new WvFile(s, O_WRONLY|O_CREAT|O_TRUNC, 0666);
54 }
55 
56 static IWvStream *creator(WvStringParm s, IObject*)
57 {
58  return new WvFile(s, O_RDWR|O_CREAT, 0666);
59 }
60 
61 static WvMoniker<IWvStream> reg0("infile", increator);
62 static WvMoniker<IWvStream> reg1("outfile", outcreator);
63 static WvMoniker<IWvStream> reg3("file", creator);
64 
65 
66 bool WvFile::open(WvStringParm filename, int mode, int create_mode)
67 {
68  noerr();
69 
70  /* We have to do it this way since O_RDONLY is defined as 0
71  in linux. */
72  int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR));
73  readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
74  writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
75 
76  // don't do the default force_select of read if we're not readable!
77  if (!readable)
78  undo_force_select(true, false, false);
79 
80  close();
81  #ifndef _WIN32
82  int rwfd = ::open(filename, mode | O_NONBLOCK, create_mode);
83  #else
84  int rwfd = ::_open(filename, mode | O_NONBLOCK, create_mode);
85  #endif
86  if (rwfd < 0)
87  {
88  seterr(errno);
89  return false;
90  }
91  setfd(rwfd);
92  fcntl(rwfd, F_SETFD, 1);
93 
94  closed = stop_read = stop_write = false;
95  return true;
96 }
97 
98 
99 #ifndef _WIN32 // since win32 doesn't support fcntl
100 bool WvFile::open(int _rwfd)
101 {
102  noerr();
103  if (_rwfd < 0)
104  return false;
105 
106  noerr();
107  close();
108 
109  int mode = fcntl(_rwfd, F_GETFL);
110  int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR));
111  readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
112  writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
113 
114  if (!readable)
115  undo_force_select(true, false, false);
116 
117  setfd(_rwfd);
118  fcntl(_rwfd, F_SETFL, mode | O_NONBLOCK);
119  fcntl(_rwfd, F_SETFD, 1);
120 
121  closed = stop_read = stop_write = false;
122  return true;
123 }
124 #endif
125 
126 
127 // files not open for read are never readable; files not open for write
128 // are never writable.
130 {
131  if (!readable) si.wants.readable = false;
132  if (!writable) si.wants.writable = false;
133 
135 }
136 
137 
139 {
140  return WvFDStream::post_select(si);
141 }
WvFile
WvFile implements a stream connected to a file or Unix device.
Definition: wvfile.h:28
IWvStream
Definition: iwvstream.h:24
WvStream::seterr
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
Definition: wvstream.cc:451
WvFdStream::post_select
virtual bool post_select(SelectInfo &si)
post_select() is called after ::select(), and returns true if this object is now ready.
Definition: wvfdstream.cc:254
WvFdStream::setfd
void setfd(int fd)
Sets the file descriptor for both reading and writing.
Definition: wvfdstream.h:36
WvErrorBase::noerr
void noerr()
Reset our error state - there's no error condition anymore.
Definition: wverror.h:78
WvFile::WvFile
WvFile()
Create an empty WvFile that you'll open later with open()
Definition: wvfile.cc:10
IWvStream::SelectInfo
the data structure used by pre_select()/post_select() and internally by select().
Definition: iwvstream.h:50
WvMoniker
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition: wvmoniker.h:61
IObject
Definition: IObject.h:65
WvFile::pre_select
virtual void pre_select(SelectInfo &si)
pre_select() sets up for eventually calling ::select().
Definition: wvfile.cc:129
WvFdStream::close
virtual void close()
Closes the file descriptors.
Definition: wvfdstream.cc:117
WvFile::post_select
virtual bool post_select(SelectInfo &si)
post_select() is called after ::select(), and returns true if this object is now ready.
Definition: wvfile.cc:138
WvFdStream
Base class for streams built on Unix file descriptors.
Definition: wvfdstream.h:20
WvStream::undo_force_select
void undo_force_select(bool readable, bool writable, bool isexception=false)
Undo a previous force_select() - ie.
Definition: wvstream.cc:1037
WvFdStream::pre_select
virtual void pre_select(SelectInfo &si)
pre_select() sets up for eventually calling ::select().
Definition: wvfdstream.cc:214
WvStream::stop_read
bool stop_read
True if noread()/nowrite()/close() have been called, respectively.
Definition: wvstream.h:57