TDCacheFile.cxx

Go to the documentation of this file.
00001 // @(#)root/dcache:$Id: TDCacheFile.cxx 35359 2010-09-17 10:10:18Z rdm $
00002 // Author: Grzegorz Mazur   20/01/2002
00003 // Modified: William Tanenbaum 01/12/2003
00004 // Modified: Tigran Mkrtchyan 29/06/2004
00005 // Modified: Tigran Mkrtchyan 06/07/2007
00006 
00007 /*************************************************************************
00008  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00009  * All rights reserved.                                                  *
00010  *                                                                       *
00011  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00012  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00013  *************************************************************************/
00014 
00015 //////////////////////////////////////////////////////////////////////////
00016 //                                                                      //
00017 // TDCacheFile                                                          //
00018 //                                                                      //
00019 // A TDCacheFile is like a normal TFile except that it may read and     //
00020 // write its data via a dCache server (for more on the dCache daemon    //
00021 // see http://www-dcache.desy.de/. Given a path which doesn't belong    //
00022 // to the dCache managed filesystem, it falls back to the ordinary      //
00023 // TFile behaviour.                                                     //
00024 //                                                                      //
00025 //////////////////////////////////////////////////////////////////////////
00026 
00027 #include "TDCacheFile.h"
00028 #include "TError.h"
00029 #include "TSystem.h"
00030 #include "TROOT.h"
00031 
00032 #include <cstdlib>
00033 #include <errno.h>
00034 #include <sys/stat.h>
00035 #include <sys/types.h>
00036 
00037 #include <dcap.h>
00038 #ifndef R__WIN32
00039 #include <unistd.h>
00040 #if defined(R__SUN) || defined(R__SGI) || defined(R__HPUX) || \
00041     defined(R__AIX) || defined(R__LINUX) || defined(R__SOLARIS) || \
00042     defined(R__ALPHA) || defined(R__HIUX) || defined(R__FBSD) || \
00043     defined(R__MACOSX) || defined(R__HURD) || defined(R__OBSD)
00044 #define HAS_DIRENT
00045 #endif
00046 #endif
00047 
00048 #ifdef HAS_DIRENT
00049 #include <dirent.h>
00050 #endif
00051 
00052 static const char* const DCACHE_PREFIX = "dcache:";
00053 static const size_t DCACHE_PREFIX_LEN = strlen(DCACHE_PREFIX);
00054 static const char* const DCAP_PREFIX = "dcap:";
00055 static const size_t DCAP_PREFIX_LEN = strlen(DCAP_PREFIX);
00056 
00057 
00058 ClassImp(TDCacheFile)
00059 
00060 //______________________________________________________________________________
00061 TDCacheFile::TDCacheFile(const char *path, Option_t *option,
00062                          const char *ftitle, Int_t compress):
00063    TFile(path, "NET", ftitle, compress)
00064 {
00065    // Create a dCache file object. A dCache file is the same as a TFile
00066    // except that it is being accessed via a dCache server. The url
00067    // argument must be of the form: dcache:/pnfs/<path>/<file>.root or
00068    // dcap://<nodename.org>/<path>/<file>.root. If the file specified in the
00069    // URL does not exist, is not accessable or can not be created the kZombie
00070    // bit will be set in the TDCacheFile object. Use IsZombie() to see if the
00071    // file is accessable. For a description of the option and other arguments
00072    // see the TFile ctor. The preferred interface to this constructor is
00073    // via TFile::Open().
00074 
00075    TString pathString = GetDcapPath(path);
00076    path = pathString.Data();
00077 
00078    fOption = option;
00079    fOption.ToUpper();
00080    fStatCached = kFALSE;
00081 
00082    if (fOption == "NEW")
00083       fOption = "CREATE";
00084 
00085    Bool_t create   = (fOption == "CREATE") ? kTRUE : kFALSE;
00086    Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
00087    Bool_t update   = (fOption == "UPDATE") ? kTRUE : kFALSE;
00088    Bool_t read     = (fOption == "READ") ? kTRUE : kFALSE;
00089    if (!create && !recreate && !update && !read) {
00090       read    = kTRUE;
00091       fOption = "READ";
00092    }
00093 
00094    TString stmp;
00095    TString stmp2;
00096    const char *fname;
00097    const char *fnameWithPrefix;
00098 
00099    if (!strncmp(path, DCAP_PREFIX, DCAP_PREFIX_LEN)) {
00100       fnameWithPrefix = fname = path;
00101    } else {
00102       // Metadata provided by PNFS
00103       char *tname;
00104       if ((tname = gSystem->ExpandPathName(path))) {
00105          stmp = tname;
00106          stmp2 = DCACHE_PREFIX;
00107          stmp2 += tname;
00108          delete [] tname;
00109          fname = stmp;
00110          fnameWithPrefix = stmp2;
00111       } else {
00112          Error("TDCacheFile", "error expanding path %s", path);
00113          goto zombie;
00114       }
00115    }
00116 
00117    if (recreate) {
00118       if (!gSystem->AccessPathName(fnameWithPrefix, kFileExists))
00119          dc_unlink(fname);
00120       recreate = kFALSE;
00121       create   = kTRUE;
00122       fOption  = "CREATE";
00123    }
00124    if (create && !gSystem->AccessPathName(fnameWithPrefix, kFileExists)) {
00125       Error("TDCacheFile", "file %s already exists", fname);
00126       goto zombie;
00127    }
00128    if (update) {
00129       if (gSystem->AccessPathName(fnameWithPrefix, kFileExists)) {
00130          update = kFALSE;
00131          create = kTRUE;
00132       }
00133       if (update && gSystem->AccessPathName(fnameWithPrefix, kWritePermission)) {
00134          Error("TDCacheFile", "no write permission, could not open file %s", fname);
00135          goto zombie;
00136       }
00137    }
00138 
00139    // Connect to file system stream
00140    fRealName = fname;
00141 
00142    if (create || update) {
00143 #ifndef WIN32
00144       fD = SysOpen(fname, O_RDWR | O_CREAT, 0644);
00145 #else
00146       fD = SysOpen(fname, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
00147 #endif
00148       if (fD == -1) {
00149          SysError("TDCacheFile", "file %s can not be opened", fname);
00150          goto zombie;
00151       }
00152       fWritable = kTRUE;
00153    } else {
00154 #ifndef WIN32
00155       fD = SysOpen(fname, O_RDONLY, 0644);
00156 #else
00157       fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
00158 #endif
00159       if (fD == -1) {
00160          if (gSystem->AccessPathName(fnameWithPrefix, kFileExists)) {
00161             Error("TDCacheFile", "file %s does not exist", fname);
00162             goto zombie;
00163          }
00164          if (gSystem->AccessPathName(fnameWithPrefix, kReadPermission)) {
00165             Error("TDCacheFile", "no read permission, could not open file %s", fname);
00166             goto zombie;
00167          }
00168          SysError("TDCacheFile", "file %s can not be opened for reading", fname);
00169          goto zombie;
00170       }
00171       fWritable = kFALSE;
00172    }
00173 
00174    // use 128K ( default ) read-ahead buffer to get file header,
00175    // the buffer size can be overriden by env var "DCACHE_RA_BUFFER",
00176    // vector read are not affected by read-ahead buffer
00177    if (read) {
00178      int dcache_RAHEAD_SIZE = RAHEAD_BUFFER_SIZE;
00179      const char *DCACHE_RA_BUFFER = gSystem->Getenv("DCACHE_RA_BUFFER");
00180      if (DCACHE_RA_BUFFER) {
00181         int ra_buffer = atoi(DCACHE_RA_BUFFER);
00182         dcache_RAHEAD_SIZE = ra_buffer<=0 ? dcache_RAHEAD_SIZE : ra_buffer;
00183      }
00184      dc_setBufferSize(fD, dcache_RAHEAD_SIZE);
00185    } else {
00186      dc_noBuffering(fD);
00187    }
00188 
00189    Init(create);
00190 
00191    return;
00192 
00193 zombie:
00194    // error in file opening occured, make this object a zombie
00195    MakeZombie();
00196    gDirectory = gROOT;
00197 }
00198 
00199 //______________________________________________________________________________
00200 TDCacheFile::~TDCacheFile()
00201 {
00202    // Close and cleanup dCache file.
00203 
00204    Close();
00205 }
00206 
00207 //______________________________________________________________________________
00208 Bool_t TDCacheFile::ReadBuffer(char *buf, Int_t len)
00209 {
00210    // Read specified byte range from remote file via dCache daemon.
00211    // Returns kTRUE in case of error.
00212 
00213    Int_t st;
00214    if ((st = ReadBufferViaCache(buf, len))) {
00215       if (st == 2)
00216          return kTRUE;
00217       return kFALSE;
00218    }
00219 
00220    return TFile::ReadBuffer(buf, len);
00221 }
00222 
00223 //______________________________________________________________________________
00224 Bool_t TDCacheFile::ReadBuffer(char *buf, Long64_t pos, Int_t len)
00225 {
00226    // Read specified byte range from remote file via dCache daemon.
00227    // Returns kTRUE in case of error.
00228 
00229    SetOffset(pos);
00230    Int_t st;
00231    if ((st = ReadBufferViaCache(buf, len))) {
00232       if (st == 2)
00233          return kTRUE;
00234       return kFALSE;
00235    }
00236 
00237    return TFile::ReadBuffer(buf, pos, len);
00238 }
00239 
00240 //______________________________________________________________________________
00241 Bool_t TDCacheFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
00242 {
00243    // Read the nbuf blocks described in arrays pos and len,
00244    // where pos[i] is the seek position of block i of length len[i].
00245    // Note that for nbuf=1, this call is equivalent to TFile::ReafBuffer.
00246    // This function is overloaded by TNetFile, TWebFile, etc.
00247    // Returns kTRUE in case of failure.
00248 
00249 #ifdef _IOVEC2_
00250 
00251    iovec2 *vector;
00252 
00253    vector = (iovec2 *)malloc(sizeof(iovec2)*nbuf);
00254 
00255    Int_t total_len = 0;
00256    for (Int_t i = 0; i < nbuf; i++) {
00257            vector[i].buf    = &buf[total_len];
00258            vector[i].offset = pos[i] + fArchiveOffset;
00259            vector[i].len    = len[i];
00260            total_len       += len[i];
00261    }
00262 
00263    Int_t rc = dc_readv2(fD, vector, nbuf);
00264    free(vector);
00265 
00266    if (rc == 0) {
00267       fBytesRead += total_len;
00268       SetFileBytesRead(GetFileBytesRead() + total_len);
00269            return kFALSE;
00270    }
00271 
00272 #endif
00273 
00274    // if we failed to get with dc_readv2 (old server), try to loop over
00275 
00276    Int_t k = 0;
00277    Bool_t result = kTRUE;
00278    TFileCacheRead *old = fCacheRead;
00279    fCacheRead = 0;
00280 
00281    Long64_t low  = pos[0];
00282    Long64_t high = pos[nbuf-1] + len[nbuf-1] - pos[0];
00283 
00284    Long64_t total = 0;
00285    for(Int_t j=0; j < nbuf; j++) {
00286       total += len[j];
00287    }
00288 
00289    if ( high / total < 10 ) {
00290 
00291       char *temp = new char[high];
00292       Seek(low);
00293       result = ReadBuffer(temp,high);
00294 
00295       if (result==0) {
00296          for (Int_t i = 0; i < nbuf; i++) {
00297             memcpy(&buf[k], &(temp[pos[i]-pos[0]]), len[i]);
00298             k += len[i];
00299          }
00300       }
00301 
00302       delete [] temp;
00303 
00304    } else {
00305 
00306       for (Int_t i = 0; i < nbuf; i++) {
00307          Seek(pos[i]);
00308          result = ReadBuffer(&buf[k], len[i]);
00309          if (result) break;
00310          k += len[i];
00311       }
00312 
00313    }
00314 
00315    fCacheRead = old;
00316    return result;
00317 }
00318 
00319 //______________________________________________________________________________
00320 Bool_t TDCacheFile::WriteBuffer(const char *buf, Int_t len)
00321 {
00322    // Write specified byte range to remote file via dCache daemon.
00323    // Returns kTRUE in case of error.
00324 
00325    if (!IsOpen() || !fWritable) return kTRUE;
00326 
00327    Int_t st;
00328    if ((st = WriteBufferViaCache(buf, len))) {
00329       if (st == 2)
00330          return kTRUE;
00331       return kFALSE;
00332    }
00333 
00334    return TFile::WriteBuffer(buf, len);
00335 }
00336 
00337 //______________________________________________________________________________
00338 Bool_t TDCacheFile::Stage(const char *path, UInt_t after, const char *location)
00339 {
00340    // Stage() returns kTRUE on success and kFALSE on failure.
00341 
00342    TString pathString = GetDcapPath(path);
00343    path = pathString.Data();
00344 
00345    dc_errno = 0;
00346 
00347    if (dc_stage(path, after, location) == 0)
00348       return kTRUE;
00349 
00350    if (dc_errno != 0)
00351       gSystem->SetErrorStr(dc_strerror(dc_errno));
00352 
00353    return kFALSE;
00354 }
00355 
00356 //______________________________________________________________________________
00357 Bool_t TDCacheFile::CheckFile(const char *path, const char *location)
00358 {
00359    // CheckFile() returns kTRUE on success and kFALSE on failure.  In
00360    // case the file exists but is not cached, CheckFile() returns
00361    // kFALSE and errno is set to EAGAIN.
00362 
00363    TString pathString = GetDcapPath(path);
00364    path = pathString.Data();
00365 
00366    dc_errno = 0;
00367 
00368    if (dc_check(path, location) == 0)
00369       return kTRUE;
00370 
00371    if (dc_errno != 0)
00372       gSystem->SetErrorStr(dc_strerror(dc_errno));
00373 
00374    return kFALSE;
00375 }
00376 
00377 //______________________________________________________________________________
00378 void TDCacheFile::SetOpenTimeout(UInt_t n)
00379 {
00380    // Set file open timeout.
00381 
00382    dc_setOpenTimeout(n);
00383 }
00384 
00385 //______________________________________________________________________________
00386 void TDCacheFile::SetOnError(OnErrorAction a)
00387 {
00388    // Set on error handler.
00389 
00390    dc_setOnError(a);
00391 }
00392 
00393 //______________________________________________________________________________
00394 void TDCacheFile::SetReplyHostName(const char *host_name)
00395 {
00396    // Set reply host name.
00397 
00398    dc_setReplyHostName((char*)host_name);
00399 }
00400 
00401 //______________________________________________________________________________
00402 const char *TDCacheFile::GetDcapVersion()
00403 {
00404    // Return dCache version string.
00405 
00406    return getDcapVersion();
00407 }
00408 
00409 //______________________________________________________________________________
00410 Int_t TDCacheFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
00411 {
00412    // Interface to system open. All arguments like in POSIX open.
00413 
00414    // often there is a filewall on front of storage system.
00415    // let clients connect to the data servers
00416    // if it's an old dCache version, pool will try to connect to the client
00417    // (if it's fine with firewall)
00418 
00419    dc_setClientActive();
00420 
00421    dc_errno = 0;
00422 
00423    Int_t rc = dc_open(pathname, flags, (Int_t) mode);
00424 
00425    if (rc < 0) {
00426       if (dc_errno != 0)
00427          gSystem->SetErrorStr(dc_strerror(dc_errno));
00428    }
00429 
00430    return rc;
00431 }
00432 
00433 //______________________________________________________________________________
00434 Int_t TDCacheFile::SysClose(Int_t fd)
00435 {
00436    // Interface to system close. All arguments like in POSIX close.
00437 
00438    dc_errno = 0;
00439 
00440    Int_t rc = dc_close(fd);
00441 
00442    if (rc < 0) {
00443       if (dc_errno != 0)
00444          gSystem->SetErrorStr(dc_strerror(dc_errno));
00445    }
00446 
00447    return rc;
00448 }
00449 
00450 //______________________________________________________________________________
00451 Int_t TDCacheFile::SysRead(Int_t fd, void *buf, Int_t len)
00452 {
00453    // Interface to system read. All arguments like in POSIX read.
00454 
00455    dc_errno = 0;
00456 
00457    Int_t rc = dc_read(fd, buf, len);
00458 
00459    if (rc < 0) {
00460       if (dc_errno != 0)
00461          gSystem->SetErrorStr(dc_strerror(dc_errno));
00462    }
00463 
00464    return rc;
00465 }
00466 
00467 //______________________________________________________________________________
00468 Int_t TDCacheFile::SysWrite(Int_t fd, const void *buf, Int_t len)
00469 {
00470    // Interface to system write. All arguments like in POSIX write.
00471 
00472    dc_errno = 0;
00473 
00474    Int_t rc =  dc_write(fd, (char *)buf, len);
00475 
00476    if (rc < 0) {
00477       if (dc_errno != 0)
00478          gSystem->SetErrorStr(dc_strerror(dc_errno));
00479    }
00480 
00481    return rc;
00482 }
00483 
00484 //______________________________________________________________________________
00485 Long64_t TDCacheFile::SysSeek(Int_t fd, Long64_t offset, Int_t whence)
00486 {
00487    // Interface to system seek. All arguments like in POSIX lseek.
00488 
00489    dc_errno = 0;
00490 
00491    Long64_t rc = dc_lseek64(fd, offset, whence);
00492 
00493    if (rc < 0) {
00494       if (dc_errno != 0)
00495          gSystem->SetErrorStr(dc_strerror(dc_errno));
00496    }
00497 
00498    return rc;
00499 }
00500 
00501 //______________________________________________________________________________
00502 Int_t TDCacheFile::SysSync(Int_t fd)
00503 {
00504    // Interface to system sync. All arguments like in POSIX fsync.
00505    // dCache always keep it's files sync'ed, so there's no need to
00506    // sync() them manually.
00507 
00508    Int_t rc;
00509    dc_errno = 0;
00510 
00511    rc = dc_fsync(fd);
00512    if (rc < 0) {
00513       if (dc_errno != 0)
00514          gSystem->SetErrorStr(dc_strerror(dc_errno));
00515    }
00516 
00517    return rc;
00518 }
00519 
00520 //______________________________________________________________________________
00521 Int_t TDCacheFile::SysStat(Int_t, Long_t *id, Long64_t *size,
00522                            Long_t *flags, Long_t *modtime)
00523 {
00524    // Get info about a file: id, size, flags, modification time.
00525    // Id      is (statbuf.st_dev << 24) + statbuf.st_ino
00526    // Size    is the file size
00527    // Flags   is file type: 0 is regular file, bit 0 set executable,
00528    //                       bit 1 set directory, bit 2 set special file
00529    //                       (socket, fifo, pipe, etc.)
00530    // Modtime is modification time.
00531    // The function returns 0 in case of success and 1 if the file could
00532    // not be stat'ed.
00533 
00534    // If in read mode, uses the cached file status, if available, to avoid
00535    // costly dc_stat() call.
00536 
00537    struct stat64 & statbuf = fStatBuffer; // reference the cache
00538 
00539    if (fOption != "READ" || !fStatCached) {
00540       // We are not in read mode, or the file status information is not yet
00541       // in the cache. Update or read the status information with dc_stat().
00542 
00543       const char *path = GetName();
00544       TString pathString = GetDcapPath(path);
00545       path = pathString.Data();
00546 
00547       if (path && (dc_stat64(path, &statbuf) >= 0)) {
00548          fStatCached = kTRUE;
00549       }
00550    }
00551 
00552    if (fStatCached) {
00553       if (id)
00554          *id = (statbuf.st_dev << 24) + statbuf.st_ino;
00555       if (size)
00556          *size = statbuf.st_size;
00557       if (modtime)
00558          *modtime = statbuf.st_mtime;
00559       if (flags) {
00560          *flags = 0;
00561          if (statbuf.st_mode & ((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
00562             *flags |= 1;
00563          if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
00564             *flags |= 2;
00565          if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
00566              (statbuf.st_mode & S_IFMT) != S_IFDIR)
00567             *flags |= 4;
00568       }
00569       return 0;
00570    }
00571    return 1;
00572 }
00573 
00574 //______________________________________________________________________________
00575 void TDCacheFile::ResetErrno() const
00576 {
00577    // Method resetting the dc_errno and errno.
00578 
00579    dc_errno = 0;
00580    TSystem::ResetErrno();
00581 }
00582 
00583 //______________________________________________________________________________
00584 TString TDCacheFile::GetDcapPath(const char *path)
00585 {
00586    // Transform the input path into a path usuable by the dcap C library,
00587    // i.e either dcap://nodename.org/where/filename.root or
00588    // /pnfs/where/filename.root
00589 
00590    // eat all 'dcache:' prefixes
00591    while (!strncmp(path, DCACHE_PREFIX, DCACHE_PREFIX_LEN)) {
00592       path += DCACHE_PREFIX_LEN;
00593    }
00594 
00595    TUrl url(path);
00596    TString pathString(url.GetUrl());
00597 
00598    // convert file://path url and dcap:///path to /path
00599    if(!strncmp(url.GetProtocol(), "file", 4) || !strcmp(url.GetHost(),"")){
00600        pathString = url.GetFile();
00601    }
00602 
00603    return pathString;
00604 }
00605 
00606 
00607 //______________________________________________________________________________
00608 TDCacheSystem::TDCacheSystem() : TSystem("-DCache", "DCache Helper System")
00609 {
00610    // Create helper class that allows directory access via dCache.
00611 
00612    // name must start with '-' to bypass the TSystem singleton check
00613    SetName("DCache");
00614 
00615    fDirp = 0;
00616 }
00617 
00618 //______________________________________________________________________________
00619 int TDCacheSystem::MakeDirectory(const char *path)
00620 {
00621    // Create a directory.
00622 
00623    Int_t rc;
00624    dc_errno = 0;
00625    TString pathString = TDCacheFile::GetDcapPath(path);
00626    path = pathString.Data();
00627 
00628    rc = dc_mkdir(path, 0755);
00629    if (rc < 0) {
00630       if (dc_errno != 0)
00631          gSystem->SetErrorStr(dc_strerror(dc_errno));
00632    }
00633 
00634    return rc;
00635 }
00636 
00637 //______________________________________________________________________________
00638 void *TDCacheSystem::OpenDirectory(const char *path)
00639 {
00640    // Open a directory.
00641 
00642    dc_errno = 0;
00643    TString pathString = TDCacheFile::GetDcapPath(path);
00644    path = pathString.Data();
00645 
00646    fDirp = dc_opendir(path);
00647    if (fDirp == 0) {
00648       if (dc_errno != 0)
00649          gSystem->SetErrorStr(dc_strerror(dc_errno));
00650    }
00651 
00652    return fDirp;
00653 }
00654 
00655 //______________________________________________________________________________
00656 void TDCacheSystem::FreeDirectory(void * dirp)
00657 {
00658    // Close a directory.
00659 
00660    Int_t rc;
00661    dc_errno = 0;
00662 
00663    rc = dc_closedir((DIR *)dirp);
00664    if (rc < 0) {
00665       if (dc_errno != 0)
00666          gSystem->SetErrorStr(dc_strerror(dc_errno));
00667    }
00668 
00669    fDirp = 0;
00670    return;
00671 }
00672 
00673 //______________________________________________________________________________
00674 const char *TDCacheSystem::GetDirEntry(void * dirp)
00675 {
00676    // Get a directory entry.
00677 
00678    struct dirent *ent;
00679    dc_errno = 0;
00680 
00681    ent = dc_readdir((DIR *)dirp);
00682    if (ent == 0) {
00683       if (dc_errno != 0)
00684          gSystem->SetErrorStr(dc_strerror(dc_errno));
00685    }
00686 
00687    return !ent ? 0 : ent->d_name;
00688 }
00689 
00690 //______________________________________________________________________________
00691 Bool_t TDCacheSystem::AccessPathName(const char *path, EAccessMode mode)
00692 {
00693    // Returns FALSE if one can access a file using the specified access mode.
00694    // Mode is the same as for the Unix access(2) function.
00695    // Attention, bizarre convention of return value!!
00696 
00697    TString pathString = TDCacheFile::GetDcapPath(path);
00698    path = pathString.Data();
00699 
00700    return dc_access(path, mode);
00701 }
00702 
00703 //______________________________________________________________________________
00704 int TDCacheSystem::GetPathInfo(const char *path, FileStat_t &buf)
00705 {
00706    // Get info about a file. Info is returned in the form of a FileStat_t
00707    // structure (see TSystem.h).
00708    // The function returns 0 in case of success and 1 if the file could
00709    // not be stat'ed.
00710 
00711    TString pathString = TDCacheFile::GetDcapPath(path);
00712    path = pathString.Data();
00713 
00714    struct stat64 sbuf;
00715 
00716    if (path && (dc_stat64(path, &sbuf) >= 0)) {
00717 
00718       buf.fDev    = sbuf.st_dev;
00719       buf.fIno    = sbuf.st_ino;
00720       buf.fMode   = sbuf.st_mode;
00721       buf.fUid    = sbuf.st_uid;
00722       buf.fGid    = sbuf.st_gid;
00723       buf.fSize   = sbuf.st_size;
00724       buf.fMtime  = sbuf.st_mtime;
00725       buf.fIsLink = kFALSE;
00726 
00727       return 0;
00728    }
00729    return 1;
00730 }

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