diff --git a/src/Makefile.am b/src/Makefile.am index 2477fbe3..324d0991 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,8 @@ COMMONCPPFLAGS = -I. \ -I$(top_srcdir)/internfile \ -I$(top_srcdir)/rcldb \ -I$(top_srcdir)/unac \ - -I$(top_srcdir)/utils + -I$(top_srcdir)/utils \ + -I$(top_srcdir)/xaposix AM_CPPFLAGS = -Wall -Wno-unused \ $(COMMONCPPFLAGS) \ @@ -50,10 +51,6 @@ aspell/rclaspell.h \ bincimapmime/config.h \ bincimapmime/convert.cc \ bincimapmime/convert.h \ -bincimapmime/iodevice.cc \ -bincimapmime/iodevice.h \ -bincimapmime/iofactory.cc \ -bincimapmime/iofactory.h \ bincimapmime/mime-inputsource.h \ bincimapmime/mime-parsefull.cc \ bincimapmime/mime-parseonlyheader.cc \ diff --git a/src/bincimapmime/convert.h b/src/bincimapmime/convert.h index 04a41acb..30b034f8 100644 --- a/src/bincimapmime/convert.h +++ b/src/bincimapmime/convert.h @@ -23,10 +23,6 @@ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. * -------------------------------------------------------------------- */ -#ifdef HAVE_CONFIG_H -#include -#endif - #ifndef convert_h_included #define convert_h_included #include @@ -35,7 +31,6 @@ #include #include -#include #include #include diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp index b9f2f154..bf897080 100644 --- a/src/common/rclconfig.cpp +++ b/src/common/rclconfig.cpp @@ -17,29 +17,22 @@ #ifndef TEST_RCLCONFIG #include "autoconfig.h" -#include -#include #include #include #include #include +#include "safesysstat.h" #include - -#include -#include -using std::list; - -#include -#include #ifdef __FreeBSD__ #include #endif +#include +#include #include #include #include #include -using namespace std; #include "cstr.h" #include "pathut.h" @@ -52,6 +45,8 @@ using namespace std; #include "fstreewalk.h" #include "cpuconf.h" +using namespace std; + typedef pair RclPII; // Static, logically const, RclConfig members are initialized once from the diff --git a/src/excludefile b/src/excludefile deleted file mode 100644 index 63b7bbdf..00000000 --- a/src/excludefile +++ /dev/null @@ -1,45 +0,0 @@ -#* -*.cache -*.core -*.o -*~ -.#* -.#* -.moc -.obj -.svn -.ui -*.pyc -CVS -TAGS -alldeps -autom4* -config.cache -config.log -config.status -doc/user/usermanual.aux -doc/user/usermanual.log -doc/user/usermanual.out -doc/user/usermanual.pdf -doc/user/usermanual.tex-pdf -doc/user/usermanual.tex-pdf-tmp -excludefile -kde/recoll_applet -lib/librcl.a -makesrcdist.sh -mk/localdefs -mk/manifest.txt -php/recoll/include/ -php/recoll/modules/ -qtgui/Makefile -qtgui/preview/Makefile -qtgui/preview/preview.pro -qtgui/preview/pvmain.cpp -qtgui/recoll.pro -qt4gui/images -recollinstall -sampleconf/recoll.conf -sysconf -wasabi -wxgui -makesrcdist-force.sh diff --git a/src/index/beaglequeue.cpp b/src/index/beaglequeue.cpp index 2a2af9ac..69747251 100644 --- a/src/index/beaglequeue.cpp +++ b/src/index/beaglequeue.cpp @@ -16,10 +16,9 @@ */ #include "autoconfig.h" -#include -#include #include #include +#include "safesysstat.h" #include "cstr.h" #include "pathut.h" @@ -43,9 +42,6 @@ using namespace std; -#include - - // Beagle creates a file named .xxx (where xxx is the name for the main file // in the queue), to hold external metadata (http or created by Beagle). // This class reads the .xxx, dotfile, and turns it into an Rcl::Doc holder diff --git a/src/index/bglfetcher.cpp b/src/index/bglfetcher.cpp index 9a927766..772e7875 100644 --- a/src/index/bglfetcher.cpp +++ b/src/index/bglfetcher.cpp @@ -14,16 +14,10 @@ * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H #include "autoconfig.h" -#endif - -#include -#include #include "debuglog.h" #include "rcldoc.h" - #include "fetcher.h" #include "bglfetcher.h" #include "debuglog.h" diff --git a/src/index/fetcher.h b/src/index/fetcher.h index 8ac83544..e741d53d 100644 --- a/src/index/fetcher.h +++ b/src/index/fetcher.h @@ -17,7 +17,7 @@ #ifndef _FETCHER_H_INCLUDED_ #define _FETCHER_H_INCLUDED_ -#include +#include "safesysstat.h" #include #include "rcldoc.h" diff --git a/src/index/fsfetcher.cpp b/src/index/fsfetcher.cpp index f1dc6f13..a62c330b 100644 --- a/src/index/fsfetcher.cpp +++ b/src/index/fsfetcher.cpp @@ -14,12 +14,10 @@ * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H #include "autoconfig.h" -#endif -#include #include +#include "safesysstat.h" #include "debuglog.h" #include "cstr.h" diff --git a/src/index/fsindexer.cpp b/src/index/fsindexer.cpp index 74947229..a9b41294 100644 --- a/src/index/fsindexer.cpp +++ b/src/index/fsindexer.cpp @@ -17,10 +17,9 @@ #include "autoconfig.h" #include -#include -#include #include #include +#include "safesysstat.h" #include #include diff --git a/src/index/indexer.cpp b/src/index/indexer.cpp index ab56a77d..ca4e6895 100644 --- a/src/index/indexer.cpp +++ b/src/index/indexer.cpp @@ -19,7 +19,6 @@ #endif #include -#include "safesystat.h" #include #include @@ -30,6 +29,7 @@ #include "fsindexer.h" #include "beaglequeue.h" #include "mimehandler.h" +#include "pathut.h" #ifdef RCL_USE_ASPELL #include "rclaspell.h" @@ -57,14 +57,12 @@ ConfIndexer::~ConfIndexer() bool ConfIndexer::runFirstIndexing() { // Indexing status file existing and not empty ? - struct stat st; - if (stat(m_config->getIdxStatusFile().c_str(), &st) == 0 && - st.st_size > 0) { + if (path_filesize(m_config->getIdxStatusFile()) > 0) { LOGDEB0(("ConfIndexer::runFirstIndexing: no: status file not empty\n")); return false; } // And only do this if the user has kept the default topdirs (~). - vectortdl = m_config->getTopdirs(); + vector tdl = m_config->getTopdirs(); if (tdl.size() != 1 || tdl[0].compare(path_canon(path_tildexpand("~")))) { LOGDEB0(("ConfIndexer::runFirstIndexing: no: not home only\n")); return false; diff --git a/src/index/mimetype.cpp b/src/index/mimetype.cpp index a295ec0e..aa18756a 100644 --- a/src/index/mimetype.cpp +++ b/src/index/mimetype.cpp @@ -18,7 +18,7 @@ #ifndef TEST_MIMETYPE #include "autoconfig.h" -#include +#include "safesysstat.h" #include #include @@ -185,7 +185,7 @@ string mimetype(const string &fn, const struct stat *stp, #else // TEST-> #include -#include +#include "safesysstat.h" #include #include diff --git a/src/index/rclmonprc.cpp b/src/index/rclmonprc.cpp index 3cacb241..dde15f2c 100644 --- a/src/index/rclmonprc.cpp +++ b/src/index/rclmonprc.cpp @@ -25,10 +25,7 @@ */ #include -#include -#include #include -#include #include #include diff --git a/src/index/rclmonrcv.cpp b/src/index/rclmonrcv.cpp index bda85e8f..826956b3 100644 --- a/src/index/rclmonrcv.cpp +++ b/src/index/rclmonrcv.cpp @@ -16,11 +16,12 @@ * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include +#include "autoconfig.h" + #include #include #include +#include "safesysstat.h" #include "debuglog.h" #include "rclmon.h" @@ -298,7 +299,6 @@ bool eraseWatchSubTree(map& idtopath, const string& top) #include #include #include -#include #include /** FAM based monitor class. We have to keep a record of FAM watch diff --git a/src/index/subtreelist.cpp b/src/index/subtreelist.cpp index d7eae613..60be975e 100644 --- a/src/index/subtreelist.cpp +++ b/src/index/subtreelist.cpp @@ -63,7 +63,6 @@ bool subtreelist(RclConfig *config, const string& top, #include #include -#include #include #include diff --git a/src/internfile/internfile.cpp b/src/internfile/internfile.cpp index ab29a903..50962697 100644 --- a/src/internfile/internfile.cpp +++ b/src/internfile/internfile.cpp @@ -19,11 +19,11 @@ #include "autoconfig.h" #include -#include -#include -#include -#include #include +#include "safefcntl.h" +#include +#include "safesysstat.h" +#include "safeunistd.h" #include #include @@ -1117,7 +1117,7 @@ bool FileInterner::maybeUncompressToTemp(TempFile& temp, const string& fn, #include #include #include -#include +#include "safesysstat.h" using namespace std; diff --git a/src/internfile/mh_mbox.cpp b/src/internfile/mh_mbox.cpp index 418004d4..142745c4 100644 --- a/src/internfile/mh_mbox.cpp +++ b/src/internfile/mh_mbox.cpp @@ -18,13 +18,11 @@ #include "autoconfig.h" #include -#include #include -#include +#include +#include "safesysstat.h" #include #include -#include -#include #include #include @@ -272,9 +270,15 @@ bool MimeHandlerMbox::set_document_file(const string& mt, const string &fn) // perror("fcntl"); } #endif - fseek((FILE *)m_vfp, 0, SEEK_END); - m_fsize = ftell((FILE*)m_vfp); - fseek((FILE*)m_vfp, 0, SEEK_SET); + // Used to use ftell() here: no good beyond 2GB + {struct stat st; + if (fstat(fileno((FILE*)m_vfp), &st) < 0) { + LOGERR(("MimeHandlerMbox:setdocfile: fstat(%s) failed errno %d\n", + fn.c_str(), errno)); + return false; + } + m_fsize = st.st_size; + } m_havedoc = true; m_offsets.clear(); m_quirks = 0; diff --git a/src/internfile/mh_text.cpp b/src/internfile/mh_text.cpp index 6aab33fa..4fe35e2f 100644 --- a/src/internfile/mh_text.cpp +++ b/src/internfile/mh_text.cpp @@ -17,15 +17,11 @@ #include "autoconfig.h" #include -#include -#include #include #include #include -#ifndef NO_NAMESPACES using namespace std; -#endif /* NO_NAMESPACES */ #include "cstr.h" #include "mh_text.h" @@ -34,6 +30,7 @@ using namespace std; #include "md5ut.h" #include "rclconfig.h" #include "pxattr.h" +#include "pathut.h" const int MB = 1024*1024; const int KB = 1024; @@ -47,8 +44,8 @@ bool MimeHandlerText::set_document_file(const string& mt, const string &fn) m_fn = fn; // file size for oversize check - struct stat st; - if (stat(m_fn.c_str(), &st) < 0) { + long long fsize = path_filesize(m_fn); + if (fsize < 0) { LOGERR(("MimeHandlerText::set_document_file: stat(%s) errno %d\n", m_fn.c_str(), errno)); return false; @@ -62,7 +59,7 @@ bool MimeHandlerText::set_document_file(const string& mt, const string &fn) int maxmbs = 20; m_config->getConfParam("textfilemaxmbs", &maxmbs); - if (maxmbs == -1 || st.st_size / MB <= maxmbs) { + if (maxmbs == -1 || fsize / MB <= maxmbs) { // Text file page size: if set, we split text files into // multiple documents int ps = 1000; diff --git a/src/internfile/uncomp.cpp b/src/internfile/uncomp.cpp index 7ef4d694..2ce1c1be 100644 --- a/src/internfile/uncomp.cpp +++ b/src/internfile/uncomp.cpp @@ -18,14 +18,10 @@ #include "autoconfig.h" #include -#include #include #include #include -using std::map; -using std::string; -using std::vector; #include "uncomp.h" #include "debuglog.h" @@ -33,6 +29,10 @@ using std::vector; #include "execmd.h" #include "pathut.h" +using std::map; +using std::string; +using std::vector; + Uncomp::UncompCache Uncomp::o_cache; bool Uncomp::uncompressfile(const string& ifn, @@ -70,8 +70,8 @@ bool Uncomp::uncompressfile(const string& ifn, m_dir->dirname())); // Hope for the best } else { - struct stat stb; - if (stat(ifn.c_str(), &stb) < 0) { + long long fsize = path_filesize(ifn); + if (fsize < 0) { LOGERR(("uncompressfile: stat input file %s errno %d\n", ifn.c_str(), errno)); return false; @@ -82,7 +82,7 @@ bool Uncomp::uncompressfile(const string& ifn, // have enough space before trying. We take a little margin // use same Mb def as fsocc() - long long filembs = stb.st_size / (1024 * 1024); + long long filembs = fsize / (1024 * 1024); if (availmbs < 2 * filembs + 1) { LOGERR(("uncompressfile. %lld MBs available in %s not enough " diff --git a/src/internfile/uncomp.h b/src/internfile/uncomp.h index 367d3608..1f2f4d6b 100644 --- a/src/internfile/uncomp.h +++ b/src/internfile/uncomp.h @@ -43,8 +43,8 @@ public: private: TempDir *m_dir; - string m_tfile; - string m_srcpath; + std::string m_tfile; + std::string m_srcpath; bool m_docache; class UncompCache { @@ -59,8 +59,8 @@ private: } PTMutexInit m_lock; TempDir *m_dir; - string m_tfile; - string m_srcpath; + std::string m_tfile; + std::string m_srcpath; }; static UncompCache o_cache; }; diff --git a/src/qtgui/fragbuts.cpp b/src/qtgui/fragbuts.cpp index ef6ff1ee..b2ce3054 100644 --- a/src/qtgui/fragbuts.cpp +++ b/src/qtgui/fragbuts.cpp @@ -17,7 +17,7 @@ #include "autoconfig.h" -#include +#include "safesysstat.h" #include #include diff --git a/src/qtgui/preview_w.cpp b/src/qtgui/preview_w.cpp index c70394c5..0f565ea6 100644 --- a/src/qtgui/preview_w.cpp +++ b/src/qtgui/preview_w.cpp @@ -14,10 +14,6 @@ * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include #include #include diff --git a/src/qtgui/rclm_saveload.cpp b/src/qtgui/rclm_saveload.cpp index 8e91582f..f4e0ce95 100644 --- a/src/qtgui/rclm_saveload.cpp +++ b/src/qtgui/rclm_saveload.cpp @@ -18,9 +18,7 @@ /** Saving and restoring named queries */ -#include -#include -#include +#include "safesysstat.h" #include #include diff --git a/src/qtgui/recoll.pro.in b/src/qtgui/recoll.pro.in index ff384f5b..0237a3c4 100644 --- a/src/qtgui/recoll.pro.in +++ b/src/qtgui/recoll.pro.in @@ -107,7 +107,7 @@ unix { @LIBICONV@ $(BDYNAMIC) @LIBQZEITGEIST@ -lz INCLUDEPATH += ../common ../index ../internfile ../query ../unac \ - ../utils ../aspell ../rcldb ../qtgui \ + ../utils ../aspell ../rcldb ../qtgui ../xaposix \ confgui DEPENDPATH += $$INCLUDEPATH } diff --git a/src/qtgui/rtitool.cpp b/src/qtgui/rtitool.cpp index 4e46e4a4..038f2bc4 100644 --- a/src/qtgui/rtitool.cpp +++ b/src/qtgui/rtitool.cpp @@ -17,12 +17,9 @@ #include "autoconfig.h" #include -#include -#include -#include -#include +#include "safesysstat.h" + #include -using std::string; #include #include @@ -35,6 +32,8 @@ using std::string; #include "readfile.h" #include "execmd.h" +using std::string; + static const char *rautostartfile = ".config/autostart/recollindex.desktop"; // Just in case we don't find the file in the shared dir, have a diff --git a/src/qtgui/uiprefs_w.cpp b/src/qtgui/uiprefs_w.cpp index b1f685f2..58150c5f 100644 --- a/src/qtgui/uiprefs_w.cpp +++ b/src/qtgui/uiprefs_w.cpp @@ -16,7 +16,7 @@ */ #include "autoconfig.h" -#include +#include "safesysstat.h" #include #include diff --git a/src/query/recollq.cpp b/src/query/recollq.cpp index 65e0f3a1..c25b0142 100644 --- a/src/query/recollq.cpp +++ b/src/query/recollq.cpp @@ -18,16 +18,13 @@ #include #include -#include #include #include -#include #include #include #include #include -using namespace std; #include "rcldb.h" #include "rclquery.h" @@ -43,6 +40,8 @@ using namespace std; #include "smallut.h" #include "base64.h" +using namespace std; + bool dump_contents(RclConfig *rclconfig, Rcl::Doc& idoc) { FileInterner interner(idoc, rclconfig, FileInterner::FIF_forPreview); diff --git a/src/utils/Makefile b/src/utils/Makefile index e298dfed..4c2ccb68 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -4,7 +4,7 @@ include ../utils/utmkdefs.mk PROGS = pxattr trclosefrom trecrontab \ trnetcon trcopyfile trcircache trmd5 trreadfile trfileudi \ trconftree wipedir smallut trfstreewalk trpathut transcode trbase64 \ - trmimeparse trexecmd utf8iter idfile + trmimeparse trexecmd utf8iter idfile ptmutex workqueue trappformime all: $(PROGS) diff --git a/src/utils/circache.cpp b/src/utils/circache.cpp index 8825b4f4..5d152b91 100644 --- a/src/utils/circache.cpp +++ b/src/utils/circache.cpp @@ -19,17 +19,39 @@ #include "autoconfig.h" #include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include "safefcntl.h" +#include +#include "safesysstat.h" +#include "safeunistd.h" +#include #include #include +#ifndef _WIN32 +#include +#else +struct iovec { + void *iov_base; + size_t iov_len; +}; +static ssize_t writev(int fd, const struct iovec *iov, int iovcnt) +{ + ssize_t tot = 0; + for (int i = 0; i < iovcnt; i++) { + ssize_t ret = ::write(fd, iov[i].iov_base, iov[i].iov_len); + if (ret > 0) + tot += ret; + if (ret != (ssize_t)iov[i].iov_len) { + return ret == -1 ? -1 : tot; + } + } + return tot; +} +#endif + + #include #include #include @@ -189,15 +211,15 @@ public: UdiH h(udi); LOGDEB2(("Circache::khEnter: h %s offs %lu udi [%s]\n", - h.asHexString().c_str(), (ULONG)ofs, udi.c_str())); + h.asHexString().c_str(), (ULONG)ofs, udi.c_str())); pair p = m_ofskh.equal_range(h); if (p.first != m_ofskh.end() && p.first->first == h) { for (kh_type::iterator it = p.first; it != p.second; it++) { LOGDEB2(("Circache::khEnter: col h %s, ofs %lu\n", - it->first.asHexString().c_str(), - (ULONG)it->second)); + it->first.asHexString().c_str(), + (ULONG)it->second)); if (it->second == ofs) { // (h,offs) already there. Happens LOGDEB2(("Circache::khEnter: already there\n")); @@ -228,7 +250,7 @@ public: UdiH h(udi); LOGDEB2(("Circache::khFind: h %s udi [%s]\n", - h.asHexString().c_str(), udi.c_str())); + h.asHexString().c_str(), udi.c_str())); pair p = m_ofskh.equal_range(h); @@ -319,10 +341,10 @@ public: bool writefirstblock() { - if (m_fd < 0) { - m_reason << "writefirstblock: not open "; - return false; - } + if (m_fd < 0) { + m_reason << "writefirstblock: not open "; + return false; + } ostringstream s; s << @@ -348,10 +370,10 @@ public: bool readfirstblock() { - if (m_fd < 0) { - m_reason << "readfirstblock: not open "; - return false; - } + if (m_fd < 0) { + m_reason << "readfirstblock: not open "; + return false; + } char bf[CIRCACHE_FIRSTBLOCK_SIZE]; @@ -394,14 +416,14 @@ public: bool writeEntryHeader(off_t offset, const EntryHeaderData& d) { - if (m_fd < 0) { - m_reason << "writeEntryHeader: not open "; - return false; - } + if (m_fd < 0) { + m_reason << "writeEntryHeader: not open "; + return false; + } char bf[CIRCACHE_HEADER_SIZE]; memset(bf, 0, CIRCACHE_HEADER_SIZE); snprintf(bf, CIRCACHE_HEADER_SIZE, - headerformat, d.dicsize, d.datasize, d.padsize, d.flags); + headerformat, d.dicsize, d.datasize, d.padsize, d.flags); if (lseek(m_fd, offset, 0) != offset) { m_reason << "CirCache::weh: lseek(" << offset << ") failed: errno " << errno; @@ -416,10 +438,10 @@ public: CCScanHook::status readEntryHeader(off_t offset, EntryHeaderData& d) { - if (m_fd < 0) { - m_reason << "readEntryHeader: not open "; + if (m_fd < 0) { + m_reason << "readEntryHeader: not open "; return CCScanHook::Error; - } + } if (lseek(m_fd, offset, 0) != offset) { m_reason << "readEntryHeader: lseek(" << offset << @@ -452,10 +474,10 @@ public: CCScanHook::status scan(off_t startoffset, CCScanHook *user, bool fold = false) { - if (m_fd < 0) { - m_reason << "scan: not open "; + if (m_fd < 0) { + m_reason << "scan: not open "; return CCScanHook::Error; - } + } off_t so0 = startoffset; bool already_folded = false; @@ -623,16 +645,16 @@ public: off_t headoffs; off_t padsize; CCScanHookRecord() - : headoffs(0), padsize(0) + : headoffs(0), padsize(0) { } virtual status takeone(off_t offs, const string& udi, - const EntryHeaderData& d) + const EntryHeaderData& d) { - headoffs = offs; - padsize = d.padsize; - LOGDEB2(("CCScanHookRecord::takeone: offs %lld padsize %lld\n", - headoffs, padsize)); + headoffs = offs; + padsize = d.padsize; + LOGDEB2(("CCScanHookRecord::takeone: offs %lld padsize %lld\n", + headoffs, padsize)); return Continue; } }; @@ -645,62 +667,62 @@ string CirCache::getpath() bool CirCache::create(off_t maxsize, int flags) { LOGDEB(("CirCache::create: [%s] maxsz %lld flags 0x%x\n", - m_dir.c_str(), maxsize, flags)); + m_dir.c_str(), maxsize, flags)); if (m_d == 0) { - LOGERR(("CirCache::create: null data\n")); - return false; + LOGERR(("CirCache::create: null data\n")); + return false; } struct stat st; if (stat(m_dir.c_str(), &st) < 0) { - // Directory does not exist, create it - if (mkdir(m_dir.c_str(), 0777) < 0) { - m_d->m_reason << "CirCache::create: mkdir(" << m_dir << - ") failed" << " errno " << errno; - return false; - } + // Directory does not exist, create it + if (mkdir(m_dir.c_str(), 0777) < 0) { + m_d->m_reason << "CirCache::create: mkdir(" << m_dir << + ") failed" << " errno " << errno; + return false; + } } else { - // If the file exists too, and truncate is not set, switch - // to open-mode. Still may need to update header params. - if (access(m_d->datafn(m_dir).c_str(), 0) >= 0 && - !(flags & CC_CRTRUNCATE)) { - if (!open(CC_OPWRITE)) { - return false; - } - if (maxsize == m_d->m_maxsize && - ((flags & CC_CRUNIQUE) != 0) == m_d->m_uniquentries) { - LOGDEB(("Header unchanged, no rewrite\n")); - return true; - } - // If the new maxsize is bigger than current size, we need - // to stop recycling if this is what we are doing. - if (maxsize > m_d->m_maxsize && maxsize > st.st_size) { - // Scan the file to find the last physical record. The - // ohead is set at physical eof, and nhead is the last - // scanned record - CCScanHookRecord rec; - m_d->scan(CIRCACHE_FIRSTBLOCK_SIZE, &rec, false); - m_d->m_oheadoffs = lseek(m_d->m_fd, 0, SEEK_END); - m_d->m_nheadoffs = rec.headoffs; - m_d->m_npadsize = rec.padsize; - } - m_d->m_maxsize = maxsize; - m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0); - LOGDEB(("CirCache::create: rewriting header with " - "maxsize %lld oheadoffs %lld nheadoffs %lld " - "npadsize %d unient %d\n", - m_d->m_maxsize, m_d->m_oheadoffs, m_d->m_nheadoffs, - m_d->m_npadsize, int(m_d->m_uniquentries))); - return m_d->writefirstblock(); - } - // Else fallthrough to create file + // If the file exists too, and truncate is not set, switch + // to open-mode. Still may need to update header params. + if (access(m_d->datafn(m_dir).c_str(), 0) >= 0 && + !(flags & CC_CRTRUNCATE)) { + if (!open(CC_OPWRITE)) { + return false; + } + if (maxsize == m_d->m_maxsize && + ((flags & CC_CRUNIQUE) != 0) == m_d->m_uniquentries) { + LOGDEB(("Header unchanged, no rewrite\n")); + return true; + } + // If the new maxsize is bigger than current size, we need + // to stop recycling if this is what we are doing. + if (maxsize > m_d->m_maxsize && maxsize > st.st_size) { + // Scan the file to find the last physical record. The + // ohead is set at physical eof, and nhead is the last + // scanned record + CCScanHookRecord rec; + m_d->scan(CIRCACHE_FIRSTBLOCK_SIZE, &rec, false); + m_d->m_oheadoffs = lseek(m_d->m_fd, 0, SEEK_END); + m_d->m_nheadoffs = rec.headoffs; + m_d->m_npadsize = rec.padsize; + } + m_d->m_maxsize = maxsize; + m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0); + LOGDEB(("CirCache::create: rewriting header with " + "maxsize %lld oheadoffs %lld nheadoffs %lld " + "npadsize %d unient %d\n", + m_d->m_maxsize, m_d->m_oheadoffs, m_d->m_nheadoffs, + m_d->m_npadsize, int(m_d->m_uniquentries))); + return m_d->writefirstblock(); + } + // Else fallthrough to create file } if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(), - O_CREAT | O_RDWR | O_TRUNC, 0666)) < 0) { + O_CREAT | O_RDWR | O_TRUNC, 0666)) < 0) { m_d->m_reason << "CirCache::create: open/creat(" << m_d->datafn(m_dir) << ") failed " << "errno " << errno; - return false; + return false; } m_d->m_maxsize = maxsize; @@ -721,15 +743,15 @@ bool CirCache::create(off_t maxsize, int flags) bool CirCache::open(OpMode mode) { if (m_d == 0) { - LOGERR(("CirCache::open: null data\n")); - return false; + LOGERR(("CirCache::open: null data\n")); + return false; } if (m_d->m_fd >= 0) ::close(m_d->m_fd); if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(), - mode == CC_OPREAD ? O_RDONLY : O_RDWR)) < 0) { + mode == CC_OPREAD ? O_RDONLY : O_RDWR)) < 0) { m_d->m_reason << "CirCache::open: open(" << m_d->datafn(m_dir) << ") failed " << "errno " << errno; return false; @@ -938,13 +960,13 @@ public: UINT sizeseen; vector > squashed_udis; CCScanHookSpacer(int sz) - : sizewanted(sz), sizeseen(0) {assert(sz > 0);} + : sizewanted(sz), sizeseen(0) {assert(sz > 0);} virtual status takeone(off_t offs, const string& udi, const EntryHeaderData& d) { LOGDEB2(("Circache:ScanSpacer:off %u dcsz %u dtsz %u pdsz %u udi[%s]\n", - (UINT)offs, d.dicsize, d.datasize, d.padsize, udi.c_str())); + (UINT)offs, d.dicsize, d.datasize, d.padsize, udi.c_str())); sizeseen += CIRCACHE_HEADER_SIZE + d.dicsize + d.datasize + d.padsize; squashed_udis.push_back(make_pair(udi, offs)); if (sizeseen >= sizewanted) @@ -1030,10 +1052,10 @@ bool CirCache::put(const string& udi, const ConfSimple *iconf, if (m_d->readEntryHeader(m_d->m_nheadoffs, pd) != CCScanHook::Continue){ return false; } - if (int(pd.padsize) != m_d->m_npadsize) { - m_d->m_reason << "CirCache::put: logic error: bad padsize "; - return false; - } + if (int(pd.padsize) != m_d->m_npadsize) { + m_d->m_reason << "CirCache::put: logic error: bad padsize "; + return false; + } if (pd.dicsize == 0) { // erased entry. Also recover the header space, no need to rewrite // the header, we're going to write on it. @@ -1093,7 +1115,7 @@ bool CirCache::put(const string& udi, const ConfSimple *iconf, char head[CIRCACHE_HEADER_SIZE]; memset(head, 0, CIRCACHE_HEADER_SIZE); snprintf(head, CIRCACHE_HEADER_SIZE, - headerformat, dic.size(), datalen, npadsize, flags); + headerformat, dic.size(), datalen, npadsize, flags); struct iovec vecs[3]; vecs[0].iov_base = head; vecs[0].iov_len = CIRCACHE_HEADER_SIZE; @@ -1133,19 +1155,19 @@ bool CirCache::rewind(bool& eof) eof = false; - off_t fsize = lseek(m_d->m_fd, 0, SEEK_END); - if (fsize == (off_t)-1) { - LOGERR(("CirCache::rewind: seek to EOF failed\n")); - return false; - } + off_t fsize = lseek(m_d->m_fd, 0, SEEK_END); + if (fsize == (off_t)-1) { + LOGERR(("CirCache::rewind: seek to EOF failed\n")); + return false; + } // Read oldest header. This is either at the position pointed to // by oheadoffs, or after the first block if the file is still // growing. - if (m_d->m_oheadoffs == fsize) { - m_d->m_itoffs = CIRCACHE_FIRSTBLOCK_SIZE; - } else { - m_d->m_itoffs = m_d->m_oheadoffs; - } + if (m_d->m_oheadoffs == fsize) { + m_d->m_itoffs = CIRCACHE_FIRSTBLOCK_SIZE; + } else { + m_d->m_itoffs = m_d->m_oheadoffs; + } CCScanHook::status st = m_d->readEntryHeader(m_d->m_itoffs, m_d->m_ithd); switch(st) { @@ -1222,11 +1244,11 @@ bool CirCache::getCurrent(string& udi, string& dic, string& data) } static void *allocmem( - void *cp, /* The array to grow. may be NULL */ - int sz, /* Unit size in bytes */ + void *cp, /* The array to grow. may be NULL */ + int sz, /* Unit size in bytes */ int *np, /* Pointer to current allocation number */ - int min, /* Number to allocate the first time */ - int maxinc) /* Maximum increment */ + int min, /* Number to allocate the first time */ + int maxinc) /* Maximum increment */ { if (cp == 0) { cp = malloc(min * sz); @@ -1274,7 +1296,7 @@ static bool inflateToDynBuf(void* inp, UINT inlen, void **outpp, UINT *outlenp) d_stream.avail_out, d_stream.total_out)); if (d_stream.avail_out == 0) { if ((outp = (char*)allocmem(outp, inlen, &alloc, - imul, mxinc)) == 0) { + imul, mxinc)) == 0) { LOGERR(("Inflate: out of memory, current alloc %d\n", alloc*inlen)); inflateEnd(&d_stream); @@ -1310,11 +1332,11 @@ static bool inflateToDynBuf(void* inp, UINT inlen, void **outpp, UINT *outlenp) #include #include -#include #include #include -#include #include +#include "safesysstat.h" +#include "safeunistd.h" #include #include @@ -1359,16 +1381,16 @@ bool resizecc(const string& dir, int newmbs) CirCache::CC_CRUNIQUE | CirCache::CC_CRTRUNCATE)) { cerr << "Cant create new file in " << tmpdir << " : " << ncc->getReason() << endl; - return false; + return false; } bool eof = false; - if (!occ->rewind(eof)) { - if (!eof) { - cerr << "Initial rewind failed" << endl; - return false; - } - } + if (!occ->rewind(eof)) { + if (!eof) { + cerr << "Initial rewind failed" << endl; + return false; + } + } int nentries = 0; while (!eof) { string udi, sdic, data; @@ -1420,14 +1442,14 @@ bool resizecc(const string& dir, int newmbs) static char *thisprog; static char usage [] = -" -c [-u] : create\n" -" -p [apath ...] : put files\n" -" -d : dump\n" -" -g [-i instance] [-D] : get\n" -" -D: also dump data\n" -" -e : erase\n" -" -s : resize\n" -; + " -c [-u] : create\n" + " -p [apath ...] : put files\n" + " -d : dump\n" + " -g [-i instance] [-D] : get\n" + " -D: also dump data\n" + " -e : erase\n" + " -s : resize\n" + ; static void Usage(FILE *fp = stderr) { @@ -1437,7 +1459,7 @@ Usage(FILE *fp = stderr) static int op_flags; #define OPT_MOINS 0x1 -#define OPT_c 0x2 +#define OPT_c 0x2 #define OPT_p 0x8 #define OPT_g 0x10 #define OPT_d 0x20 @@ -1455,27 +1477,27 @@ int main(int argc, char **argv) argc--; argv++; while (argc > 0 && **argv == '-') { - (*argv)++; - if (!(**argv)) - /* Cas du "adb - core" */ - Usage(); - while (**argv) - switch (*(*argv)++) { - case 'c': op_flags |= OPT_c; break; - case 'D': op_flags |= OPT_D; break; - case 'd': op_flags |= OPT_d; break; - case 'e': op_flags |= OPT_e; break; - case 'g': op_flags |= OPT_g; break; - case 'i': op_flags |= OPT_i; if (argc < 2) Usage(); - if ((sscanf(*(++argv), "%d", &instance)) != 1) - Usage(); - argc--; - goto b1; - case 'p': op_flags |= OPT_p; break; - case 's': op_flags |= OPT_s; break; - case 'u': op_flags |= OPT_u; break; - default: Usage(); break; - } + (*argv)++; + if (!(**argv)) + /* Cas du "adb - core" */ + Usage(); + while (**argv) + switch (*(*argv)++) { + case 'c': op_flags |= OPT_c; break; + case 'D': op_flags |= OPT_D; break; + case 'd': op_flags |= OPT_d; break; + case 'e': op_flags |= OPT_e; break; + case 'g': op_flags |= OPT_g; break; + case 'i': op_flags |= OPT_i; if (argc < 2) Usage(); + if ((sscanf(*(++argv), "%d", &instance)) != 1) + Usage(); + argc--; + goto b1; + case 'p': op_flags |= OPT_p; break; + case 's': op_flags |= OPT_s; break; + case 'u': op_flags |= OPT_u; break; + default: Usage(); break; + } b1: argc--; argv++; } @@ -1483,19 +1505,19 @@ int main(int argc, char **argv) DebugLog::setfilename("stderr"); if (argc < 1) - Usage(); + Usage(); string dir = *argv++;argc--; CirCache cc(dir); if (op_flags & OPT_c) { - int flags = 0; - if (op_flags & OPT_u) - flags |= CirCache::CC_CRUNIQUE; - if (!cc.create(100*1024, flags)) { - cerr << "Create failed:" << cc.getReason() << endl; - exit(1); - } + int flags = 0; + if (op_flags & OPT_u) + flags |= CirCache::CC_CRUNIQUE; + if (!cc.create(100*1024, flags)) { + cerr << "Create failed:" << cc.getReason() << endl; + exit(1); + } } else if (op_flags & OPT_s) { if (argc != 1) { Usage(); @@ -1505,72 +1527,72 @@ int main(int argc, char **argv) exit(1); } } else if (op_flags & OPT_p) { - if (argc < 1) - Usage(); - if (!cc.open(CirCache::CC_OPWRITE)) { - cerr << "Open failed: " << cc.getReason() << endl; - exit(1); - } - while (argc) { - string fn = *argv++;argc--; - char dic[1000]; - string data, reason; - if (!file_to_string(fn, data, &reason)) { - cerr << "File_to_string: " << reason << endl; - exit(1); - } - string udi; - make_udi(fn, "", udi); - sprintf(dic, "#whatever...\nmimetype = text/plain\nudi=%s\n", - udi.c_str()); - string sdic; - sdic.assign(dic, strlen(dic)); - ConfSimple conf(sdic); + if (argc < 1) + Usage(); + if (!cc.open(CirCache::CC_OPWRITE)) { + cerr << "Open failed: " << cc.getReason() << endl; + exit(1); + } + while (argc) { + string fn = *argv++;argc--; + char dic[1000]; + string data, reason; + if (!file_to_string(fn, data, &reason)) { + cerr << "File_to_string: " << reason << endl; + exit(1); + } + string udi; + make_udi(fn, "", udi); + sprintf(dic, "#whatever...\nmimetype = text/plain\nudi=%s\n", + udi.c_str()); + string sdic; + sdic.assign(dic, strlen(dic)); + ConfSimple conf(sdic); - if (!cc.put(udi, &conf, data, 0)) { - cerr << "Put failed: " << cc.getReason() << endl; - cerr << "conf: ["; conf.write(cerr); cerr << "]" << endl; - exit(1); - } - } - cc.open(CirCache::CC_OPREAD); + if (!cc.put(udi, &conf, data, 0)) { + cerr << "Put failed: " << cc.getReason() << endl; + cerr << "conf: ["; conf.write(cerr); cerr << "]" << endl; + exit(1); + } + } + cc.open(CirCache::CC_OPREAD); } else if (op_flags & OPT_g) { - if (!cc.open(CirCache::CC_OPREAD)) { - cerr << "Open failed: " << cc.getReason() << endl; - exit(1); - } - while (argc) { - string udi = *argv++;argc--; - string dic, data; - if (!cc.get(udi, dic, data, instance)) { - cerr << "Get failed: " << cc.getReason() << endl; - exit(1); - } - cout << "Dict: [" << dic << "]" << endl; - if (op_flags & OPT_D) - cout << "Data: [" << data << "]" << endl; - } + if (!cc.open(CirCache::CC_OPREAD)) { + cerr << "Open failed: " << cc.getReason() << endl; + exit(1); + } + while (argc) { + string udi = *argv++;argc--; + string dic, data; + if (!cc.get(udi, dic, data, instance)) { + cerr << "Get failed: " << cc.getReason() << endl; + exit(1); + } + cout << "Dict: [" << dic << "]" << endl; + if (op_flags & OPT_D) + cout << "Data: [" << data << "]" << endl; + } } else if (op_flags & OPT_e) { - if (!cc.open(CirCache::CC_OPWRITE)) { - cerr << "Open failed: " << cc.getReason() << endl; - exit(1); - } - while (argc) { - string udi = *argv++;argc--; - string dic, data; - if (!cc.erase(udi)) { - cerr << "Erase failed: " << cc.getReason() << endl; - exit(1); - } - } + if (!cc.open(CirCache::CC_OPWRITE)) { + cerr << "Open failed: " << cc.getReason() << endl; + exit(1); + } + while (argc) { + string udi = *argv++;argc--; + string dic, data; + if (!cc.erase(udi)) { + cerr << "Erase failed: " << cc.getReason() << endl; + exit(1); + } + } } else if (op_flags & OPT_d) { - if (!cc.open(CirCache::CC_OPREAD)) { - cerr << "Open failed: " << cc.getReason() << endl; - exit(1); - } - cc.dump(); + if (!cc.open(CirCache::CC_OPREAD)) { + cerr << "Open failed: " << cc.getReason() << endl; + exit(1); + } + cc.dump(); } else - Usage(); + Usage(); exit(0); } diff --git a/src/utils/conftree.cpp b/src/utils/conftree.cpp index 7cb89875..3671f1a8 100644 --- a/src/utils/conftree.cpp +++ b/src/utils/conftree.cpp @@ -20,10 +20,9 @@ #ifndef TEST_CONFTREE -#include // for access(2) #include #include -#include +#include "safesysstat.h" #include #include diff --git a/src/utils/copyfile.cpp b/src/utils/copyfile.cpp index fee9c440..290027dd 100644 --- a/src/utils/copyfile.cpp +++ b/src/utils/copyfile.cpp @@ -16,11 +16,11 @@ */ #ifndef TEST_COPYFILE #include -#include #include -#include +#include "safefcntl.h" #include -#include +#include "safesysstat.h" +#include "safeunistd.h" #include #include diff --git a/src/utils/pathut.cpp b/src/utils/pathut.cpp index b722de91..60e1b3a7 100644 --- a/src/utils/pathut.cpp +++ b/src/utils/pathut.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include "safesysstat.h" #include // Let's include all files where statfs can be defined and hope for no @@ -425,6 +425,14 @@ bool path_isdir(const string& path) return false; } +long long path_filesize(const string& path) +{ + struct stat st; + if (stat(path.c_str(), &st) < 0) + return -1; + return (long long)st.st_size; +} + // Allowed punctuation in the path part of an URI according to RFC2396 // -_.!~*'():@&=+$, /* diff --git a/src/utils/pathut.h b/src/utils/pathut.h index c1405bcd..8e8ca5b7 100644 --- a/src/utils/pathut.h +++ b/src/utils/pathut.h @@ -72,6 +72,9 @@ extern std::string url_gpath(const std::string& url); /// Stat parameter and check if it's a directory extern bool path_isdir(const std::string& path); +/// Retrieve file size +extern long long path_filesize(const std::string& path); + /// Dump directory extern bool readdir(const std::string& dir, std::string& reason, std::set& entries); diff --git a/src/utils/readfile.cpp b/src/utils/readfile.cpp index 4c6905d6..0cd74ec4 100644 --- a/src/utils/readfile.cpp +++ b/src/utils/readfile.cpp @@ -17,14 +17,11 @@ #ifndef TEST_READFILE #include "autoconfig.h" -#include -#include -#include -#include - #include -#include -#include +#include "safefcntl.h" +#include +#include "safesysstat.h" +#include "safeunistd.h" #include @@ -163,9 +160,9 @@ bool file_scan(const string &fn, FileScanDo* doer, off_t startoffs, #include "autoconfig.h" #include -#include -#include #include +#include "safesysstat.h" +#include #include #include diff --git a/src/utils/wipedir.cpp b/src/utils/wipedir.cpp index 847d705f..1e7103be 100644 --- a/src/utils/wipedir.cpp +++ b/src/utils/wipedir.cpp @@ -19,22 +19,22 @@ #ifndef TEST_WIPEDIR #include "autoconfig.h" -#include -#include -#include -#include #include +#include "safefcntl.h" +#include +#include "safesysstat.h" +#include "safeunistd.h" +#include #include #include -#ifndef NO_NAMESPACES -using namespace std; -#endif /* NO_NAMESPACES */ #include "debuglog.h" #include "pathut.h" #include "wipedir.h" +using namespace std; + int wipedir(const string& dir, bool selfalso, bool recurse) { struct stat st; @@ -114,7 +114,6 @@ int wipedir(const string& dir, bool selfalso, bool recurse) #include #include -#include #include "wipedir.h" diff --git a/src/xaposix/safefcntl.h b/src/xaposix/safefcntl.h new file mode 100644 index 00000000..6248351e --- /dev/null +++ b/src/xaposix/safefcntl.h @@ -0,0 +1,71 @@ +/* safefcntl.h: #include , but working around broken platforms. + * + * Copyright (C) 2006,2007 Olly Betts + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef XAPIAN_INCLUDED_SAFEFCNTL_H +#define XAPIAN_INCLUDED_SAFEFCNTL_H + +#include + +#if defined __cplusplus && defined open + +// On some versions of Solaris, fcntl.h pollutes the namespace by #define-ing +// "open" to "open64" when largefile support is enabled. This causes problems +// if you have a method called "open" (other symbols are also #define-d +// e.g. "creat" to "creat64", but only "open" is a problem for Xapian so +// that's the only one we currently fix). + +#ifdef _MSC_VER +// MSVC #define-s open but also defines a function called open, so just undef +// the macro. +# undef open +#else + +inline int fcntl_open_(const char *filename, int flags, mode_t mode) { + return open(filename, flags, mode); +} + +inline int fcntl_open_(const char *filename, int flags) { + return open(filename, flags); +} + +#undef open + +inline int open(const char *filename, int flags, mode_t mode) { + return fcntl_open_(filename, flags, mode); +} + +inline int open(const char *filename, int flags) { + return fcntl_open_(filename, flags); +} + +#endif + +#endif + +// O_BINARY is only useful for platforms like Windows which distinguish between +// text and binary files, but it's cleaner to define it to 0 here for other +// platforms so we can avoid #ifdef where we need to use it in the code. +#ifndef __WIN32__ +# ifndef O_BINARY +# define O_BINARY 0 +# endif +#endif + +#endif /* XAPIAN_INCLUDED_SAFEFCNTL_H */ diff --git a/src/xaposix/safesysstat.h b/src/xaposix/safesysstat.h new file mode 100644 index 00000000..83179b7d --- /dev/null +++ b/src/xaposix/safesysstat.h @@ -0,0 +1,91 @@ +/* safesysstat.h: #include , but enabling large file support. + * + * Copyright (C) 2007,2012 Olly Betts + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef XAPIAN_INCLUDED_SAFESYSSTAT_H +#define XAPIAN_INCLUDED_SAFESYSSTAT_H + +#include + +// For most platforms, AC_SYS_LARGEFILE enables support for large files at +// configure time, but MSVC doesn't use configure so we have to put the +// magic somewhere else - i.e. here! + +#ifdef _MSC_VER +// MSVC needs to call _stati64() instead of stat() and the struct which holds +// the information is "struct _stati64" instead of "struct stat" so we just +// use #define to replace both in one go. We also want to use _fstati64() +// instead of fstat() but in this case we can use a function-like macro. +// +// This hack is a problem is we ever want a method called "stat", or one called +// fstat which takes 2 parameters, but we can probably live with these +// limitations. + +#ifdef stat +# undef stat +#endif + +#ifdef fstat +# undef fstat +#endif + +// NB: _stati64 not _stat64 (the latter just returns a 64 bit timestamp). +#define stat _stati64 +#define fstat(FD, BUF) _fstati64(FD,BUF) + +#endif + +#ifdef __WIN32__ + +// MSVC lacks these POSIX macros and other compilers may too: +#ifndef S_ISDIR +# define S_ISDIR(ST_MODE) (((ST_MODE) & _S_IFMT) == _S_IFDIR) +#endif +#ifndef S_ISREG +# define S_ISREG(ST_MODE) (((ST_MODE) & _S_IFMT) == _S_IFREG) +#endif + +// On UNIX, mkdir() is prototyped in but on Windows it's in +// , so just include that from here to avoid build failures on +// MSVC just because of some new use of mkdir(). This also reduces the +// number of conditionalised #include statements we need in the sources. +#include + +// Add overloaded version of mkdir which takes an (ignored) mode argument +// to allow source code to just specify a mode argument unconditionally. +// +// The () around mkdir are in case it's defined as a macro. +inline int (mkdir)(const char *pathname, mode_t /*mode*/) { + return _mkdir(pathname); +} + +#else + +// These were specified by POSIX.1-1996, so most platforms should have +// these by now: +#ifndef S_ISDIR +# define S_ISDIR(ST_MODE) (((ST_MODE) & S_IFMT) == S_IFDIR) +#endif +#ifndef S_ISREG +# define S_ISREG(ST_MODE) (((ST_MODE) & S_IFMT) == S_IFREG) +#endif + +#endif + +#endif /* XAPIAN_INCLUDED_SAFESYSSTAT_H */ diff --git a/src/xaposix/safeunistd.h b/src/xaposix/safeunistd.h new file mode 100644 index 00000000..0045c417 --- /dev/null +++ b/src/xaposix/safeunistd.h @@ -0,0 +1,78 @@ +/* safeunistd.h: , but with compat. and large file support for MSVC. + * + * Copyright (C) 2007 Olly Betts + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef XAPIAN_INCLUDED_SAFEUNISTD_H +#define XAPIAN_INCLUDED_SAFEUNISTD_H + +#ifndef _MSC_VER +# include +#else + +// sys/types.h has a typedef for off_t so make sure we've seen that before +// we hide it behind a #define. +# include + +// MSVC doesn't even HAVE unistd.h - io.h seems the nearest equivalent. +// We also need to do some renaming of functions to get versions which +// work on large files. +# include + +# ifdef lseek +# undef lseek +# endif + +# ifdef off_t +# undef off_t +# endif + +# define lseek(FD, OFF, WHENCE) _lseeki64(FD, OFF, WHENCE) +# define off_t __int64 + +// process.h is needed for getpid(). +# include + +#endif + +#ifdef __WIN32__ + +inline unsigned int +sleep(unsigned int seconds) +{ + // Use our own little helper function to avoid pulling in . + extern void xapian_sleep_milliseconds(unsigned int millisecs); + + // Sleep takes a time interval in milliseconds, whereas POSIX sleep takes + // a time interval in seconds, so we need to multiply 'seconds' by 1000. + // + // But make sure the multiplication won't overflow! 4294967 seconds is + // nearly 50 days, so just sleep for that long and return the number of + // seconds left to sleep for. The common case of sleep(CONSTANT) should + // optimise to just xapian_sleep_milliseconds(CONSTANT). + if (seconds > 4294967u) { + xapian_sleep_milliseconds(4294967000u); + return seconds - 4294967u; + } + xapian_sleep_milliseconds(seconds * 1000u); + return 0; +} + +#endif + +#endif /* XAPIAN_INCLUDED_SAFEUNISTD_H */