WvStreams
|
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 } 00014 00015 #ifndef _WIN32 // meaningless to do this on win32 00016 /* 00017 * The Win32 runtime library doesn't provide fcntl so we can't 00018 * set readable and writable reliably. Use the other constructor. 00019 */ 00020 WvFile::WvFile(int rwfd) : WvFDStream(rwfd) 00021 { 00022 if (rwfd > -1) 00023 { 00024 /* We have to do it this way since O_RDONLY is defined as 0 00025 in linux. */ 00026 mode_t xmode = fcntl(rwfd, F_GETFL); 00027 xmode = xmode & (O_RDONLY | O_WRONLY | O_RDWR); 00028 readable = (xmode == O_RDONLY) || (xmode == O_RDWR); 00029 writable = (xmode == O_WRONLY) || (xmode == O_RDWR); 00030 } 00031 else 00032 readable = writable = false; 00033 } 00034 #endif 00035 00036 00037 WvFile::WvFile(WvStringParm filename, int mode, int create_mode) 00038 { 00039 #ifdef _WIN32 00040 mode |= O_BINARY; // WvStreams users aren't expecting crlf mangling 00041 #endif 00042 open(filename, mode, create_mode); 00043 } 00044 00045 00046 static IWvStream *increator(WvStringParm s, IObject*) 00047 { 00048 return new WvFile(s, O_RDONLY, 0666); 00049 } 00050 00051 static IWvStream *outcreator(WvStringParm s, IObject*) 00052 { 00053 return new WvFile(s, O_WRONLY|O_CREAT|O_TRUNC, 0666); 00054 } 00055 00056 static IWvStream *creator(WvStringParm s, IObject*) 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 00066 bool WvFile::open(WvStringParm filename, int mode, int create_mode) 00067 { 00068 noerr(); 00069 00070 /* We have to do it this way since O_RDONLY is defined as 0 00071 in linux. */ 00072 int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR)); 00073 readable = (xmode == O_RDONLY) || (xmode == O_RDWR); 00074 writable = (xmode == O_WRONLY) || (xmode == O_RDWR); 00075 00076 // don't do the default force_select of read if we're not readable! 00077 if (!readable) 00078 undo_force_select(true, false, false); 00079 00080 close(); 00081 #ifndef _WIN32 00082 int rwfd = ::open(filename, mode | O_NONBLOCK, create_mode); 00083 #else 00084 int rwfd = ::_open(filename, mode | O_NONBLOCK, create_mode); 00085 #endif 00086 if (rwfd < 0) 00087 { 00088 seterr(errno); 00089 return false; 00090 } 00091 setfd(rwfd); 00092 fcntl(rwfd, F_SETFD, 1); 00093 00094 closed = stop_read = stop_write = false; 00095 return true; 00096 } 00097 00098 00099 #ifndef _WIN32 // since win32 doesn't support fcntl 00100 bool WvFile::open(int _rwfd) 00101 { 00102 noerr(); 00103 if (_rwfd < 0) 00104 return false; 00105 00106 noerr(); 00107 close(); 00108 00109 int mode = fcntl(_rwfd, F_GETFL); 00110 int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR)); 00111 readable = (xmode == O_RDONLY) || (xmode == O_RDWR); 00112 writable = (xmode == O_WRONLY) || (xmode == O_RDWR); 00113 00114 if (!readable) 00115 undo_force_select(true, false, false); 00116 00117 setfd(_rwfd); 00118 fcntl(_rwfd, F_SETFL, mode | O_NONBLOCK); 00119 fcntl(_rwfd, F_SETFD, 1); 00120 00121 closed = stop_read = stop_write = false; 00122 return true; 00123 } 00124 #endif 00125 00126 00127 // files not open for read are never readable; files not open for write 00128 // are never writable. 00129 void WvFile::pre_select(SelectInfo &si) 00130 { 00131 if (!readable) si.wants.readable = false; 00132 if (!writable) si.wants.writable = false; 00133 00134 WvFDStream::pre_select(si); 00135 } 00136 00137 00138 bool WvFile::post_select(SelectInfo &si) 00139 { 00140 return WvFDStream::post_select(si); 00141 }