wvfile.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2004 Net Integration Technologies, Inc.
00004  * 
00005  * A simple class to access filesystem files using WvStreams.
00006  */
00007 #include "wvfile.h"
00008 #include "wvmoniker.h"
00009 
00010 WvFile::WvFile()
00011 {
00012     readable = writable = false;
00013     skip_select = false;
00014 }
00015 
00016 #ifndef _WIN32 // meaningless to do this on win32
00017 /*
00018  * The Win32 runtime library doesn't provide fcntl so we can't
00019  * set readable and writable reliably. Use the other constructor.
00020  */
00021 WvFile::WvFile(int rwfd) : WvFDStream(rwfd)
00022 {
00023     if (rwfd > -1)
00024     {
00025         /* We have to do it this way since O_RDONLY is defined as 0
00026             in linux. */
00027         mode_t xmode = fcntl(rwfd, F_GETFL);
00028         xmode = xmode & (O_RDONLY | O_WRONLY | O_RDWR);
00029         readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
00030         writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
00031     }
00032     else
00033         readable = writable = false;
00034 
00035     skip_select = false;
00036 }
00037 #endif
00038 
00039 
00040 WvFile::WvFile(WvStringParm filename, int mode, int create_mode)
00041 {
00042     open(filename, mode, create_mode);
00043 }
00044 
00045 
00046 static IWvStream *increator(WvStringParm s)
00047 {
00048     return new WvFile(s, O_RDONLY, 0666);
00049 }
00050 
00051 static IWvStream *outcreator(WvStringParm s)
00052 {
00053     return new WvFile(s, O_WRONLY|O_CREAT|O_TRUNC, 0666);
00054 }
00055 
00056 static IWvStream *creator(WvStringParm s)
00057 {
00058     return new WvFile(s, O_RDWR|O_CREAT, 0666);
00059 }
00060 
00061 static WvMoniker<IWvStream> reg0("infile", increator);
00062 static WvMoniker<IWvStream> reg1("outfile", outcreator);
00063 static WvMoniker<IWvStream> reg3("file", creator);
00064 
00065 bool WvFile::open(WvStringParm filename, int mode, int create_mode)
00066 {
00067     noerr();
00068     
00069     /* We have to do it this way since O_RDONLY is defined as 0
00070        in linux. */
00071     int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR));
00072     readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
00073     writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
00074 
00075     skip_select = false;
00076     
00077     // don't do the default force_select of read if we're not readable!
00078     if (!readable)
00079         undo_force_select(true, false, false);
00080     
00081     close();
00082     #ifndef _WIN32
00083     int rwfd = ::open(filename, mode | O_NONBLOCK, create_mode);
00084     #else
00085     int rwfd = ::_open(filename, mode | O_NONBLOCK, create_mode);
00086     #endif
00087     if (rwfd < 0)
00088     {
00089         seterr(errno);
00090         return false;
00091     }
00092     setfd(rwfd);
00093     fcntl(rwfd, F_SETFD, 1);
00094 
00095     closed = stop_read = stop_write = false;
00096     return true;
00097 }
00098 
00099 #ifndef _WIN32  // since win32 doesn't support fcntl
00100 
00101 bool WvFile::open(int _rwfd)
00102 {
00103     noerr();
00104     if (_rwfd < 0)
00105         return false;
00106 
00107     noerr();
00108     close();
00109     
00110     int mode = fcntl(_rwfd, F_GETFL);
00111     int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR));
00112     readable = (xmode == O_RDONLY) || (xmode == O_RDWR);
00113     writable = (xmode == O_WRONLY) || (xmode == O_RDWR);
00114 
00115     skip_select = false;
00116     
00117     if (!readable)
00118         undo_force_select(true, false, false);
00119 
00120     setfd(_rwfd);
00121     fcntl(_rwfd, F_SETFL, mode | O_NONBLOCK);
00122     fcntl(_rwfd, F_SETFD, 1);
00123 
00124     closed = stop_read = stop_write = false;
00125     return true;
00126 }
00127 
00128 #endif 
00129 
00130 // files not open for read are never readable; files not open for write
00131 // are never writable.
00132 bool WvFile::pre_select(SelectInfo &si)
00133 {
00134     bool ret;
00135     
00136     SelectRequest oldwant = si.wants;
00137     
00138     if (!readable) si.wants.readable = false;
00139     if (!writable) si.wants.writable = false;
00140     ret = WvFDStream::pre_select(si);
00141     
00142     si.wants = oldwant;
00143 
00144     // Force select() to always return true by causing it to not wait and
00145     // setting our pre_select() return value to true.
00146     if (skip_select)
00147     {
00148         si.msec_timeout = 0;
00149         ret = true;
00150     }
00151     return ret;
00152 }

Generated on Sun Sep 24 20:10:50 2006 for WvStreams by  doxygen 1.4.7