Drizzled Public API Documentation

CSSys_unix.cc
00001 /* Copyright (C) 2010 PrimeBase Technologies GmbH, Germany
00002  *
00003  * PrimeBase Media Stream for MySQL
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00018  *
00019  * Author: Barry Leslie
00020  *
00021  * 2010-02-05
00022  *
00023  * CORE SYSTEM:
00024  * Basic UNIX specific file I/O classes.
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 // CSSysFile
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 // CSSys
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   // Set the access privileges.
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     /* This is the Linux version: */
00221     mod_time->setUTC1970(sb.st_mtim.tv_sec, sb.st_mtim.tv_nsec);
00222 #else
00223     /* This is the Mac OS X version: */
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 // CSSysDir
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     /* Filter out '.' and '..': */
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