79 #define _XOPEN_SOURCE 600
90 # include <sys/types.h>
96 #include "RConfigure.h"
128 #include "compiledata.h"
140 std::atomic<Long64_t> TFile::fgBytesRead{0};
141 std::atomic<Long64_t> TFile::fgBytesWrite{0};
142 std::atomic<Long64_t> TFile::fgFileCounter{0};
143 std::atomic<Int_t> TFile::fgReadCalls{0};
144 Int_t TFile::fgReadaheadSize = 256000;
145 Bool_t TFile::fgReadInfo = kTRUE;
146 TList *TFile::fgAsyncOpenRequests =
nullptr;
147 TString TFile::fgCacheFileDir;
148 Bool_t TFile::fgCacheFileForce = kFALSE;
149 Bool_t TFile::fgCacheFileDisconnected = kTRUE;
150 UInt_t TFile::fgOpenTimeout = TFile::kEternalTimeout;
151 Bool_t TFile::fgOnlyStaged = kFALSE;
153 ROOT::TRWSpinLock TFile::fgRwLock;
154 ROOT::Internal::RConcurrentHashColl TFile::fgTsSIHashes;
157 const Int_t kBEGIN = 100;
164 static struct AddPseudoGlobals {
168 TGlobalMappedFunction::MakeFunctor(
"gFile",
"TFile*", TFile::CurrentFile);
175 TFile::TFile() : TDirectoryFile(), fCompress(ROOT::RCompressionSetting::EAlgorithm::kUseGlobal)
177 fCacheReadMap =
new TMap();
178 SetBit(kBinaryFile, kTRUE);
181 Info(
"TFile",
"default ctor");
296 TFile::TFile(
const char *fname1, Option_t *option,
const char *ftitle, Int_t compress)
297 : TDirectoryFile(), fCompress(compress), fUrl(fname1,kTRUE)
300 ::Fatal(
"TFile::TFile",
"ROOT system not initialized");
303 TString sfname1 = fname1;
304 if (sfname1.Index(
"?") != kNPOS) {
305 TString s = sfname1(0, sfname1.Index(
"?"));
307 fNoAnchorInName = kTRUE;
314 fname1 = fUrl.GetFile();
317 if (strstr(fUrl.GetOptions(),
"filetype=raw"))
318 fIsRootFile = kFALSE;
321 if (strstr(fUrl.GetOptions(),
"filetype=pcm"))
324 if (fUrl.HasOption(
"reproducible"))
325 SetBit(kReproducible);
328 fAsyncOpenStatus = kAOSNotAsync;
330 BuildDirectoryFile(
this,
nullptr);
332 fVersion = gROOT->GetVersionInt();
335 fCacheReadMap =
new TMap();
336 SetBit(kBinaryFile, kTRUE);
340 if (fIsRootFile && !fIsPcmFile && fOption !=
"NEW" && fOption !=
"CREATE"
341 && fOption !=
"RECREATE") {
344 fArchive = gPluginMgr ? TArchiveFile::Open(fUrl.GetUrl(),
this) :
nullptr;
346 fname1 = fArchive->GetArchiveName();
349 if (!strlen(fArchive->GetMemberName()))
354 if (fOption ==
"NET")
357 if (fOption ==
"WEB") {
363 if (fOption ==
"NEW")
366 Bool_t create = (fOption ==
"CREATE") ? kTRUE : kFALSE;
367 Bool_t recreate = (fOption ==
"RECREATE") ? kTRUE : kFALSE;
368 Bool_t update = (fOption ==
"UPDATE") ? kTRUE : kFALSE;
369 Bool_t read = (fOption ==
"READ") ? kTRUE : kFALSE;
370 if (!create && !recreate && !update && !read) {
375 Bool_t devnull = kFALSE;
377 if (!fname1 || !fname1[0]) {
378 Error(
"TFile",
"file name is not specified");
383 if (!strcmp(fname1,
"/dev/null") &&
384 !gSystem->AccessPathName(fname1, kWritePermission)) {
395 if ((fname = gSystem->ExpandPathName(fname1))) {
398 fRealName = GetName();
399 fname = fRealName.Data();
401 Error(
"TFile",
"error expanding path %s", fname1);
406 if (!gSystem->AccessPathName(fname, kFileExists)) {
407 if (gSystem->Unlink(fname) != 0) {
408 SysError(
"TFile",
"could not delete %s (errno: %d)",
409 fname, gSystem->GetErrno());
417 if (create && !devnull && !gSystem->AccessPathName(fname, kFileExists)) {
418 Error(
"TFile",
"file %s already exists", fname);
422 if (gSystem->AccessPathName(fname, kFileExists)) {
426 if (update && gSystem->AccessPathName(fname, kWritePermission)) {
427 Error(
"TFile",
"no write permission, could not open file %s", fname);
432 if (gSystem->AccessPathName(fname, kFileExists)) {
433 Error(
"TFile",
"file %s does not exist", fname);
436 if (gSystem->AccessPathName(fname, kReadPermission)) {
437 Error(
"TFile",
"no read permission, could not open file %s", fname);
443 if (create || update) {
445 fD = TFile::SysOpen(fname, O_RDWR | O_CREAT, 0644);
447 fD = TFile::SysOpen(fname, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
450 SysError(
"TFile",
"file %s can not be opened", fname);
456 fD = TFile::SysOpen(fname, O_RDONLY, 0644);
458 fD = TFile::SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
461 SysError(
"TFile",
"file %s can not be opened for reading", fname);
475 R__LOCKGUARD(gROOTMutex);
476 gROOT->GetListOfClosedObjects()->Add(
this);
498 fList->Delete(
"slow");
500 SafeDelete(fAsyncHandle);
501 SafeDelete(fCacheRead);
502 SafeDelete(fCacheReadMap);
503 SafeDelete(fCacheWrite);
504 SafeDelete(fProcessIDs);
506 SafeDelete(fArchive);
507 SafeDelete(fInfoCache);
508 SafeDelete(fOpenPhases);
511 R__LOCKGUARD(gROOTMutex);
512 gROOT->GetListOfClosedObjects()->Remove(
this);
513 gROOT->GetUUIDs()->RemoveUUID(GetUniqueID());
519 gInterpreter->ResetGlobalVar(
this);
523 Info(
"~TFile",
"dtor called for %s [%lx]", GetName(),(Long_t)
this);
535 void TFile::Init(Bool_t create)
548 if (fOption !=
"READ") {
549 Error(
"Init",
"archive %s can only be opened in read mode", GetName());
556 fArchive->OpenArchive();
558 if (fIsArchive)
return;
561 if (!fNoAnchorInName)
562 if (!strchr(GetName(),
'#'))
563 SetName(TString::Format(
"%s#%s", GetName(), fArchive->GetMemberName()));
565 if (fArchive->SetCurrentMember() != -1)
566 fArchiveOffset = fArchive->GetMemberFilePosition();
568 Error(
"Init",
"member %s not found in archive %s",
569 fArchive->GetMemberName(), fArchive->GetArchiveName());
578 fBEGIN = (Long64_t)kBEGIN;
587 new TFree(fFree, fBEGIN, Long64_t(kStartBigFile));
590 Int_t namelen= TNamed::Sizeof();
591 Int_t nbytes = namelen + TDirectoryFile::Sizeof();
592 TKey *key =
new TKey(fName, fTitle, IsA(), nbytes,
this);
593 fNbytesName = key->GetKeylen() + namelen;
594 fSeekDir = key->GetSeekKey();
598 char *buffer = key->GetBuffer();
599 TNamed::FillBuffer(buffer);
600 TDirectoryFile::FillBuffer(buffer);
606 char *header =
new char[kBEGIN+200];
609 if (ReadBuffer(header, kBEGIN+200)) {
611 Error(
"Init",
"%s failed to read the file type data.",
618 if (strncmp(header,
"root", 4)) {
619 Error(
"Init",
"%s not a ROOT file", GetName());
624 char *buffer = header + 4;
625 frombuf(buffer, &fVersion);
627 frombuf(buffer, &headerLength);
628 fBEGIN = (Long64_t)headerLength;
629 if (fVersion < 1000000) {
630 Int_t send,sfree,sinfo;
631 frombuf(buffer, &send); fEND = (Long64_t)send;
632 frombuf(buffer, &sfree); fSeekFree= (Long64_t)sfree;
633 frombuf(buffer, &fNbytesFree);
634 frombuf(buffer, &nfree);
635 frombuf(buffer, &fNbytesName);
636 frombuf(buffer, &fUnits );
637 frombuf(buffer, &fCompress);
638 frombuf(buffer, &sinfo); fSeekInfo = (Long64_t)sinfo;
639 frombuf(buffer, &fNbytesInfo);
641 frombuf(buffer, &fEND);
642 frombuf(buffer, &fSeekFree);
643 frombuf(buffer, &fNbytesFree);
644 frombuf(buffer, &nfree);
645 frombuf(buffer, &fNbytesName);
646 frombuf(buffer, &fUnits );
647 frombuf(buffer, &fCompress);
648 frombuf(buffer, &fSeekInfo);
649 frombuf(buffer, &fNbytesInfo);
651 if (fBEGIN < 0 || fBEGIN > fEND) {
653 Error(
"Init",
"file %s has an incorrect header length (%lld) or incorrect end of file length (%lld)",
654 GetName(),fBEGIN,fEND);
661 if (fSeekFree > fBEGIN) {
664 Warning(
"Init",
"file %s probably not closed, cannot read free segments",GetName());
669 char *buffer_keyloc =
nullptr;
671 Int_t nbytes = fNbytesName + TDirectoryFile::Sizeof();
672 if ( (nbytes + fBEGIN) > fEND) {
674 Error(
"Init",
"file %s has an incorrect header length (%lld) or incorrect end of file length (%lld)",
675 GetName(),fBEGIN+nbytes,fEND);
678 if (nbytes+fBEGIN > kBEGIN+200) {
680 header =
new char[nbytes];
683 if (ReadBuffer(buffer,nbytes)) {
685 Error(
"Init",
"%s failed to read the file header information at %lld (size=%d)",
686 GetName(),fBEGIN,nbytes);
690 buffer = header+fNbytesName;
691 buffer_keyloc = header;
693 buffer = header+fBEGIN+fNbytesName;
694 buffer_keyloc = header+fBEGIN;
696 Version_t version,versiondir;
697 frombuf(buffer,&version); versiondir = version%1000;
698 fDatimeC.ReadBuffer(buffer);
699 fDatimeM.ReadBuffer(buffer);
700 frombuf(buffer, &fNbytesKeys);
701 frombuf(buffer, &fNbytesName);
702 if (version > 1000) {
703 frombuf(buffer, &fSeekDir);
704 frombuf(buffer, &fSeekParent);
705 frombuf(buffer, &fSeekKeys);
707 Int_t sdir,sparent,skeys;
708 frombuf(buffer, &sdir); fSeekDir = (Long64_t)sdir;
709 frombuf(buffer, &sparent); fSeekParent = (Long64_t)sparent;
710 frombuf(buffer, &skeys); fSeekKeys = (Long64_t)skeys;
712 if (versiondir > 1) fUUID.ReadBuffer(buffer);
715 buffer_keyloc +=
sizeof(Int_t);
716 Version_t keyversion;
717 frombuf(buffer_keyloc, &keyversion);
719 if (keyversion > 1000) {
721 buffer_keyloc += 2*
sizeof(Int_t)+2*
sizeof(Short_t)+2*
sizeof(Long64_t);
723 buffer_keyloc += 2*
sizeof(Int_t)+2*
sizeof(Short_t)+2*
sizeof(Int_t);
726 cname.ReadBuffer(buffer_keyloc);
727 cname.ReadBuffer(buffer_keyloc);
728 fTitle.ReadBuffer(buffer_keyloc);
730 if (fNbytesName < 10 || fNbytesName > 10000) {
731 Error(
"Init",
"cannot read directory info of file %s", GetName());
737 if ((size = GetSize()) == -1) {
738 Error(
"Init",
"cannot stat the file %s", GetName());
744 Bool_t tryrecover = (gEnv->GetValue(
"TFile.Recover", 1) == 1) ? kTRUE : kFALSE;
747 if (fSeekKeys > fBEGIN && fEND <= size) {
749 TDirectoryFile::ReadKeys(kFALSE);
755 Error(
"Init",
"file %s has no keys", GetName());
759 }
else if ((fBEGIN+nbytes == fEND) && (fEND == size)) {
761 Warning(
"Init",
"file %s has no keys", GetName());
767 Error(
"Init",
"file %s is truncated at %lld bytes: should be %lld, "
768 "trying to recover", GetName(), size, fEND);
770 Error(
"Init",
"file %s is truncated at %lld bytes: should be %lld",
771 GetName(), size, fEND);
776 Warning(
"Init",
"file %s probably not closed, "
777 "trying to recover", GetName());
779 Warning(
"Init",
"file %s probably not closed", GetName());
783 Int_t nrecov = Recover();
785 Warning(
"Init",
"successfully recovered %d keys", nrecov);
787 Warning(
"Init",
"no keys recovered, file has been made a Zombie");
794 R__LOCKGUARD(gROOTMutex);
795 gROOT->GetListOfFiles()->Add(
this);
796 gROOT->GetUUIDs()->AddUUID(fUUID,
this);
801 Int_t lenIndex = gROOT->GetListOfStreamerInfo()->GetSize()+1;
802 if (lenIndex < 5000) lenIndex = 5000;
803 fClassIndex =
new TArrayC(lenIndex);
805 if (fSeekInfo > fBEGIN) {
808 R__LOCKGUARD(gROOTMutex);
809 gROOT->GetListOfFiles()->Remove(
this);
812 }
else if (fVersion != gROOT->GetVersionInt() && fVersion > 30000) {
814 if (fKeys->GetSize()) {
815 Warning(
"Init",
"no StreamerInfo found in %s therefore preventing schema evolution when reading this file."
816 " The file was produced with version %d.%02d/%02d of ROOT.",
817 GetName(), fVersion / 10000, (fVersion / 100) % (100), fVersion % 100);
827 while ((key = (TKey*)next())) {
828 if (!strcmp(key->GetClassName(),
"TProcessID")) fNProcessIDs++;
830 fProcessIDs =
new TObjArray(fNProcessIDs+1);
836 R__LOCKGUARD(gROOTMutex);
837 gROOT->GetListOfClosedObjects()->Add(
this);
857 void TFile::Close(Option_t *option)
859 TString opt = option;
863 if (!IsOpen())
return;
865 if (fIsArchive || !fIsRootFile) {
870 if (gMonitoringWriter)
871 gMonitoringWriter->SendFileCloseEvent(
this);
881 if (fCacheRead) fCacheRead->Close();
883 TIter iter(fCacheReadMap);
884 TObject *key =
nullptr;
885 while ((key = iter()) !=
nullptr) {
886 TFileCacheRead *cache =
dynamic_cast<TFileCacheRead *
>(fCacheReadMap->GetValue(key));
895 TDirectoryFile::Close(option);
898 TFree *f1 = (TFree*)fFree->First();
910 if (gMonitoringWriter)
911 gMonitoringWriter->SendFileCloseEvent(
this);
914 fClassIndex =
nullptr;
930 TIter next(fProcessIDs);
932 while ((pid = (TProcessID*)next())) {
933 if (!pid->DecrementCount()) {
934 if (pid != TProcessID::GetSessionProcessID()) pidDeleted.Add(pid);
935 }
else if(opt.Contains(
"r")) {
942 R__LOCKGUARD(gROOTMutex);
943 gROOT->GetListOfFiles()->Remove(
this);
944 gROOT->GetListOfBrowsers()->RecursiveRemove(
this);
945 gROOT->GetListOfClosedObjects()->Add(
this);
954 TKey* TFile::CreateKey(TDirectory* mother,
const TObject* obj,
const char* name, Int_t bufsize)
956 return new TKey(obj, name, bufsize, mother);
962 TKey* TFile::CreateKey(TDirectory* mother,
const void* obj,
const TClass* cl,
const char* name, Int_t bufsize)
964 return new TKey(obj, cl, name, bufsize, mother);
974 TFile *&TFile::CurrentFile()
976 static TFile *currentFile =
nullptr;
980 return *(TFile**)(*gThreadTsd)(¤tFile,ROOT::kFileThreadSlot);
1005 void TFile::Delete(
const char *namecycle)
1008 Info(
"Delete",
"deleting name = %s", namecycle);
1010 TDirectoryFile::Delete(namecycle);
1018 void TFile::Draw(Option_t *option)
1020 GetList()->R__FOR_EACH(TObject,Draw)(option);
1026 void TFile::DrawMap(
const char *keys, Option_t *option)
1029 if ((h = gROOT->GetPluginManager()->FindHandler(
"TFileDrawMap"))) {
1030 if (h->LoadPlugin() == -1)
1032 h->ExecPlugin(3,
this, keys, option);
1041 if (IsOpen() && fWritable) {
1043 if (SysSync(fD) < 0) {
1045 SetBit(kWriteError); SetWritable(kFALSE);
1046 SysError(
"Flush",
"error flushing file %s", GetName());
1056 Bool_t TFile::FlushWriteCache()
1058 if (fCacheWrite && IsOpen() && fWritable)
1059 return fCacheWrite->Flush();
1068 void TFile::FillBuffer(
char *&buffer)
1070 Version_t version = TFile::Class_Version();
1071 tobuf(buffer, version);
1081 Int_t TFile::GetBestBuffer()
const
1083 if (!fWritten)
return TBuffer::kInitialSize;
1084 Double_t mean = fSumBuffer/fWritten;
1085 Double_t rms2 = TMath::Abs(fSum2Buffer/fSumBuffer -mean*mean);
1086 Double_t result = mean + sqrt(rms2);
1087 if (result >= (
double)std::numeric_limits<Int_t>::max()) {
1088 return std::numeric_limits<Int_t>::max() -1;
1090 return (Int_t)result;
1100 Float_t TFile::GetCompressionFactor()
1104 Int_t nbytes, objlen, nwh = 64;
1105 char *header =
new char[fBEGIN];
1107 Long64_t idcur = fBEGIN;
1108 Float_t comp,uncomp;
1109 comp = uncomp = fBEGIN;
1111 while (idcur < fEND-100) {
1113 if (ReadBuffer(header, nwh)) {
1120 frombuf(buffer, &nbytes);
1126 if (nbytes == 0)
break;
1127 Version_t versionkey;
1128 frombuf(buffer, &versionkey);
1129 frombuf(buffer, &objlen);
1130 frombuf(buffer, &datime);
1131 frombuf(buffer, &keylen);
1132 if (!objlen) objlen = nbytes-keylen;
1134 uncomp += keylen + objlen;
1144 Int_t TFile::GetErrno()
const
1146 return TSystem::GetErrno();
1152 void TFile::ResetErrno()
const
1154 TSystem::ResetErrno();
1160 TFileCacheRead *TFile::GetCacheRead(
const TObject* tree)
const
1163 if (!fCacheRead && fCacheReadMap->GetSize() == 1) {
1164 TIter next(fCacheReadMap);
1165 return (TFileCacheRead *)fCacheReadMap->GetValue(next());
1169 TFileCacheRead *cache = (TFileCacheRead *)fCacheReadMap->GetValue(tree);
1170 if (!cache)
return fCacheRead;
1177 TFileCacheWrite *TFile::GetCacheWrite()
const
1197 Int_t TFile::GetRecordHeader(
char *buf, Long64_t first, Int_t maxbytes, Int_t &nbytes, Int_t &objlen, Int_t &keylen)
1202 if (first < fBEGIN)
return 0;
1203 if (first > fEND)
return 0;
1205 Int_t nread = maxbytes;
1206 if (first+maxbytes > fEND) nread = fEND-maxbytes;
1208 Warning(
"GetRecordHeader",
"%s: parameter maxbytes = %d must be >= 4",
1212 if (ReadBuffer(buf,nread)) {
1214 Warning(
"GetRecordHeader",
"%s: failed to read header data (maxbytes = %d)",
1218 Version_t versionkey;
1223 frombuf(buffer,&nb);
1225 if (nb < 0)
return nread;
1227 const Int_t headerSize = 16;
1228 if (nread < headerSize)
return nread;
1229 frombuf(buffer, &versionkey);
1230 frombuf(buffer, &olen);
1231 frombuf(buffer, &datime);
1232 frombuf(buffer, &klen);
1233 if (!olen) olen = nbytes-klen;
1243 Long64_t TFile::GetSize()
const
1247 if (fArchive && fArchive->GetMember()) {
1248 size = fArchive->GetMember()->GetDecompressedSize();
1250 Long_t id, flags, modtime;
1251 if (const_cast<TFile*>(
this)->SysStat(fD, &
id, &size, &flags, &modtime)) {
1252 Error(
"GetSize",
"cannot stat the file %s", GetName());
1262 const TList *TFile::GetStreamerInfoCache()
1264 return fInfoCache ? fInfoCache : (fInfoCache=GetStreamerInfoList());
1272 TFile::InfoListRet TFile::GetStreamerInfoListImpl(
bool lookupSICache)
1274 ROOT::Internal::RConcurrentHashColl::HashValue hash;
1276 if (fIsPcmFile)
return {
nullptr, 1, hash};
1278 TList *list =
nullptr;
1280 TDirectory::TContext ctxt(
this);
1281 auto key = std::make_unique<TKey>(
this);
1282 std::vector<char> buffer(fNbytesInfo+1);
1283 auto buf = buffer.data();
1285 if (ReadBuffer(buf,fNbytesInfo)) {
1287 Warning(
"GetRecordHeader",
"%s: failed to read the StreamerInfo data from disk.",
1289 return {
nullptr, 1, hash};
1293 if (lookupSICache) {
1294 hash = fgTsSIHashes.Hash(buf, fNbytesInfo);
1295 if (fgTsSIHashes.Find(hash)) {
1296 if (gDebug > 0) Info(
"GetStreamerInfo",
"The streamer info record for file %s has already been treated, skipping it.", GetName());
1297 return {
nullptr, 0, hash};
1301 (void) lookupSICache;
1303 key->ReadKeyBuffer(buf);
1304 list =
dynamic_cast<TList*
>(key->ReadObjWithBuffer(buffer.data()));
1305 if (list) list->SetOwner();
1307 list = (TList*)Get(
"StreamerInfo");
1311 Info(
"GetStreamerInfoList",
"cannot find the StreamerInfo record in file %s",
1313 return {
nullptr, 1, hash};
1316 return {list, 0, hash};
1339 TList *TFile::GetStreamerInfoList()
1341 return GetStreamerInfoListImpl(
false).fList;
1351 void TFile::ls(Option_t *option)
const
1353 TROOT::IndentLevel();
1354 std::cout <<ClassName()<<
"**\t\t"<<GetName()<<
"\t"<<GetTitle()<<std::endl;
1355 TROOT::IncreaseDirLevel();
1356 TDirectoryFile::ls(option);
1357 TROOT::DecreaseDirLevel();
1363 Bool_t TFile::IsOpen()
const
1365 return fD == -1 ? kFALSE : kTRUE;
1378 void TFile::MakeFree(Long64_t first, Long64_t last)
1380 TFree *f1 = (TFree*)fFree->First();
1382 TFree *newfree = f1->AddFree(fFree,first,last);
1383 if(!newfree)
return;
1384 Long64_t nfirst = newfree->GetFirst();
1385 Long64_t nlast = newfree->GetLast();
1386 Long64_t nbytesl= nlast-nfirst+1;
1387 if (nbytesl > 2000000000) nbytesl = 2000000000;
1388 Int_t nbytes = -Int_t (nbytesl);
1389 Int_t nb =
sizeof(Int_t);
1390 char * buffer =
new char[nb];
1391 char * psave = buffer;
1392 tobuf(buffer, nbytes);
1393 if (last == fEND-1) fEND = nfirst;
1400 WriteBuffer(psave, nb);
1401 if (fMustFlush) Flush();
1447 void TFile::Map(Option_t *opt)
1449 TString options(opt);
1451 bool forComp = options.Contains(
"forcomp");
1453 Short_t keylen,cycle;
1455 Int_t nbytes,date,time,objlen,nwheader;
1458 Long64_t seekkey,seekpdir;
1461 Long64_t idcur = fBEGIN;
1464 Int_t nread = nwheader;
1466 char header[kBEGIN];
1467 char classname[512];
1469 unsigned char nDigits = std::log10(fEND) + 1;
1471 while (idcur < fEND) {
1473 if (idcur+nread >= fEND) nread = fEND-idcur-1;
1474 if (ReadBuffer(header, nread)) {
1476 Warning(
"Map",
"%s: failed to read the key data from disk at %lld.",
1482 frombuf(buffer, &nbytes);
1484 Printf(
"Address = %lld\tNbytes = %d\t=====E R R O R=======", idcur, nbytes);
1489 Printf(
"Address = %lld\tNbytes = %d\t=====G A P===========", idcur, nbytes);
1494 Version_t versionkey;
1495 frombuf(buffer, &versionkey);
1496 frombuf(buffer, &objlen);
1497 frombuf(buffer, &datime);
1498 frombuf(buffer, &keylen);
1499 frombuf(buffer, &cycle);
1500 if (versionkey > 1000) {
1501 frombuf(buffer, &seekkey);
1502 frombuf(buffer, &seekpdir);
1505 frombuf(buffer, &skey); seekkey = (Long64_t)skey;
1506 frombuf(buffer, &sdir); seekpdir = (Long64_t)sdir;
1508 frombuf(buffer, &nwhc);
1509 for (
int i = 0;i < nwhc; i++) frombuf(buffer, &classname[i]);
1510 classname[(int)nwhc] =
'\0';
1511 if (idcur == fSeekFree) strlcpy(classname,
"FreeSegments",512);
1512 if (idcur == fSeekInfo) strlcpy(classname,
"StreamerInfo",512);
1513 if (idcur == fSeekKeys) strlcpy(classname,
"KeysList",512);
1514 TDatime::GetDateTime(datime, date, time);
1516 if (objlen != nbytes - keylen) {
1517 Float_t cx = Float_t(objlen + keylen) / Float_t(nbytes);
1518 Printf(
"%d/%06d At:%-*lld N=%-8d %-14s CX = %5.2f", date, time, nDigits + 1, idcur, nbytes, classname,
1521 Printf(
"%d/%06d At:%-*lld N=%-8d %-14s", date, time, nDigits + 1, idcur, nbytes, classname);
1525 if (objlen != nbytes - keylen) {
1526 Float_t cx = Float_t(objlen + keylen) / Float_t(nbytes);
1527 Printf(
"At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = %5.2f", nDigits+1, idcur, nbytes, keylen, objlen, classname, cx);
1529 Printf(
"At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = 1", nDigits+1, idcur, nbytes, keylen, objlen, classname);
1535 Printf(
"%d/%06d At:%-*lld N=%-8d %-14s",date,time, nDigits+1, idcur,1,
"END");
1537 Printf(
"At:%-*lld N=%-8d K= O= %-14s", nDigits+1, idcur,1,
"END");
1543 void TFile::Paint(Option_t *option)
1545 GetList()->R__FOR_EACH(TObject,Paint)(option);
1551 void TFile::Print(Option_t *option)
const
1553 Printf(
"TFile: name=%s, title=%s, option=%s", GetName(), GetTitle(), GetOption());
1554 GetList()->R__FOR_EACH(TObject,Print)(option);
1565 Bool_t TFile::ReadBuffer(
char *buf, Long64_t pos, Int_t len)
1573 if (gPerfStats) start = TTimeStamp();
1575 if ((st = ReadBufferViaCache(buf, len))) {
1584 while ((siz = SysRead(fD, buf, len)) < 0 && GetErrno() == EINTR)
1588 SysError(
"ReadBuffer",
"error reading from file %s", GetName());
1592 Error(
"ReadBuffer",
"error reading all requested bytes from file %s, got %ld of %d",
1593 GetName(), (Long_t)siz, len);
1601 if (gMonitoringWriter)
1602 gMonitoringWriter->SendFileReadProgress(
this);
1604 gPerfStats->FileReadEvent(
this, len, start);
1615 Bool_t TFile::ReadBuffer(
char *buf, Int_t len)
1620 if ((st = ReadBufferViaCache(buf, len))) {
1629 if (gPerfStats) start = TTimeStamp();
1631 while ((siz = SysRead(fD, buf, len)) < 0 && GetErrno() == EINTR)
1635 SysError(
"ReadBuffer",
"error reading from file %s", GetName());
1639 Error(
"ReadBuffer",
"error reading all requested bytes from file %s, got %ld of %d",
1640 GetName(), (Long_t)siz, len);
1648 if (gMonitoringWriter)
1649 gMonitoringWriter->SendFileReadProgress(
this);
1651 gPerfStats->FileReadEvent(
this, len, start);
1666 Bool_t TFile::ReadBuffers(
char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
1670 for (Int_t j = 0; j < nbuf; j++) {
1671 if (ReadBufferAsync(pos[j], len[j])) {
1679 Bool_t result = kTRUE;
1680 TFileCacheRead *old = fCacheRead;
1681 fCacheRead =
nullptr;
1682 Long64_t curbegin = pos[0];
1684 char *buf2 =
nullptr;
1687 cur = pos[i]+len[i];
1688 Bool_t bigRead = kTRUE;
1689 if (cur -curbegin < fgReadaheadSize) {n++; i++; bigRead = kFALSE;}
1690 if (bigRead || (i>=nbuf)) {
1695 result = ReadBuffer(&buf[k], len[i]);
1702 if (!buf2) buf2 =
new char[fgReadaheadSize];
1704 Long64_t nahead = pos[i-1]+len[i-1]-curbegin;
1705 result = ReadBuffer(buf2, nahead);
1709 for (Int_t j=0;j<n;j++) {
1710 memcpy(&buf[k],&buf2[pos[i-n+j]-curbegin],len[i-n+j]);
1714 Long64_t extra = nahead-nok;
1715 fBytesReadExtra += extra;
1716 fBytesRead -= extra;
1717 fgBytesRead -= extra;
1720 curbegin = i < nbuf ? pos[i] : 0;
1723 if (buf2)
delete [] buf2;
1734 Int_t TFile::ReadBufferViaCache(
char *buf, Int_t len)
1736 Long64_t off = GetRelOffset();
1738 Int_t st = fCacheRead->ReadBuffer(buf, off, len);
1743 SetOffset(off + len);
1750 if (fWritable && fCacheWrite) {
1751 if (fCacheWrite->ReadBuffer(buf, off, len) == 0) {
1752 SetOffset(off + len);
1770 void TFile::ReadFree()
1773 if (fNbytesFree < 0 || fNbytesFree > fEND) {
1777 TKey *headerfree =
new TKey(fSeekFree, fNbytesFree,
this);
1778 headerfree->ReadFile();
1779 char *buffer = headerfree->GetBuffer();
1780 headerfree->ReadKeyBuffer(buffer);
1781 buffer = headerfree->GetBuffer();
1783 TFree *afree =
new TFree();
1784 afree->ReadBuffer(buffer);
1786 if (afree->GetLast() > fEND)
break;
1796 TProcessID *TFile::ReadProcessID(UShort_t pidf)
1798 TProcessID *pid =
nullptr;
1799 TObjArray *pids = GetListOfProcessIDs();
1800 if (pidf < pids->GetSize()) pid = (TProcessID *)pids->UncheckedAt(pidf);
1809 snprintf(pidname,32,
"ProcessID%d",pidf);
1810 pid = (TProcessID *)Get(pidname);
1812 printf(
"ReadProcessID, name=%s, file=%s, pid=%lx\n",pidname,GetName(),(Long_t)pid);
1820 TObjArray *pidslist = TProcessID::GetPIDs();
1821 TIter next(pidslist);
1824 R__RWLOCK_ACQUIRE_READ(fgRwLock);
1825 while ((p = (TProcessID*)next())) {
1826 if (!strcmp(p->GetTitle(),pid->GetTitle())) {
1831 R__RWLOCK_RELEASE_READ(fgRwLock);
1835 pids->AddAtAndExpand(p,pidf);
1836 p->IncrementCount();
1840 pids->AddAtAndExpand(pid,pidf);
1841 pid->IncrementCount();
1843 R__RWLOCK_ACQUIRE_WRITE(fgRwLock);
1845 Int_t ind = pidslist->IndexOf(pid);
1846 pid->SetUniqueID((UInt_t)ind);
1847 R__RWLOCK_RELEASE_WRITE(fgRwLock);
1890 Int_t TFile::Recover()
1892 Short_t keylen,cycle;
1894 Int_t nbytes,date,time,objlen,nwheader;
1895 Long64_t seekkey,seekpdir;
1897 char *buffer, *bufread;
1899 Long64_t idcur = fBEGIN;
1902 if ((size = GetSize()) == -1) {
1903 Error(
"Recover",
"cannot stat the file %s", GetName());
1907 fEND = Long64_t(size);
1909 if (fWritable && !fFree) fFree =
new TList;
1914 Int_t nread = nwheader;
1916 while (idcur < fEND) {
1918 if (idcur+nread >= fEND) nread = fEND-idcur-1;
1919 if (ReadBuffer(header, nread)) {
1921 Error(
"Recover",
"%s: failed to read the key data from disk at %lld.",
1927 frombuf(buffer, &nbytes);
1929 Error(
"Recover",
"Address = %lld\tNbytes = %d\t=====E R R O R=======", idcur, nbytes);
1934 if (fWritable)
new TFree(fFree,idcur,idcur-nbytes-1);
1938 Version_t versionkey;
1939 frombuf(buffer, &versionkey);
1940 frombuf(buffer, &objlen);
1941 frombuf(buffer, &datime);
1942 frombuf(buffer, &keylen);
1943 frombuf(buffer, &cycle);
1944 if (versionkey > 1000) {
1945 frombuf(buffer, &seekkey);
1946 frombuf(buffer, &seekpdir);
1949 frombuf(buffer, &skey); seekkey = (Long64_t)skey;
1950 frombuf(buffer, &sdir); seekpdir = (Long64_t)sdir;
1952 frombuf(buffer, &nwhc);
1953 char *classname =
nullptr;
1954 if (nwhc <= 0 || nwhc > 100)
break;
1955 classname =
new char[nwhc+1];
1956 int i, nwhci = nwhc;
1957 for (i = 0;i < nwhc; i++) frombuf(buffer, &classname[i]);
1958 classname[nwhci] =
'\0';
1959 TDatime::GetDateTime(datime, date, time);
1960 TClass *tclass = TClass::GetClass(classname);
1961 if (seekpdir == fSeekDir && tclass && !tclass->InheritsFrom(TFile::Class())
1962 && strcmp(classname,
"TBasket")) {
1963 key =
new TKey(
this);
1964 key->ReadKeyBuffer(bufread);
1965 if (!strcmp(key->GetName(),
"StreamerInfo")) {
1966 fSeekInfo = seekkey;
1967 SafeDelete(fInfoCache);
1968 fNbytesInfo = nbytes;
1973 Info(
"Recover",
"%s, recovered key %s:%s at address %lld",GetName(),key->GetClassName(),key->GetName(),idcur);
1976 delete [] classname;
1980 Long64_t max_file_size = Long64_t(kStartBigFile);
1981 if (max_file_size < fEND) max_file_size = fEND+1000000000;
1982 TFree *last = (TFree*)fFree->Last();
1984 last->AddFree(fFree,fEND,max_file_size);
1986 new TFree(fFree,fEND,max_file_size);
1988 if (nrecov) Write();
2004 Int_t TFile::ReOpen(Option_t *mode)
2011 if (opt !=
"READ" && opt !=
"UPDATE") {
2012 Error(
"ReOpen",
"mode must be either READ or UPDATE, not %s", opt.Data());
2016 if (opt == fOption || (opt ==
"UPDATE" && fOption ==
"CREATE"))
2019 if (opt ==
"READ") {
2023 if (IsOpen() && IsWritable()) {
2024 WriteStreamerInfo();
2029 TFree *f1 = (TFree*)fFree->First();
2044 SetWritable(kFALSE);
2050 fD = SysOpen(fRealName, O_RDONLY, 0644);
2052 fD = SysOpen(fRealName, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
2055 SysError(
"ReOpen",
"file %s can not be opened in read mode", GetName());
2058 SetWritable(kFALSE);
2072 fD = SysOpen(fRealName, O_RDWR | O_CREAT, 0644);
2074 fD = SysOpen(fRealName, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
2077 SysError(
"ReOpen",
"file %s can not be opened in update mode", GetName());
2083 if (fSeekFree > fBEGIN)
2086 Warning(
"ReOpen",
"file %s probably not closed, cannot read free segments", GetName());
2095 void TFile::SetOffset(Long64_t offset, ERelativeTo pos)
2099 fOffset = offset + fArchiveOffset;
2107 Error(
"SetOffset",
"seeking from end in archive is not (yet) supported");
2108 fOffset = fEND + offset;
2116 void TFile::Seek(Long64_t offset, ERelativeTo pos)
2122 offset += fArchiveOffset;
2131 Error(
"Seek",
"seeking from end in archive is not (yet) supported");
2135 if ((retpos = SysSeek(fD, offset, whence)) < 0)
2136 SysError(
"Seek",
"cannot seek to position %lld in file %s, retpos=%lld",
2137 offset, GetName(), retpos);
2147 void TFile::SetCompressionAlgorithm(Int_t algorithm)
2149 if (algorithm < 0 || algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined) algorithm = 0;
2150 if (fCompress < 0) {
2151 fCompress = 100 * algorithm + ROOT::RCompressionSetting::ELevel::kUseMin;
2153 int level = fCompress % 100;
2154 fCompress = 100 * algorithm + level;
2161 void TFile::SetCompressionLevel(Int_t level)
2163 if (level < 0) level = 0;
2164 if (level > 99) level = 99;
2165 if (fCompress < 0) {
2169 int algorithm = fCompress / 100;
2170 if (algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined) algorithm = 0;
2171 fCompress = 100 * algorithm + level;
2180 void TFile::SetCompressionSettings(Int_t settings)
2182 fCompress = settings;
2207 void TFile::SetCacheRead(TFileCacheRead *cache, TObject* tree, ECacheAction action)
2210 if (cache) fCacheReadMap->Add(tree, cache);
2214 TFileCacheRead* tpf = (TFileCacheRead *)fCacheReadMap->GetValue(tree);
2215 fCacheReadMap->Remove(tree);
2216 if (tpf && (tpf->GetFile() ==
this) && (action != kDoNotDisconnect)) tpf->SetFile(0, action);
2219 if (cache) cache->SetFile(
this, action);
2220 else if (!tree && fCacheRead && (action != kDoNotDisconnect)) fCacheRead->SetFile(0, action);
2230 void TFile::SetCacheWrite(TFileCacheWrite *cache)
2232 if (!cache && fCacheWrite)
delete fCacheWrite;
2233 fCacheWrite = cache;
2239 Int_t TFile::Sizeof()
const
2247 void TFile::Streamer(TBuffer &b)
2249 if (b.IsReading()) {
2252 b.WriteVersion(TFile::IsA());
2259 void TFile::SumBuffer(Int_t bufsize)
2262 fSumBuffer += double(bufsize);
2263 fSum2Buffer += double(bufsize) * double(bufsize);
2278 Int_t TFile::Write(
const char *, Int_t opt, Int_t bufsiz)
2280 if (!IsWritable()) {
2281 if (!TestBit(kWriteError)) {
2283 Warning(
"Write",
"file %s not opened in write mode", GetName());
2289 if (!GetTitle() || strlen(GetTitle()) == 0)
2290 Info(
"Write",
"writing name = %s", GetName());
2292 Info(
"Write",
"writing name = %s title = %s", GetName(), GetTitle());
2295 fMustFlush = kFALSE;
2296 Int_t nbytes = TDirectoryFile::Write(0, opt, bufsiz);
2297 WriteStreamerInfo();
2308 Int_t TFile::Write(
const char *n, Int_t opt, Int_t bufsize)
const
2310 Error(
"Write const",
"A const TFile object should not be saved. We try to proceed anyway.");
2311 return const_cast<TFile*
>(
this)->Write(n, opt, bufsize);
2318 Bool_t TFile::WriteBuffer(
const char *buf, Int_t len)
2320 if (IsOpen() && fWritable) {
2323 if ((st = WriteBufferViaCache(buf, len))) {
2330 gSystem->IgnoreInterrupt();
2331 while ((siz = SysWrite(fD, buf, len)) < 0 && GetErrno() == EINTR)
2333 gSystem->IgnoreInterrupt(kFALSE);
2336 SetBit(kWriteError); SetWritable(kFALSE);
2337 SysError(
"WriteBuffer",
"error writing to file %s (%ld)", GetName(), (Long_t)siz);
2341 SetBit(kWriteError);
2342 Error(
"WriteBuffer",
"error writing all requested bytes to file %s, wrote %ld of %d",
2343 GetName(), (Long_t)siz, len);
2347 fgBytesWrite += siz;
2349 if (gMonitoringWriter)
2350 gMonitoringWriter->SendFileWriteProgress(
this);
2361 Int_t TFile::WriteBufferViaCache(
const char *buf, Int_t len)
2363 if (!fCacheWrite)
return 0;
2366 Long64_t off = GetRelOffset();
2367 if ((st = fCacheWrite->WriteBuffer(buf, off, len)) < 0) {
2368 SetBit(kWriteError);
2369 Error(
"WriteBuffer",
"error writing to cache");
2385 void TFile::WriteFree()
2388 if (fSeekFree != 0) {
2389 MakeFree(fSeekFree, fSeekFree + fNbytesFree -1);
2392 Bool_t largeFile = (fEND > TFile::kStartBigFile);
2394 auto createKey = [
this]() {
2398 while ((afree = (TFree*) next())) {
2399 nbytes += afree->Sizeof();
2401 if (!nbytes)
return (TKey*)
nullptr;
2403 TKey *key =
new TKey(fName,fTitle,IsA(),nbytes,
this);
2405 if (key->GetSeekKey() == 0) {
2407 return (TKey*)
nullptr;
2412 TKey *key = createKey();
2415 if (!largeFile && (fEND > TFile::kStartBigFile)) {
2427 Int_t nbytes = key->GetObjlen();
2428 char *buffer = key->GetBuffer();
2429 char *start = buffer;
2433 while ((afree = (TFree*) next())) {
2436 afree->FillBuffer(buffer);
2438 auto actualBytes = buffer-start;
2439 if ( actualBytes != nbytes ) {
2440 if (actualBytes < nbytes) {
2443 memset(buffer,0,nbytes-actualBytes);
2445 Error(
"WriteFree",
"The free block list TKey wrote more data than expected (%d vs %ld). Most likely there has been an out-of-bound write.",nbytes,(
long int)actualBytes);
2448 fNbytesFree = key->GetNbytes();
2449 fSeekFree = key->GetSeekKey();
2457 void TFile::WriteHeader()
2459 SafeDelete(fInfoCache);
2460 TFree *lastfree = (TFree*)fFree->Last();
2461 if (lastfree) fEND = lastfree->GetFirst();
2462 const char *root =
"root";
2463 char *psave =
new char[fBEGIN];
2464 char *buffer = psave;
2465 Int_t nfree = fFree->GetSize();
2466 memcpy(buffer, root, 4); buffer += 4;
2467 Int_t version = fVersion;
2468 if (version <1000000 && fEND > kStartBigFile) {version += 1000000; fUnits = 8;}
2469 tobuf(buffer, version);
2470 tobuf(buffer, (Int_t)fBEGIN);
2471 if (version < 1000000) {
2472 tobuf(buffer, (Int_t)fEND);
2473 tobuf(buffer, (Int_t)fSeekFree);
2474 tobuf(buffer, fNbytesFree);
2475 tobuf(buffer, nfree);
2476 tobuf(buffer, fNbytesName);
2477 tobuf(buffer, fUnits);
2478 tobuf(buffer, fCompress);
2479 tobuf(buffer, (Int_t)fSeekInfo);
2480 tobuf(buffer, fNbytesInfo);
2482 tobuf(buffer, fEND);
2483 tobuf(buffer, fSeekFree);
2484 tobuf(buffer, fNbytesFree);
2485 tobuf(buffer, nfree);
2486 tobuf(buffer, fNbytesName);
2487 tobuf(buffer, fUnits);
2488 tobuf(buffer, fCompress);
2489 tobuf(buffer, fSeekInfo);
2490 tobuf(buffer, fNbytesInfo);
2492 if (TestBit(kReproducible))
2493 TUUID(
"00000000-0000-0000-0000-000000000000").FillBuffer(buffer);
2495 fUUID.FillBuffer(buffer);
2496 Int_t nbytes = buffer - psave;
2498 WriteBuffer(psave, nbytes);
2568 void TFile::MakeProject(
const char *dirname,
const char * ,
2571 TString opt = option;
2573 Bool_t makepar = kFALSE;
2574 TString parname, pardir;
2575 if (opt.Contains(
"par")) {
2577 parname = gSystem->BaseName(dirname);
2578 if (parname.EndsWith(
".par")) parname.ReplaceAll(
".par",
"");
2579 pardir = gSystem->DirName(dirname);
2581 TString path, filepath;
2582 void *dir = gSystem->OpenDirectory(pardir);
2584 path.Form(
"%s/%s", pardir.Data(), parname.Data());
2585 void *dirp = gSystem->OpenDirectory(path);
2587 path +=
"/PROOF-INF";
2588 void *dirinf = gSystem->OpenDirectory(path);
2589 const char *afile = 0;
2591 while ((afile = gSystem->GetDirEntry(dirinf))) {
2592 if (strcmp(afile,
".") == 0)
continue;
2593 if (strcmp(afile,
"..") == 0)
continue;
2594 filepath.Form(
"%s/%s", path.Data(), afile);
2595 if (gSystem->Unlink(filepath))
2596 Warning(
"MakeProject",
"1: problems unlinking '%s' ('%s', '%s')", filepath.Data(), path.Data(), afile);
2598 gSystem->FreeDirectory(dirinf);
2600 gSystem->Unlink(path);
2601 path.Form(
"%s/%s", pardir.Data(), parname.Data());
2602 while ((afile = gSystem->GetDirEntry(dirp))) {
2603 if (strcmp(afile,
".") == 0)
continue;
2604 if (strcmp(afile,
"..") == 0)
continue;
2605 filepath.Form(
"%s/%s", path.Data(), afile);
2606 if (gSystem->Unlink(filepath))
2607 Warning(
"MakeProject",
"2: problems unlinking '%s' ('%s', '%s')", filepath.Data(), path.Data(), afile);
2609 gSystem->FreeDirectory(dirp);
2610 if (gSystem->Unlink(path))
2611 Warning(
"MakeProject",
"problems unlinking '%s'", path.Data());
2615 path.Form(
"%s/%s/PROOF-INF", pardir.Data(), parname.Data());
2616 if (gSystem->mkdir(path, kTRUE)) {
2617 Error(
"MakeProject",
"problems creating '%s'", path.Data());
2623 void *dir = gSystem->OpenDirectory(dirname);
2626 if (opt.Contains(
"update")) {
2629 gSystem->mkdir(dirname);
2632 }
else if (opt.Contains(
"recreate")) {
2635 if (gSystem->mkdir(dirname) < 0) {
2636 Error(
"MakeProject",
"cannot create directory '%s'",dirname);
2642 const char *afile = gSystem->GetDirEntry(dir);
2644 if (strcmp(afile,
".") == 0)
continue;
2645 if (strcmp(afile,
"..") == 0)
continue;
2646 dirpath.Form(
"%s/%s",dirname,afile);
2647 gSystem->Unlink(dirpath);
2654 Error(
"MakeProject",
"cannot create directory %s, already existing",dirname);
2655 gSystem->FreeDirectory(dir);
2658 if (gSystem->mkdir(dirname) < 0) {
2659 Error(
"MakeProject",
"cannot create directory '%s'",dirname);
2664 gSystem->FreeDirectory(dir);
2667 Bool_t genreflex = opt.Contains(
"genreflex");
2671 TList *filelist = (TList*)GetStreamerInfoCache();
2672 if (filelist) filelist = (TList*)filelist->Clone();
2674 Error(
"MakeProject",
"file %s has no StreamerInfo", GetName());
2678 TString clean_dirname(dirname);
2679 if (makepar) clean_dirname.Form(
"%s/%s", pardir.Data(), parname.Data());
2680 if (clean_dirname[clean_dirname.Length()-1]==
'/') {
2681 clean_dirname.Remove(clean_dirname.Length()-1);
2682 }
else if (clean_dirname[clean_dirname.Length()-1]==
'\\') {
2683 clean_dirname.Remove(clean_dirname.Length()-1);
2684 if (clean_dirname[clean_dirname.Length()-1]==
'\\') {
2685 clean_dirname.Remove(clean_dirname.Length()-1);
2688 TString subdirname( gSystem->BaseName(clean_dirname) );
2689 if (makepar) subdirname = parname;
2690 if (subdirname ==
"") {
2691 Error(
"MakeProject",
"Directory name must not be empty.");
2696 TString spath; spath.Form(
"%s/%sProjectSource.cxx",clean_dirname.Data(),subdirname.Data());
2697 FILE *sfp = fopen(spath.Data(),
"w");
2699 Error(
"MakeProject",
"Unable to create the source file %s.",spath.Data());
2702 fprintf(sfp,
"namespace std {}\nusing namespace std;\n");
2703 fprintf(sfp,
"#include \"%sProjectHeaders.h\"\n\n",subdirname.Data() );
2704 if (!genreflex) fprintf(sfp,
"#include \"%sLinkDef.h\"\n\n",subdirname.Data() );
2705 fprintf(sfp,
"#include \"%sProjectDict.cxx\"\n\n",subdirname.Data() );
2706 fprintf(sfp,
"struct DeleteObjectFunctor {\n");
2707 fprintf(sfp,
" template <typename T>\n");
2708 fprintf(sfp,
" void operator()(const T *ptr) const {\n");
2709 fprintf(sfp,
" delete ptr;\n");
2710 fprintf(sfp,
" }\n");
2711 fprintf(sfp,
" template <typename T, typename Q>\n");
2712 fprintf(sfp,
" void operator()(const std::pair<T,Q> &) const {\n");
2713 fprintf(sfp,
" // Do nothing\n");
2714 fprintf(sfp,
" }\n");
2715 fprintf(sfp,
" template <typename T, typename Q>\n");
2716 fprintf(sfp,
" void operator()(const std::pair<T,Q*> &ptr) const {\n");
2717 fprintf(sfp,
" delete ptr.second;\n");
2718 fprintf(sfp,
" }\n");
2719 fprintf(sfp,
" template <typename T, typename Q>\n");
2720 fprintf(sfp,
" void operator()(const std::pair<T*,Q> &ptr) const {\n");
2721 fprintf(sfp,
" delete ptr.first;\n");
2722 fprintf(sfp,
" }\n");
2723 fprintf(sfp,
" template <typename T, typename Q>\n");
2724 fprintf(sfp,
" void operator()(const std::pair<T*,Q*> &ptr) const {\n");
2725 fprintf(sfp,
" delete ptr.first;\n");
2726 fprintf(sfp,
" delete ptr.second;\n");
2727 fprintf(sfp,
" }\n");
2728 fprintf(sfp,
"};\n\n");
2734 TStreamerInfo *info;
2735 TIter flnext(filelist);
2737 TList *list =
new TList();
2738 while ((info = (TStreamerInfo*)flnext())) {
2739 if (info->IsA() != TStreamerInfo::Class()) {
2742 if (strstr(info->GetName(),
"@@")) {
2746 TClass *cl = TClass::GetClass(info->GetName());
2748 if (cl->HasInterpreterInfo())
continue;
2751 TMakeProject::GenerateMissingStreamerInfos( &extrainfos, info->GetName() );
2752 TIter enext( info->GetElements() );
2753 TStreamerElement *el;
2754 ROOT::Detail::TSchemaRuleSet::TMatches rules;
2755 if (cl && cl->GetSchemaRules()) {
2756 rules = cl->GetSchemaRules()->FindRules(cl->GetName(), info->GetClassVersion());
2758 while( (el=(TStreamerElement*)enext()) ) {
2759 for(
auto rule : rules) {
2760 if( rule->IsRenameRule() || rule->IsAliasRule() )
2763 if ( rule->HasTarget( el->GetName()) && rule->GetAttributes()[0] != 0 ) {
2764 TString attr( rule->GetAttributes() );
2766 if (attr.Contains(
"owner")) {
2767 if (attr.Contains(
"notowner")) {
2768 el->SetBit(TStreamerElement::kDoNotDelete);
2770 el->ResetBit(TStreamerElement::kDoNotDelete);
2775 TMakeProject::GenerateMissingStreamerInfos(&extrainfos, el);
2777 TVirtualStreamerInfo *alternate = (TVirtualStreamerInfo*)list->FindObject(info->GetName());
2779 if ((info->GetClass() && info->GetClassVersion() == info->GetClass()->GetClassVersion())
2780 || (info->GetClassVersion() > alternate->GetClassVersion()) ) {
2781 list->AddAfter(alternate, info);
2782 list->Remove(alternate);
2790 TIter nextextra(&extrainfos);
2791 while ((info = (TStreamerInfo*)nextextra())) {
2793 filelist->Add(info);
2799 while ((info = (TStreamerInfo*)next())) {
2800 if (info->IsA() != TStreamerInfo::Class()) {
2803 if (info->GetClassVersion()==-4)
continue;
2804 TIter subnext(list);
2805 TStreamerInfo *subinfo;
2807 Int_t len = strlen(info->GetName());
2808 while ((subinfo = (TStreamerInfo*)subnext())) {
2809 if (subinfo->IsA() != TStreamerInfo::Class()) {
2812 if (strncmp(info->GetName(),subinfo->GetName(),len)==0) {
2815 const Int_t sublen = strlen(subinfo->GetName());
2816 if ( (sublen > len) && subinfo->GetName()[len+1]==
':'
2817 && !subClasses.FindObject(subinfo->GetName()) )
2819 subClasses.Add(subinfo);
2823 ngener += info->GenerateHeaderFile(clean_dirname.Data(),&subClasses,&extrainfos);
2824 subClasses.Clear(
"nodelete");
2826 extrainfos.Clear(
"nodelete");
2829 path.Form(
"%s/%sProjectHeaders.h",clean_dirname.Data(),subdirname.Data());
2830 FILE *allfp = fopen(path,
"a");
2832 Error(
"MakeProject",
"Cannot open output file:%s\n",path.Data());
2834 fprintf(allfp,
"#include \"%sProjectInstances.h\"\n", subdirname.Data());
2838 printf(
"MakeProject has generated %d classes in %s\n",ngener,clean_dirname.Data());
2841 if (!opt.Contains(
"+") && !makepar) {
2849 FILE *fpMAKE =
nullptr;
2854 path.Form(
"%s/makep.cmd",clean_dirname.Data());
2856 path.Form(
"%s/MAKEP",clean_dirname.Data());
2859 fpMAKE = fopen(path,
"wb");
2861 fpMAKE = fopen(path,
"w");
2864 Error(
"MakeProject",
"cannot open file %s", path.Data());
2873 FILE *ifp =
nullptr;
2874 path.Form(
"%s/%sProjectInstances.h",clean_dirname.Data(),subdirname.Data());
2876 ifp = fopen(path,
"wb");
2878 ifp = fopen(path,
"w");
2881 Error(
"MakeProject",
"cannot open path file %s", path.Data());
2891 fprintf(fpMAKE,
"genreflex %sProjectHeaders.h -o %sProjectDict.cxx --comments --iocomments %s ",subdirname.Data(),subdirname.Data(),gSystem->GetIncludePath());
2892 path.Form(
"%s/%sSelection.xml",clean_dirname.Data(),subdirname.Data());
2894 fprintf(fpMAKE,
"rootcint -v1 -f %sProjectDict.cxx %s ", subdirname.Data(), gSystem->GetIncludePath());
2895 path.Form(
"%s/%sLinkDef.h",clean_dirname.Data(),subdirname.Data());
2898 path.Form(
"%s/%sLinkDef.h",clean_dirname.Data(),subdirname.Data());
2904 FILE *fp = fopen(path,
"wb");
2906 FILE *fp = fopen(path,
"w");
2909 Error(
"MakeProject",
"cannot open path file %s", path.Data());
2918 fprintf(fp,
"<lcgdict>\n");
2921 fprintf(fp,
"#ifdef __CINT__\n");
2929 while ((info = (TStreamerInfo*)next())) {
2930 if (info->IsA() != TStreamerInfo::Class()) {
2933 if (strncmp(info->GetName(),
"auto_ptr<", strlen(
"auto_ptr<")) == 0) {
2936 TClass *cl = TClass::GetClass(info->GetName());
2938 if (cl->HasInterpreterInfo())
continue;
2939 if (cl->GetSchemaRules()) {
2940 auto rules = cl->GetSchemaRules()->FindRules(cl->GetName(), info->GetClassVersion());
2942 for(
auto rule : rules) {
2945 rule->AsString(strrule,
"x");
2946 strrule.Append(
"\n");
2947 if ( selections.Index(strrule) == kNPOS ) {
2948 selections.Append(strrule);
2951 rule->AsString(strrule);
2952 if (strncmp(strrule.Data(),
"type=",5)==0) {
2953 strrule.Remove(0,5);
2955 fprintf(fp,
"#pragma %s;\n",strrule.Data());
2961 if ((info->GetClass() && info->GetClass()->GetCollectionType()) || TClassEdit::IsSTLCont(info->GetName())) {
2962 std::vector<std::string> inside;
2964 TClassEdit::GetSplit( info->GetName(), inside, nestedLoc, TClassEdit::kLong64 );
2965 Int_t stlkind = TClassEdit::STLKind(inside[0]);
2966 TClass *key = TClass::GetClass(inside[1].c_str());
2969 switch ( stlkind ) {
2971 case ROOT::kSTLmultimap:
2972 if (TClass::GetClass(inside[1].c_str())) {
2973 what =
"std::pair<";
2974 what += TMakeProject::UpdateAssociativeToVector( inside[1].c_str() );
2976 what += TMakeProject::UpdateAssociativeToVector( inside[2].c_str() );
2977 if (what[what.Length()-1]==
'>') {
2983 tmp.Form(
"<class name=\"%s\" />\n",what.Data());
2984 if ( selections.Index(tmp) == kNPOS ) {
2985 selections.Append(tmp);
2987 tmp.Form(
"template class %s;\n",what.Data());
2988 if ( instances.Index(tmp) == kNPOS ) {
2989 instances.Append(tmp);
2992 what.ReplaceAll(
"std::",
"");
2993 TClass *paircl = TClass::GetClass(what.Data());
2994 if (!paircl || !paircl->HasInterpreterInfo()) {
2995 fprintf(fp,
"#pragma link C++ class %s+;\n",what.Data());
3001 if (strncmp(key->GetName(),
"pair<",strlen(
"pair<"))==0) {
3003 tmp.Form(
"<class name=\"%s\" />\n",key->GetName());
3004 if ( selections.Index(tmp) == kNPOS ) {
3005 selections.Append(tmp);
3007 tmp.Form(
"template class %s;\n",key->GetName());
3008 if ( instances.Index(tmp) == kNPOS ) {
3009 instances.Append(tmp);
3012 what.ReplaceAll(
"std::",
"");
3013 fprintf(fp,
"#pragma link C++ class %s+;\n",key->GetName());
3022 TString what(TMakeProject::UpdateAssociativeToVector(info->GetName()).Data());
3024 tmp.Form(
"<class name=\"%s\" />\n",what.Data());
3025 if ( selections.Index(tmp) == kNPOS ) {
3026 selections.Append(tmp);
3028 if (what[what.Length()-1] ==
'>') {
3029 tmp.Form(
"template class %s;\n",what.Data());
3030 if ( instances.Index(tmp) == kNPOS ) {
3031 instances.Append(tmp);
3035 what.ReplaceAll(
"std::",
"");
3036 fprintf(fp,
"#pragma link C++ class %s+;\n",what.Data());
3041 TIter eliter( info->GetElements() );
3042 TStreamerElement *element;
3043 while( (element = (TStreamerElement*)eliter() ) ) {
3044 if (element->GetClass() && !element->GetClass()->IsLoaded() && element->GetClass()->GetCollectionProxy()) {
3045 TString what( TMakeProject::UpdateAssociativeToVector(element->GetClass()->GetName()) );
3046 tmp.Form(
"<class name=\"%s\" />\n",what.Data());
3047 if ( selections.Index(tmp) == kNPOS ) {
3048 selections.Append(tmp);
3050 tmp.Form(
"template class %s;\n",what.Data());
3051 if ( instances.Index(tmp) == kNPOS ) {
3052 instances.Append(tmp);
3059 fprintf(ifp,
"#ifndef PROJECT_INSTANCES_H\n");
3060 fprintf(ifp,
"#define PROJECT_INSTANCES_H\n");
3061 fprintf(ifp,
"%s",instances.Data());
3062 fprintf(ifp,
"#endif\n");
3063 fprintf(fp,
"%s",selections.Data());
3064 fprintf(fp,
"</lcgdict>\n");
3066 fprintf(fp,
"#endif\n");
3073 TString sdirname(subdirname);
3075 TString cmd = gSystem->GetMakeSharedLib();
3076 TString sources = TString::Format(
"%sProjectSource.cxx ", sdirname.Data());
3077 cmd.ReplaceAll(
"$SourceFiles",sources.Data());
3078 TString
object = TString::Format(
"%sProjectSource.", sdirname.Data());
3079 object.Append( gSystem->GetObjExt() );
3080 cmd.ReplaceAll(
"$ObjectFiles",
object.Data());
3081 cmd.ReplaceAll(
"$IncludePath",TString(gSystem->GetIncludePath()) +
" -I" + clean_dirname.Data());
3082 cmd.ReplaceAll(
"$SharedLib",sdirname+
"."+gSystem->GetSoExt());
3083 cmd.ReplaceAll(
"$LinkedLibs",gSystem->GetLibraries(
"",
"SDL"));
3084 cmd.ReplaceAll(
"$LibName",sdirname);
3085 cmd.ReplaceAll(
"$BuildDir",
".");
3087 TString rootbuild = ROOTBUILD;
3088 if (rootbuild.Index(
"debug",0,TString::kIgnoreCase)==kNPOS) {
3089 sOpt = gSystem->GetFlagsOpt();
3091 sOpt = gSystem->GetFlagsDebug();
3093 cmd.ReplaceAll(
"$Opt", sOpt);
3096 fprintf(fpMAKE,
"-s %sSelection.xml \n",subdirname.Data());
3098 fprintf(fpMAKE,
"%sProjectHeaders.h ",subdirname.Data());
3099 fprintf(fpMAKE,
"%sLinkDef.h \n",subdirname.Data());
3102 fprintf(fpMAKE,
"%s\n",cmd.Data());
3104 printf(
"%s/MAKEP file has been generated\n", clean_dirname.Data());
3111 TString filemake = TString::Format(
"%s/Makefile", clean_dirname.Data());
3112 if (MakeProjectParMake(parname, filemake.Data()) != 0) {
3113 Error(
"MakeProject",
"problems creating PAR make file '%s'", filemake.Data());
3120 TString mkarchsrc = TString::Format(
"%s/Makefile.arch", TROOT::GetEtcDir().Data());
3121 if (gSystem->ExpandPathName(mkarchsrc))
3122 Warning(
"MakeProject",
"problems expanding '%s'", mkarchsrc.Data());
3123 TString mkarchdst = TString::Format(
"%s/Makefile.arch", clean_dirname.Data());
3124 if (gSystem->CopyFile(mkarchsrc.Data(), mkarchdst.Data(), kTRUE) != 0) {
3125 Error(
"MakeProject",
"problems retrieving '%s' to '%s'", mkarchsrc.Data(), mkarchdst.Data());
3132 TString proofinf = TString::Format(
"%s/PROOF-INF", clean_dirname.Data());
3133 if (MakeProjectParProofInf(parname, proofinf.Data()) != 0) {
3134 Error(
"MakeProject",
"problems creating BUILD.sh and/or SETUP.C under '%s'", proofinf.Data());
3142 TString cmod = TString::Format(
"chmod +x %s/PROOF-INF/BUILD.sh", clean_dirname.Data());
3144 gSystem->Exec(cmod.Data());
3147 chmod(cmod.Data(), 00700);
3149 Printf(
"Files Makefile, Makefile.arch, PROOF-INF/BUILD.sh and"
3150 " PROOF-INF/SETUP.C have been generated under '%s'", clean_dirname.Data());
3154 TString curdir = gSystem->WorkingDirectory();
3155 if (gSystem->ChangeDirectory(pardir)) {
3156 TString cmd = TString::Format(
"tar czvf %s.par %s", parname.Data(), parname.Data());
3157 gSystem->Exec(cmd.Data());
3158 if (gSystem->ChangeDirectory(curdir)) {
3159 Info(
"MakeProject",
"PAR file %s.par generated", clean_dirname.Data());
3161 Warning(
"MakeProject",
"problems changing directory back to '%s'", curdir.Data());
3164 Error(
"MakeProject",
"problems changing directory to '%s' - skipping PAR file generation", pardir.Data());
3167 Warning(
"MakeProject",
"on Windows systems the PAR file cannot be generated out of the package directory!");
3172 if (!makepar && !opt.Contains(
"nocompilation")) {
3174 path = gSystem->WorkingDirectory();
3175 gSystem->ChangeDirectory(clean_dirname.Data());
3177 gSystem->Exec(
"chmod +x MAKEP");
3178 int res = !gSystem->Exec(
"./MAKEP");
3181 chmod(
"makep.cmd",00700);
3182 int res = !gSystem->Exec(
"MAKEP");
3184 gSystem->ChangeDirectory(path);
3185 path.Form(
"%s/%s.%s",clean_dirname.Data(),subdirname.Data(),gSystem->GetSoExt());
3186 if (res) printf(
"Shared lib %s has been generated\n",path.Data());
3189 if (opt.Contains(
"++")) {
3190 res = !gSystem->Load(path);
3191 if (res) printf(
"Shared lib %s has been dynamically linked\n",path.Data());
3206 Int_t TFile::MakeProjectParMake(
const char *pack,
const char *filemake)
3209 if (!filemake || (filemake && strlen(filemake) <= 0)) {
3210 Error(
"MakeProjectParMake",
"path for output file undefined!");
3215 if (!pack || (pack && strlen(pack) <= 0)) {
3216 Error(
"MakeProjectParMake",
"package name undefined!");
3221 FILE *fmk = fopen(filemake,
"wb");
3223 FILE *fmk = fopen(filemake,
"w");
3226 Error(
"MakeProjectParMake",
"cannot create file '%s' (errno: %d)", filemake, TSystem::GetErrno());
3231 fprintf(fmk,
"# Makefile for the ROOT test programs.\n");
3232 fprintf(fmk,
"# This Makefile shows how to compile and link applications\n");
3233 fprintf(fmk,
"# using the ROOT libraries on all supported platforms.\n");
3234 fprintf(fmk,
"#\n");
3235 fprintf(fmk,
"# Copyright (c) 2000 Rene Brun and Fons Rademakers\n");
3236 fprintf(fmk,
"#\n");
3237 fprintf(fmk,
"# Author: this makefile has been automatically generated via TFile::MakeProject\n");
3239 fprintf(fmk,
"include Makefile.arch\n");
3241 fprintf(fmk,
"#------------------------------------------------------------------------------\n");
3243 fprintf(fmk,
"PACKO = %sProjectSource.$(ObjSuf)\n", pack);
3244 fprintf(fmk,
"PACKS = %sProjectSource.$(SrcSuf) %sProjectDict.$(SrcSuf)\n", pack, pack);
3245 fprintf(fmk,
"PACKSO = lib%s.$(DllSuf)\n", pack);
3247 fprintf(fmk,
"ifeq ($(PLATFORM),win32)\n");
3248 fprintf(fmk,
"PACKLIB = lib%s.lib\n", pack);
3249 fprintf(fmk,
"else\n");
3250 fprintf(fmk,
"PACKLIB = $(PACKSO)\n");
3251 fprintf(fmk,
"endif\n");
3253 fprintf(fmk,
"OBJS = $(PACKO)\n");
3255 fprintf(fmk,
"PROGRAMS =\n");
3257 fprintf(fmk,
"#------------------------------------------------------------------------------\n");
3259 fprintf(fmk,
".SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)\n");
3261 fprintf(fmk,
"all: $(PACKLIB)\n");
3263 fprintf(fmk,
"$(PACKSO): $(PACKO)\n");
3264 fprintf(fmk,
"ifeq ($(ARCH),aix)\n");
3265 fprintf(fmk,
"\t\t/usr/ibmcxx/bin/makeC++SharedLib $(OutPutOpt) $@ $(LIBS) -p 0 $^\n");
3266 fprintf(fmk,
"else\n");
3267 fprintf(fmk,
"ifeq ($(ARCH),aix5)\n");
3268 fprintf(fmk,
"\t\t/usr/vacpp/bin/makeC++SharedLib $(OutPutOpt) $@ $(LIBS) -p 0 $^\n");
3269 fprintf(fmk,
"else\n");
3270 fprintf(fmk,
"ifeq ($(PLATFORM),macosx)\n");
3271 fprintf(fmk,
"# We need to make both the .dylib and the .so\n");
3272 fprintf(fmk,
"\t\t$(LD) $(SOFLAGS)$@ $(LDFLAGS) $^ $(OutPutOpt) $@ $(LIBS)\n");
3273 fprintf(fmk,
"ifneq ($(subst $(MACOSX_MINOR),,1234),1234)\n");
3274 fprintf(fmk,
"ifeq ($(MACOSX_MINOR),4)\n");
3275 fprintf(fmk,
"\t\tln -sf $@ $(subst .$(DllSuf),.so,$@)\n");
3276 fprintf(fmk,
"else\n");
3277 fprintf(fmk,
"\t\t$(LD) -bundle -undefined $(UNDEFOPT) $(LDFLAGS) $^ \\\n");
3278 fprintf(fmk,
"\t\t $(OutPutOpt) $(subst .$(DllSuf),.so,$@)\n");
3279 fprintf(fmk,
"endif\n");
3280 fprintf(fmk,
"endif\n");
3281 fprintf(fmk,
"else\n");
3282 fprintf(fmk,
"ifeq ($(PLATFORM),win32)\n");
3283 fprintf(fmk,
"\t\tbindexplib $* $^ > $*.def\n");
3284 fprintf(fmk,
"\t\tlib -nologo -MACHINE:IX86 $^ -def:$*.def \\\n");
3285 fprintf(fmk,
"\t\t $(OutPutOpt)$(PACKLIB)\n");
3286 fprintf(fmk,
"\t\t$(LD) $(SOFLAGS) $(LDFLAGS) $^ $*.exp $(LIBS) \\\n");
3287 fprintf(fmk,
"\t\t $(OutPutOpt)$@\n");
3288 fprintf(fmk,
"else\n");
3289 fprintf(fmk,
"\t\t$(LD) $(SOFLAGS) $(LDFLAGS) $^ $(OutPutOpt) $@ $(LIBS) $(EXPLLINKLIBS)\n");
3290 fprintf(fmk,
"endif\n");
3291 fprintf(fmk,
"endif\n");
3292 fprintf(fmk,
"endif\n");
3293 fprintf(fmk,
"endif\n");
3294 fprintf(fmk,
"\t\t@echo \"$@ done\"\n");
3296 fprintf(fmk,
"clean:\n");
3297 fprintf(fmk,
"\t\t@rm -f $(OBJS) core\n");
3299 fprintf(fmk,
"distclean: clean\n");
3300 fprintf(fmk,
"\t\t@rm -f $(PROGRAMS) $(PACKSO) $(PACKLIB) *Dict.* *.def *.exp \\\n");
3301 fprintf(fmk,
"\t\t *.so *.lib *.dll *.d *.log .def so_locations\n");
3302 fprintf(fmk,
"\t\t@rm -rf cxx_repository\n");
3304 fprintf(fmk,
"# Dependencies\n");
3306 fprintf(fmk,
"%sProjectSource.$(ObjSuf): %sProjectHeaders.h %sLinkDef.h %sProjectDict.$(SrcSuf)\n", pack, pack, pack, pack);
3308 fprintf(fmk,
"%sProjectDict.$(SrcSuf): %sProjectHeaders.h %sLinkDef.h\n", pack, pack, pack);
3309 fprintf(fmk,
"\t\t@echo \"Generating dictionary $@...\"\n");
3310 fprintf(fmk,
"\t\t@rootcint -f $@ $^\n");
3312 fprintf(fmk,
".$(SrcSuf).$(ObjSuf):\n");
3313 fprintf(fmk,
"\t\t$(CXX) $(CXXFLAGS) -c $<\n");
3328 Int_t TFile::MakeProjectParProofInf(
const char *pack,
const char *proofinf)
3331 if (!proofinf || (proofinf && strlen(proofinf) <= 0)) {
3332 Error(
"MakeProjectParProofInf",
"directory path undefined!");
3339 if ((rcst = gSystem->GetPathInfo(proofinf, st)) != 0 || !R_ISDIR(st.fMode)) {
3340 Error(
"MakeProjectParProofInf",
"path '%s' %s", proofinf,
3341 ((rcst == 0) ?
"is not a directory" :
"does not exist"));
3346 if (!pack || (pack && strlen(pack) <= 0)) {
3347 Error(
"MakeProjectParProofInf",
"package name undefined!");
3354 path.Form(
"%s/BUILD.sh", proofinf);
3356 FILE *f = fopen(path.Data(),
"wb");
3358 FILE *f = fopen(path.Data(),
"w");
3361 Error(
"MakeProjectParProofInf",
"cannot create file '%s' (errno: %d)",
3362 path.Data(), TSystem::GetErrno());
3366 fprintf(f,
"#! /bin/sh\n");
3367 fprintf(f,
"# Build libEvent library.\n");
3370 fprintf(f,
"# The environment variables ROOTPROOFLITE and ROOTPROOFCLIENT can be used to\n");
3371 fprintf(f,
"# adapt the script to the calling environment\n");
3373 fprintf(f,
"# if test ! \"x$ROOTPROOFLITE\" = \"x\"; then\n");
3374 fprintf(f,
"# echo \"event-BUILD: PROOF-Lite node (session has $ROOTPROOFLITE workers)\"\n");
3375 fprintf(f,
"# elif test ! \"x$ROOTPROOFCLIENT\" = \"x\"; then\n");
3376 fprintf(f,
"# echo \"event-BUILD: PROOF client\"\n");
3377 fprintf(f,
"# else\n");
3378 fprintf(f,
"# echo \"event-BUILD: standard PROOF node\"\n");
3379 fprintf(f,
"# fi\n");
3381 fprintf(f,
"if [ \"\" = \"clean\" ]; then\n");
3382 fprintf(f,
" make distclean\n");
3383 fprintf(f,
" exit 0\n");
3386 fprintf(f,
"make\n");
3387 fprintf(f,
"rc=$?\n");
3388 fprintf(f,
"echo \"rc=$?\"\n");
3389 fprintf(f,
"if [ $? != \"0\" ] ; then\n");
3390 fprintf(f,
" exit 1\n");
3392 fprintf(f,
"exit 0\n");
3398 path.Form(
"%s/SETUP.C", proofinf);
3400 f = fopen(path.Data(),
"wb");
3402 f = fopen(path.Data(),
"w");
3405 Error(
"MakeProjectParProofInf",
"cannot create file '%s' (errno: %d)",
3406 path.Data(), TSystem::GetErrno());
3410 fprintf(f,
"Int_t SETUP()\n");
3414 fprintf(f,
"// The environment variables ROOTPROOFLITE and ROOTPROOFCLIENT can be used to\n");
3415 fprintf(f,
"// adapt the macro to the calling environment\n");
3417 fprintf(f,
"// if (gSystem->Getenv(\"ROOTPROOFLITE\")) {\n");
3418 fprintf(f,
"// Printf(\"event-SETUP: PROOF-Lite node (session has %%s workers)\",\n");
3419 fprintf(f,
"// gSystem->Getenv(\"ROOTPROOFLITE\"));\n");
3420 fprintf(f,
"// } else if (gSystem->Getenv(\"ROOTPROOFCLIENT\")) {\n");
3421 fprintf(f,
"// Printf(\"event-SETUP: PROOF client\");\n");
3422 fprintf(f,
"// } else {\n");
3423 fprintf(f,
"// Printf(\"event-SETUP: standard PROOF node\");\n");
3424 fprintf(f,
"// }\n");
3426 fprintf(f,
" if (gSystem->Load(\"lib%s\") == -1)\n", pack);
3427 fprintf(f,
" return -1;\n");
3428 fprintf(f,
" return 0;\n");
3447 void TFile::ReadStreamerInfo()
3449 auto listRetcode = GetStreamerInfoListImpl(
true);
3450 TList *list = listRetcode.fList;
3451 auto retcode = listRetcode.fReturnCode;
3453 if (retcode) MakeZombie();
3457 list->SetOwner(kFALSE);
3459 if (gDebug > 0) Info(
"ReadStreamerInfo",
"called for file %s",GetName());
3461 TStreamerInfo *info;
3463 Int_t version = fVersion;
3464 if (version > 1000000) version -= 1000000;
3465 if (version < 53419 || (59900 < version && version < 59907)) {
3469 TObjLink *lnk = list->FirstLink();
3471 info = (TStreamerInfo*)lnk->GetObject();
3472 if (!info || info->IsA() != TStreamerInfo::Class()) {
3476 TIter next(info->GetElements());
3477 TStreamerElement *element;
3478 while ((element = (TStreamerElement*) next())) {
3479 TStreamerBase *base =
dynamic_cast<TStreamerBase*
>(element);
3480 if (!base)
continue;
3481 if (base->GetBaseCheckSum() != 0)
continue;
3482 TStreamerInfo *baseinfo = (TStreamerInfo*)list->FindObject(base->GetName());
3484 base->SetBaseCheckSum(baseinfo->GetCheckSum());
3492 for (
int mode=0;mode<2; ++mode) {
3495 TObjLink *lnk = list->FirstLink();
3497 info = (TStreamerInfo*)lnk->GetObject();
3502 if (info->IsA() != TStreamerInfo::Class()) {
3504 TObject *obj = (TObject*)info;
3505 if (strcmp(obj->GetName(),
"listOfRules")==0) {
3508 TList *listOfRules = (TList*)obj;
3509 TObjLink *rulelnk = listOfRules->FirstLink();
3511 TObjString *rule = (TObjString*)rulelnk->GetObject();
3512 TClass::AddRule( rule->String().Data() );
3513 rulelnk = rulelnk->Next();
3517 Warning(
"ReadStreamerInfo",
"%s has a %s in the list of TStreamerInfo.", GetName(), info->IsA()->GetName());
3519 info->SetBit(kCanDelete);
3526 if (info->GetElements()==0) {
3527 Warning(
"ReadStreamerInfo",
"The StreamerInfo for %s does not have a list of elements.",info->GetName());
3531 TObject *element = info->GetElements()->UncheckedAt(0);
3532 Bool_t isstl = element && strcmp(
"This",element->GetName())==0;
3534 if ( (!isstl && mode ==0) || (isstl && mode ==1) ) {
3537 info->BuildCheck(
this);
3538 Int_t uid = info->GetNumber();
3539 Int_t asize = fClassIndex->GetSize();
3540 if (uid >= asize && uid <100000) fClassIndex->Set(2*asize);
3541 if (uid >= 0 && uid < fClassIndex->GetSize()) fClassIndex->fArray[uid] = 1;
3543 printf(
"ReadStreamerInfo, class:%s, illegal uid=%d\n",info->GetName(),uid);
3545 if (gDebug > 0) printf(
" -class: %s version: %d info read at slot %d\n",info->GetName(), info->GetClassVersion(),uid);
3550 fClassIndex->fArray[0] = 0;
3557 fgTsSIHashes.Insert(listRetcode.fHash);
3572 void TFile::SetReadStreamerInfo(Bool_t readinfo)
3574 fgReadInfo = readinfo;
3582 Bool_t TFile::GetReadStreamerInfo()
3590 void TFile::ShowStreamerInfo()
3592 TList *list = GetStreamerInfoList();
3603 UShort_t TFile::WriteProcessID(TProcessID *pidd)
3605 TProcessID *pid = pidd;
3606 if (!pid) pid = TProcessID::GetPID();
3607 TObjArray *pids = GetListOfProcessIDs();
3608 Int_t npids = GetNProcessIDs();
3609 for (Int_t i=0;i<npids;i++) {
3610 if (pids->At(i) == pid)
return (UShort_t)i;
3613 this->SetBit(TFile::kHasReferences);
3614 pids->AddAtAndExpand(pid,npids);
3615 pid->IncrementCount();
3617 snprintf(name,32,
"ProcessID%d",npids);
3618 this->WriteTObject(pid,name);
3619 this->IncrementProcessIDs();
3621 Info(
"WriteProcessID",
"name=%s, file=%s", name, GetName());
3623 return (UShort_t)npids;
3632 void TFile::WriteStreamerInfo()
3635 if (!fWritable)
return;
3636 if (!fClassIndex)
return;
3637 if (fIsPcmFile)
return;
3638 if (fClassIndex->fArray[0] == 0
3639 && fSeekInfo != 0) {
3645 if (gDebug > 0) Info(
"WriteStreamerInfo",
"called for file %s",GetName());
3647 SafeDelete(fInfoCache);
3650 TIter next(gROOT->GetListOfStreamerInfo());
3651 TStreamerInfo *info;
3654 listOfRules.SetOwner(kTRUE);
3655 listOfRules.SetName(
"listOfRules");
3656 std::set<TClass*> classSet;
3659 while ((info = (TStreamerInfo*)next())) {
3660 Int_t uid = info->GetNumber();
3661 if (fClassIndex->fArray[uid]) {
3663 if (gDebug > 0) printf(
" -class: %s info number %d saved\n",info->GetName(),uid);
3667 TClass *clinfo = info->GetClass();
3668 if (clinfo && clinfo->GetSchemaRules()) {
3669 if ( classSet.find( clinfo ) == classSet.end() ) {
3670 if (gDebug > 0) printf(
" -class: %s stored the I/O customization rules\n",info->GetName());
3672 TObjArrayIter it( clinfo->GetSchemaRules()->GetRules() );
3673 ROOT::TSchemaRule *rule;
3674 while( (rule = (ROOT::TSchemaRule*)it.Next()) ) {
3675 TObjString *obj =
new TObjString();
3676 rule->AsString(obj->String());
3677 listOfRules.Add(obj);
3679 classSet.insert(clinfo);
3686 fClassIndex->fArray[0] = 2;
3688 if (listOfRules.GetEntries()) {
3690 list.Add(&listOfRules);
3694 if (fSeekInfo) MakeFree(fSeekInfo,fSeekInfo+fNbytesInfo-1);
3696 TKey key(&list,
"StreamerInfo",GetBestBuffer(),
this);
3697 fKeys->Remove(&key);
3698 fSeekInfo = key.GetSeekKey();
3699 fNbytesInfo = key.GetNbytes();
3700 SumBuffer(key.GetObjlen());
3703 fClassIndex->fArray[0] = 0;
3715 TFile *TFile::OpenFromCache(
const char *name, Option_t *,
const char *ftitle,
3716 Int_t compress, Int_t netopt)
3720 if (fgCacheFileDir ==
"") {
3721 ::Warning(
"TFile::OpenFromCache",
3722 "you want to read through a cache, but you have no valid cache "
3723 "directory set - reading remotely");
3724 ::Info(
"TFile::OpenFromCache",
"set cache directory using TFile::SetCacheFileDir()");
3729 if ((!strcmp(fileurl.GetProtocol(),
"file"))) {
3731 if (!fgCacheFileForce)
3732 ::Warning(
"TFile::OpenFromCache",
3733 "you want to read through a cache, but you are reading "
3734 "local files - CACHEREAD disabled");
3738 TString cachefilepath;
3739 TString cachefilepathbasedir;
3740 cachefilepath = fgCacheFileDir;
3741 cachefilepath += fileurl.GetFile();
3742 cachefilepathbasedir = gSystem->DirName(cachefilepath);
3743 if ((gSystem->mkdir(cachefilepathbasedir, kTRUE) < 0) &&
3744 (gSystem->AccessPathName(cachefilepathbasedir, kFileExists))) {
3745 ::Warning(
"TFile::OpenFromCache",
"you want to read through a cache, but I "
3746 "cannot create the directory %s - CACHEREAD disabled",
3747 cachefilepathbasedir.Data());
3750 if (strlen(fileurl.GetAnchor())) {
3752 cachefilepath +=
"__";
3753 cachefilepath += fileurl.GetAnchor();
3754 fileurl.SetAnchor(
"");
3756 if (strstr(name,
"zip=")) {
3758 TString urloptions = fileurl.GetOptions();
3760 TObjArray *objOptions = urloptions.Tokenize(
"&");
3761 Int_t optioncount = 0;
3763 for (Int_t n = 0; n < objOptions->GetEntries(); n++) {
3764 TString loption = ((TObjString*)objOptions->At(n))->GetName();
3765 TObjArray *objTags = loption.Tokenize(
"=");
3766 if (objTags->GetEntries() == 2) {
3767 TString key = ((TObjString*)objTags->At(0))->GetName();
3768 TString value = ((TObjString*)objTags->At(1))->GetName();
3769 if (key.CompareTo(
"zip", TString::kIgnoreCase)) {
3770 if (optioncount!=0) {
3775 newoptions += value;
3784 fileurl.SetOptions(newoptions.Data());
3785 cachefilepath +=
"__";
3786 cachefilepath += zipname;
3787 fileurl.SetAnchor(
"");
3790 Bool_t need2copy = kFALSE;
3797 if (!gSystem->GetPathInfo(cachefilepath, &
id, &size, &flags, &modtime)) {
3799 if (!fgCacheFileDisconnected) {
3800 char cacheblock[256];
3801 char remotblock[256];
3804 cfurl = cachefilepath;
3805 cfurl +=
"?filetype=raw";
3807 TString ropt = rurl.GetOptions();
3808 ropt +=
"&filetype=raw";
3809 rurl.SetOptions(ropt);
3811 Bool_t forcedcache = fgCacheFileForce;
3812 fgCacheFileForce = kFALSE;
3814 TFile *cachefile = TFile::Open(cfurl,
"READ");
3815 TFile *remotfile = TFile::Open(rurl.GetUrl(),
"READ");
3817 fgCacheFileForce = forcedcache;
3821 ::Error(
"TFile::OpenFromCache",
3822 "cannot open the cache file to check cache consistency");
3827 ::Error(
"TFile::OpenFromCache",
3828 "cannot open the remote file to check cache consistency");
3835 if ((!cachefile->ReadBuffer(cacheblock,256)) &&
3836 (!remotfile->ReadBuffer(remotblock,256))) {
3837 if (memcmp(cacheblock, remotblock, 256)) {
3838 ::Warning(
"TFile::OpenFromCache",
"the header of the cache file "
3839 "differs from the remote file - forcing an update");
3843 ::Warning(
"TFile::OpenFromCache",
"the header of the cache and/or "
3844 "remote file are not readable - forcing an update");
3856 Bool_t forcedcache = fgCacheFileForce;
3857 fgCacheFileForce = kFALSE;
3858 if (need2copy && !TFile::Cp(name, cachefilepath)) {
3859 ::Warning(
"TFile::OpenFromCache",
"you want to read through a cache, but I "
3860 "cannot make a cache copy of %s - CACHEREAD disabled",
3861 cachefilepathbasedir.Data());
3862 fgCacheFileForce = forcedcache;
3863 if (fgOpenTimeout != 0)
3866 fgCacheFileForce = forcedcache;
3867 ::Info(
"TFile::OpenFromCache",
"using local cache copy of %s [%s]",
3868 name, cachefilepath.Data());
3870 fileurl.SetProtocol(
"file");
3871 fileurl.SetFile(cachefilepath);
3875 tagfile = cachefilepath;
3876 tagfile +=
".ROOT.cachefile";
3877 tagurl.SetFile(tagfile);
3879 gSystem->Symlink(gSystem->BaseName(cachefilepath), tagfile);
3880 return TFile::Open(fileurl.GetUrl(),
"READ", ftitle, compress, netopt);
3924 TFile *TFile::Open(
const char *url, Option_t *options,
const char *ftitle,
3925 Int_t compress, Int_t netopt)
3929 EFileType type = kFile;
3932 if (!url || strlen(url) <= 0) {
3933 ::Error(
"TFile::Open",
"no url specified");
3937 TString expandedUrl(url);
3938 gSystem->ExpandPathName(expandedUrl);
3943 TString opts(options);
3944 Int_t ito = opts.Index(
"TIMEOUT=");
3946 TString sto = opts(ito + strlen(
"TIMEOUT="), opts.Length());
3947 while (!(sto.IsDigit()) && !(sto.IsNull())) { sto.Remove(sto.Length()-1,1); }
3948 if (!(sto.IsNull())) {
3950 Int_t toms = sto.Atoi() * 1000;
3951 if (gDebug > 0) ::Info(
"TFile::Open",
"timeout of %d millisec requested", toms);
3953 sto.Insert(0,
"TIMEOUT=");
3954 opts.ReplaceAll(sto,
"");
3956 TFileOpenHandle *fh = TFile::AsyncOpen(expandedUrl, opts, ftitle, compress, netopt);
3958 TFile::EAsyncOpenStatus aos = TFile::kAOSNotAsync;
3959 aos = TFile::GetAsyncOpenStatus(fh);
3961 while (aos == TFile::kAOSInProgress && xtms > 0) {
3964 aos = TFile::GetAsyncOpenStatus(fh);
3966 if (aos == TFile::kAOSNotAsync || aos == TFile::kAOSSuccess) {
3968 f = TFile::Open(fh);
3970 if (aos == TFile::kAOSSuccess)
3971 ::Info(
"TFile::Open",
"waited %d millisec for asynchronous open", toms - xtms);
3973 ::Info(
"TFile::Open",
"timeout option not supported (requires asynchronous"
3978 ::Error(
"TFile::Open",
"timeout expired while opening '%s'", expandedUrl.Data());
3985 ::Warning(
"TFile::Open",
"incomplete 'TIMEOUT=' option specification - ignored");
3986 opts.ReplaceAll(
"TIMEOUT=",
"");
3991 const char *option = opts;
3994 TString namelist(expandedUrl);
3995 Ssiz_t ip = namelist.Index(
"|");
3996 Bool_t rediroutput = (ip != kNPOS &&
3997 ip != namelist.Length()-1 && gDebug <= 0) ? kTRUE : kFALSE;
3998 RedirectHandle_t rh;
4000 TString outf =
".TFileOpen_";
4001 FILE *fout = gSystem->TempFileName(outf);
4004 gSystem->RedirectOutput(outf,
"w", &rh);
4011 while (namelist.Tokenize(n, from,
"|") && !f) {
4014 if (!strcasecmp(option,
"CACHEREAD") ||
4015 ((!strcasecmp(option,
"READ") || !option[0]) && fgCacheFileForce)) {
4017 if ((f = TFile::OpenFromCache(n, option, ftitle, compress, netopt)))
4021 IncrementFileCounter();
4025 TUrl urlname(n, kTRUE);
4026 name = urlname.GetUrl();
4028 if (fgAsyncOpenRequests && (fgAsyncOpenRequests->GetSize() > 0)) {
4029 TIter nxr(fgAsyncOpenRequests);
4030 TFileOpenHandle *fh =
nullptr;
4031 while ((fh = (TFileOpenHandle *)nxr()))
4032 if (fh->Matches(name))
4033 return TFile::Open(fh);
4036 TString urlOptions(urlname.GetOptions());
4037 if (urlOptions.BeginsWith(
"pmerge") || urlOptions.Contains(
"&pmerge") || urlOptions.Contains(
" pmerge")) {
4041 f = (TFile*) gROOT->ProcessLineFast(TString::Format(
"new TParallelMergingFile(\"%s\",\"%s\",\"%s\",%d)",n.Data(),option,ftitle,compress));
4045 TString lfname = gEnv->GetValue(
"Path.Localroot",
"");
4046 type = GetType(name, option, &lfname);
4048 if (type == kLocal) {
4051 if (lfname.IsNull()) {
4052 urlname.SetHost(
"");
4053 urlname.SetProtocol(
"file");
4054 lfname = urlname.GetUrl();
4056 f =
new TFile(lfname.Data(), option, ftitle, compress);
4058 }
else if (type == kNet) {
4061 if ((h = gROOT->GetPluginManager()->FindHandler(
"TFile", name))) {
4062 if (h->LoadPlugin() == -1)
4064 f = (TFile*) h->ExecPlugin(5, name.Data(), option, ftitle, compress, netopt);
4067 }
else if (type == kWeb) {
4070 if ((h = gROOT->GetPluginManager()->FindHandler(
"TFile", name))) {
4071 if (h->LoadPlugin() == -1)
4073 f = (TFile*) h->ExecPlugin(2, name.Data(), option);
4076 }
else if (type == kFile) {
4079 if ((h = gROOT->GetPluginManager()->FindHandler(
"TFile", name)) &&
4080 h->LoadPlugin() == 0) {
4081 name.ReplaceAll(
"file:",
"");
4082 f = (TFile*) h->ExecPlugin(4, name.Data(), option, ftitle, compress);
4084 f =
new TFile(name.Data(), option, ftitle, compress);
4089 if ((h = gROOT->GetPluginManager()->FindHandler(
"TFile", name.Data()))) {
4090 if (h->LoadPlugin() == -1)
4092 TClass *cl = TClass::GetClass(h->GetClass());
4093 if (cl && cl->InheritsFrom(
"TNetFile"))
4094 f = (TFile*) h->ExecPlugin(5, name.Data(), option, ftitle, compress, netopt);
4096 f = (TFile*) h->ExecPlugin(4, name.Data(), option, ftitle, compress);
4100 f = TFile::Open(urlname.GetFileAndOptions(), option, ftitle, compress);
4105 if (f && f->IsZombie()) {
4106 TString newUrl = f->GetNewUrl();
4108 if( newUrl.Length() && gEnv->GetValue(
"TFile.CrossProtocolRedirects", 1) )
4109 f = TFile::Open( newUrl, option, ftitle, compress );
4117 gSystem->RedirectOutput(0,
"", &rh);
4120 gSystem->ShowOutput(&rh);
4122 gSystem->Unlink(rh.fFile);
4127 if (type != kLocal && type != kFile &&
4128 f && f->IsWritable() && !f->IsRaw()) {
4129 new TFileCacheWrite(f, 1);
4162 TFileOpenHandle *TFile::AsyncOpen(
const char *url, Option_t *option,
4163 const char *ftitle, Int_t compress,
4166 TFileOpenHandle *fh =
nullptr;
4168 Bool_t notfound = kTRUE;
4171 if (!url || strlen(url) <= 0) {
4172 ::Error(
"TFile::AsyncOpen",
"no url specified");
4177 TString namelist(url);
4178 gSystem->ExpandPathName(namelist);
4179 Ssiz_t ip = namelist.Index(
"|");
4180 Bool_t rediroutput = (ip != kNPOS &&
4181 ip != namelist.Length()-1 && gDebug <= 0) ? kTRUE : kFALSE;
4182 RedirectHandle_t rh;
4184 TString outf =
".TFileAsyncOpen_";
4185 FILE *fout = gSystem->TempFileName(outf);
4188 gSystem->RedirectOutput(outf,
"w", &rh);
4195 while (namelist.Tokenize(n, from,
"|") && !f) {
4199 TUrl urlname(n, kTRUE);
4200 name = urlname.GetUrl();
4203 EFileType type = GetType(name, option);
4205 TPluginHandler *h =
nullptr;
4210 if ((h = gROOT->GetPluginManager()->FindHandler(
"TFile", name)) &&
4211 (!strcmp(h->GetClass(),
"TXNetFile") || !strcmp(h->GetClass(),
"TNetXNGFile"))
4212 && h->LoadPlugin() == 0) {
4213 f = (TFile*) h->ExecPlugin(6, name.Data(), option, ftitle, compress, netopt, kTRUE);
4217 if ((h = gROOT->GetPluginManager()->FindHandler(
"TFile", name)) &&
4218 !strcmp(h->GetClass(),
"TAlienFile") && h->LoadPlugin() == 0) {
4219 f = (TFile*) h->ExecPlugin(5, name.Data(), option, ftitle, compress, kTRUE);
4227 gSystem->RedirectOutput(0,
"", &rh);
4229 if (!notfound && !f)
4230 gSystem->ShowOutput(&rh);
4232 gSystem->Unlink(rh.fFile);
4240 fh =
new TFileOpenHandle(name, option, ftitle, compress, netopt);
4243 fh =
new TFileOpenHandle(f);
4249 if (!fgAsyncOpenRequests)
4250 fgAsyncOpenRequests =
new TList;
4251 fgAsyncOpenRequests->Add(fh);
4264 TFile *TFile::Open(TFileOpenHandle *fh)
4269 if (fh && fgAsyncOpenRequests) {
4272 fgAsyncOpenRequests->Remove(fh);
4274 if ((f = fh->GetFile()) && !(f->IsZombie())) {
4276 Bool_t cr = (!strcmp(f->GetOption(),
"CREATE") ||
4277 !strcmp(f->GetOption(),
"RECREATE") ||
4278 !strcmp(f->GetOption(),
"NEW")) ? kTRUE : kFALSE;
4282 f = TFile::Open(fh->GetName(), fh->GetOpt(), fh->GetTitle(),
4283 fh->GetCompress(), fh->GetNetOpt());
4288 if (f) f->fAsyncHandle = fh;
4298 Int_t TFile::SysOpen(
const char *pathname, Int_t flags, UInt_t mode)
4300 #if defined(R__WINGCC)
4303 return ::open(pathname, flags | O_BINARY, mode);
4304 #elif defined(R__SEEK64)
4305 return ::open64(pathname, flags, mode);
4307 return ::open(pathname, flags, mode);
4314 Int_t TFile::SysClose(Int_t fd)
4316 if (fd < 0)
return 0;
4323 Int_t TFile::SysRead(Int_t fd,
void *buf, Int_t len)
4325 return ::read(fd, buf, len);
4331 Int_t TFile::SysWrite(Int_t fd,
const void *buf, Int_t len)
4333 return ::write(fd, buf, len);
4342 Long64_t TFile::SysSeek(Int_t fd, Long64_t offset, Int_t whence)
4344 #if defined (R__SEEK64)
4345 return ::lseek64(fd, offset, whence);
4346 #elif defined(WIN32)
4347 return ::_lseeki64(fd, offset, whence);
4349 return ::lseek(fd, offset, whence);
4360 Int_t TFile::SysStat(Int_t, Long_t *
id, Long64_t *size, Long_t *flags,
4363 return gSystem->GetPathInfo(fRealName,
id, size, flags, modtime);
4369 Int_t TFile::SysSync(Int_t fd)
4371 if (TestBit(kDevNull))
return 0;
4376 return ::_commit(fd);
4383 Long64_t TFile::GetBytesWritten()
const
4385 return fCacheWrite ? fCacheWrite->GetBytesInCache() + fBytesWrite : fBytesWrite;
4391 Long64_t TFile::GetFileBytesRead()
4400 Long64_t TFile::GetFileBytesWritten()
4402 return fgBytesWrite;
4408 Int_t TFile::GetFileReadCalls()
4416 Int_t TFile::GetReadaheadSize()
4418 return fgReadaheadSize;
4422 void TFile::SetReadaheadSize(Int_t bytes) { fgReadaheadSize = bytes; }
4425 void TFile::SetFileBytesRead(Long64_t bytes) { fgBytesRead = bytes; }
4428 void TFile::SetFileBytesWritten(Long64_t bytes) { fgBytesWrite = bytes; }
4431 void TFile::SetFileReadCalls(Int_t readcalls) { fgReadCalls = readcalls; }
4434 Long64_t TFile::GetFileCounter() {
return fgFileCounter; }
4437 void TFile::IncrementFileCounter() { fgFileCounter++; }
4443 Bool_t TFile::SetCacheFileDir(std::string_view cachedir, Bool_t operatedisconnected,
4444 Bool_t forcecacheread )
4446 TString cached{cachedir};
4447 if (!cached.EndsWith(
"/"))
4450 if (gSystem->AccessPathName(cached, kFileExists)) {
4452 gSystem->mkdir(cached, kTRUE);
4453 if (gSystem->AccessPathName(cached, kFileExists)) {
4454 ::Error(
"TFile::SetCacheFileDir",
"no sufficient permissions on cache directory %s or cannot create it", TString(cachedir).Data());
4455 fgCacheFileDir =
"";
4458 gSystem->Chmod(cached, 0700);
4460 if (gSystem->AccessPathName(cached, kWritePermission))
4461 gSystem->Chmod(cached, 0700);
4462 fgCacheFileDir = cached;
4463 fgCacheFileDisconnected = operatedisconnected;
4464 fgCacheFileForce = forcecacheread;
4471 const char *TFile::GetCacheFileDir()
4473 return fgCacheFileDir;
4483 Bool_t TFile::ShrinkCacheFileDir(Long64_t shrinksize, Long_t cleanupinterval)
4485 if (fgCacheFileDir ==
"") {
4495 TString cachetagfile = fgCacheFileDir;
4496 cachetagfile +=
".tag.ROOT.cache";
4497 if (!gSystem->GetPathInfo(cachetagfile, &
id, &size, &flags, &modtime)) {
4499 Long_t lastcleanuptime = ((Long_t)time(0) - modtime);
4500 if (lastcleanuptime < cleanupinterval) {
4501 ::Info(
"TFile::ShrinkCacheFileDir",
"clean-up is skipped - last cleanup %lu seconds ago - you requested %lu", lastcleanuptime, cleanupinterval);
4507 cachetagfile +=
"?filetype=raw";
4508 TFile *tagfile =
nullptr;
4510 if (!(tagfile = TFile::Open(cachetagfile,
"RECREATE"))) {
4511 ::Error(
"TFile::ShrinkCacheFileDir",
"cannot create the cache tag file %s", cachetagfile.Data());
4519 #if defined(R__WIN32)
4520 cmd =
"echo <TFile::ShrinkCacheFileDir>: cleanup to be implemented";
4521 #elif defined(R__MACOSX)
4522 cmd.Format(
"perl -e 'my $cachepath = \"%s\"; my $cachesize = %lld;my $findcommand=\"find $cachepath -type f -exec stat -f \\\"\\%%a::\\%%N::\\%%z\\\" \\{\\} \\\\\\;\";my $totalsize=0;open FIND, \"$findcommand | sort -k 1 |\";while (<FIND>) { my ($accesstime, $filename, $filesize) = split \"::\",$_; $totalsize += $filesize;if ($totalsize > $cachesize) {if ( ( -e \"${filename}.ROOT.cachefile\" ) && ( -e \"${filename}\" ) ) {unlink \"$filename.ROOT.cachefile\";unlink \"$filename\";}}}close FIND;' ", fgCacheFileDir.Data(),shrinksize);
4524 cmd.Format(
"perl -e 'my $cachepath = \"%s\"; my $cachesize = %lld;my $findcommand=\"find $cachepath -type f -exec stat -c \\\"\\%%x::\\%%n::\\%%s\\\" \\{\\} \\\\\\;\";my $totalsize=0;open FIND, \"$findcommand | sort -k 1 |\";while (<FIND>) { my ($accesstime, $filename, $filesize) = split \"::\",$_; $totalsize += $filesize;if ($totalsize > $cachesize) {if ( ( -e \"${filename}.ROOT.cachefile\" ) && ( -e \"${filename}\" ) ) {unlink \"$filename.ROOT.cachefile\";unlink \"$filename\";}}}close FIND;' ", fgCacheFileDir.Data(),shrinksize);
4527 tagfile->WriteBuffer(cmd, 4096);
4530 if ((gSystem->Exec(cmd)) != 0) {
4531 ::Error(
"TFile::ShrinkCacheFileDir",
"error executing clean-up script");
4541 UInt_t TFile::SetOpenTimeout(UInt_t timeout)
4543 UInt_t to = fgOpenTimeout;
4544 fgOpenTimeout = timeout;
4551 UInt_t TFile::GetOpenTimeout()
4553 return fgOpenTimeout;
4561 Bool_t TFile::SetOnlyStaged(Bool_t onlystaged)
4563 Bool_t f = fgOnlyStaged;
4564 fgOnlyStaged = onlystaged;
4571 Bool_t TFile::GetOnlyStaged()
4573 return fgOnlyStaged;
4583 Bool_t TFile::Matches(
const char *url)
4589 if (!strcmp(u.GetFile(), fUrl.GetFile())) {
4591 if (u.GetPort() == fUrl.GetPort()) {
4592 if (!strcmp(u.GetHostFQDN(), fUrl.GetHostFQDN())) {
4607 Bool_t TFileOpenHandle::Matches(
const char *url)
4610 return fFile->Matches(url);
4611 }
else if (fName.Length() > 0){
4615 if (!strcmp(u.GetFile(), uref.GetFile())) {
4617 if (u.GetPort() == uref.GetPort()) {
4619 if (!strcmp(u.GetHostFQDN(), uref.GetHostFQDN())) {
4638 TFile::EFileType TFile::GetType(
const char *name, Option_t *option, TString *prefix)
4640 EFileType type = kDefault;
4642 TPMERegexp re(
"^(root|xroot).*",
"i");
4643 if (re.Match(name)) {
4653 Bool_t localFile = kFALSE;
4657 Bool_t forceRemote = gEnv->GetValue(
"Path.ForceRemote", 0);
4658 forceRemote = (forceRemote) ? kTRUE : gEnv->GetValue(
"TFile.ForceRemote", 0);
4659 TString opts = url.GetOptions();
4660 if (opts.Contains(
"remote=1"))
4661 forceRemote = kTRUE;
4662 else if (opts.Contains(
"remote=0"))
4663 forceRemote = kFALSE;
4666 localFile = gSystem->IsPathLocal(name);
4669 const char *fname = url.GetFileAndOptions();
4671 if (fname[0] ==
'/') {
4673 lfname.Form(
"%s%s", prefix->Data(), fname);
4676 }
else if (fname[0] ==
'~' || fname[0] ==
'$') {
4679 lfname.Form(
"%s/%s", gSystem->HomeDirectory(), fname);
4682 TString opt = option;
4683 Bool_t read = (opt.IsNull() ||
4684 !opt.CompareTo(
"READ", TString::kIgnoreCase)) ? kTRUE : kFALSE;
4687 if ((fn = gSystem->ExpandPathName(TUrl(lfname).GetFile()))) {
4688 if (gSystem->AccessPathName(fn, kReadPermission))
4694 if (localFile && prefix)
4700 type = (localFile) ? kLocal : type;
4701 }
else if (TPMERegexp(
"^(http[s]?|s3http[s]?|[a]?s3|gs|gshttp[s]?){1}:",
"i").Match(name)) {
4705 }
else if (!strncmp(name,
"file:", 5)) {
4717 TFile::EAsyncOpenStatus TFile::GetAsyncOpenStatus(
const char* name)
4720 if (fgAsyncOpenRequests && (fgAsyncOpenRequests->GetSize() > 0)) {
4721 TIter nxr(fgAsyncOpenRequests);
4722 TFileOpenHandle *fh =
nullptr;
4723 while ((fh = (TFileOpenHandle *)nxr()))
4724 if (fh->Matches(name))
4725 return TFile::GetAsyncOpenStatus(fh);
4729 R__LOCKGUARD(gROOTMutex);
4730 TSeqCollection *of = gROOT->GetListOfFiles();
4731 if (of && (of->GetSize() > 0)) {
4734 while ((f = (TFile *)nxf()))
4735 if (f->Matches(name))
4736 return f->GetAsyncOpenStatus();
4740 return kAOSNotAsync;
4746 TFile::EAsyncOpenStatus TFile::GetAsyncOpenStatus(TFileOpenHandle *handle)
4748 if (handle && handle->fFile) {
4749 if (!handle->fFile->IsZombie())
4750 return handle->fFile->GetAsyncOpenStatus();
4752 return TFile::kAOSFailure;
4756 return TFile::kAOSNotAsync;
4763 const TUrl *TFile::GetEndpointUrl(
const char* name)
4766 if (fgAsyncOpenRequests && (fgAsyncOpenRequests->GetSize() > 0)) {
4767 TIter nxr(fgAsyncOpenRequests);
4768 TFileOpenHandle *fh =
nullptr;
4769 while ((fh = (TFileOpenHandle *)nxr()))
4770 if (fh->Matches(name))
4772 return fh->fFile->GetEndpointUrl();
4776 R__LOCKGUARD(gROOTMutex);
4777 TSeqCollection *of = gROOT->GetListOfFiles();
4778 if (of && (of->GetSize() > 0)) {
4781 while ((f = (TFile *)nxf()))
4782 if (f->Matches(name))
4783 return f->GetEndpointUrl();
4787 return (
const TUrl *)
nullptr;
4793 void TFile::CpProgress(Long64_t bytesread, Long64_t size, TStopwatch &watch)
4795 fprintf(stderr,
"[TFile::Cp] Total %.02f MB\t|", (Double_t)size/1048576);
4797 for (
int l = 0; l < 20; l++) {
4799 if (l < 20*bytesread/size)
4800 fprintf(stderr,
"=");
4801 else if (l == 20*bytesread/size)
4802 fprintf(stderr,
">");
4803 else if (l > 20*bytesread/size)
4804 fprintf(stderr,
".");
4806 fprintf(stderr,
"=");
4809 gSystem->ProcessEvents();
4811 Double_t lCopy_time = watch.RealTime();
4812 fprintf(stderr,
"| %.02f %% [%.01f MB/s]\r",
4813 100.0*(size?(bytesread/((
float)size)):1), (lCopy_time>0.)?bytesread/lCopy_time/1048576.:0.);
4821 Bool_t TFile::Cp(
const char *dst, Bool_t progressbar, UInt_t buffersize)
4823 Bool_t rmdestiferror = kFALSE;
4825 Bool_t success = kFALSE;
4827 TUrl dURL(dst, kTRUE);
4829 TString oopt =
"RECREATE";
4830 TString ourl = dURL.GetUrl();
4833 TString raw =
"filetype=raw";
4836 TString opt = dURL.GetOptions();
4837 if (opt !=
"") opt +=
"&";
4841 if (!strcmp(dURL.GetProtocol(),
"alien"))
4842 opt += TString::Format(
"&source=%s", GetName());
4844 dURL.SetOptions(opt);
4846 char *copybuffer =
nullptr;
4848 TFile *sfile =
this;
4849 TFile *dfile =
nullptr;
4854 if (TFile::GetType(ourl,
"") == TFile::kNet) {
4855 if (gSystem->AccessPathName(ourl)) {
4859 dURL.SetOptions(opt);
4864 if (!(dfile = TFile::Open(dURL.GetUrl(), oopt))) {
4865 ::Error(
"TFile::Cp",
"cannot open destination file %s", dst);
4871 rmdestiferror = kTRUE;
4876 copybuffer =
new char[buffersize];
4878 ::Error(
"TFile::Cp",
"cannot allocate the copy buffer");
4882 Bool_t readop, writeop;
4883 Long64_t read, written, totalread, filesize, b00;
4886 filesize = sfile->GetSize();
4890 b00 = sfile->GetBytesRead();
4893 if (progressbar) CpProgress(totalread, filesize,watch);
4895 Long64_t b1 = sfile->GetBytesRead() - b00;
4898 if (filesize - b1 > (Long64_t)buffersize) {
4899 readsize = buffersize;
4901 readsize = filesize - b1;
4904 if (readsize == 0)
break;
4906 Long64_t b0 = sfile->GetBytesRead();
4907 sfile->Seek(totalread,TFile::kBeg);
4908 readop = sfile->ReadBuffer(copybuffer, (Int_t)readsize);
4909 read = sfile->GetBytesRead() - b0;
4910 if ((read <= 0) || readop) {
4911 ::Error(
"TFile::Cp",
"cannot read from source file %s. readsize=%lld read=%lld readop=%d",
4912 sfile->GetName(), readsize, read, readop);
4916 Long64_t w0 = dfile->GetBytesWritten();
4917 writeop = dfile->WriteBuffer(copybuffer, (Int_t)read);
4918 written = dfile->GetBytesWritten() - w0;
4919 if ((written != read) || writeop) {
4920 ::Error(
"TFile::Cp",
"cannot write %lld bytes to destination file %s", read, dst);
4924 }
while (read == (Long64_t)buffersize);
4927 CpProgress(totalread, filesize,watch);
4928 fprintf(stderr,
"\n");
4934 if (dfile) dfile->Close();
4936 if (dfile)
delete dfile;
4937 if (copybuffer)
delete[] copybuffer;
4939 if (rmdestiferror && (success != kTRUE))
4940 gSystem->Unlink(dst);
4952 Bool_t TFile::Cp(
const char *src,
const char *dst, Bool_t progressbar,
4955 TUrl sURL(src, kTRUE);
4958 TString raw =
"filetype=raw";
4961 TString opt = sURL.GetOptions();
4962 if (opt !=
"") opt +=
"&";
4968 opt += TString::Format(
"&cachesz=%d&readaheadsz=%d&rmpolicy=1", 4*buffersize, 2*buffersize);
4969 sURL.SetOptions(opt);
4971 TFile *sfile =
nullptr;
4973 Bool_t success = kFALSE;
4976 if (!(sfile = TFile::Open(sURL.GetUrl(),
"READ"))) {
4977 ::Error(
"TFile::Cp",
"cannot open source file %s", src);
4979 success = sfile->Cp(dst, progressbar, buffersize);
4994 #if defined(R__neverLINUX) && !defined(R__WINGCC)
4995 Bool_t TFile::ReadBufferAsync(Long64_t offset, Int_t len)
5003 if (IsA() != TFile::Class())
5006 int advice = POSIX_FADV_WILLNEED;
5011 advice = POSIX_FADV_NORMAL;
5014 if (gPerfStats) start = TTimeStamp();
5015 #if defined(R__SEEK64)
5016 Int_t result = posix_fadvise64(fD, offset, len, advice);
5018 Int_t result = posix_fadvise(fD, offset, len, advice);
5021 gPerfStats->FileReadEvent(
this, len, start);
5023 return (result != 0);
5026 Bool_t TFile::ReadBufferAsync(Long64_t, Int_t)
5040 Int_t TFile::GetBytesToPrefetch()
const
5042 TFileCacheRead *cr =
nullptr;
5043 if ((cr = GetCacheRead())) {
5044 Int_t bytes = cr->GetBufferSize() / 4 * 3;
5045 return ((bytes < 0) ? 0 : bytes);