Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

wvwatcher.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * The WvFileWatcher class provides support for files which sometimes
00006  * have data appended at the end.  It only polls as often as your select()
00007  * delay, so be careful!
00008  * 
00009  * The file is rewound and reopened if its inode changes or its
00010  * length gets shorter, under the assumption that we will want to see the
00011  * entire contents of the new file.
00012  *
00013  * See wvwatcher.h.
00014  */
00015 #include "wvwatcher.h"
00016 #include <sys/time.h>
00017 #include <errno.h>
00018 
00019 WvFileWatcher::WvFileWatcher(const char *_filename, int _mode)
00020                         : WvFile(_filename, _mode), filename(_filename)
00021 {
00022     once_ok = WvFile::isok();
00023     openmode = _mode;
00024     fpos = 0;
00025     if (stat(filename, &last_st) && WvFile::isok())
00026     {
00027         errnum = errno;
00028         close();
00029         once_ok = false;
00030     }
00031 }
00032 
00033 
00034 bool WvFileWatcher::isok() const
00035 {
00036     return once_ok;
00037 }
00038 
00039 
00040 bool WvFileWatcher::make_ok(bool retry)
00041 {
00042     // if the inode has changed, or the size is smaller than last
00043     // time, or we cannot stat the file, close it and start over.
00044     struct stat st;
00045     if (getrfd() >= 0 
00046         && (stat(filename, &st)
00047             || st.st_ino != last_st.st_ino || st.st_size < last_st.st_size))
00048     {
00049         close();
00050     }
00051     
00052     // make sure the file is open
00053     while (!WvFile::isok())
00054     {
00055         fpos = 0;
00056         if (!open(filename, openmode) && retry)
00057             sleep(1);
00058         if (!retry && !WvFile::isok())
00059             return false; // no such luck
00060     }
00061 
00062     stat(filename, &last_st);
00063     return true;
00064 }
00065 
00066 
00067 size_t WvFileWatcher::uread(void *buf, size_t size)
00068 {
00069     size_t len;
00070     if (!once_ok) return 0; // this is never going to work
00071     
00072     if (select(0))
00073     {
00074         len = WvFile::uread(buf, size);
00075         fpos += len;
00076         return len;
00077     }
00078     
00079     return 0;
00080 }
00081 
00082 
00083 size_t WvFileWatcher::uwrite(const void *buf, size_t size)
00084 {
00085     size_t len;
00086     if (!once_ok) return 0;
00087     make_ok(true);
00088     len = WvFile::uwrite(buf, size);
00089     fpos += len;
00090     return len;
00091 }
00092 
00093 
00094 // since you cannot really select() on a real file, we fake it:
00095 // pre_select() returns true if the file is longer than it was last time,
00096 // or you want to write to it.  Otherwise the file is "not ready."
00097 // Because this happens in pre_select, the file will only be checked as
00098 // often as your select() delay.  So infinite delays are a bad idea!
00099 bool WvFileWatcher::pre_select(SelectInfo &si)
00100 {
00101     struct stat st;
00102     
00103     if (!once_ok) return false;
00104     
00105     if (si.wants.writable)
00106         return true; // always writable
00107     
00108     if (!si.wants.readable)
00109         return false; // what are you asking?
00110     
00111     // readable if the current location pointer is < size
00112     if (getrfd() >= 0 && si.wants.readable 
00113            && !fstat(getrfd(), &st) && fpos < st.st_size)
00114         return true;
00115             
00116     // get the file open, at least
00117     if (make_ok(false))
00118     {
00119         // writable as long as file is open
00120         if (si.wants.writable)
00121             return true;
00122         
00123         if (si.wants.readable && fpos < last_st.st_size)
00124             return true;
00125     }
00126     
00127     return false;
00128 }

Generated on Fri Apr 5 15:16:53 2002 for WvStreams by doxygen1.2.15