00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00043
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
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;
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;
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
00095
00096
00097
00098
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;
00107
00108 if (!si.wants.readable)
00109 return false;
00110
00111
00112 if (getrfd() >= 0 && si.wants.readable
00113 && !fstat(getrfd(), &st) && fpos < st.st_size)
00114 return true;
00115
00116
00117 if (make_ok(false))
00118 {
00119
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 }