00001
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
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>
00045 #include <cstdio>
00046 #include <cstdlib>
00047 #include <cstring>
00048 #include <dirent.h>
00049 #include <sys/stat.h>
00050 #include <unistd.h>
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