TChirpFile.cxx

Go to the documentation of this file.
00001 // @(#)root/chirp:$Id: TChirpFile.cxx 35358 2010-09-17 09:58:04Z rdm $
00002 // Author: Dan Bradley   17/12/2002
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TChirpFile                                                           //
00015 //                                                                      //
00016 // A TChirpFile is like a normal TFile except that it may read and      //
00017 // write its data via a Chirp server (for more on the Chirp protocol    //
00018 // see http://www.cs.wisc.edu/condor/chirp).                            //
00019 //                                                                      //
00020 //////////////////////////////////////////////////////////////////////////
00021 
00022 #include "TChirpFile.h"
00023 #include "TError.h"
00024 #include "TSystem.h"
00025 #include "TROOT.h"
00026 
00027 #include <errno.h>
00028 #include <sys/stat.h>
00029 #include <unistd.h>
00030 
00031 #include "chirp_client.h"
00032 
00033 
00034 static const char* const CHIRP_PREFIX = "chirp:";
00035 static const size_t CHIRP_PREFIX_LEN = 6;
00036 
00037 
00038 ClassImp(TChirpFile)
00039 
00040 //______________________________________________________________________________
00041 TChirpFile::TChirpFile(const char *path, Option_t *option,
00042                        const char *ftitle, Int_t compress):
00043    TFile(path, "NET", ftitle, compress)
00044 {
00045    //Passing option "NET" to prevent base-class from doing any local access.
00046 
00047    chirp_client = 0;
00048 
00049    fOption = option;
00050    fOption.ToUpper();
00051 
00052    if (fOption == "NEW")
00053       fOption = "CREATE";
00054 
00055    Bool_t create   = (fOption == "CREATE") ? kTRUE : kFALSE;
00056    Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
00057    Bool_t update   = (fOption == "UPDATE") ? kTRUE : kFALSE;
00058    Bool_t read     = (fOption == "READ") ? kTRUE : kFALSE;
00059    if (!create && !recreate && !update && !read) {
00060       read    = kTRUE;
00061       fOption = "READ";
00062    }
00063 
00064    char const *path_part;
00065    const char *fname;
00066 
00067    if (OpenChirpClient(path, &path_part)) {
00068       SysError("TChirpFile", "chirp client for %s can not be opened", path);
00069       goto zombie;
00070    }
00071 
00072    fname = path_part;
00073 
00074    fRealName = fname;
00075 
00076    if (create || update || recreate) {
00077       Int_t mode = O_RDWR | O_CREAT;
00078       if (recreate) mode |= O_TRUNC;
00079 
00080 #ifndef WIN32
00081       fD = SysOpen(fname, mode, 0644);
00082 #else
00083       fD = SysOpen(fname, mode | O_BINARY, S_IREAD | S_IWRITE);
00084 #endif
00085       if (fD == -1) {
00086          SysError("TChirpFile", "file %s can not be opened", fname);
00087          goto zombie;
00088       }
00089       fWritable = kTRUE;
00090    } else {
00091 #ifndef WIN32
00092       fD = SysOpen(fname, O_RDONLY, 0644);
00093 #else
00094       fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
00095 #endif
00096       if (fD == -1) {
00097          SysError("TFile", "file %s can not be opened for reading", fname);
00098          goto zombie;
00099       }
00100       fWritable = kFALSE;
00101    }
00102 
00103    Init(create || recreate);
00104 
00105    return;
00106 
00107 zombie:
00108    // error in file opening occured, make this object a zombie
00109    MakeZombie();
00110    gDirectory = gROOT;
00111 }
00112 
00113 //______________________________________________________________________________
00114 TChirpFile::~TChirpFile()
00115 {
00116    // Close and cleanup Chirp file.
00117 
00118    Close();
00119    CloseChirpClient();
00120 }
00121 
00122 //______________________________________________________________________________
00123 Bool_t TChirpFile::ReadBuffer(char *buf, Int_t len)
00124 {
00125    // Read specified byte range from remote file via Chirp daemon.
00126    // Returns kTRUE in case of error.
00127 
00128    Int_t st;
00129    if ((st = ReadBufferViaCache(buf, len))) {
00130       if (st == 2)
00131          return kTRUE;
00132       return kFALSE;
00133    }
00134 
00135    return TFile::ReadBuffer(buf, len);
00136 }
00137 
00138 //______________________________________________________________________________
00139 Bool_t TChirpFile::ReadBuffer(char *buf, Long64_t pos, Int_t len)
00140 {
00141    // Read specified byte range from remote file via Chirp daemon.
00142    // Returns kTRUE in case of error.
00143 
00144    SetOffset(pos);
00145    Int_t st;
00146    if ((st = ReadBufferViaCache(buf, len))) {
00147       if (st == 2)
00148          return kTRUE;
00149       return kFALSE;
00150    }
00151 
00152    return TFile::ReadBuffer(buf, pos, len);
00153 }
00154 
00155 //______________________________________________________________________________
00156 Bool_t TChirpFile::WriteBuffer(const char *buf, Int_t len)
00157 {
00158    // Write specified byte range to remote file via Chirp daemon.
00159    // Returns kTRUE in case of error.
00160 
00161    if (!IsOpen() || !fWritable) return kTRUE;
00162 
00163    Int_t st;
00164    if ((st = WriteBufferViaCache(buf, len))) {
00165       if (st == 2)
00166          return kTRUE;
00167       return kFALSE;
00168    }
00169 
00170    return TFile::WriteBuffer(buf, len);
00171 }
00172 
00173 //______________________________________________________________________________
00174 Int_t TChirpFile::OpenChirpClient(char const *URL, char const **path_part)
00175 {
00176    // Caller should delete [] path when finished.
00177    // URL format: chirp:machine.name:port/path
00178    // or:         chirp:path      (use default connection to Condor job manager)
00179 
00180    *path_part = 0;
00181 
00182    CloseChirpClient();
00183 
00184    chirp_client = chirp_client_connect_url(URL, path_part);
00185 
00186    if (!chirp_client) {
00187       gSystem->SetErrorStr(strerror(errno));
00188       return -1;
00189    }
00190    return 0;
00191 }
00192 
00193 //______________________________________________________________________________
00194 Int_t TChirpFile::CloseChirpClient()
00195 {
00196    if (chirp_client) {
00197       struct chirp_client *c = chirp_client;
00198       chirp_client = 0;
00199 
00200       chirp_client_disconnect(c);
00201    }
00202 
00203    return 0;
00204 }
00205 
00206 //______________________________________________________________________________
00207 Int_t TChirpFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
00208 {
00209    char open_flags[8];
00210    char *f = open_flags;
00211 
00212    if ((flags & O_WRONLY) || (flags & O_RDWR)) *(f++) = 'w';
00213    if ((flags & O_RDONLY) || (flags & O_RDWR) || !flags) *(f++) = 'r';
00214    if (flags & O_APPEND) *(f++) = 'a';
00215    if (flags & O_CREAT)  *(f++) = 'c';
00216    if (flags & O_TRUNC)  *(f++) = 't';
00217    if (flags & O_EXCL)   *(f++) = 'x';
00218 
00219    *f = '\0';
00220 
00221    Int_t rc = chirp_client_open(chirp_client, pathname, open_flags, (Int_t) mode);
00222 
00223    if (rc < 0) {
00224       gSystem->SetErrorStr(strerror(errno));
00225    }
00226 
00227    return rc;
00228 }
00229 
00230 //______________________________________________________________________________
00231 Int_t TChirpFile::SysClose(Int_t fd)
00232 {
00233    Int_t rc = chirp_client_close(chirp_client,fd);
00234 
00235    if (rc < 0) {
00236       gSystem->SetErrorStr(strerror(errno));
00237    }
00238 
00239    return rc;
00240 }
00241 
00242 //______________________________________________________________________________
00243 Int_t TChirpFile::SysRead(Int_t fd, void *buf, Int_t len)
00244 {
00245    Int_t rc = chirp_client_read(chirp_client, fd, buf, len);
00246 
00247    if (rc < 0) {
00248       gSystem->SetErrorStr(strerror(errno));
00249    }
00250 
00251    return rc;
00252 }
00253 
00254 //______________________________________________________________________________
00255 Int_t TChirpFile::SysWrite(Int_t fd, const void *buf, Int_t len)
00256 {
00257    Int_t rc = chirp_client_write(chirp_client, fd, (char *)buf, len);
00258 
00259    if (rc < 0) {
00260       gSystem->SetErrorStr(strerror(errno));
00261    }
00262 
00263    return rc;
00264 }
00265 
00266 //______________________________________________________________________________
00267 Long64_t TChirpFile::SysSeek(Int_t fd, Long64_t offset, Int_t whence)
00268 {
00269    Long64_t rc = chirp_client_lseek(chirp_client, fd, offset, whence);
00270 
00271    if (rc < 0)
00272       gSystem->SetErrorStr(strerror(errno));
00273 
00274    return rc;
00275 }
00276 
00277 //______________________________________________________________________________
00278 Int_t TChirpFile::SysSync(Int_t fd)
00279 {
00280    Int_t rc = chirp_client_fsync(chirp_client, fd);
00281 
00282    if (rc < 0) {
00283       gSystem->SetErrorStr(strerror(errno));
00284    }
00285 
00286    return rc;
00287 }
00288 
00289 //______________________________________________________________________________
00290 Int_t TChirpFile::SysStat(Int_t fd, Long_t *id, Long64_t *size,
00291                            Long_t *flags, Long_t *modtime)
00292 {
00293    // FIXME: chirp library doesn't (yet) provide any stat() capabilities.
00294 
00295    *id = ::Hash(fRealName);
00296 
00297    Long64_t offset = SysSeek(fd, 0, SEEK_CUR);
00298    *size = SysSeek(fd, 0, SEEK_END);
00299    SysSeek(fd, offset, SEEK_SET);
00300 
00301    *flags = 0;
00302    *modtime = 0;
00303    return 0;
00304 }
00305 
00306 //______________________________________________________________________________
00307 void TChirpFile::ResetErrno() const
00308 {
00309    TSystem::ResetErrno();
00310 }

Generated on Tue Jul 5 14:28:34 2011 for ROOT_528-00b_version by  doxygen 1.5.1