00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "CSConfig.h"
00029 #include <sys/stat.h>
00030 #include <fcntl.h>
00031 #include <errno.h>
00032 #include <string.h>
00033 #include <sys/file.h>
00034 #include <unistd.h>
00035 #include <signal.h>
00036
00037 #include "CSGlobal.h"
00038 #include "CSDefs.h"
00039 #include "CSStrUtil.h"
00040 #include "CSSys.h"
00041
00042 #define CS_MASK ((S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP) | (S_IROTH))
00043
00044
00045
00046 bool CSSysFile::isDirNotFound(CSException *e) { return e->getErrorCode() == ENOENT; }
00047 bool CSSysFile::isFileNotFound(CSException *e) { return e->getErrorCode() == ENOENT; }
00048 bool CSSysFile::isDirExists(CSException *e) { return e->getErrorCode() == EEXIST; }
00049
00050
00051 void CSSysFile::sf_open(const char *path, bool readonly, bool create)
00052 {
00053 int flags;
00054
00055 flags = (readonly)?O_RDONLY:O_RDWR;
00056
00057 if (create)
00058 flags |= O_CREAT;
00059
00060 if (sf_fh != -1)
00061 sf_close();
00062
00063 sf_path = CSString::newString(path);
00064
00065 sf_fh = open(path, flags, CS_MASK);
00066 if (sf_fh == -1) {
00067 sf_path->release();
00068 sf_path = NULL;
00069 CSException::throwFileError(CS_CONTEXT, path, errno);
00070 }
00071 }
00072
00073
00074 void CSSysFile::sf_close()
00075 {
00076 if (sf_fh != -1) {
00077 close(sf_fh);
00078 sf_fh = -1;
00079 sf_path->release();
00080 sf_path = NULL;
00081 }
00082 }
00083
00084
00085 size_t CSSysFile::sf_pread(void *data, size_t size, off64_t offset)
00086 {
00087 ssize_t read_size;
00088
00089 read_size = pread(sf_fh, data, size, offset);
00090 if (read_size == -1)
00091 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
00092
00093 return read_size;
00094 }
00095
00096
00097 void CSSysFile::sf_pwrite(const void *data, size_t size, off64_t offset)
00098 {
00099 size_t write_size;
00100
00101 write_size = pwrite(sf_fh, data, size, offset);
00102 if (write_size != size)
00103 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
00104
00105 }
00106
00107
00108 void CSSysFile::sf_setEOF(off64_t offset)
00109 {
00110 if (ftruncate(sf_fh, offset) == -1)
00111 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
00112 }
00113
00114
00115 off64_t CSSysFile::sf_getEOF()
00116 {
00117 off64_t eof;
00118
00119 if ((eof = lseek(sf_fh, 0, SEEK_END)) == ((off64_t)-1))
00120 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
00121
00122 return eof;
00123 }
00124
00125
00126 void CSSysFile::sf_sync()
00127 {
00128 fsync(sf_fh);
00129 }
00130
00131
00132 void CSSysFile::sf_lock(bool shared)
00133 {
00134 if (flock(sf_fh, (shared)?LOCK_SH:LOCK_EX) == -1)
00135 CSException::throwOSError(CS_CONTEXT, errno);
00136 }
00137
00138
00139 void CSSysFile::sf_unlock()
00140 {
00141 if (flock(sf_fh, LOCK_UN) == -1)
00142 CSException::throwOSError(CS_CONTEXT, errno);
00143 }
00144
00145
00146
00147
00148
00149 bool CSSys::sys_exists(const char *path)
00150 {
00151 return (access(path, F_OK) != -1);
00152 }
00153
00154
00155 void CSSys::sys_makeDir(const char *path)
00156 {
00157 char super_path[PATH_MAX];
00158 struct stat stats;
00159 char *ptr;
00160
00161 if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) == -1)
00162 CSException::throwFileError(CS_CONTEXT, path, errno);
00163
00164
00165 ptr = cs_last_name_of_path(path);
00166 if (ptr == path)
00167 strcpy(super_path, ".");
00168 else {
00169 cs_strcpy(PATH_MAX, super_path, path);
00170
00171 if ((ptr = cs_last_name_of_path(super_path)))
00172 *ptr = 0;
00173 }
00174
00175 if (stat(super_path, &stats) == -1)
00176 CSException::throwFileError(CS_CONTEXT, path, errno);
00177
00178 if (chmod(path, stats.st_mode) == -1)
00179 CSException::throwFileError(CS_CONTEXT, path, errno);
00180
00181 }
00182
00183
00184 void CSSys::sys_removeDir(const char *path)
00185 {
00186 if (rmdir(path) == -1) {
00187 int err = errno;
00188
00189 if (err != ENOENT)
00190 CSException::throwFileError(CS_CONTEXT, path, err);
00191 }
00192 }
00193
00194
00195 void CSSys::sys_removeFile(const char *path)
00196 {
00197 if (unlink(path) == -1) {
00198 int err = errno;
00199
00200 if (err != ENOENT)
00201 CSException::throwFileError(CS_CONTEXT, path, err);
00202 }
00203 }
00204
00205
00206
00207
00208 void CSSys::sys_stat(const char *path, bool *is_dir, off64_t *size, CSTime *mod_time)
00209 {
00210 struct stat sb;
00211
00212 if (stat(path, &sb) == -1)
00213 CSException::throwFileError(CS_CONTEXT, path, errno);
00214 if (is_dir)
00215 *is_dir = sb.st_mode & S_IFDIR;
00216 if (size)
00217 *size = sb.st_size;
00218 if (mod_time)
00219 #ifdef __USE_MISC
00220
00221 mod_time->setUTC1970(sb.st_mtim.tv_sec, sb.st_mtim.tv_nsec);
00222 #else
00223
00224 mod_time->setUTC1970(sb.st_mtimespec.tv_sec, sb.st_mtimespec.tv_nsec);
00225 #endif
00226 }
00227
00228
00229 bool CSSys::sys_isLink(const char *path)
00230 {
00231 struct stat sb;
00232
00233 if (lstat(path, &sb) == -1)
00234 CSException::throwFileError(CS_CONTEXT, path, errno);
00235
00236 return S_ISLNK(sb.st_mode);
00237 }
00238
00239
00240 void CSSys::sys_rename(const char *old_path, const char *new_path)
00241 {
00242 if (rename(old_path, new_path) == -1)
00243 CSException::throwFileError(CS_CONTEXT, old_path, errno);
00244 }
00245
00246
00247 void CSSys::sys_getcwd(char *path, size_t size)
00248 {
00249 if (getcwd(path, size) == NULL)
00250 CSException::throwOSError(CS_CONTEXT, errno);
00251 }
00252
00253
00254 void CSSys::sys_setcwd(const char *path)
00255 {
00256 if (chdir(path) == -1)
00257 CSException::throwFileError(CS_CONTEXT, path, errno);
00258 }
00259
00260
00261 uint32_t CSSys::sys_getpid()
00262 {
00263 return getpid();
00264 }
00265
00266
00267 bool CSSys::sys_isAlive(uint32_t pid)
00268 {
00269 return (kill(pid, 0) == 0);
00270 }
00271
00272
00273
00274
00275 CSSysDir::~CSSysDir()
00276 {
00277 close();
00278 if (sd_path)
00279 sd_path->release();
00280
00281 if (sd_filter)
00282 sd_filter->release();
00283 }
00284
00285
00286 void CSSysDir::open()
00287 {
00288 enter_();
00289 if (!(sd_dir = opendir(sd_path->getCString())))
00290 CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), errno);
00291 exit_();
00292 }
00293
00294
00295 void CSSysDir::close()
00296 {
00297 enter_();
00298 if (sd_dir) {
00299 closedir(sd_dir);
00300 sd_dir = NULL;
00301 }
00302 exit_();
00303 }
00304
00305
00306 bool CSSysDir::next()
00307 {
00308 int err;
00309 struct dirent *result;
00310
00311 enter_();
00312 for (;;) {
00313 err = readdir_r(sd_dir, &sd_entry, &result);
00314 self->interrupted();
00315 if (err)
00316 CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), err);
00317 if (!result)
00318 break;
00319
00320 if (sd_entry.d_name[0] == '.') {
00321 if (sd_entry.d_name[1] == '.') {
00322 if (sd_entry.d_name[2] == '\0')
00323 continue;
00324 }
00325 else {
00326 if (sd_entry.d_name[1] == '\0')
00327 continue;
00328 }
00329 }
00330 break;
00331 }
00332 return_(result ? true : false);
00333 }
00334
00335
00336
00337 void CSSysDir::getEntryPath(char *path, size_t size)
00338 {
00339 cs_strcpy(size, path, sd_path->getCString());
00340 cs_add_dir_char(size, path);
00341 cs_strcat(size, path, sd_entry.d_name);
00342 }
00343
00344
00345 const char *CSSysDir::entryName()
00346 {
00347 return sd_entry.d_name;
00348 }
00349
00350
00351 bool CSSysDir::entryIsFile()
00352 {
00353 if (sd_entry.d_type & DT_DIR)
00354 return false;
00355 return true;
00356 }
00357
00358
00359 extern void unix_close(int h);
00360 void unix_close(int h) {close(h);}
00361