diff options
Diffstat (limited to 'doc/api-documentation/html/filemgr_8cpp-source.html')
-rw-r--r-- | doc/api-documentation/html/filemgr_8cpp-source.html | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/doc/api-documentation/html/filemgr_8cpp-source.html b/doc/api-documentation/html/filemgr_8cpp-source.html new file mode 100644 index 0000000..b807e94 --- /dev/null +++ b/doc/api-documentation/html/filemgr_8cpp-source.html @@ -0,0 +1,278 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> +<title>filemgr.cpp Source File</title> +<link href="doxygen.css" rel="stylesheet" type="text/css"> +</head><body> +<!-- Generated by Doxygen 1.2.15 --> +<center> +<a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="hierarchy.html">Class Hierarchy</a> <a class="qindex" href="classes.html">Alphabetical List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> </center> +<hr><h1>filemgr.cpp</h1><div class="fragment"><pre>00001 <font class="comment">/******************************************************************************</font> +00002 <font class="comment"> * filemgr.cpp - implementation of class FileMgr used for pooling file</font> +00003 <font class="comment"> * handles</font> +00004 <font class="comment"> *</font> +00005 <font class="comment"> * $Id: filemgr_8cpp-source.html,v 1.3 2002/06/20 20:23:08 mgruner Exp $</font> +00006 <font class="comment"> *</font> +00007 <font class="comment"> * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)</font> +00008 <font class="comment"> * CrossWire Bible Society</font> +00009 <font class="comment"> * P. O. Box 2528</font> +00010 <font class="comment"> * Tempe, AZ 85280-2528</font> +00011 <font class="comment"> *</font> +00012 <font class="comment"> * This program is free software; you can redistribute it and/or modify it</font> +00013 <font class="comment"> * under the terms of the GNU General Public License as published by the</font> +00014 <font class="comment"> * Free Software Foundation version 2.</font> +00015 <font class="comment"> *</font> +00016 <font class="comment"> * This program is distributed in the hope that it will be useful, but</font> +00017 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font> +00018 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font> +00019 <font class="comment"> * General Public License for more details.</font> +00020 <font class="comment"> *</font> +00021 <font class="comment"> */</font> +00022 +00023 <font class="preprocessor">#include <filemgr.h></font> +00024 <font class="preprocessor">#include <utilstr.h></font> +00025 +00026 <font class="preprocessor">#include <dirent.h></font> +00027 <font class="preprocessor">#include <fcntl.h></font> +00028 <font class="preprocessor">#include <sys/stat.h></font> +00029 <font class="preprocessor">#include <sys/types.h></font> +00030 <font class="preprocessor">#include <stdio.h></font> +00031 <font class="preprocessor">#include <string.h></font> +00032 <font class="preprocessor">#ifndef __GNUC__</font> +00033 <font class="preprocessor"></font><font class="preprocessor">#include <io.h></font> +00034 <font class="preprocessor">#else</font> +00035 <font class="preprocessor"></font><font class="preprocessor">#include <unistd.h></font> +00036 <font class="preprocessor">#endif</font> +00037 <font class="preprocessor"></font> +00038 <font class="comment">// ---------------- statics -----------------</font> +00039 FileMgr FileMgr::systemFileMgr; +00040 +00041 <font class="comment">// --------------- end statics --------------</font> +00042 +00043 +00044 FileDesc::FileDesc(FileMgr *parent, <font class="keywordtype">char</font> *path, <font class="keywordtype">int</font> mode, <font class="keywordtype">int</font> perms, <font class="keywordtype">bool</font> tryDowngrade) { +00045 this->parent = parent; +00046 this->path = 0; +00047 stdstr(&this->path, path); +00048 this->mode = mode; +00049 this->perms = perms; +00050 this->tryDowngrade = tryDowngrade; +00051 offset = 0; +00052 fd = -77; +00053 } +00054 +00055 +00056 FileDesc::~FileDesc() { +00057 <font class="keywordflow">if</font> (fd > 0) +00058 close(fd); +00059 +00060 <font class="keywordflow">if</font> (path) +00061 <font class="keyword">delete</font> [] path; +00062 } +00063 +00064 +00065 <font class="keywordtype">int</font> FileDesc::getFd() { +00066 <font class="keywordflow">if</font> (fd == -77) +00067 fd = parent->sysOpen(<font class="keyword">this</font>); +00068 <font class="keywordflow">return</font> fd; +00069 } +00070 +00071 +00072 FileMgr::FileMgr(<font class="keywordtype">int</font> maxFiles) { +00073 this->maxFiles = maxFiles; <font class="comment">// must be at least 2</font> +00074 files = 0; +00075 } +00076 +00077 +00078 FileMgr::~FileMgr() { +00079 FileDesc *tmp; +00080 +00081 <font class="keywordflow">while</font>(files) { +00082 tmp = files->next; +00083 <font class="keyword">delete</font> files; +00084 files = tmp; +00085 } +00086 } +00087 +00088 +00089 FileDesc *FileMgr::open(<font class="keywordtype">char</font> *path, <font class="keywordtype">int</font> mode, <font class="keywordtype">bool</font> tryDowngrade) { +00090 <font class="keywordflow">return</font> open(path, mode, S_IREAD | S_IWRITE, tryDowngrade); +00091 } +00092 +00093 FileDesc *FileMgr::open(<font class="keywordtype">char</font> *path, <font class="keywordtype">int</font> mode, <font class="keywordtype">int</font> perms, <font class="keywordtype">bool</font> tryDowngrade) { +00094 FileDesc **tmp, *tmp2; +00095 +00096 <font class="keywordflow">for</font> (tmp = &files; *tmp; tmp = &((*tmp)->next)) { +00097 <font class="keywordflow">if</font> ((*tmp)->fd < 0) <font class="comment">// insert as first non-system_open file</font> +00098 <font class="keywordflow">break</font>; +00099 } +00100 +00101 tmp2 = <font class="keyword">new</font> FileDesc(<font class="keyword">this</font>, path, mode, perms, tryDowngrade); +00102 tmp2->next = *tmp; +00103 *tmp = tmp2; +00104 +00105 <font class="keywordflow">return</font> tmp2; +00106 } +00107 +00108 +00109 <font class="keywordtype">void</font> FileMgr::close(FileDesc *file) { +00110 FileDesc **loop; +00111 +00112 <font class="keywordflow">for</font> (loop = &files; *loop; loop = &((*loop)->next)) { +00113 <font class="keywordflow">if</font> (*loop == file) { +00114 *loop = (*loop)->next; +00115 <font class="keyword">delete</font> file; +00116 <font class="keywordflow">break</font>; +00117 } +00118 } +00119 } +00120 +00121 +00122 <font class="comment">// to truncate a file at its current position</font> +00123 <font class="comment">// leaving byte at current possition intact</font> +00124 <font class="comment">// deleting everything afterward.</font> +00125 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> FileMgr::trunc(FileDesc *file) { +00126 +00127 <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font> *writeTest = <font class="stringliteral">"x"</font>; +00128 <font class="keywordtype">long</font> size = lseek(file->getFd(), 1, SEEK_CUR); +00129 <font class="keywordtype">char</font> nibble [ 32767 ]; +00130 <font class="keywordtype">bool</font> writable = write(file->getFd(), writeTest, 1); +00131 <font class="keywordtype">int</font> bytes = 0; +00132 +00133 <font class="keywordflow">if</font> (writable) { +00134 <font class="comment">// get tmpfilename</font> +00135 <font class="keywordtype">char</font> *buf = <font class="keyword">new</font> <font class="keywordtype">char</font> [ strlen(file->path) + 10 ]; +00136 <font class="keywordtype">int</font> i; +00137 <font class="keywordflow">for</font> (i = 0; i < 9999; i++) { +00138 sprintf(buf, <font class="stringliteral">"%stmp%.4d"</font>, file->path, i); +00139 <font class="keywordflow">if</font> (!existsFile(buf)) +00140 <font class="keywordflow">break</font>; +00141 } +00142 <font class="keywordflow">if</font> (i == 9999) +00143 <font class="keywordflow">return</font> -2; +00144 +00145 <font class="keywordtype">int</font> fd = ::open(buf, O_CREAT|O_RDWR, S_IREAD|S_IWRITE); +00146 <font class="keywordflow">if</font> (fd < 0) +00147 <font class="keywordflow">return</font> -3; +00148 +00149 lseek(file->getFd(), 0, SEEK_SET); +00150 <font class="keywordflow">while</font> (size > 0) { +00151 bytes = read(file->getFd(), nibble, 32767); +00152 write(fd, nibble, (bytes < size)?bytes:size); +00153 size -= bytes; +00154 } +00155 <font class="comment">// zero out the file</font> +00156 ::close(file->fd); +00157 file->fd = ::open(file->path, O_TRUNC, S_IREAD|S_IWRITE); +00158 ::close(file->fd); +00159 file->fd = -77; <font class="comment">// force file open by filemgr</font> +00160 <font class="comment">// copy tmp file back (dumb, but must preserve file permissions)</font> +00161 lseek(fd, 0, SEEK_SET); +00162 <font class="keywordflow">do</font> { +00163 bytes = read(fd, nibble, 32767); +00164 write(file->getFd(), nibble, bytes); +00165 } <font class="keywordflow">while</font> (bytes == 32767); +00166 +00167 ::close(fd); +00168 ::close(file->fd); +00169 unlink(buf); <font class="comment">// remove our tmp file</font> +00170 file->fd = -77; <font class="comment">// causes file to be swapped out forcing open on next call to getFd()</font> +00171 } +00172 <font class="keywordflow">else</font> { <font class="comment">// put offset back and return failure</font> +00173 lseek(file->getFd(), -1, SEEK_CUR); +00174 <font class="keywordflow">return</font> -1; +00175 } +00176 <font class="keywordflow">return</font> 0; +00177 } +00178 +00179 +00180 <font class="keywordtype">int</font> FileMgr::sysOpen(FileDesc *file) { +00181 FileDesc **loop; +00182 <font class="keywordtype">int</font> openCount = 1; <font class="comment">// because we are presently opening 1 file, and we need to be sure to close files to accomodate, if necessary</font> +00183 +00184 <font class="keywordflow">for</font> (loop = &files; *loop; loop = &((*loop)->next)) { +00185 +00186 <font class="keywordflow">if</font> ((*loop)->fd > 0) { +00187 <font class="keywordflow">if</font> (++openCount > maxFiles) { +00188 (*loop)->offset = lseek((*loop)->fd, 0, SEEK_CUR); +00189 ::close((*loop)->fd); +00190 (*loop)->fd = -77; +00191 } +00192 } +00193 +00194 <font class="keywordflow">if</font> (*loop == file) { +00195 <font class="keywordflow">if</font> (*loop != files) { +00196 *loop = (*loop)->next; +00197 file->next = files; +00198 files = file; +00199 } +00200 <font class="keywordflow">if</font> ((!access(file->path, 04)) || ((file->mode & O_CREAT) == O_CREAT)) { <font class="comment">// check for at least file exists / read access before we try to open</font> +00201 <font class="keywordtype">char</font> tries = (((file->mode & O_RDWR) == O_RDWR) && (file->tryDowngrade)) ? 2 : 1; <font class="comment">// try read/write if possible</font> +00202 <font class="keywordflow">for</font> (<font class="keywordtype">int</font> i = 0; i < tries; i++) { +00203 <font class="keywordflow">if</font> (i > 0) { +00204 file->mode = (file->mode & ~O_RDWR); <font class="comment">// remove write access</font> +00205 file->mode = (file->mode | O_RDONLY);<font class="comment">// add read access</font> +00206 } +00207 file->fd = ::open(file->path, file->mode, file->perms); +00208 +00209 <font class="keywordflow">if</font> (file->fd >= 0) +00210 <font class="keywordflow">break</font>; +00211 } +00212 +00213 <font class="keywordflow">if</font> (file->fd >= 0) +00214 lseek(file->fd, file->offset, SEEK_SET); +00215 } +00216 <font class="keywordflow">else</font> file->fd = -1; +00217 <font class="keywordflow">if</font> (!*loop) +00218 <font class="keywordflow">break</font>; +00219 } +00220 } +00221 <font class="keywordflow">return</font> file->fd; +00222 } +00223 +00224 +00225 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> FileMgr::existsFile(<font class="keyword">const</font> <font class="keywordtype">char</font> *ipath, <font class="keyword">const</font> <font class="keywordtype">char</font> *ifileName) +00226 { +00227 <font class="keywordtype">int</font> len = strlen(ipath) + ((ifileName)?strlen(ifileName):0) + 3; +00228 <font class="keywordtype">char</font> *ch; +00229 <font class="keywordtype">char</font> *path = <font class="keyword">new</font> <font class="keywordtype">char</font> [ len ]; +00230 strcpy(path, ipath); +00231 +00232 <font class="keywordflow">if</font> ((path[strlen(path)-1] == <font class="charliteral">'\\'</font>) || (path[strlen(path)-1] == <font class="charliteral">'/'</font>)) +00233 path[strlen(path)-1] = 0; +00234 +00235 <font class="keywordflow">if</font> (ifileName) { +00236 ch = path + strlen(path); +00237 sprintf(ch, <font class="stringliteral">"/%s"</font>, ifileName); +00238 } +00239 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> retVal = !access(path, 04); +00240 <font class="keyword">delete</font> [] path; +00241 <font class="keywordflow">return</font> retVal; +00242 } +00243 +00244 +00245 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> FileMgr::existsDir(<font class="keyword">const</font> <font class="keywordtype">char</font> *ipath, <font class="keyword">const</font> <font class="keywordtype">char</font> *idirName) +00246 { +00247 <font class="keywordtype">char</font> *ch; +00248 <font class="keywordtype">int</font> len = strlen(ipath) + ((idirName)?strlen(idirName):0) + 1; +00249 <font class="keywordflow">if</font> (idirName) +00250 len += strlen(idirName); +00251 <font class="keywordtype">char</font> *path = <font class="keyword">new</font> <font class="keywordtype">char</font> [ len ]; +00252 strcpy(path, ipath); +00253 +00254 <font class="keywordflow">if</font> ((path[strlen(path)-1] == <font class="charliteral">'\\'</font>) || (path[strlen(path)-1] == <font class="charliteral">'/'</font>)) +00255 path[strlen(path)-1] = 0; +00256 +00257 <font class="keywordflow">if</font> (idirName) { +00258 ch = path + strlen(path); +00259 sprintf(ch, <font class="stringliteral">"/%s"</font>, idirName); +00260 } +00261 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> retVal = !access(path, 04); +00262 <font class="keyword">delete</font> [] path; +00263 <font class="keywordflow">return</font> retVal; +00264 } +</pre></div><hr><address align="right"><small>Generated on Thu Jun 20 22:12:59 2002 for The Sword Project by +<a href="http://www.doxygen.org/index.html"> +<img src="doxygen.png" alt="doxygen" align="middle" border=0 +width=110 height=53></a>1.2.15 </small></address> +</body> +</html> |