unixcall.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Wed Nov 17 15:05:41 1999
00010 // commit: $Id: unixcall.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/rutz/unixcall.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_RUTZ_UNIXCALL_CC_UTC20050626084019_DEFINED
00035 #define GROOVX_RUTZ_UNIXCALL_CC_UTC20050626084019_DEFINED
00036 
00037 #include "unixcall.h"
00038 
00039 #include "rutz/arrays.h"
00040 #include "rutz/error.h"
00041 #include "rutz/fstring.h"
00042 #include "rutz/sfmt.h"
00043 
00044 #include <cerrno> // for ::errno
00045 #include <cstdio> // for ::rename(), ::remove()
00046 #include <cstdlib> // for ::atoi()
00047 #include <cstring> // for ::strerror()
00048 #include <dirent.h> // for ::opendir(), ::readdir()
00049 #include <sys/stat.h> // for ::chmod(), ::stat()
00050 #include <unistd.h> // for ::getcwd() (POSIX)
00051 
00052 #include "rutz/trace.h"
00053 #include "rutz/debug.h"
00054 GVX_DBG_REGISTER
00055 
00056 namespace
00057 {
00058   void throwErrno(const char* where, const rutz::file_pos& pos)
00059   {
00060     throw rutz::error(rutz::sfmt("in \"%s\": %s", where,
00061                                  ::strerror(errno)), pos);
00062   }
00063 
00064   class ErrnoSaver
00065   {
00066   public:
00067     ErrnoSaver() : saved(errno)
00068     {
00069       errno = 0;
00070     }
00071 
00072     ~ErrnoSaver()
00073     {
00074       errno = saved;
00075     }
00076 
00077     const int saved;
00078   };
00079 }
00080 
00081 void rutz::unixcall::chmod(const char* path, mode_t mode)
00082 {
00083 GVX_TRACE("rutz::unixcall::chmod");
00084 
00085   ErrnoSaver saver;
00086 
00087   if ( ::chmod(path, mode) != 0 )
00088     throwErrno("chmod", SRC_POS);
00089 }
00090 
00091 void rutz::unixcall::rename(const char* oldpath, const char* newpath)
00092 {
00093 GVX_TRACE("rutz::unixcall::rename");
00094 
00095   ErrnoSaver saver;
00096 
00097   if ( ::rename(oldpath, newpath) != 0 )
00098     throwErrno("rename", SRC_POS);
00099 }
00100 
00101 void rutz::unixcall::remove(const char* pathname)
00102 {
00103 GVX_TRACE("rutz::unixcall::remove");
00104 
00105   errno = 0;
00106 
00107   if ( ::remove(pathname) != 0 )
00108     throwErrno("rutz::unixcall::remove", SRC_POS);
00109 }
00110 
00111 rutz::fstring rutz::unixcall::getcwd()
00112 {
00113 GVX_TRACE("rutz::unixcall::getcwd");
00114 
00115   ErrnoSaver saver;
00116 
00117   const int INIT_SIZE = 256;
00118   rutz::dynamic_block<char> buf(INIT_SIZE);
00119 
00120   while ( ::getcwd(&buf[0], buf.size()) == 0 )
00121     {
00122       if (errno == ERANGE)
00123         {
00124           errno = 0;
00125           buf.resize(buf.size() * 2);
00126         }
00127       else
00128         {
00129           throwErrno("getcwd", SRC_POS);
00130         }
00131     }
00132 
00133   return rutz::fstring(&buf[0]);
00134 }
00135 
00136 pid_t rutz::unixcall::get_file_user_pid(const char* fname)
00137 {
00138 GVX_TRACE("rutz::unixcall::get_file_user_pid");
00139   DIR* const proc_dir = opendir("/proc");
00140 
00141   if (proc_dir == 0)
00142     return 0;
00143 
00144   struct stat target_statbuf;
00145   if (stat(fname, &target_statbuf) != 0)
00146     return 0;
00147 
00148   const pid_t my_pid = getpid();
00149 
00150   struct dirent* proc_dent = 0;
00151 
00152   while ((proc_dent = readdir(proc_dir)) != 0)
00153     {
00154       if (proc_dent == 0)
00155         break;
00156 
00157       if (!isdigit(proc_dent->d_name[0]))
00158         continue;
00159 
00160       const pid_t pid = atoi(proc_dent->d_name);
00161 
00162       if (pid == my_pid)
00163         continue;
00164 
00165       const rutz::fstring fd_dirname =
00166         rutz::sfmt("/proc/%s/fd", proc_dent->d_name);
00167 
00168       DIR* const fd_dir = opendir(fd_dirname.c_str());
00169 
00170       if (fd_dir == 0)
00171         continue;
00172 
00173       struct dirent* fd_dent = 0;
00174 
00175       while ((fd_dent = readdir(fd_dir)) != 0)
00176         {
00177           if (!isdigit(fd_dent->d_name[0]))
00178             continue;
00179 
00180           const rutz::fstring fd_fname =
00181             rutz::sfmt("%s/%s", fd_dirname.c_str(), fd_dent->d_name);
00182 
00183           struct stat fd_statbuf;
00184           if (stat(fd_fname.c_str(), &fd_statbuf) != 0)
00185             continue;
00186 
00187           if (fd_statbuf.st_dev == target_statbuf.st_dev &&
00188               fd_statbuf.st_ino == target_statbuf.st_ino)
00189             return pid;
00190         }
00191 
00192       closedir(fd_dir);
00193     }
00194 
00195   closedir(proc_dir);
00196 
00197   return 0;
00198 }
00199 
00200 static const char __attribute__((used)) vcid_groovx_rutz_unixcall_cc_utc20050626084019[] = "$Id: unixcall.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00201 #endif // !GROOVX_RUTZ_UNIXCALL_CC_UTC20050626084019_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:41 2008 by Doxygen version 1.5.5.