Back to index

nordugrid-arc-nox  1.1.0~rc6
FileUtils.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include "config.h"
00003 #endif
00004 
00005 #ifndef WIN32
00006 // These utilities are POSIX specific.
00007 // They may work in MinGW but that needs testing.
00008 // So currently they are disabled in windows environment.
00009 
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <sys/types.h>
00013 #include <sys/stat.h>
00014 #include <fcntl.h>
00015 #include <unistd.h>
00016 #include <poll.h>
00017 #include <errno.h>
00018 #include <glibmm.h>
00019 
00020 #include "FileUtils.h"
00021 #include "User.h"
00022 
00023 namespace Arc {
00024 
00025 Glib::Mutex suid_lock;
00026 
00027 int FileOpen(const char* path,int flags,mode_t mode) {
00028   return FileOpen(path,flags,0,0,mode);
00029 }
00030 
00031 int FileOpen(const char* path,int flags,uid_t uid,gid_t gid,mode_t mode) {
00032   int h = -1;
00033   {
00034     UserSwitch usw(uid,gid);
00035     if(!usw) return -1;
00036     h = open(path,flags | O_NONBLOCK,mode);
00037   };
00038   if(h == -1) return -1;
00039   if(flags & O_NONBLOCK) return h;
00040   while(1) {
00041     pollfd ph;
00042     ph.fd=h; ph.events=POLLOUT; ph.revents=0;
00043     if(poll(&ph,1,-1) <= 0) {
00044       if(errno != EINTR) {
00045         close(h);
00046         return -1;
00047       };
00048     };
00049     if(ph.revents & POLLOUT) break;
00050   };
00051   int fl = fcntl(h,F_GETFL);
00052   if(fl == -1) {
00053     close(h);
00054     return -1;
00055   };
00056   fl &= ~O_NONBLOCK;
00057   if(fcntl(h,F_SETFL,fl) == -1) {
00058     close(h);
00059     return -1;
00060   };
00061   return h;
00062 }
00063 
00064 Glib::Dir* DirOpen(const char* path) {
00065   return DirOpen(path,0,0);
00066 }
00067 
00068 // TODO: find non-blocking way to open directory
00069 Glib::Dir* DirOpen(const char* path,uid_t uid,gid_t gid) {
00070   Glib::Dir* dir = NULL;
00071   {
00072     UserSwitch usw(uid,gid);
00073     if(!usw) return NULL;
00074     try {
00075       dir = new Glib::Dir(path);
00076     } catch(Glib::FileError& e) {
00077       // err=e.what();
00078     };
00079   };
00080   return dir;
00081 }
00082 
00083 bool FileStat(const char* path,struct stat *st,bool follow_symlinks) {
00084   return FileStat(path,st,0,0,follow_symlinks);
00085 }
00086 
00087 // TODO: maybe by using open + fstat it would be possible to 
00088 // make this functin less blocking
00089 bool FileStat(const char* path,struct stat *st,uid_t uid,gid_t gid,bool follow_symlinks) {
00090   int r = -1;
00091   {
00092     UserSwitch usw(uid,gid);
00093     if(!usw) return false;
00094     if(follow_symlinks) {
00095       r = stat(path,st);
00096     } else {
00097       r = lstat(path,st);
00098     };
00099   };
00100   return (r == 0);
00101 }
00102 
00103 bool DirCreate(const char* path,mode_t mode) {
00104   return DirCreate(path,0,0,mode);
00105 }
00106 
00107 // TODO: find non-blocking way to create directory
00108 bool DirCreate(const char* path,uid_t uid,gid_t gid,mode_t mode) {
00109   int r = -1;
00110   {
00111     UserSwitch usw(uid,gid);
00112     if(!usw) return false;
00113     r = mkdir(path,mode);
00114   };
00115   return (r == 0);
00116 }
00117 
00118 
00119 } // namespace Arc
00120 
00121 #endif
00122