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