unixcall.cc
Go to the documentation of this file.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 
00029 
00030 
00031 
00032 
00033 
00034 #ifndef GROOVX_RUTZ_UNIXCALL_CC_UTC20050626084019_DEFINED
00035 #define GROOVX_RUTZ_UNIXCALL_CC_UTC20050626084019_DEFINED
00036 
00037 #include <cctype>
00038 #include "unixcall.h"
00039 
00040 #include "rutz/arrays.h"
00041 #include "rutz/error.h"
00042 #include "rutz/fstring.h"
00043 #include "rutz/sfmt.h"
00044 
00045 #include <cerrno> 
00046 #include <cstdio> 
00047 #include <cstdlib> 
00048 #include <cstring> 
00049 #include <dirent.h> 
00050 #include <sys/stat.h> 
00051 #include <unistd.h> 
00052 
00053 #include "rutz/trace.h"
00054 #include "rutz/debug.h"
00055 GVX_DBG_REGISTER
00056 
00057 namespace
00058 {
00059   void throwErrno(const char* where, const rutz::file_pos& pos)
00060   {
00061     throw rutz::error(rutz::sfmt("in \"%s\": %s", where,
00062                                  ::strerror(errno)), pos);
00063   }
00064 
00065   class ErrnoSaver
00066   {
00067   public:
00068     ErrnoSaver() : saved(errno)
00069     {
00070       errno = 0;
00071     }
00072 
00073     ~ErrnoSaver()
00074     {
00075       errno = saved;
00076     }
00077 
00078     const int saved;
00079   };
00080 }
00081 
00082 void rutz::unixcall::chmod(const char* path, mode_t mode)
00083 {
00084 GVX_TRACE("rutz::unixcall::chmod");
00085 
00086   ErrnoSaver saver;
00087 
00088   if ( ::chmod(path, mode) != 0 )
00089     throwErrno("chmod", SRC_POS);
00090 }
00091 
00092 void rutz::unixcall::rename(const char* oldpath, const char* newpath)
00093 {
00094 GVX_TRACE("rutz::unixcall::rename");
00095 
00096   ErrnoSaver saver;
00097 
00098   if ( ::rename(oldpath, newpath) != 0 )
00099     throwErrno("rename", SRC_POS);
00100 }
00101 
00102 void rutz::unixcall::remove(const char* pathname)
00103 {
00104 GVX_TRACE("rutz::unixcall::remove");
00105 
00106   errno = 0;
00107 
00108   if ( ::remove(pathname) != 0 )
00109     throwErrno("rutz::unixcall::remove", SRC_POS);
00110 }
00111 
00112 rutz::fstring rutz::unixcall::getcwd()
00113 {
00114 GVX_TRACE("rutz::unixcall::getcwd");
00115 
00116   ErrnoSaver saver;
00117 
00118   const int INIT_SIZE = 256;
00119   rutz::dynamic_block<char> buf(INIT_SIZE);
00120 
00121   while ( ::getcwd(&buf[0], buf.size()) == 0 )
00122     {
00123       if (errno == ERANGE)
00124         {
00125           errno = 0;
00126           buf.resize(buf.size() * 2);
00127         }
00128       else
00129         {
00130           throwErrno("getcwd", SRC_POS);
00131         }
00132     }
00133 
00134   return rutz::fstring(&buf[0]);
00135 }
00136 
00137 pid_t rutz::unixcall::get_file_user_pid(const char* fname)
00138 {
00139 GVX_TRACE("rutz::unixcall::get_file_user_pid");
00140   DIR* const proc_dir = opendir("/proc");
00141 
00142   if (proc_dir == 0)
00143     return 0;
00144 
00145   struct stat target_statbuf;
00146   if (stat(fname, &target_statbuf) != 0)
00147     return 0;
00148 
00149   const pid_t my_pid = getpid();
00150 
00151   struct dirent* proc_dent = 0;
00152 
00153   while ((proc_dent = readdir(proc_dir)) != 0)
00154     {
00155       if (proc_dent == 0)
00156         break;
00157 
00158       if (!isdigit(proc_dent->d_name[0]))
00159         continue;
00160 
00161       const pid_t pid = atoi(proc_dent->d_name);
00162 
00163       if (pid == my_pid)
00164         continue;
00165 
00166       const rutz::fstring fd_dirname =
00167         rutz::sfmt("/proc/%s/fd", proc_dent->d_name);
00168 
00169       DIR* const fd_dir = opendir(fd_dirname.c_str());
00170 
00171       if (fd_dir == 0)
00172         continue;
00173 
00174       struct dirent* fd_dent = 0;
00175 
00176       while ((fd_dent = readdir(fd_dir)) != 0)
00177         {
00178           if (!isdigit(fd_dent->d_name[0]))
00179             continue;
00180 
00181           const rutz::fstring fd_fname =
00182             rutz::sfmt("%s/%s", fd_dirname.c_str(), fd_dent->d_name);
00183 
00184           struct stat fd_statbuf;
00185           if (stat(fd_fname.c_str(), &fd_statbuf) != 0)
00186             continue;
00187 
00188           if (fd_statbuf.st_dev == target_statbuf.st_dev &&
00189               fd_statbuf.st_ino == target_statbuf.st_ino)
00190             return pid;
00191         }
00192 
00193       closedir(fd_dir);
00194     }
00195 
00196   closedir(proc_dir);
00197 
00198   return 0;
00199 }
00200 
00201 static const char __attribute__((used)) vcid_groovx_rutz_unixcall_cc_utc20050626084019[] = "$Id: unixcall.cc 14376 2011-01-11 02:44:34Z pez $ $HeadURL: svn:
00202 #endif // !GROOVX_RUTZ_UNIXCALL_CC_UTC20050626084019_DEFINED