Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TFile.cxx
Go to the documentation of this file.
1// @(#)root/io:$Id: 3a19890259ad6443ee313e090166614971ad4296 $
2// Author: Rene Brun 28/11/94
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**
13\file TFile.cxx
14\class TFile
15\ingroup IO
16
17A ROOT file is composed of a header, followed by consecutive data records
18(`TKey` instances) with a well defined format.
19
20The first data record starts at byte fBEGIN (currently set to kBEGIN).
21Bytes 1->kBEGIN contain the file description, when fVersion >= 1000000
22it is a large file (> 2 GB) and the offsets will be 8 bytes long and
23fUnits will be set to 8:
24Byte Range | Record Name | Description
25----------------|-------------|------------
261->4 | "root" | Root file identifier
275->8 | fVersion | File format version
289->12 | fBEGIN | Pointer to first data record
2913->16 [13->20] | fEND | Pointer to first free word at the EOF
3017->20 [21->28] | fSeekFree | Pointer to FREE data record
3121->24 [29->32] | fNbytesFree | Number of bytes in FREE data record
3225->28 [33->36] | nfree | Number of free data records
3329->32 [37->40] | fNbytesName | Number of bytes in TNamed at creation time
3433->33 [41->41] | fUnits | Number of bytes for file pointers
3534->37 [42->45] | fCompress | Compression level and algorithm
3638->41 [46->53] | fSeekInfo | Pointer to TStreamerInfo record
3742->45 [54->57] | fNbytesInfo | Number of bytes in TStreamerInfo record
3846->63 [58->75] | fUUID | Universal Unique ID
39
40For the purpose of magic bytes in the context of ROOT files' MIME definition,
41the following additional requirements are introduced:
42- The value of `fBEGIN` is fixed at 100.
43- The four bytes starting at position 96 are reserved and must be 0.
44If any changes to this need to be made, `media-types@iana.org` needs to be
45notified in accordance with RFC 6838.
46
47The key structure is as follows; if a key is located past the 32 bit file
48limit (> 2 GB) then some fields will be 8 instead of 4 bytes (see parts marked
49with square brackets below):
50
51Byte Range | Member Name | Description
52----------------|-----------|--------------
531->4 | Nbytes | Length of compressed object (in bytes)
545->6 | Version | TKey version identifier
557->10 | ObjLen | Length of uncompressed object
5611->14 | Datime | Date and time when object was written to file
5715->16 | KeyLen | Length of the key structure (in bytes)
5817->18 | Cycle | Cycle of key
5919->22 [19->26] | SeekKey | Pointer to record itself (consistency check)
6023->26 [27->34] | SeekPdir | Pointer to directory header
6127->27 [35->35] | lname | Number of bytes in the class name
6228->.. [36->..] | ClassName | Object Class Name
63..->.. | lname | Number of bytes in the object name
64..->.. | Name | lName bytes with the name of the object
65..->.. | lTitle | Number of bytes in the object title
66..->.. | Title | Title of the object
67-----> | DATA | Data bytes associated to the object
68
69Begin_Macro
70../../../tutorials/io/file.C
71End_Macro
72The structure of a directory is shown in TDirectoryFile::TDirectoryFile
73*/
74
75#include <ROOT/RConfig.hxx>
76
77#ifdef R__LINUX
78// for posix_fadvise
79#ifndef _XOPEN_SOURCE
80#define _XOPEN_SOURCE 600
81#endif
82#endif
83#include <fcntl.h>
84#include <errno.h>
85#include <sys/stat.h>
86#ifndef WIN32
87#include <unistd.h>
88#ifndef R__FBSD
89#include <sys/xattr.h>
90#endif
91#else
92# define ssize_t int
93# include <io.h>
94# include <sys/types.h>
95#endif
96
97#include "Bytes.h"
98#include "Compression.h"
99#include "RConfigure.h"
100#include "Strlen.h"
101#include "strlcpy.h"
102#include "snprintf.h"
103#include "TArrayC.h"
104#include "TBuffer.h"
105#include "TClass.h"
106#include "TClassEdit.h"
107#include "TClassTable.h"
108#include "TDatime.h"
109#include "TError.h"
110#include "TFile.h"
111#include "TFileCacheRead.h"
112#include "TFileCacheWrite.h"
113#include "TFree.h"
114#include "TInterpreter.h"
115#include "TKey.h"
116#include "TMakeProject.h"
117#include "TPluginManager.h"
118#include "TProcessUUID.h"
119#include "TRegexp.h"
120#include "TPRegexp.h"
121#include "TROOT.h"
122#include "TStreamerInfo.h"
123#include "TStreamerElement.h"
124#include "TSystem.h"
125#include "TTimeStamp.h"
126#include "TVirtualPerfStats.h"
127#include "TArchiveFile.h"
128#include "TEnv.h"
129#include "TVirtualMonitoring.h"
130#include "TVirtualMutex.h"
131#include "TMap.h"
132#include "TMathBase.h"
133#include "TObjString.h"
134#include "TStopwatch.h"
135#include "compiledata.h"
136#include <cmath>
137#include <iostream>
138#include <set>
139#include "TSchemaRule.h"
140#include "TSchemaRuleSet.h"
141#include "TThreadSlots.h"
142#include "TGlobal.h"
144#include <memory>
145
146#ifdef R__FBSD
147#include <sys/extattr.h>
148#endif
149
150using std::sqrt;
151
152std::atomic<Long64_t> TFile::fgBytesRead{0};
153std::atomic<Long64_t> TFile::fgBytesWrite{0};
154std::atomic<Long64_t> TFile::fgFileCounter{0};
155std::atomic<Int_t> TFile::fgReadCalls{0};
165
166#ifdef R__MACOSX
167/* On macOS getxattr takes two extra arguments that should be set to 0 */
168#define getxattr(path, name, value, size) getxattr(path, name, value, size, 0u, 0)
169#endif
170#ifdef R__FBSD
171#define getxattr(path, name, value, size) extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, value, size)
172#endif
174const Int_t kBEGIN = 100;
175
177
178//*-*x17 macros/layout_file
179// Needed to add the "fake" global gFile to the list of globals.
180namespace {
181static struct AddPseudoGlobals {
182AddPseudoGlobals() {
183 // User "gCling" as synonym for "libCore static initialization has happened".
184 // This code here must not trigger it.
186}
187} gAddPseudoGlobals;
188}
189////////////////////////////////////////////////////////////////////////////////
190/// File default Constructor.
192TFile::TFile() : TDirectoryFile(), fCompress(ROOT::RCompressionSetting::EAlgorithm::kUseGlobal)
193{
194 fCacheReadMap = new TMap();
196
197 if (gDebug)
198 Info("TFile", "default ctor");
199}
200
201////////////////////////////////////////////////////////////////////////////////
202/// Opens or creates a local ROOT file.
203///
204/// \param[in] fname1 The name of the file
205/// \param[in] option Specifies the mode in which the file is opened
206/// \param[in] ftitle The title of the file
207/// \param[in] compress Specifies the compression algorithm and level
208///
209/// It is recommended to specify fname1 as "<file>.root". The suffix ".root"
210/// will be used by object browsers to automatically identify the file as
211/// a ROOT file. If the constructor fails in any way IsZombie() will
212/// return true. Use IsOpen() to check if the file is (still) open.
213/// To open non-local files use the static TFile::Open() method, that
214/// will take care of opening the files using the correct remote file
215/// access plugin.
216///
217/// Option | Description
218/// -------|------------
219/// NEW or CREATE | Create a new file and open it for writing, if the file already exists the file is not opened.
220/// RECREATE | Create a new file, if the file already exists it will be overwritten.
221/// UPDATE | Open an existing file for writing. If no file exists, it is created.
222/// READ | Open an existing file for reading (default).
223/// NET | Used by derived remote file access classes, not a user callable option.
224/// WEB | Used by derived remote http access class, not a user callable option.
225/// READ_WITHOUT_GLOBALREGISTRATION | Used by TTreeProcessorMT, not a user callable option.
226///
227/// If option = "" (default), READ is assumed.
228/// The file can be specified as a URL of the form:
229///
230/// file:///user/rdm/bla.root or file:/user/rdm/bla.root
231///
232/// The file can also be a member of an archive, in which case it is
233/// specified as:
234///
235/// multi.zip#file.root or multi.zip#0
236///
237/// which will open file.root which is a member of the file multi.zip
238/// archive or member 1 from the archive. For more on archive file
239/// support see the TArchiveFile class.
240/// TFile and its remote access plugins can also be used to open any
241/// file, i.e. also non ROOT files, using:
242///
243/// file.tar?filetype=raw
244///
245/// This is convenient because the many remote file access plugins allow
246/// easy access to/from the many different mass storage systems.
247/// The title of the file (ftitle) will be shown by the ROOT browsers.
248/// A ROOT file (like a Unix file system) may contain objects and
249/// directories. There are no restrictions for the number of levels
250/// of directories.
251/// A ROOT file is designed such that one can write in the file in pure
252/// sequential mode (case of BATCH jobs). In this case, the file may be
253/// read sequentially again without using the file index written
254/// at the end of the file. In case of a job crash, all the information
255/// on the file is therefore protected.
256/// A ROOT file can be used interactively. In this case, one has the
257/// possibility to delete existing objects and add new ones.
258/// When an object is deleted from the file, the freed space is added
259/// into the FREE linked list (fFree). The FREE list consists of a chain
260/// of consecutive free segments on the file. At the same time, the first
261/// 4 bytes of the freed record on the file are overwritten by GAPSIZE
262/// where GAPSIZE = -(Number of bytes occupied by the record).
263/// Option compress is used to specify the compression level and algorithm:
264///
265/// compress = 100 * algorithm + level
266///
267/// Level | Explanation
268/// ------|-------------
269/// 0 | objects written to this file will not be compressed.
270/// 1 | minimal compression level but fast.
271/// ... | ....
272/// 9 | maximal compression level but slower and might use more memory.
273/// (For the currently supported algorithms, the maximum level is 9)
274/// If compress is negative it indicates the compression level is not set yet.
275/// The enumeration ROOT::RCompressionSetting::EAlgorithm associates each
276/// algorithm with a number. There is a utility function to help
277/// to set the value of compress. For example,
278/// ROOT::CompressionSettings(ROOT::kLZMA, 1)
279/// will build an integer which will set the compression to use
280/// the LZMA algorithm and compression level 1. These are defined
281/// in the header file <em>Compression.h</em>.
282/// Note that the compression settings may be changed at any time.
283/// The new compression settings will only apply to branches created
284/// or attached after the setting is changed and other objects written
285/// after the setting is changed.
286/// In case the file does not exist or is not a valid ROOT file,
287/// it is made a Zombie. One can detect this situation with a code like:
288/// ~~~{.cpp}
289/// TFile f("file.root");
290/// if (f.IsZombie()) {
291/// std::cout << "Error opening file" << std::endl;
292/// exit(-1);
293/// }
294/// ~~~
295/// If you open a file instead with TFile::Open("file.root") use rather
296/// the following code as a nullptr is returned.
297/// ~~~{.cpp}
298/// TFile* f = TFile::Open("file.root");
299/// if (!f) {
300/// std::cout << "Error opening file" << std::endl;
301/// exit(-1);
302/// }
303/// ~~~
304/// When opening the file, the system checks the validity of this directory.
305/// If something wrong is detected, an automatic Recovery is performed. In
306/// this case, the file is scanned sequentially reading all logical blocks
307/// and attempting to rebuild a correct directory (see TFile::Recover).
308/// One can disable the automatic recovery procedure when reading one
309/// or more files by setting the environment variable "TFile.Recover: 0"
310/// in the system.rootrc file.
311///
312/// A bit `TFile::kReproducible` can be enabled specifying
313/// the `"reproducible"` url option when creating the file:
314/// ~~~{.cpp}
315/// TFile *f = TFile::Open("name.root?reproducible","RECREATE","File title");
316/// ~~~
317/// Unlike regular `TFile`s, the content of such file has reproducible binary
318/// content when writing exactly same data. This achieved by writing pre-defined
319/// values for creation and modification date of TKey/TDirectory objects and
320/// null value for TUUID objects inside TFile. As drawback, TRef objects stored
321/// in such file cannot be read correctly.
322///
323/// In case the name of the file is not reproducible either (in case of
324/// creating temporary filenames) a value can be passed to the reproducible
325/// option to replace the name stored in the file.
326/// ~~~{.cpp}
327/// TFile *f = TFile::Open("tmpname.root?reproducible=fixedname","RECREATE","File title");
328/// ~~~
330TFile::TFile(const char *fname1, Option_t *option, const char *ftitle, Int_t compress)
331 : TDirectoryFile(), fCompress(compress), fUrl(fname1,kTRUE)
332{
333 if (!gROOT)
334 ::Fatal("TFile::TFile", "ROOT system not initialized");
335
336 auto zombify = [this] {
337 // error in file opening occurred, make this object a zombie
340 gROOT->GetListOfClosedObjects()->Add(this);
341 }
342 MakeZombie();
344 };
345
346 fOption = option;
347 if (strlen(fUrl.GetProtocol()) != 0 && strcmp(fUrl.GetProtocol(), "file") != 0 && !fOption.BeginsWith("NET") &&
348 !fOption.BeginsWith("WEB")) {
349 Error("TFile",
350 "please use TFile::Open to access remote files:\n\tauto f = std::unique_ptr<TFile>{TFile::Open(\"%s\")};",
351 fname1);
352 zombify();
353 return;
354 }
355
356 // store name without the options as name and title
357 TString sfname1 = fname1;
358 if (sfname1.Index("?") != kNPOS) {
359 TString s = sfname1(0, sfname1.Index("?"));
360 SetName(s);
362 } else
363 SetName(fname1);
364
365 SetTitle(ftitle);
366
367 // accept also URL like "file:..." syntax
368 fname1 = fUrl.GetFile();
369
370 // if option contains filetype=raw then go into raw file mode
371 if (strstr(fUrl.GetOptions(), "filetype=raw"))
373
374 // if option contains filetype=pcm then go into ROOT PCM file mode
375 if (strstr(fUrl.GetOptions(), "filetype=pcm"))
377
378 if (fUrl.HasOption("reproducible"))
380
381 // We are opening synchronously
383
384 BuildDirectoryFile(this, nullptr);
385
386 fVersion = gROOT->GetVersionInt(); //ROOT version in integer format
387 fUnits = 4;
388 fCacheReadMap = new TMap();
390
392
393 if (fIsRootFile && !fIsPcmFile && fOption != "NEW" && fOption != "CREATE"
394 && fOption != "RECREATE") {
395 // If !gPluginMgr then we are at startup and cannot handle plugins
396 // as TArchiveFile yet.
397 fArchive = gPluginMgr ? TArchiveFile::Open(fUrl.GetUrl(), this) : nullptr;
398 if (fArchive) {
399 fname1 = fArchive->GetArchiveName();
400 // if no archive member is specified then this TFile is just used
401 // to read the archive contents
402 if (!strlen(fArchive->GetMemberName()))
404 }
405 }
406
407 if (fOption.Contains("_WITHOUT_GLOBALREGISTRATION")) {
408 fOption = fOption.ReplaceAll("_WITHOUT_GLOBALREGISTRATION", "");
409 fGlobalRegistration = false;
410 if (fList) {
411 fList->UseRWLock(false);
412 }
413 }
414
415 if (fOption == "NET")
416 return;
417
418 if (fOption == "WEB") {
419 fOption = "READ";
421 return;
422 }
423
424 if (fOption == "NEW")
425 fOption = "CREATE";
426
427 Bool_t create = (fOption == "CREATE") ? kTRUE : kFALSE;
428 Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
429 Bool_t update = (fOption == "UPDATE") ? kTRUE : kFALSE;
430 Bool_t read = (fOption == "READ") ? kTRUE : kFALSE;
431 if (!create && !recreate && !update && !read) {
432 read = kTRUE;
433 fOption = "READ";
434 }
435
436 Bool_t devnull = kFALSE;
437
438 if (!fname1 || !fname1[0]) {
439 Error("TFile", "file name is not specified");
440 zombify();
441 return;
442 }
443
444 // support dumping to /dev/null on UNIX
445 if (!strcmp(fname1, "/dev/null") &&
447 devnull = kTRUE;
448 create = kTRUE;
449 recreate = kFALSE;
450 update = kFALSE;
451 read = kFALSE;
452 fOption = "CREATE";
454 }
455
456 const char *fname;
457 if ((fname = gSystem->ExpandPathName(fname1))) {
458 SetName(fname);
459 delete [] fname;
460 fRealName = GetName();
463 }
464 fname = fRealName.Data();
465 } else {
466 Error("TFile", "error expanding path %s", fname1);
467 zombify();
468 return;
469 }
470
471 // If the user supplied a value to the option take it as the name to set for
472 // the file instead of the actual filename
473 if (TestBit(kReproducible)) {
474 if(auto name=fUrl.GetValueFromOptions("reproducible")) {
475 SetName(name);
476 }
477 }
478
479 if (recreate) {
480 if (!gSystem->AccessPathName(fname, kFileExists)) {
481 if (gSystem->Unlink(fname) != 0) {
482 SysError("TFile", "could not delete %s (errno: %d)",
483 fname, gSystem->GetErrno());
484 zombify();
485 return;
486 }
487 }
488 recreate = kFALSE;
489 create = kTRUE;
490 fOption = "CREATE";
491 }
492 if (create && !devnull && !gSystem->AccessPathName(fname, kFileExists)) {
493 Error("TFile", "file %s already exists", fname);
494 zombify();
495 return;
496 }
497 if (update) {
498 if (gSystem->AccessPathName(fname, kFileExists)) {
499 update = kFALSE;
500 create = kTRUE;
501 }
503 Error("TFile", "no write permission, could not open file %s", fname);
504 zombify();
505 return;
506 }
507 }
508 if (read) {
509 if (gSystem->AccessPathName(fname, kFileExists)) {
510 Error("TFile", "file %s does not exist", fname);
511 zombify();
512 return;
513 }
515 Error("TFile", "no read permission, could not open file %s", fname);
516 zombify();
517 return;
518 }
519 }
520
521 // Connect to file system stream
522 if (create || update) {
523#ifndef WIN32
524 fD = TFile::SysOpen(fname, O_RDWR | O_CREAT, 0644);
525#else
526 fD = TFile::SysOpen(fname, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
527#endif
528 if (fD == -1) {
529 SysError("TFile", "file %s can not be opened", fname);
530 zombify();
531 return;
532 }
534 } else {
535#ifndef WIN32
536 fD = TFile::SysOpen(fname, O_RDONLY, 0644);
537#else
538 fD = TFile::SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
539#endif
540 if (fD == -1) {
541 SysError("TFile", "file %s can not be opened for reading", fname);
542 zombify();
543 return;
544 }
546 }
547
548 // calling virtual methods from constructor not a good idea, but it is how code was developed
549 TFile::Init(create); // NOLINT: silence clang-tidy warnings
550
551 return;
552}
553
554////////////////////////////////////////////////////////////////////////////////
555/// File destructor.
558{
559 Close(); // NOLINT: silence clang-tidy warnings
560
561 // In case where the TFile is still open at 'tear-down' time the order of operation will be
562 // call Close("nodelete")
563 // then later call delete TFile
564 // which means that at this point we might still have object held and those
565 // might requires a 'valid' TFile object in their desctructor (for example,
566 // TTree call's GetReadCache which expects a non-null fCacheReadMap).
567 // So delete the objects (if any) now.
568
569 if (fList)
570 fList->Delete("slow");
571
581
584 gROOT->GetListOfClosedObjects()->Remove(this);
585 gROOT->GetUUIDs()->RemoveUUID(GetUniqueID());
586 }
587
588 if (IsOnHeap()) {
589 // Delete object from CINT symbol table so it can not be used anymore.
590 // CINT object are always on the heap.
591 gInterpreter->ResetGlobalVar(this);
592 }
593
594 if (gDebug)
595 Info("~TFile", "dtor called for %s [%zx]", GetName(),(size_t)this);
596}
597
598////////////////////////////////////////////////////////////////////////////////
599/// Initialize a TFile object.
600///
601/// \param[in] create Create a new file.
602///
603/// TFile implementations providing asynchronous open functionality need to
604/// override this method to run the appropriate checks before calling this
605/// standard initialization part. See TXNetFile::Init for an example.
608{
609 if (fInitDone)
610 // Already called once
611 return;
613
614 if (!fIsRootFile) {
616 return;
617 }
618
619 if (fArchive) {
620 if (fOption != "READ") {
621 Error("Init", "archive %s can only be opened in read mode", GetName());
622 delete fArchive;
623 fArchive = nullptr;
625 goto zombie;
626 }
627
629
630 if (fIsArchive) return;
631
632 // Make sure the anchor is in the name
633 if (!fNoAnchorInName)
634 if (!strchr(GetName(),'#'))
636
637 if (fArchive->SetCurrentMember() != -1)
639 else {
640 Error("Init", "member %s not found in archive %s",
642 delete fArchive;
643 fArchive = nullptr;
645 goto zombie;
646 }
647 }
648
649 Int_t nfree;
650 fBEGIN = (Long64_t)kBEGIN; //First used word in file following the file header
651
652 // make newly opened file the current file and directory
653 cd();
654
655 if (create) {
656 //*-*---------------NEW file
657 fFree = new TList;
658 fEND = fBEGIN; //Pointer to end of file
659 new TFree(fFree, fBEGIN, Long64_t(kStartBigFile)); //Create new free list
660
661 //*-* Write Directory info
662 Int_t namelen= TNamed::Sizeof();
663 Int_t nbytes = namelen + TDirectoryFile::Sizeof();
664 TKey *key = new TKey(fName, fTitle, IsA(), nbytes, this);
665 fNbytesName = key->GetKeylen() + namelen;
666 fSeekDir = key->GetSeekKey();
667 fSeekFree = 0;
668 fNbytesFree = 0;
669 WriteHeader();
670 char *buffer = key->GetBuffer();
671 TNamed::FillBuffer(buffer);
673 key->WriteFile();
674 delete key;
675 } else {
676 //*-*----------------UPDATE
677 //char *header = new char[kBEGIN];
678 char *header = new char[kBEGIN+200];
679 Seek(0); // NOLINT: silence clang-tidy warnings
680 //ReadBuffer(header, kBEGIN);
681 if (ReadBuffer(header, kBEGIN+200)) { // NOLINT: silence clang-tidy warnings
682 // ReadBuffer returns kTRUE in case of failure.
683 Error("Init","%s failed to read the file type data.",
684 GetName());
685 delete [] header;
686 goto zombie;
687 }
688
689 // make sure this is a ROOT file
690 if (strncmp(header, "root", 4)) {
691 Error("Init", "%s not a ROOT file", GetName());
692 delete [] header;
693 goto zombie;
694 }
695
696 char *buffer = header + 4; // skip the "root" file identifier
697 frombuf(buffer, &fVersion);
698 Int_t headerLength;
699 frombuf(buffer, &headerLength);
700 fBEGIN = (Long64_t)headerLength;
701 if (fVersion < 1000000) { //small file
702 Int_t send,sfree,sinfo;
703 frombuf(buffer, &send); fEND = (Long64_t)send;
704 frombuf(buffer, &sfree); fSeekFree= (Long64_t)sfree;
705 frombuf(buffer, &fNbytesFree);
706 frombuf(buffer, &nfree);
707 frombuf(buffer, &fNbytesName);
708 frombuf(buffer, &fUnits );
709 frombuf(buffer, &fCompress);
710 frombuf(buffer, &sinfo); fSeekInfo = (Long64_t)sinfo;
711 frombuf(buffer, &fNbytesInfo);
712 } else { // new format to support large files
713 frombuf(buffer, &fEND);
714 frombuf(buffer, &fSeekFree);
715 frombuf(buffer, &fNbytesFree);
716 frombuf(buffer, &nfree);
717 frombuf(buffer, &fNbytesName);
718 frombuf(buffer, &fUnits );
719 frombuf(buffer, &fCompress);
720 frombuf(buffer, &fSeekInfo);
721 frombuf(buffer, &fNbytesInfo);
722 }
723 if (fBEGIN < 0 || fBEGIN > fEND) {
724 // humm fBEGIN is wrong ....
725 Error("Init","file %s has an incorrect header length (%lld) or incorrect end of file length (%lld)",
727 delete [] header;
728 goto zombie;
729 }
731 //*-*-------------Read Free segments structure if file is writable
732 if (fWritable) {
733 fFree = new TList;
734 if (fSeekFree > fBEGIN) {
735 ReadFree(); // NOLINT: silence clang-tidy warnings
736 } else {
737 Warning("Init","file %s probably not closed, cannot read free segments",GetName());
738 }
739 }
740 //*-*-------------Read directory info
741 // buffer_keyloc is the start of the key record.
742 char *buffer_keyloc = nullptr;
743
745 if ( (nbytes + fBEGIN) > fEND) {
746 // humm fBEGIN is wrong ....
747 Error("Init","file %s has an incorrect header length (%lld) or incorrect end of file length (%lld)",
748 GetName(),fBEGIN+nbytes,fEND);
749 delete [] header;
750 goto zombie;
751 }
752 if (nbytes+fBEGIN > kBEGIN+200) {
753 delete [] header;
754 header = new char[nbytes];
755 buffer = header;
756 Seek(fBEGIN); // NOLINT: silence clang-tidy warnings
757 if (ReadBuffer(buffer,nbytes)) { // NOLINT: silence clang-tidy warnings
758 // ReadBuffer returns kTRUE in case of failure.
759 Error("Init","%s failed to read the file header information at %lld (size=%d)",
760 GetName(),fBEGIN,nbytes);
761 delete [] header;
762 goto zombie;
763 }
764 buffer = header+fNbytesName;
765 buffer_keyloc = header;
766 } else {
767 buffer = header+fBEGIN+fNbytesName;
768 buffer_keyloc = header+fBEGIN;
769 }
770 Version_t version,versiondir;
771 frombuf(buffer,&version); versiondir = version%1000;
772 fDatimeC.ReadBuffer(buffer);
773 fDatimeM.ReadBuffer(buffer);
774 frombuf(buffer, &fNbytesKeys);
775 frombuf(buffer, &fNbytesName);
776 if (version > 1000) {
777 frombuf(buffer, &fSeekDir);
778 frombuf(buffer, &fSeekParent);
779 frombuf(buffer, &fSeekKeys);
780 } else {
781 Int_t sdir,sparent,skeys;
782 frombuf(buffer, &sdir); fSeekDir = (Long64_t)sdir;
783 frombuf(buffer, &sparent); fSeekParent = (Long64_t)sparent;
784 frombuf(buffer, &skeys); fSeekKeys = (Long64_t)skeys;
785 }
786 if (versiondir > 1) fUUID.ReadBuffer(buffer);
787
788 //*-*---------read TKey::FillBuffer info
789 buffer_keyloc += sizeof(Int_t); // Skip NBytes;
790 Version_t keyversion;
791 frombuf(buffer_keyloc, &keyversion);
792 // Skip ObjLen, DateTime, KeyLen, Cycle, SeekKey, SeekPdir
793 if (keyversion > 1000) {
794 // Large files
795 buffer_keyloc += 2*sizeof(Int_t)+2*sizeof(Short_t)+2*sizeof(Long64_t);
796 } else {
797 buffer_keyloc += 2*sizeof(Int_t)+2*sizeof(Short_t)+2*sizeof(Int_t);
798 }
800 cname.ReadBuffer(buffer_keyloc);
801 cname.ReadBuffer(buffer_keyloc); // fName.ReadBuffer(buffer); file may have been renamed
802 fTitle.ReadBuffer(buffer_keyloc);
803 delete [] header;
804 if (fNbytesName < 10 || fNbytesName > 10000) {
805 Error("Init","cannot read directory info of file %s", GetName());
806 goto zombie;
807 }
808
809 //*-* -------------Check if file is truncated
811 if ((size = GetSize()) == -1) { // NOLINT: silence clang-tidy warnings
812 Error("Init", "cannot stat the file %s", GetName());
813 goto zombie;
814 }
815
816 //*-* -------------Check if, in case of inconsistencies, we are requested to
817 //*-* -------------attempt recovering the file
818 Bool_t tryrecover = (gEnv->GetValue("TFile.Recover", 1) == 1) ? kTRUE : kFALSE;
819
820 //*-* -------------Check if we need to enable forward compatible with version
821 //*-* -------------prior to v6.30
822 if (gEnv->GetValue("TFile.v630forwardCompatibility", 0) == 1)
824
825 //*-* -------------Read keys of the top directory
826 if (fSeekKeys > fBEGIN && fEND <= size) {
827 //normal case. Recover only if file has no keys
829 gDirectory = this;
830 if (!GetNkeys()) {
831 if (tryrecover) {
832 Recover(); // NOLINT: silence clang-tidy warnings
833 } else {
834 Error("Init", "file %s has no keys", GetName());
835 goto zombie;
836 }
837 }
838 } else if ((fBEGIN+nbytes == fEND) && (fEND == size)) {
839 //the file might be open by another process and nothing written to the file yet
840 Warning("Init","file %s has no keys", GetName());
841 gDirectory = this;
842 } else {
843 //something had been written to the file. Trailer is missing, must recover
844 if (fEND > size) {
845 if (tryrecover) {
846 Error("Init","file %s is truncated at %lld bytes: should be %lld, "
847 "trying to recover", GetName(), size, fEND);
848 } else {
849 Error("Init","file %s is truncated at %lld bytes: should be %lld",
850 GetName(), size, fEND);
851 goto zombie;
852 }
853 } else {
854 if (tryrecover) {
855 Warning("Init","file %s probably not closed, "
856 "trying to recover", GetName());
857 } else {
858 Warning("Init","file %s probably not closed", GetName());
859 goto zombie;
860 }
861 }
862 Int_t nrecov = Recover(); // NOLINT: silence clang-tidy warnings
863 if (nrecov) {
864 Warning("Init", "successfully recovered %d keys", nrecov);
865 } else {
866 Warning("Init", "no keys recovered, file has been made a Zombie");
867 goto zombie;
868 }
869 }
870 }
871
874 gROOT->GetListOfFiles()->Add(this);
875 gROOT->GetUUIDs()->AddUUID(fUUID, this);
876 }
877
878 // Create StreamerInfo index
879 {
880 Int_t lenIndex = gROOT->GetListOfStreamerInfo()->GetSize()+1;
881 if (lenIndex < 5000) lenIndex = 5000;
882 fClassIndex = new TArrayC(lenIndex);
883 if (fgReadInfo) {
884 if (fSeekInfo > fBEGIN) {
885 ReadStreamerInfo(); // NOLINT: silence clang-tidy warnings
886 if (IsZombie()) {
888 gROOT->GetListOfFiles()->Remove(this);
889 goto zombie;
890 }
891 } else if (fVersion != gROOT->GetVersionInt() && fVersion > 30000) {
892 // Don't complain about missing streamer info for empty files.
893 if (fKeys->GetSize()) {
894 Warning("Init","no StreamerInfo found in %s therefore preventing schema evolution when reading this file."
895 " The file was produced with version %d.%02d/%02d of ROOT.",
896 GetName(), fVersion / 10000, (fVersion / 100) % (100), fVersion % 100);
897 }
898 }
899 }
900 }
901
902 // Count number of TProcessIDs in this file
903 {
904 TIter next(fKeys);
905 TKey *key;
906 while ((key = (TKey*)next())) {
907 if (!strcmp(key->GetClassName(),"TProcessID")) fNProcessIDs++;
908 }
910 }
911
912 return;
913
914zombie:
917 gROOT->GetListOfClosedObjects()->Add(this);
918 }
919 // error in file opening occurred, make this object a zombie
921 MakeZombie();
923}
924
925////////////////////////////////////////////////////////////////////////////////
926/// Close a file.
927///
928/// \param[in] option If option == "R", all TProcessIDs referenced by this file are deleted.
929///
930/// Calling TFile::Close("R") might be necessary in case one reads a long list
931/// of files having TRef, writing some of the referenced objects or TRef
932/// to a new file. If the TRef or referenced objects of the file being closed
933/// will not be referenced again, it is possible to minimize the size
934/// of the TProcessID data structures in memory by forcing a delete of
935/// the unused TProcessID.
938{
939 TString opt = option;
940
941 opt.ToLower();
942
943 if (!IsOpen()) return;
944
945 if (fIsArchive || !fIsRootFile) {
947 SysClose(fD);
948 fD = -1;
949
952
953 return;
954 }
955
956 if (IsWritable()) {
958 }
959
960 // Finish any concurrent I/O operations before we close the file handles.
962 {
963 TIter iter(fCacheReadMap);
964 TObject *key = nullptr;
965 while ((key = iter()) != nullptr) {
966 TFileCacheRead *cache = dynamic_cast<TFileCacheRead *>(fCacheReadMap->GetValue(key));
967 cache->Close();
968 }
969 }
970
971 // Delete all supported directories structures from memory
972 // If gDirectory points to this object or any of the nested
973 // TDirectoryFile, TDirectoryFile::Close will induce the proper cd.
974 fMustFlush = kFALSE; // Make sure there is only one Flush.
976
977 if (IsWritable()) {
978 TFree *f1 = (TFree*)fFree->First();
979 if (f1) {
980 WriteFree(); //*-*- Write free segments linked list
981 WriteHeader(); //*-*- Now write file header ; this forces a Flush/fsync
982 } else {
983 Flush();
984 }
985 }
987
989
992
993 delete fClassIndex;
994 fClassIndex = nullptr;
995
996 // Delete free segments from free list (but don't delete list header)
997 if (fFree) {
998 fFree->Delete();
999 }
1000
1001 if (IsOpen()) {
1002 SysClose(fD);
1003 fD = -1;
1004 }
1005
1006 fWritable = kFALSE;
1007
1008 // delete the TProcessIDs
1009 TList pidDeleted;
1010 TIter next(fProcessIDs);
1011 TProcessID *pid;
1012 while ((pid = (TProcessID*)next())) {
1013 if (!pid->DecrementCount()) {
1014 if (pid != TProcessID::GetSessionProcessID()) pidDeleted.Add(pid);
1015 } else if(opt.Contains("r")) {
1016 pid->Clear();
1017 }
1018 }
1019 pidDeleted.Delete();
1020
1021 if (!IsZombie() && fGlobalRegistration) {
1023 gROOT->GetListOfFiles()->Remove(this);
1024 gROOT->GetListOfBrowsers()->RecursiveRemove(this);
1025 gROOT->GetListOfClosedObjects()->Add(this);
1026 } else {
1027 // If we are a zombie, we are already in the list of closed objects.
1028 }
1029}
1030
1031////////////////////////////////////////////////////////////////////////////////
1032/// Creates key for object and converts data to buffer.
1034TKey* TFile::CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t bufsize)
1035{
1036 return new TKey(obj, name, bufsize, mother);
1037}
1038
1039////////////////////////////////////////////////////////////////////////////////
1040/// Creates key for object and converts data to buffer.
1042TKey* TFile::CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t bufsize)
1043{
1044 return new TKey(obj, cl, name, bufsize, mother);
1045}
1046
1047////////////////////////////////////////////////////////////////////////////////
1048/// Return the current ROOT file if any.
1049///
1050/// Note that if 'cd' has been called on a TDirectory that does not belong to a file,
1051/// gFile will be unchanged and still points to the file of the previous current
1052/// directory that was a file.
1055{
1056 static TFile *currentFile = nullptr;
1057 if (!gThreadTsd)
1058 return currentFile;
1059 else
1060 return *(TFile**)(*gThreadTsd)(&currentFile,ROOT::kFileThreadSlot);
1061}
1062
1063////////////////////////////////////////////////////////////////////////////////
1064/// Delete object namecycle.
1065///
1066/// \param[in] namecycle Encodes the name and cycle of the objects to delete
1067///
1068/// Namecycle identifies an object in the top directory of the file namecycle
1069/// has the format <em>name;cycle</em>.
1070/// - <em>name = *</em> means all objects
1071/// - <em>cycle = *</em> means all cycles (memory and keys)
1072/// - <em>cycle = ""</em> or cycle = 9999 ==> apply to a memory object
1073/// When name=* use T* to delete subdirectories also
1074///
1075/// Examples:
1076/// name/cycle | Action
1077/// -----------|-------
1078/// foo | delete object named foo in memory
1079/// foo;1 | delete cycle 1 of foo on file
1080/// foo;* | delete all cycles of foo on disk and also from memory
1081/// *;2 | delete all objects on file having the cycle 2
1082/// *;* | delete all objects from memory and file
1083/// T*;* | delete all objects from memory and file and all subdirectories
1085void TFile::Delete(const char *namecycle)
1086{
1087 if (gDebug)
1088 Info("Delete", "deleting name = %s", namecycle);
1089
1090 TDirectoryFile::Delete(namecycle);
1091}
1092
1093////////////////////////////////////////////////////////////////////////////////
1094/// Fill Graphics Structure and Paint.
1095///
1096/// Loop on all objects (memory or file) and all subdirectories.
1099{
1100 GetList()->R__FOR_EACH(TObject,Draw)(option);
1101}
1102
1103////////////////////////////////////////////////////////////////////////////////
1104/// Draw map of objects in this file. The map drawing is handled by TFileDrawMap.
1105/// Once the map is drawn, turn on the TCanvas option "View->Event Statusbar". Then, when
1106/// moving the mouse in the canvas, the "Event Status" panels shows the object corresponding
1107/// to the mouse position.
1108///
1109/// Example:
1110/// ~~~{.cpp}
1111/// auto f = new TFile("myfile.root");
1112/// f->DrawMap();
1113/// ~~~
1115void TFile::DrawMap(const char *keys, Option_t *option)
1116{
1118 if ((h = gROOT->GetPluginManager()->FindHandler("TFileDrawMap"))) {
1119 if (h->LoadPlugin() == -1)
1120 return;
1121 h->ExecPlugin(3, this, keys, option);
1122 }
1123}
1124
1125////////////////////////////////////////////////////////////////////////////////
1126/// Synchronize a file's in-memory and on-disk states.
1128void TFile::Flush()
1129{
1130 if (IsOpen() && fWritable) {
1132 if (SysSync(fD) < 0) {
1133 // Write the system error only once for this file
1135 SysError("Flush", "error flushing file %s", GetName());
1136 }
1137 }
1138}
1139
1140////////////////////////////////////////////////////////////////////////////////
1141/// Flush the write cache if active.
1142///
1143/// Return kTRUE in case of error
1146{
1147 if (fCacheWrite && IsOpen() && fWritable)
1148 return fCacheWrite->Flush();
1149 return kFALSE;
1150}
1151
1152////////////////////////////////////////////////////////////////////////////////
1153/// Encode file output buffer.
1154///
1155/// The file output buffer contains only the FREE data record.
1157void TFile::FillBuffer(char *&buffer)
1158{
1159 Version_t version = TFile::Class_Version();
1160 tobuf(buffer, version);
1161}
1162
1163////////////////////////////////////////////////////////////////////////////////
1164/// Return the best buffer size of objects on this file.
1165///
1166/// The best buffer size is estimated based on the current mean value
1167/// and standard deviation of all objects written so far to this file.
1168/// Returns mean value + one standard deviation.
1171{
1172 if (!fWritten) return TBuffer::kInitialSize;
1174 Double_t rms2 = TMath::Abs(fSum2Buffer/fSumBuffer -mean*mean);
1175 Double_t result = mean + sqrt(rms2);
1176 if (result >= (double)std::numeric_limits<Int_t>::max()) {
1177 return std::numeric_limits<Int_t>::max() -1;
1178 } else {
1179 return (Int_t)result;
1180 }
1181}
1182
1183////////////////////////////////////////////////////////////////////////////////
1184/// Return the file compression factor.
1185///
1186/// Add total number of compressed/uncompressed bytes for each key.
1187/// Returns the ratio of the two.
1190{
1191 Short_t keylen;
1192 UInt_t datime;
1193 Int_t nbytes, objlen, nwh = 64;
1194 char *header = new char[fBEGIN];
1195 char *buffer;
1196 Long64_t idcur = fBEGIN;
1197 Float_t comp,uncomp;
1198 comp = uncomp = fBEGIN;
1199
1200 while (idcur < fEND-100) {
1201 Seek(idcur);
1202 if (ReadBuffer(header, nwh)) {
1203 // ReadBuffer returns kTRUE in case of failure.
1204// Error("GetCompressionFactor","%s failed to read the key header information at %lld (size=%d).",
1205// GetName(),idcur,nwh);
1206 break;
1207 }
1208 buffer=header;
1209 frombuf(buffer, &nbytes);
1210 if (nbytes < 0) {
1211 idcur -= nbytes;
1212 Seek(idcur);
1213 continue;
1214 }
1215 if (nbytes == 0) break; //this may happen when the file is corrupted
1216 Version_t versionkey;
1217 frombuf(buffer, &versionkey);
1218 frombuf(buffer, &objlen);
1219 frombuf(buffer, &datime);
1220 frombuf(buffer, &keylen);
1221 if (!objlen) objlen = nbytes-keylen;
1222 comp += nbytes;
1223 uncomp += keylen + objlen;
1224 idcur += nbytes;
1225 }
1226 delete [] header;
1227 return uncomp/comp;
1228}
1229
1230////////////////////////////////////////////////////////////////////////////////
1231/// Method returning errno.
1233Int_t TFile::GetErrno() const
1234{
1235 return TSystem::GetErrno();
1236}
1237
1238////////////////////////////////////////////////////////////////////////////////
1239/// Method resetting the errno.
1241void TFile::ResetErrno() const
1242{
1244}
1245
1246////////////////////////////////////////////////////////////////////////////////
1247/// Return a pointer to the current read cache.
1250{
1251 if (!tree) {
1252 if (!fCacheRead && fCacheReadMap->GetSize() == 1) {
1253 TIter next(fCacheReadMap);
1254 return (TFileCacheRead *)fCacheReadMap->GetValue(next());
1255 }
1256 return fCacheRead;
1257 }
1259 if (!cache) return fCacheRead;
1260 return cache;
1261}
1262
1263////////////////////////////////////////////////////////////////////////////////
1264/// Return a pointer to the current write cache.
1267{
1268 return fCacheWrite;
1269}
1270
1271////////////////////////////////////////////////////////////////////////////////
1272/// Read the logical record header starting at a certain postion.
1273///
1274/// \param[in] buf pointer to buffer
1275/// \param[in] first read offset
1276/// \param[in] maxbytes Bytes which are read into buf.
1277/// \param[out] nbytes Number of bytes in record if negative, this is a deleted
1278/// record if 0, cannot read record, wrong value of argument first
1279/// \param[out] objlen Uncompressed object size
1280/// \param[out] keylen Length of logical record header
1281///
1282/// The function reads nread bytes
1283/// where nread is the minimum of maxbytes and the number of bytes
1284/// before the end of file. The function returns nread.
1285/// Note that the arguments objlen and keylen are returned only
1286/// if maxbytes >=16
1288Int_t TFile::GetRecordHeader(char *buf, Long64_t first, Int_t maxbytes, Int_t &nbytes, Int_t &objlen, Int_t &keylen)
1289{
1290 nbytes = 0;
1291 objlen = 0;
1292 keylen = 0;
1293 if (first < fBEGIN) return 0;
1294 if (first > fEND) return 0;
1295 Seek(first);
1296 Int_t nread = maxbytes;
1297 if (first+maxbytes > fEND) nread = fEND-maxbytes;
1298 if (nread < 4) {
1299 Warning("GetRecordHeader","%s: parameter maxbytes = %d must be >= 4",
1300 GetName(), nread);
1301 return nread;
1302 }
1303 if (ReadBuffer(buf,nread)) {
1304 // ReadBuffer return kTRUE in case of failure.
1305 Warning("GetRecordHeader","%s: failed to read header data (maxbytes = %d)",
1306 GetName(), nread);
1307 return nread;
1308 }
1309 Version_t versionkey;
1310 Short_t klen;
1311 UInt_t datime;
1312 Int_t nb,olen;
1313 char *buffer = buf;
1314 frombuf(buffer,&nb);
1315 nbytes = nb;
1316 if (nb < 0) return nread;
1317 // const Int_t headerSize = Int_t(sizeof(nb) +sizeof(versionkey) +sizeof(olen) +sizeof(datime) +sizeof(klen));
1318 const Int_t headerSize = 16;
1319 if (nread < headerSize) return nread;
1320 frombuf(buffer, &versionkey);
1321 frombuf(buffer, &olen);
1322 frombuf(buffer, &datime);
1323 frombuf(buffer, &klen);
1324 if (!olen) olen = nbytes-klen;
1325 objlen = olen;
1326 keylen = klen;
1327 return nread;
1328}
1329
1330////////////////////////////////////////////////////////////////////////////////
1331/// Returns the current file size. Returns -1 in case the file could not
1332/// be stat'ed.
1335{
1336 Long64_t size;
1337
1338 if (fArchive && fArchive->GetMember()) {
1340 } else {
1341 Long_t id, flags, modtime;
1342 if (const_cast<TFile*>(this)->SysStat(fD, &id, &size, &flags, &modtime)) { // NOLINT: silence clang-tidy warnings
1343 Error("GetSize", "cannot stat the file %s", GetName());
1344 return -1;
1345 }
1346 }
1347 return size;
1348}
1349
1350////////////////////////////////////////////////////////////////////////////////
1351/// Returns the cached list of StreamerInfos used in this file.
1354{
1356}
1357
1358////////////////////////////////////////////////////////////////////////////////
1359/// See documentation of GetStreamerInfoList for more details.
1360/// This is an internal method which returns the list of streamer infos and also
1361/// information about the success of the operation.
1364{
1366
1367 if (fIsPcmFile) return {nullptr, 1, hash}; // No schema evolution for ROOT PCM files.
1368
1369 TList *list = nullptr;
1370 if (fSeekInfo) {
1371 TDirectory::TContext ctxt(this); // gFile and gDirectory used in ReadObj
1372 auto key = std::make_unique<TKey>(this);
1373 std::vector<char> buffer(fNbytesInfo+1);
1374 auto buf = buffer.data();
1375 Seek(fSeekInfo); // NOLINT: silence clang-tidy warnings
1376 if (ReadBuffer(buf,fNbytesInfo)) { // NOLINT: silence clang-tidy warnings
1377 // ReadBuffer returns kTRUE in case of failure.
1378 Warning("GetRecordHeader","%s: failed to read the StreamerInfo data from disk.",
1379 GetName());
1380 return {nullptr, 1, hash};
1381 }
1382
1383 if (lookupSICache) {
1384 // key data must be excluded from the hash, otherwise the timestamp will
1385 // always lead to unique hashes for each file
1386 hash = fgTsSIHashes.Hash(buf + key->GetKeylen(), fNbytesInfo - key->GetKeylen());
1387 auto si_uids = fgTsSIHashes.Find(hash);
1388 if (si_uids) {
1389 if (gDebug > 0)
1390 Info("GetStreamerInfo", "The streamer info record for file %s has already been treated, skipping it.", GetName());
1391 for(auto uid : *si_uids)
1392 fClassIndex->fArray[uid] = 1;
1393 return {nullptr, 0, hash};
1394 }
1395 }
1396 key->ReadKeyBuffer(buf);
1397 list = dynamic_cast<TList*>(key->ReadObjWithBuffer(buffer.data()));
1398 if (list) list->SetOwner();
1399 } else {
1400 list = (TList*)Get("StreamerInfo"); //for versions 2.26 (never released)
1401 }
1402
1403 if (!list) {
1404 Info("GetStreamerInfoList", "cannot find the StreamerInfo record in file %s",
1405 GetName());
1406 return {nullptr, 1, hash};
1407 }
1408
1409 return {list, 0, hash};
1410}
1411
1412////////////////////////////////////////////////////////////////////////////////
1413/// Read the list of TStreamerInfo objects written to this file.
1414///
1415/// The function returns a TList. It is the user's responsibility
1416/// to delete the list created by this function.
1417///
1418/// Note the list, in addition to TStreamerInfo object, contains sometimes
1419/// a TList named 'listOfRules' and containing the schema evolution rules
1420/// related to the file's content.
1421///
1422/// Using the list, one can access additional information, e.g.:
1423/// ~~~{.cpp}
1424/// TFile f("myfile.root");
1425/// auto list = f.GetStreamerInfoList();
1426/// auto info = dynamic_cast<TStreamerInfo*>(list->FindObject("MyClass"));
1427/// if (info) auto classversionid = info->GetClassVersion();
1428/// delete list;
1429/// ~~~
1430///
1433{
1434 return GetStreamerInfoListImpl(/*lookupSICache*/ false).fList;
1435}
1436
1437////////////////////////////////////////////////////////////////////////////////
1438/// List file contents.
1439///
1440/// Indentation is used to identify the file tree.
1441/// Subdirectories are listed first, then objects in memory,
1442/// then objects on the file.
1444void TFile::ls(Option_t *option) const
1445{
1447 std::cout <<ClassName()<<"**\t\t"<<GetName()<<"\t"<<GetTitle()<<std::endl;
1451}
1452
1453////////////////////////////////////////////////////////////////////////////////
1454/// Returns kTRUE in case file is open and kFALSE if file is not open.
1456Bool_t TFile::IsOpen() const
1457{
1458 return fD == -1 ? kFALSE : kTRUE;
1459}
1460
1461////////////////////////////////////////////////////////////////////////////////
1462/// Mark unused bytes on the file.
1463///
1464/// The list of free segments is in the fFree linked list.
1465/// When an object is deleted from the file, the freed space is added
1466/// into the FREE linked list (fFree). The FREE list consists of a chain
1467/// of consecutive free segments on the file. At the same time, the first
1468/// 4 bytes of the freed record on the file are overwritten by GAPSIZE
1469/// where GAPSIZE = -(Number of bytes occupied by the record).
1472{
1473 TFree *f1 = (TFree*)fFree->First();
1474 if (!f1) return;
1475 TFree *newfree = f1->AddFree(fFree,first,last);
1476 if(!newfree) return;
1477 Long64_t nfirst = newfree->GetFirst();
1478 Long64_t nlast = newfree->GetLast();
1479 Long64_t nbytesl= nlast-nfirst+1;
1480 if (nbytesl > 2000000000) nbytesl = 2000000000;
1481 Int_t nbytes = -Int_t (nbytesl);
1482 Int_t nb = sizeof(Int_t);
1483 char * buffer = new char[nb];
1484 char * psave = buffer;
1485 tobuf(buffer, nbytes);
1486 if (last == fEND-1) fEND = nfirst;
1487 Seek(nfirst);
1488 // We could not update the meta data for this block on the file.
1489 // This is not fatal as this only means that we won't get it 'right'
1490 // if we ever need to Recover the file before the block is actually
1491 // (attempted to be reused.
1492 // coverity[unchecked_value]
1493 WriteBuffer(psave, nb);
1494 if (fMustFlush) Flush();
1495 delete [] psave;
1496}
1497
1498////////////////////////////////////////////////////////////////////////////////
1499/// List the contents of a file sequentially.
1500/// For each logical record found, it prints:
1501///
1502/// Date/Time Record_Adress Logical_Record_Length ClassName CompressionFactor
1503///
1504/// Example of output
1505///
1506/// 20010404/150437 At:64 N=150 TFile
1507/// 20010404/150440 At:214 N=28326 TBasket CX = 1.13
1508/// 20010404/150440 At:28540 N=29616 TBasket CX = 1.08
1509/// 20010404/150440 At:58156 N=29640 TBasket CX = 1.08
1510/// 20010404/150440 At:87796 N=29076 TBasket CX = 1.10
1511/// 20010404/150440 At:116872 N=10151 TBasket CX = 3.15
1512/// 20010404/150441 At:127023 N=28341 TBasket CX = 1.13
1513/// 20010404/150441 At:155364 N=29594 TBasket CX = 1.08
1514/// 20010404/150441 At:184958 N=29616 TBasket CX = 1.08
1515/// 20010404/150441 At:214574 N=29075 TBasket CX = 1.10
1516/// 20010404/150441 At:243649 N=9583 TBasket CX = 3.34
1517/// 20010404/150442 At:253232 N=28324 TBasket CX = 1.13
1518/// 20010404/150442 At:281556 N=29641 TBasket CX = 1.08
1519/// 20010404/150442 At:311197 N=29633 TBasket CX = 1.08
1520/// 20010404/150442 At:340830 N=29091 TBasket CX = 1.10
1521/// 20010404/150442 At:369921 N=10341 TBasket CX = 3.09
1522/// 20010404/150442 At:380262 N=509 TH1F CX = 1.93
1523/// 20010404/150442 At:380771 N=1769 TH2F CX = 4.32
1524/// 20010404/150442 At:382540 N=1849 TProfile CX = 1.65
1525/// 20010404/150442 At:384389 N=18434 TNtuple CX = 4.51
1526/// 20010404/150442 At:402823 N=307 KeysList
1527/// 20010404/150443 At:403130 N=4548 StreamerInfo CX = 3.65
1528/// 20010404/150443 At:407678 N=86 FreeSegments
1529/// 20010404/150443 At:407764 N=1 END
1530///
1531/// If the parameter opt contains "forComp", the Date/Time is omitted
1532/// and the decompressed size is also printed.
1533///
1534/// Record_Adress Logical_Record_Length Key_Length Object_Record_Length ClassName CompressionFactor
1535///
1536/// If the parameter opt contains "extended", the name and title of the keys are added:
1537/// 20200820/155031 At:100 N=180 TFile name: hsimple.root title: Demo ROOT file with histograms
1538/// 220200820/155032 At:280 N=28880 TBasket CX = 1.11 name: random title: ntuple
1539/// 220200820/155032 At:29160 N=29761 TBasket CX = 1.08 name: px title: ntuple
1540/// 220200820/155032 At:58921 N=29725 TBasket CX = 1.08 name: py title: ntuple
1541/// 220200820/155032 At:88646 N=29209 TBasket CX = 1.10 name: pz title: ntuple
1542/// 220200820/155032 At:117855 N=10197 TBasket CX = 3.14 name: i title: ntuple
1543/// ...
1544/// 20200820/155032 At:405110 N=808 TNtuple CX = 3.53 name: ntuple title: Demo ntuple
1545/// 20200820/155706 At:405918 N=307 KeysList name: hsimple.root title: Demo ROOT file with histograms
1546/// 20200820/155032 At:406225 N=8556 StreamerInfo CX = 3.42 name: StreamerInfo title: Doubly linked list
1547/// 20200820/155708 At:414781 N=86 FreeSegments name: hsimple.root title: Demo ROOT file with histograms
1548/// 20200820/155708 At:414867 N=1 END
1549///
1550/// Note: The combined size of the classname, name and title is truncated to 476 characters (a little more for regular keys of small files)
1551///
1552
1554void TFile::Map(Option_t *opt)
1555{
1556 TString options(opt);
1557 options.ToLower();
1558 bool forComp = options.Contains("forcomp");
1559 bool extended = options.Contains("extended");
1560
1561 Short_t keylen,cycle;
1562 UInt_t datime;
1563 Int_t nbytes,date,time,objlen;
1564 date = 0;
1565 time = 0;
1566 Long64_t seekkey,seekpdir;
1567 char *buffer;
1568 char nwhc;
1569 Long64_t idcur = fBEGIN;
1570
1571 constexpr Int_t nwheader = 512;
1572
1573 char header[nwheader];
1574 char classname[512];
1575 char keyname[512];
1576 char keytitle[512];
1577 TString extrainfo;
1578
1579 unsigned char nDigits = std::log10(fEND) + 1;
1580
1581 while (idcur < fEND) {
1582 Seek(idcur);
1583 Int_t nread = nwheader;
1584 if (idcur+nread >= fEND) nread = fEND-idcur-1;
1585 if (ReadBuffer(header, nread)) {
1586 // ReadBuffer returns kTRUE in case of failure.
1587 Warning("Map","%s: failed to read the key data from disk at %lld.",
1588 GetName(),idcur);
1589 break;
1590 }
1591
1592 buffer=header;
1593 frombuf(buffer, &nbytes);
1594 if (!nbytes) {
1595 Printf("Address = %lld\tNbytes = %d\t=====E R R O R=======", idcur, nbytes);
1596 date = 0; time = 0;
1597 break;
1598 }
1599 if (nbytes < 0) {
1600 Printf("Address = %lld\tNbytes = %d\t=====G A P===========", idcur, nbytes);
1601 idcur -= nbytes;
1602 Seek(idcur);
1603 continue;
1604 }
1605 Version_t versionkey;
1606 frombuf(buffer, &versionkey);
1607 frombuf(buffer, &objlen);
1608 frombuf(buffer, &datime);
1609 frombuf(buffer, &keylen);
1610 frombuf(buffer, &cycle);
1611 if (versionkey > 1000) {
1612 frombuf(buffer, &seekkey);
1613 frombuf(buffer, &seekpdir);
1614 } else {
1615 Int_t skey,sdir;
1616 frombuf(buffer, &skey); seekkey = (Long64_t)skey;
1617 frombuf(buffer, &sdir); seekpdir = (Long64_t)sdir;
1618 }
1619 frombuf(buffer, &nwhc);
1620 if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1621 nwhc = nwheader - (buffer-header);
1622 for (int i = 0;i < nwhc; i++) frombuf(buffer, &classname[i]);
1623 classname[(int)nwhc] = '\0'; //cast to avoid warning with gcc3.4
1624 if (idcur == fSeekFree) strlcpy(classname,"FreeSegments",512);
1625 if (idcur == fSeekInfo) strlcpy(classname,"StreamerInfo",512);
1626 if (idcur == fSeekKeys) strlcpy(classname,"KeysList",512);
1627
1628 if (extended) {
1629 if ( (buffer-header) >= nwheader )
1630 nwhc = 0;
1631 else {
1632 frombuf(buffer, &nwhc);
1633 if (nwhc < 0)
1634 nwhc = 0;
1635 else if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1636 nwhc = nwheader - (buffer-header);
1637 }
1638 for (int i = 0;i < nwhc; i++) frombuf(buffer, &keyname[i]);
1639 keyname[(int)nwhc] = '\0'; //cast to avoid warning with gcc3.4
1640
1641 if ( (buffer-header) >= nwheader )
1642 nwhc = 0;
1643 else {
1644 frombuf(buffer, &nwhc);
1645 if (nwhc < 0)
1646 nwhc = 0;
1647 else if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1648 nwhc = nwheader - (buffer-header);
1649 }
1650 for (int i = 0;i < nwhc; i++) frombuf(buffer, &keytitle[i]);
1651 keytitle[(int)nwhc] = '\0'; //cast to avoid warning with gcc3.4
1652
1653 extrainfo.Form(" name: %-16s title: %s", keyname, keytitle);
1654 }
1655
1656 TDatime::GetDateTime(datime, date, time);
1657 if (!forComp) {
1658 if (objlen != nbytes - keylen) {
1659 Float_t cx = Float_t(objlen + keylen) / Float_t(nbytes);
1660 Printf("%d/%06d At:%-*lld N=%-8d %-14s CX = %5.2f %s", date, time, nDigits + 1, idcur, nbytes, classname,
1661 cx, extrainfo.Data());
1662 } else {
1663 Printf("%d/%06d At:%-*lld N=%-8d %-14s %s", date, time, nDigits + 1, idcur, nbytes, classname, extrainfo.Data());
1664 }
1665 } else {
1666 // Printing to help compare two files.
1667 if (objlen != nbytes - keylen) {
1668 Float_t cx = Float_t(objlen + keylen) / Float_t(nbytes);
1669 Printf("At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = %5.2f %s", nDigits+1, idcur, nbytes, keylen, objlen, classname, cx, extrainfo.Data());
1670 } else {
1671 Printf("At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = 1 %s", nDigits+1, idcur, nbytes, keylen, objlen, classname, extrainfo.Data());
1672 }
1673 }
1674 idcur += nbytes;
1675 }
1676 if (!forComp)
1677 Printf("%d/%06d At:%-*lld N=%-8d %-14s",date,time, nDigits+1, idcur,1,"END");
1678 else
1679 Printf("At:%-*lld N=%-8d K= O= %-14s", nDigits+1, idcur,1,"END");
1680}
1681
1682////////////////////////////////////////////////////////////////////////////////
1683/// Paint all objects in the file.
1686{
1687 GetList()->R__FOR_EACH(TObject,Paint)(option);
1688}
1689
1690////////////////////////////////////////////////////////////////////////////////
1691/// Print all objects in the file.
1693void TFile::Print(Option_t *option) const
1694{
1695 Printf("TFile: name=%s, title=%s, option=%s", GetName(), GetTitle(), GetOption());
1696 GetList()->R__FOR_EACH(TObject,Print)(option);
1697}
1698
1699////////////////////////////////////////////////////////////////////////////////
1700/// Read a buffer from the file at the offset 'pos' in the file.
1701///
1702/// Returns kTRUE in case of failure.
1703/// Compared to ReadBuffer(char*, Int_t), this routine does _not_
1704/// change the cursor on the physical file representation (fD)
1705/// if the data is in this TFile's cache.
1707Bool_t TFile::ReadBuffer(char *buf, Long64_t pos, Int_t len)
1708{
1709 if (IsOpen()) {
1710
1711 SetOffset(pos);
1712
1713 Int_t st;
1714 Double_t start = 0;
1715 if (gPerfStats) start = TTimeStamp();
1716
1717 if ((st = ReadBufferViaCache(buf, len))) {
1718 if (st == 2)
1719 return kTRUE;
1720 return kFALSE;
1721 }
1722
1723 Seek(pos);
1724 ssize_t siz;
1725
1726 while ((siz = SysRead(fD, buf, len)) < 0 && GetErrno() == EINTR)
1727 ResetErrno();
1728
1729 if (siz < 0) {
1730 SysError("ReadBuffer", "error reading from file %s", GetName());
1731 return kTRUE;
1732 }
1733 if (siz != len) {
1734 Error("ReadBuffer", "error reading all requested bytes from file %s, got %ld of %d",
1735 GetName(), (Long_t)siz, len);
1736 return kTRUE;
1737 }
1738 fBytesRead += siz;
1739 fgBytesRead += siz;
1740 fReadCalls++;
1741 fgReadCalls++;
1742
1745 if (gPerfStats) {
1746 gPerfStats->FileReadEvent(this, len, start);
1747 }
1748 return kFALSE;
1749 }
1750 return kTRUE;
1751}
1752
1753////////////////////////////////////////////////////////////////////////////////
1754/// Read a buffer from the file. This is the basic low level read operation.
1755/// Returns kTRUE in case of failure.
1758{
1759 if (IsOpen()) {
1760
1761 Int_t st;
1762 if ((st = ReadBufferViaCache(buf, len))) {
1763 if (st == 2)
1764 return kTRUE;
1765 return kFALSE;
1766 }
1767
1768 ssize_t siz;
1769 Double_t start = 0;
1770
1771 if (gPerfStats) start = TTimeStamp();
1772
1773 while ((siz = SysRead(fD, buf, len)) < 0 && GetErrno() == EINTR)
1774 ResetErrno();
1775
1776 if (siz < 0) {
1777 SysError("ReadBuffer", "error reading from file %s", GetName());
1778 return kTRUE;
1779 }
1780 if (siz != len) {
1781 Error("ReadBuffer", "error reading all requested bytes from file %s, got %ld of %d",
1782 GetName(), (Long_t)siz, len);
1783 return kTRUE;
1784 }
1785 fBytesRead += siz;
1786 fgBytesRead += siz;
1787 fReadCalls++;
1788 fgReadCalls++;
1789
1792 if (gPerfStats) {
1793 gPerfStats->FileReadEvent(this, len, start);
1794 }
1795 return kFALSE;
1796 }
1797 return kTRUE;
1798}
1799
1800////////////////////////////////////////////////////////////////////////////////
1801/// Read the nbuf blocks described in arrays pos and len.
1802///
1803/// The value pos[i] is the seek position of block i of length len[i].
1804/// Note that for nbuf=1, this call is equivalent to TFile::ReafBuffer.
1805/// This function is overloaded by TNetFile, TWebFile, etc.
1806/// Returns kTRUE in case of failure.
1808Bool_t TFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
1809{
1810 // called with buf=0, from TFileCacheRead to pass list of readahead buffers
1811 if (!buf) {
1812 for (Int_t j = 0; j < nbuf; j++) {
1813 if (ReadBufferAsync(pos[j], len[j])) {
1814 return kTRUE;
1815 }
1816 }
1817 return kFALSE;
1818 }
1819
1820 Int_t k = 0;
1823 fCacheRead = nullptr;
1824 Long64_t curbegin = pos[0];
1825 Long64_t cur;
1826 char *buf2 = nullptr;
1827 Int_t i = 0, n = 0;
1828 while (i < nbuf) {
1829 cur = pos[i]+len[i];
1830 Bool_t bigRead = kTRUE;
1831 if (cur -curbegin < fgReadaheadSize) {n++; i++; bigRead = kFALSE;}
1832 if (bigRead || (i>=nbuf)) {
1833 if (n == 0) {
1834 //if the block to read is about the same size as the read-ahead buffer
1835 //we read the block directly
1836 Seek(pos[i]);
1837 result = ReadBuffer(&buf[k], len[i]);
1838 if (result) break;
1839 k += len[i];
1840 i++;
1841 } else {
1842 //otherwise we read all blocks that fit in the read-ahead buffer
1843 Seek(curbegin);
1844 if (!buf2) buf2 = new char[fgReadaheadSize];
1845 //we read ahead
1846 Long64_t nahead = pos[i-1]+len[i-1]-curbegin;
1847 result = ReadBuffer(buf2, nahead);
1848 if (result) break;
1849 //now copy from the read-ahead buffer to the cache
1850 Int_t kold = k;
1851 for (Int_t j=0;j<n;j++) {
1852 memcpy(&buf[k],&buf2[pos[i-n+j]-curbegin],len[i-n+j]);
1853 k += len[i-n+j];
1854 }
1855 Int_t nok = k-kold;
1856 Long64_t extra = nahead-nok;
1857 fBytesReadExtra += extra;
1858 fBytesRead -= extra;
1859 fgBytesRead -= extra;
1860 n = 0;
1861 }
1862 curbegin = i < nbuf ? pos[i] : 0;
1863 }
1864 }
1865 if (buf2) delete [] buf2;
1866 fCacheRead = old;
1867 return result;
1868}
1869
1870////////////////////////////////////////////////////////////////////////////////
1871/// Read buffer via cache.
1872///
1873/// Returns 0 if the requested block is not in the cache, 1 in case read via
1874/// cache was successful, 2 in case read via cache failed.
1877{
1878 Long64_t off = GetRelOffset();
1879 if (fCacheRead) {
1880 Int_t st = fCacheRead->ReadBuffer(buf, off, len);
1881 if (st < 0)
1882 return 2; // failure reading
1883 else if (st == 1) {
1884 // fOffset might have been changed via TFileCacheRead::ReadBuffer(), reset it
1885 SetOffset(off + len);
1886 return 1;
1887 }
1888 // fOffset might have been changed via TFileCacheRead::ReadBuffer(), reset it
1889 Seek(off);
1890 } else {
1891 // if write cache is active check if data still in write cache
1892 if (fWritable && fCacheWrite) {
1893 if (fCacheWrite->ReadBuffer(buf, off, len) == 0) {
1894 SetOffset(off + len);
1895 return 1;
1896 }
1897 // fOffset might have been changed via TFileCacheWrite::ReadBuffer(), reset it
1898 SetOffset(off);
1899 }
1900 }
1901
1902 return 0;
1903}
1904
1905////////////////////////////////////////////////////////////////////////////////
1906/// Read the FREE linked list.
1907///
1908/// Every file has a linked list (fFree) of free segments.
1909/// This linked list has been written on the file via WriteFree
1910/// as a single data record.
1912void TFile::ReadFree()
1913{
1914 // Avoid problem with file corruption.
1915 if (fNbytesFree < 0 || fNbytesFree > fEND) {
1916 fNbytesFree = 0;
1917 return;
1918 }
1919 TKey *headerfree = new TKey(fSeekFree, fNbytesFree, this);
1920 headerfree->ReadFile();
1921 char *buffer = headerfree->GetBuffer();
1922 headerfree->ReadKeyBuffer(buffer);
1923 buffer = headerfree->GetBuffer();
1924 while (1) {
1925 TFree *afree = new TFree();
1926 afree->ReadBuffer(buffer);
1927 fFree->Add(afree);
1928 if (afree->GetLast() > fEND) break;
1929 }
1930 delete headerfree;
1931}
1932
1933////////////////////////////////////////////////////////////////////////////////
1934/// The TProcessID with number pidf is read from this file.
1935///
1936/// If the object is not already entered in the gROOT list, it is added.
1939{
1940 TProcessID *pid = nullptr;
1942 if (pidf < pids->GetSize()) pid = (TProcessID *)pids->UncheckedAt(pidf);
1943 if (pid) {
1944 pid->CheckInit();
1945 return pid;
1946 }
1947
1948 //check if fProcessIDs[uid] is set in file
1949 //if not set, read the process uid from file
1950 char pidname[32];
1951 snprintf(pidname,32,"ProcessID%d",pidf);
1952 pid = (TProcessID *)Get(pidname);
1953 if (gDebug > 0) {
1954 printf("ReadProcessID, name=%s, file=%s, pid=%zx\n",pidname,GetName(),(size_t)pid);
1955 }
1956 if (!pid) {
1957 //file->Error("ReadProcessID","Cannot find %s in file %s",pidname,file->GetName());
1958 return pid;
1959 }
1960
1961 //check that a similar pid is not already registered in fgPIDs
1962 TObjArray *pidslist = TProcessID::GetPIDs();
1963 TIter next(pidslist);
1964 TProcessID *p;
1965 bool found = false;
1966
1967 {
1969 while ((p = (TProcessID*)next())) {
1970 if (!strcmp(p->GetTitle(),pid->GetTitle())) {
1971 found = true;
1972 break;
1973 }
1974 }
1975 }
1976
1977 if (found) {
1978 delete pid;
1979 pids->AddAtAndExpand(p,pidf);
1980 p->IncrementCount();
1981 return p;
1982 }
1983
1984 pids->AddAtAndExpand(pid,pidf);
1985 pid->IncrementCount();
1986
1987 {
1989 pidslist->Add(pid);
1990 Int_t ind = pidslist->IndexOf(pid);
1991 pid->SetUniqueID((UInt_t)ind);
1992 }
1993
1994 return pid;
1995}
1996
1997
1998////////////////////////////////////////////////////////////////////////////////
1999/// Attempt to recover file if not correctly closed
2000///
2001/// The function returns the number of keys that have been recovered.
2002/// If no keys can be recovered, the file will be declared Zombie by
2003/// the calling function. This function is automatically called when
2004/// opening a file.
2005/// If the file is open in read only mode, the file is not modified.
2006/// If open in update mode and the function finds something to recover,
2007/// a new directory header is written to the file. When opening the file gain
2008/// no message from Recover will be reported.
2009/// If keys have been recovered, the file is usable and you can safely
2010/// read the corresponding objects.
2011/// If the file is not usable (a zombie), you can test for this case
2012/// with code like:
2013///
2014/// ~~~{.cpp}
2015/// TFile f("myfile.root");
2016/// if (f.IsZombie()) {<actions to take if file is unusable>}
2017/// ~~~
2018///
2019/// If the file has been recovered, the bit kRecovered is set in the TFile object in memory.
2020/// You can test if the file has been recovered with
2021///
2022/// if (f.TestBit(TFile::kRecovered)) {... the file has been recovered}
2023///
2024/// When writing TTrees to a file, it is important to save the Tree header
2025/// at regular intervals (see TTree::AutoSave). If a file containing a Tree
2026/// is recovered, the last Tree header written to the file will be used.
2027/// In this case all the entries in all the branches written before writing
2028/// the header are valid entries.
2029/// One can disable the automatic recovery procedure by setting
2030///
2031/// TFile.Recover 0
2032///
2033/// in the <em>system.rootrc</em> file.
2036{
2037 Short_t keylen,cycle;
2038 UInt_t datime;
2039 Int_t nbytes,date,time,objlen,nwheader;
2040 Long64_t seekkey,seekpdir;
2041 char header[1024];
2042 char *buffer, *bufread;
2043 char nwhc;
2044 Long64_t idcur = fBEGIN;
2045
2046 Long64_t size;
2047 if ((size = GetSize()) == -1) { // NOLINT: silence clang-tidy warnings
2048 Error("Recover", "cannot stat the file %s", GetName());
2049 return 0;
2050 }
2051
2052 fEND = Long64_t(size);
2053
2054 if (fWritable && !fFree) fFree = new TList;
2055
2056 TKey *key;
2057 Int_t nrecov = 0;
2058 nwheader = 1024;
2059 Int_t nread = nwheader;
2060
2061 while (idcur < fEND) {
2062 Seek(idcur); // NOLINT: silence clang-tidy warnings
2063 if (idcur+nread >= fEND) nread = fEND-idcur-1;
2064 if (ReadBuffer(header, nread)) { // NOLINT: silence clang-tidy warnings
2065 // ReadBuffer returns kTRUE in case of failure.
2066 Error("Recover","%s: failed to read the key data from disk at %lld.",
2067 GetName(),idcur);
2068 break;
2069 }
2070 buffer = header;
2071 bufread = header;
2072 frombuf(buffer, &nbytes);
2073 if (!nbytes) {
2074 Error("Recover","Address = %lld\tNbytes = %d\t=====E R R O R=======", idcur, nbytes);
2075 break;
2076 }
2077 if (nbytes < 0) {
2078 idcur -= nbytes;
2079 if (fWritable) new TFree(fFree,idcur,idcur-nbytes-1);
2080 Seek(idcur);
2081 continue;
2082 }
2083 Version_t versionkey;
2084 frombuf(buffer, &versionkey);
2085 frombuf(buffer, &objlen);
2086 frombuf(buffer, &datime);
2087 frombuf(buffer, &keylen);
2088 frombuf(buffer, &cycle);
2089 if (versionkey > 1000) {
2090 frombuf(buffer, &seekkey);
2091 frombuf(buffer, &seekpdir);
2092 } else {
2093 Int_t skey,sdir;
2094 frombuf(buffer, &skey); seekkey = (Long64_t)skey;
2095 frombuf(buffer, &sdir); seekpdir = (Long64_t)sdir;
2096 }
2097 frombuf(buffer, &nwhc);
2098 char *classname = nullptr;
2099 if (nwhc <= 0 || nwhc > 100) break;
2100 classname = new char[nwhc+1];
2101 int i, nwhci = nwhc;
2102 for (i = 0;i < nwhc; i++) frombuf(buffer, &classname[i]);
2103 classname[nwhci] = '\0';
2104 TDatime::GetDateTime(datime, date, time);
2105 TClass *tclass = TClass::GetClass(classname);
2106 if (seekpdir == fSeekDir && tclass && !tclass->InheritsFrom(TFile::Class())
2107 && strcmp(classname,"TBasket")) {
2108 key = new TKey(this);
2109 key->ReadKeyBuffer(bufread);
2110 if (!strcmp(key->GetName(),"StreamerInfo")) {
2111 fSeekInfo = seekkey;
2113 fNbytesInfo = nbytes;
2114 } else {
2115 AppendKey(key);
2116 nrecov++;
2118 Info("Recover", "%s, recovered key %s:%s at address %lld",GetName(),key->GetClassName(),key->GetName(),idcur);
2119 }
2120 }
2121 delete [] classname;
2122 idcur += nbytes;
2123 }
2124 if (fWritable) {
2125 Long64_t max_file_size = Long64_t(kStartBigFile);
2126 if (max_file_size < fEND) max_file_size = fEND+1000000000;
2127 TFree *last = (TFree*)fFree->Last();
2128 if (last) {
2129 last->AddFree(fFree,fEND,max_file_size);
2130 } else {
2131 new TFree(fFree,fEND,max_file_size);
2132 }
2133 if (nrecov) Write();
2134 }
2135 return nrecov;
2136}
2137
2138////////////////////////////////////////////////////////////////////////////////
2139/// Reopen a file with a different access mode.
2140///
2141/// For example, it is possible to change from READ to
2142/// UPDATE or from NEW, CREATE, RECREATE, UPDATE to READ. Thus the
2143/// mode argument can be either "READ" or "UPDATE". The method returns
2144/// 0 in case the mode was successfully modified, 1 in case the mode
2145/// did not change (was already as requested or wrong input arguments)
2146/// and -1 in case of failure, in which case the file cannot be used
2147/// anymore. The current directory (gFile) is changed to this file.
2150{
2151 cd();
2152
2153 TString opt = mode;
2154 opt.ToUpper();
2155
2156 if (opt != "READ" && opt != "UPDATE") {
2157 Error("ReOpen", "mode must be either READ or UPDATE, not %s", opt.Data());
2158 return 1;
2159 }
2160
2161 if (opt == fOption || (opt == "UPDATE" && fOption == "CREATE"))
2162 return 1;
2163
2164 if (opt == "READ") {
2165 // switch to READ mode
2166
2167 // flush data still in the pipeline and close the file
2168 if (IsOpen() && IsWritable()) {
2170
2171 // save directory key list and header
2172 Save();
2173
2174 TFree *f1 = (TFree*)fFree->First();
2175 if (f1) {
2176 WriteFree(); // write free segments linked list
2177 WriteHeader(); // now write file header
2178 }
2179
2181
2182 // delete free segments from free list
2183 fFree->Delete();
2185
2186 SysClose(fD);
2187 fD = -1;
2188
2190 }
2191
2192 // open in READ mode
2193 fOption = opt; // set fOption before SysOpen() for TNetFile
2194#ifndef WIN32
2195 fD = SysOpen(fRealName, O_RDONLY, 0644);
2196#else
2197 fD = SysOpen(fRealName, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
2198#endif
2199 if (fD == -1) {
2200 SysError("ReOpen", "file %s can not be opened in read mode", GetName());
2201 return -1;
2202 }
2204
2205 } else {
2206 // switch to UPDATE mode
2207
2208 // close readonly file
2209 if (IsOpen()) {
2210 SysClose(fD);
2211 fD = -1;
2212 }
2213
2214 // open in UPDATE mode
2215 fOption = opt; // set fOption before SysOpen() for TNetFile
2216#ifndef WIN32
2217 fD = SysOpen(fRealName, O_RDWR | O_CREAT, 0644);
2218#else
2219 fD = SysOpen(fRealName, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
2220#endif
2221 if (fD == -1) {
2222 SysError("ReOpen", "file %s can not be opened in update mode", GetName());
2223 return -1;
2224 }
2226
2227 fFree = new TList;
2228 if (fSeekFree > fBEGIN)
2229 ReadFree();
2230 else
2231 Warning("ReOpen","file %s probably not closed, cannot read free segments", GetName());
2232 }
2233
2234 return 0;
2235}
2236
2237////////////////////////////////////////////////////////////////////////////////
2238/// Set position from where to start reading.
2241{
2242 switch (pos) {
2243 case kBeg:
2245 break;
2246 case kCur:
2247 fOffset += offset;
2248 break;
2249 case kEnd:
2250 // this option is not used currently in the ROOT code
2251 if (fArchiveOffset)
2252 Error("SetOffset", "seeking from end in archive is not (yet) supported");
2253 fOffset = fEND + offset; // is fEND really EOF or logical EOF?
2254 break;
2255 }
2256}
2257
2258////////////////////////////////////////////////////////////////////////////////
2259/// Seek to a specific position in the file. Pos it either kBeg, kCur or kEnd.
2262{
2263 int whence = 0;
2264 switch (pos) {
2265 case kBeg:
2266 whence = SEEK_SET;
2268 break;
2269 case kCur:
2270 whence = SEEK_CUR;
2271 break;
2272 case kEnd:
2273 whence = SEEK_END;
2274 // this option is not used currently in the ROOT code
2275 if (fArchiveOffset)
2276 Error("Seek", "seeking from end in archive is not (yet) supported");
2277 break;
2278 }
2279 Long64_t retpos;
2280 if ((retpos = SysSeek(fD, offset, whence)) < 0) // NOLINT: silence clang-tidy warnings
2281 SysError("Seek", "cannot seek to position %lld in file %s, retpos=%lld",
2282 offset, GetName(), retpos);
2283
2284 // used by TFileCacheRead::ReadBuffer()
2285 fOffset = retpos;
2286}
2287
2288////////////////////////////////////////////////////////////////////////////////
2289/// See comments for function SetCompressionSettings
2290///
2293{
2294 if (algorithm < 0 || algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined) algorithm = 0;
2295 if (fCompress < 0) {
2297 } else {
2298 int level = fCompress % 100;
2299 fCompress = 100 * algorithm + level;
2300 }
2301}
2302
2303////////////////////////////////////////////////////////////////////////////////
2304/// See comments for function SetCompressionSettings
2307{
2308 if (level < 0) level = 0;
2309 if (level > 99) level = 99;
2310 if (fCompress < 0) {
2311 // if the algorithm is not defined yet use 0 as a default
2312 fCompress = level;
2313 } else {
2314 int algorithm = fCompress / 100;
2315 if (algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined) algorithm = 0;
2316 fCompress = 100 * algorithm + level;
2317 }
2318}
2319
2320////////////////////////////////////////////////////////////////////////////////
2321/// Used to specify the compression level and algorithm.
2322///
2323/// See the TFile constructor for the details.
2326{
2327 fCompress = settings;
2328}
2329
2330////////////////////////////////////////////////////////////////////////////////
2331/// Set a pointer to the read cache.
2332///
2333/// <b>This relinquishes ownership</b> of the previous cache, so if you do not
2334/// already have a pointer to the previous cache (and there was a previous
2335/// cache), you ought to retrieve (and delete it if needed) using:
2336///
2337/// TFileCacheRead *older = myfile->GetCacheRead();
2338///
2339/// The action specifies how to behave when detaching a cache from the
2340/// the TFile. If set to (default) kDisconnect, the contents of the cache
2341/// will be flushed when it is removed from the file, and it will disconnect
2342/// the cache object from the file. In almost all cases, this is what you want.
2343/// If you want to disconnect the cache temporarily from this tree and re-attach
2344/// later to the same fil, you can set action to kDoNotDisconnect. This will allow
2345/// things like prefetching to continue in the background while it is no longer the
2346/// default cache for the TTree. Except for a few expert use cases, kDisconnect is
2347/// likely the correct setting.
2348///
2349/// WARNING: if action=kDoNotDisconnect, you MUST delete the cache before TFile.
2350///
2353{
2354 if (tree) {
2355 if (cache) fCacheReadMap->Add(tree, cache);
2356 else {
2357 // The only addition to fCacheReadMap is via an interface that takes
2358 // a TFileCacheRead* so the C-cast is safe.
2361 if (tpf && (tpf->GetFile() == this) && (action != kDoNotDisconnect)) tpf->SetFile(0, action);
2362 }
2363 }
2364 if (cache) cache->SetFile(this, action);
2365 else if (!tree && fCacheRead && (action != kDoNotDisconnect)) fCacheRead->SetFile(0, action);
2366 // For backward compatibility the last Cache set is the default cache.
2367 fCacheRead = cache;
2368}
2369
2370////////////////////////////////////////////////////////////////////////////////
2371/// Set a pointer to the write cache.
2372///
2373/// If file is null the existing write cache is deleted.
2376{
2377 if (!cache && fCacheWrite) delete fCacheWrite;
2378 fCacheWrite = cache;
2379}
2380
2381////////////////////////////////////////////////////////////////////////////////
2382/// Return the size in bytes of the file header.
2384Int_t TFile::Sizeof() const
2385{
2386 return 0;
2387}
2388
2389////////////////////////////////////////////////////////////////////////////////
2390/// Stream a TFile object.
2393{
2394 if (b.IsReading()) {
2395 b.ReadVersion(); //Version_t v = b.ReadVersion();
2396 } else {
2397 b.WriteVersion(TFile::IsA());
2398 }
2399}
2400
2401////////////////////////////////////////////////////////////////////////////////
2402/// Increment statistics for buffer sizes of objects in this file.
2404void TFile::SumBuffer(Int_t bufsize)
2405{
2406 fWritten++;
2407 fSumBuffer += double(bufsize);
2408 fSum2Buffer += double(bufsize) * double(bufsize); // avoid reaching MAXINT for temporary
2409}
2410
2411////////////////////////////////////////////////////////////////////////////////
2412/// Write memory objects to this file.
2413///
2414/// Loop on all objects in memory (including subdirectories).
2415/// A new key is created in the KEYS linked list for each object.
2416/// The list of keys is then saved on the file (via WriteKeys)
2417/// as a single data record.
2418/// For values of opt see TObject::Write().
2419/// The directory header info is rewritten on the directory header record.
2420/// The linked list of FREE segments is written.
2421/// The file header is written (bytes 1->fBEGIN).
2423Int_t TFile::Write(const char *, Int_t opt, Int_t bufsiz)
2424{
2425 if (!IsWritable()) {
2426 if (!TestBit(kWriteError)) {
2427 // Do not print the warning if we already had a SysError.
2428 Warning("Write", "file %s not opened in write mode", GetName());
2429 }
2430 return 0;
2431 }
2432
2433 if (gDebug) {
2434 if (!GetTitle() || strlen(GetTitle()) == 0)
2435 Info("Write", "writing name = %s", GetName());
2436 else
2437 Info("Write", "writing name = %s title = %s", GetName(), GetTitle());
2438 }
2439
2441 Int_t nbytes = TDirectoryFile::Write(0, opt, bufsiz); // Write directory tree
2443 WriteFree(); // Write free segments linked list
2444 WriteHeader(); // Now write file header
2445 fMustFlush = kTRUE;
2446
2447 return nbytes;
2448}
2449
2450////////////////////////////////////////////////////////////////////////////////
2451/// One can not save a const TDirectory object.
2453Int_t TFile::Write(const char *n, Int_t opt, Int_t bufsize) const
2454{
2455 Error("Write const","A const TFile object should not be saved. We try to proceed anyway.");
2456 return const_cast<TFile*>(this)->Write(n, opt, bufsize);
2457}
2458
2459////////////////////////////////////////////////////////////////////////////////
2460/// Write a buffer to the file. This is the basic low level write operation.
2461/// Returns kTRUE in case of failure.
2463Bool_t TFile::WriteBuffer(const char *buf, Int_t len)
2464{
2465 if (IsOpen() && fWritable) {
2466
2467 Int_t st;
2468 if ((st = WriteBufferViaCache(buf, len))) {
2469 if (st == 2)
2470 return kTRUE;
2471 return kFALSE;
2472 }
2473
2474 ssize_t siz;
2476 while ((siz = SysWrite(fD, buf, len)) < 0 && GetErrno() == EINTR) // NOLINT: silence clang-tidy warnings
2477 ResetErrno(); // NOLINT: silence clang-tidy warnings
2479 if (siz < 0) {
2480 // Write the system error only once for this file
2482 SysError("WriteBuffer", "error writing to file %s (%ld)", GetName(), (Long_t)siz);
2483 return kTRUE;
2484 }
2485 if (siz != len) {
2487 Error("WriteBuffer", "error writing all requested bytes to file %s, wrote %ld of %d",
2488 GetName(), (Long_t)siz, len);
2489 return kTRUE;
2490 }
2491 fBytesWrite += siz;
2492 fgBytesWrite += siz;
2493
2496
2497 return kFALSE;
2498 }
2499 return kTRUE;
2500}
2501
2502////////////////////////////////////////////////////////////////////////////////
2503/// Write buffer via cache. Returns 0 if cache is not active, 1 in case
2504/// write via cache was successful, 2 in case write via cache failed.
2506Int_t TFile::WriteBufferViaCache(const char *buf, Int_t len)
2507{
2508 if (!fCacheWrite) return 0;
2509
2510 Int_t st;
2511 Long64_t off = GetRelOffset();
2512 if ((st = fCacheWrite->WriteBuffer(buf, off, len)) < 0) {
2514 Error("WriteBuffer", "error writing to cache");
2515 return 2;
2516 }
2517 if (st > 0) {
2518 // fOffset might have been changed via TFileCacheWrite::WriteBuffer(), reset it
2519 Seek(off + len);
2520 return 1;
2521 }
2522 return 0;
2523}
2524
2525////////////////////////////////////////////////////////////////////////////////
2526/// Write FREE linked list on the file.
2527/// The linked list of FREE segments (fFree) is written as a single data
2528/// record.
2530void TFile::WriteFree()
2531{
2532 //*-* Delete old record if it exists
2533 if (fSeekFree != 0) {
2535 }
2536
2537 Bool_t largeFile = (fEND > TFile::kStartBigFile);
2538
2539 auto createKey = [this]() {
2540 Int_t nbytes = 0;
2541 TFree *afree;
2542 TIter next (fFree);
2543 while ((afree = (TFree*) next())) {
2544 nbytes += afree->Sizeof();
2545 }
2546 if (!nbytes) return (TKey*)nullptr;
2547
2548 TKey *key = new TKey(fName,fTitle,IsA(),nbytes,this);
2549
2550 if (key->GetSeekKey() == 0) {
2551 delete key;
2552 return (TKey*)nullptr;
2553 }
2554 return key;
2555 };
2556
2557 TKey *key = createKey();
2558 if (!key) return;
2559
2560 if (!largeFile && (fEND > TFile::kStartBigFile)) {
2561 // The free block list is large enough to bring the file to larger
2562 // than 2Gb, the references/offsets are now 64bits in the output
2563 // so we need to redo the calculation since the list of free block
2564 // information will not fit in the original size.
2565 key->Delete();
2566 delete key;
2567
2568 key = createKey();
2569 if (!key) return;
2570 }
2571
2572 Int_t nbytes = key->GetObjlen();
2573 char *buffer = key->GetBuffer();
2574 char *start = buffer;
2575
2576 TIter next (fFree);
2577 TFree *afree;
2578 while ((afree = (TFree*) next())) {
2579 // We could 'waste' time here and double check that
2580 // (buffer+afree->Sizeof() < (start+nbytes)
2581 afree->FillBuffer(buffer);
2582 }
2583 auto actualBytes = buffer-start;
2584 if ( actualBytes != nbytes ) {
2585 if (actualBytes < nbytes) {
2586 // Most likely one of the 'free' segment was used to store this
2587 // TKey, so we had one less TFree to store than we planned.
2588 memset(buffer,0,nbytes-actualBytes);
2589 } else {
2590 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);
2591 }
2592 }
2593 fNbytesFree = key->GetNbytes();
2594 fSeekFree = key->GetSeekKey();
2595 key->WriteFile();
2596 delete key;
2597}
2598
2599////////////////////////////////////////////////////////////////////////////////
2600/// Write File Header.
2602void TFile::WriteHeader()
2603{
2605 TFree *lastfree = (TFree*)fFree->Last();
2606 if (lastfree) fEND = lastfree->GetFirst();
2607 const char *root = "root";
2608 char *psave = new char[fBEGIN];
2609 char *buffer = psave;
2610 Int_t nfree = fFree->GetSize();
2611 memcpy(buffer, root, 4); buffer += 4;
2612 Int_t version = fVersion;
2613 if (version <1000000 && fEND > kStartBigFile) {version += 1000000; fUnits = 8;}
2614 tobuf(buffer, version);
2615 tobuf(buffer, (Int_t)fBEGIN);
2616 if (version < 1000000) {
2617 tobuf(buffer, (Int_t)fEND);
2618 tobuf(buffer, (Int_t)fSeekFree);
2619 tobuf(buffer, fNbytesFree);
2620 tobuf(buffer, nfree);
2621 tobuf(buffer, fNbytesName);
2622 tobuf(buffer, fUnits);
2623 tobuf(buffer, fCompress);
2624 tobuf(buffer, (Int_t)fSeekInfo);
2625 tobuf(buffer, fNbytesInfo);
2626 } else {
2627 tobuf(buffer, fEND);
2628 tobuf(buffer, fSeekFree);
2629 tobuf(buffer, fNbytesFree);
2630 tobuf(buffer, nfree);
2631 tobuf(buffer, fNbytesName);
2632 tobuf(buffer, fUnits);
2633 tobuf(buffer, fCompress);
2634 tobuf(buffer, fSeekInfo);
2635 tobuf(buffer, fNbytesInfo);
2636 }
2638 TUUID("00000000-0000-0000-0000-000000000000").FillBuffer(buffer);
2639 else
2640 fUUID.FillBuffer(buffer);
2641 Int_t nbytes = buffer - psave;
2642 Seek(0); // NOLINT: silence clang-tidy warnings
2643 WriteBuffer(psave, nbytes); // NOLINT: silence clang-tidy warnings
2644 Flush(); // NOLINT: silence clang-tidy warnings, Intentionally not conditional on fMustFlush, this is the 'obligatory' flush.
2645 delete [] psave;
2646}
2647
2648////////////////////////////////////////////////////////////////////////////////
2649/// Generate source code necessary to access the objects stored in the file.
2650///
2651/// Generate code in directory dirname for all classes specified in
2652/// argument classes If classes = "*" (default and currently the
2653/// only supported value), the function generates an include file
2654/// for each class in the StreamerInfo list for which a TClass
2655/// object does not exist.
2656///
2657/// The code generated includes:
2658/// - <em>dirnameProjectHeaders.h</em>, which contains one `#include` statement per generated header file
2659/// - <em>dirnameProjectSource.cxx</em>,which contains all the constructors and destructors implementation.
2660/// and one header per class that is not nested inside another class.
2661/// The header file name is the fully qualified name of the class after all the special characters
2662/// "<>,:" are replaced by underscored. For example for std::pair<edm::Vertex,int> the file name is
2663/// pair_edm__Vertex_int_.h
2664///
2665/// In the generated classes, map, multimap when the first template parameter is a class
2666/// are replaced by a vector of pair. set and multiset when the tempalte parameter
2667/// is a class are replaced by a vector. This is required since we do not have the
2668/// code needed to order and/or compare the object of the classes.
2669/// This is a quick explanation of the options available:
2670/// Option | Details
2671/// -------|--------
2672/// new (default) | A new directory dirname is created. If dirname already exist, an error message is printed and the function returns.
2673/// recreate | If dirname does not exist, it is created (like in "new"). If dirname already exist, all existing files in dirname are deleted before creating the new files.
2674/// update | New classes are added to the existing directory. Existing classes with the same name are replaced by the new definition. If the directory dirname doest not exist, same effect as "new".
2675/// genreflex | Use genreflex rather than rootcint to generate the dictionary.
2676/// par | Create a PAR file with the minimal set of code needed to read the content of the ROOT file. The name of the PAR file is basename(dirname), with extension '.par' enforced; the PAR file will be created at dirname(dirname).
2677///
2678/// If, in addition to one of the 3 above options, the option "+" is specified,
2679/// the function will generate:
2680/// - a script called MAKEP to build the shared lib
2681/// - a dirnameLinkDef.h file
2682/// - rootcint will be run to generate a dirnameProjectDict.cxx file
2683/// - dirnameProjectDict.cxx will be compiled with the current options in compiledata.h
2684/// - a shared lib dirname.so will be created.
2685/// If the option "++" is specified, the generated shared lib is dynamically
2686/// linked with the current executable module.
2687/// If the option "+" and "nocompile" are specified, the utility files are generated
2688/// as in the option "+" but they are not executed.
2689/// Example:
2690/// file.MakeProject("demo","*","recreate++");
2691/// - creates a new directory demo unless it already exist
2692/// - clear the previous directory content
2693/// - generate the xxx.h files for all classes xxx found in this file
2694/// and not yet known to the CINT dictionary.
2695/// - creates the build script MAKEP
2696/// - creates a LinkDef.h file
2697/// - runs rootcint generating demoProjectDict.cxx
2698/// - compiles demoProjectDict.cxx into demoProjectDict.o
2699/// - generates a shared lib demo.so
2700/// - dynamically links the shared lib demo.so to the executable
2701/// If only the option "+" had been specified, one can still link the
2702/// shared lib to the current executable module with:
2703///
2704/// gSystem->load("demo/demo.so");
2705///
2706/// The following feature is not yet enabled:
2707/// One can restrict the list of classes to be generated by using expressions like:
2708///
2709/// classes = "Ali*" generate code only for classes starting with Ali
2710/// classes = "myClass" generate code for class MyClass only.
2711///
2713void TFile::MakeProject(const char *dirname, const char * /*classes*/,
2715{
2716 TString opt = option;
2717 opt.ToLower();
2718 Bool_t makepar = kFALSE;
2719 TString parname, pardir;
2720 if (opt.Contains("par")) {
2721 // Create a PAR file
2722 parname = gSystem->BaseName(dirname);
2723 if (parname.EndsWith(".par")) parname.ReplaceAll(".par","");
2724 pardir = gSystem->GetDirName(dirname);
2725 // Cleanup or prepare the dirs
2726 TString path, filepath;
2727 void *dir = gSystem->OpenDirectory(pardir);
2728 if (dir) {
2729 path.Form("%s/%s", pardir.Data(), parname.Data());
2730 void *dirp = gSystem->OpenDirectory(path);
2731 if (dirp) {
2732 path += "/PROOF-INF";
2733 void *dirinf = gSystem->OpenDirectory(path);
2734 const char *afile = 0;
2735 if (dirinf) {
2736 while ((afile = gSystem->GetDirEntry(dirinf))) {
2737 if (strcmp(afile,".") == 0) continue;
2738 if (strcmp(afile,"..") == 0) continue;
2739 filepath.Form("%s/%s", path.Data(), afile);
2740 if (gSystem->Unlink(filepath))
2741 Warning("MakeProject", "1: problems unlinking '%s' ('%s', '%s')", filepath.Data(), path.Data(), afile);
2742 }
2743 gSystem->FreeDirectory(dirinf);
2744 }
2745 gSystem->Unlink(path);
2746 path.Form("%s/%s", pardir.Data(), parname.Data());
2747 while ((afile = gSystem->GetDirEntry(dirp))) {
2748 if (strcmp(afile,".") == 0) continue;
2749 if (strcmp(afile,"..") == 0) continue;
2750 filepath.Form("%s/%s", path.Data(), afile);
2751 if (gSystem->Unlink(filepath))
2752 Warning("MakeProject", "2: problems unlinking '%s' ('%s', '%s')", filepath.Data(), path.Data(), afile);
2753 }
2754 gSystem->FreeDirectory(dirp);
2755 if (gSystem->Unlink(path))
2756 Warning("MakeProject", "problems unlinking '%s'", path.Data());
2757 }
2758 }
2759 // Make sure that the relevant dirs exists: this is mandatory, so we fail if unsuccessful
2760 path.Form("%s/%s/PROOF-INF", pardir.Data(), parname.Data());
2761 if (gSystem->mkdir(path, kTRUE)) {
2762 Error("MakeProject", "problems creating '%s'", path.Data());
2763 return;
2764 }
2765 makepar = kTRUE;
2766
2767 } else {
2768 void *dir = gSystem->OpenDirectory(dirname);
2769 TString dirpath;
2770
2771 if (opt.Contains("update")) {
2772 // check that directory exist, if not create it
2773 if (!dir) {
2774 gSystem->mkdir(dirname);
2775 }
2776
2777 } else if (opt.Contains("recreate")) {
2778 // check that directory exist, if not create it
2779 if (!dir) {
2780 if (gSystem->mkdir(dirname) < 0) {
2781 Error("MakeProject","cannot create directory '%s'",dirname);
2782 return;
2783 }
2784 }
2785 // clear directory
2786 while (dir) {
2787 const char *afile = gSystem->GetDirEntry(dir);
2788 if (!afile) break;
2789 if (strcmp(afile,".") == 0) continue;
2790 if (strcmp(afile,"..") == 0) continue;
2791 dirpath.Form("%s/%s",dirname,afile);
2792 gSystem->Unlink(dirpath);
2793 }
2794
2795 } else {
2796 // new is assumed
2797 // if directory already exist, print error message and return
2798 if (dir) {
2799 Error("MakeProject","cannot create directory %s, already existing",dirname);
2800 gSystem->FreeDirectory(dir);
2801 return;
2802 }
2803 if (gSystem->mkdir(dirname) < 0) {
2804 Error("MakeProject","cannot create directory '%s'",dirname);
2805 return;
2806 }
2807 }
2808 if (dir) {
2809 gSystem->FreeDirectory(dir);
2810 }
2811 }
2812 Bool_t genreflex = opt.Contains("genreflex");
2813
2814 // we are now ready to generate the classes
2815 // loop on all TStreamerInfo
2816 TList *filelist = (TList*)GetStreamerInfoCache();
2817 if (filelist) filelist = (TList*)filelist->Clone();
2818 if (!filelist) {
2819 Error("MakeProject","file %s has no StreamerInfo", GetName());
2820 return;
2821 }
2822
2823 TString clean_dirname(dirname);
2824 if (makepar) clean_dirname.Form("%s/%s", pardir.Data(), parname.Data());
2825 if (clean_dirname[clean_dirname.Length()-1]=='/') {
2826 clean_dirname.Remove(clean_dirname.Length()-1);
2827 } else if (clean_dirname[clean_dirname.Length()-1]=='\\') {
2828 clean_dirname.Remove(clean_dirname.Length()-1);
2829 if (clean_dirname[clean_dirname.Length()-1]=='\\') {
2830 clean_dirname.Remove(clean_dirname.Length()-1);
2831 }
2832 }
2833 TString subdirname( gSystem->BaseName(clean_dirname) );
2834 if (makepar) subdirname = parname;
2835 if (subdirname == "") {
2836 Error("MakeProject","Directory name must not be empty.");
2837 return;
2838 }
2839
2840 // Start the source file
2841 TString spath; spath.Form("%s/%sProjectSource.cxx",clean_dirname.Data(),subdirname.Data());
2842 FILE *sfp = fopen(spath.Data(),"w");
2843 if (!sfp) {
2844 Error("MakeProject","Unable to create the source file %s.",spath.Data());
2845 return;
2846 }
2847 fprintf(sfp, "namespace std {}\nusing namespace std;\n");
2848 fprintf(sfp, "#include \"%sProjectHeaders.h\"\n\n",subdirname.Data() );
2849 if (!genreflex) fprintf(sfp, "#include \"%sLinkDef.h\"\n\n",subdirname.Data() );
2850 fprintf(sfp, "#include \"%sProjectDict.cxx\"\n\n",subdirname.Data() );
2851 fprintf(sfp, "struct DeleteObjectFunctor {\n");
2852 fprintf(sfp, " template <typename T>\n");
2853 fprintf(sfp, " void operator()(const T *ptr) const {\n");
2854 fprintf(sfp, " delete ptr;\n");
2855 fprintf(sfp, " }\n");
2856 fprintf(sfp, " template <typename T, typename Q>\n");
2857 fprintf(sfp, " void operator()(const std::pair<T,Q> &) const {\n");
2858 fprintf(sfp, " // Do nothing\n");
2859 fprintf(sfp, " }\n");
2860 fprintf(sfp, " template <typename T, typename Q>\n");
2861 fprintf(sfp, " void operator()(const std::pair<T,Q*> &ptr) const {\n");
2862 fprintf(sfp, " delete ptr.second;\n");
2863 fprintf(sfp, " }\n");
2864 fprintf(sfp, " template <typename T, typename Q>\n");
2865 fprintf(sfp, " void operator()(const std::pair<T*,Q> &ptr) const {\n");
2866 fprintf(sfp, " delete ptr.first;\n");
2867 fprintf(sfp, " }\n");
2868 fprintf(sfp, " template <typename T, typename Q>\n");
2869 fprintf(sfp, " void operator()(const std::pair<T*,Q*> &ptr) const {\n");
2870 fprintf(sfp, " delete ptr.first;\n");
2871 fprintf(sfp, " delete ptr.second;\n");
2872 fprintf(sfp, " }\n");
2873 fprintf(sfp, "};\n\n");
2874 fclose( sfp );
2875
2876 // loop on all TStreamerInfo classes to check for empty classes
2877 // and enums listed either as data member or template parameters,
2878 // and filter out 'duplicates' classes/streamerInfos.
2879 TStreamerInfo *info;
2880 TIter flnext(filelist);
2881 TList extrainfos;
2882 TList *list = new TList();
2883 while ((info = (TStreamerInfo*)flnext())) {
2884 if (info->IsA() != TStreamerInfo::Class()) {
2885 continue;
2886 }
2887 if (strstr(info->GetName(),"@@")) {
2888 // Skip schema evolution support streamerInfo
2889 continue;
2890 }
2891 TClass *cl = TClass::GetClass(info->GetName());
2892 if (cl) {
2893 if (cl->HasInterpreterInfo()) continue; // skip known classes
2894 }
2895 // Find and use the proper rules for the TStreamerInfos.
2897 TIter enext( info->GetElements() );
2898 TStreamerElement *el;
2900 if (cl && cl->GetSchemaRules()) {
2901 rules = cl->GetSchemaRules()->FindRules(cl->GetName(), info->GetClassVersion());
2902 }
2903 while( (el=(TStreamerElement*)enext()) ) {
2904 for(auto rule : rules) {
2905 if( rule->IsRenameRule() || rule->IsAliasRule() )
2906 continue;
2907 // Check whether this is an 'attribute' rule.
2908 if ( rule->HasTarget( el->GetName()) && rule->GetAttributes()[0] != 0 ) {
2909 TString attr( rule->GetAttributes() );
2910 attr.ToLower();
2911 if (attr.Contains("owner")) {
2912 if (attr.Contains("notowner")) {
2914 } else {
2916 }
2917 }
2918 }
2919 }
2921 }
2922 TVirtualStreamerInfo *alternate = (TVirtualStreamerInfo*)list->FindObject(info->GetName());
2923 if (alternate) {
2924 if ((info->GetClass() && info->GetClassVersion() == info->GetClass()->GetClassVersion())
2925 || (info->GetClassVersion() > alternate->GetClassVersion()) ) {
2926 list->AddAfter(alternate, info);
2927 list->Remove(alternate);
2928 } // otherwise ignore this info as not being the official one.
2929 } else {
2930 list->Add(info);
2931 }
2932 }
2933 // Now transfer the new StreamerInfo onto the main list and
2934 // to the owning list.
2935 TIter nextextra(&extrainfos);
2936 while ((info = (TStreamerInfo*)nextextra())) {
2937 list->Add(info);
2938 filelist->Add(info);
2939 }
2940
2941 // loop on all TStreamerInfo classes
2942 TIter next(list);
2943 Int_t ngener = 0;
2944 while ((info = (TStreamerInfo*)next())) {
2945 if (info->IsA() != TStreamerInfo::Class()) {
2946 continue;
2947 }
2948 if (info->GetClassVersion()==-4) continue; // Skip outer level namespace
2949 TIter subnext(list);
2950 TStreamerInfo *subinfo;
2951 TList subClasses;
2952 Int_t len = strlen(info->GetName());
2953 while ((subinfo = (TStreamerInfo*)subnext())) {
2954 if (subinfo->IsA() != TStreamerInfo::Class()) {
2955 continue;
2956 }
2957 if (strncmp(info->GetName(),subinfo->GetName(),len)==0) {
2958 // The 'sub' StreamerInfo start with the main StreamerInfo name,
2959 // it subinfo is likely to be a nested class.
2960 const Int_t sublen = strlen(subinfo->GetName());
2961 if ( (sublen > len) && subinfo->GetName()[len+1]==':'
2962 && !subClasses.FindObject(subinfo->GetName()) /* We need to insure uniqueness */)
2963 {
2964 subClasses.Add(subinfo);
2965 }
2966 }
2967 }
2968 ngener += info->GenerateHeaderFile(clean_dirname.Data(),&subClasses,&extrainfos);
2969 subClasses.Clear("nodelete");
2970 }
2971 extrainfos.Clear("nodelete"); // We are done with this list.
2972
2973 TString path;
2974 path.Form("%s/%sProjectHeaders.h",clean_dirname.Data(),subdirname.Data());
2975 FILE *allfp = fopen(path,"a");
2976 if (!allfp) {
2977 Error("MakeProject","Cannot open output file:%s\n",path.Data());
2978 } else {
2979 fprintf(allfp,"#include \"%sProjectInstances.h\"\n", subdirname.Data());
2980 fclose(allfp);
2981 }
2982
2983 printf("MakeProject has generated %d classes in %s\n",ngener,clean_dirname.Data());
2984
2985 // generate the shared lib
2986 if (!opt.Contains("+") && !makepar) {
2987 delete list;
2988 filelist->Delete();
2989 delete filelist;
2990 return;
2991 }
2992
2993 // Makefiles files
2994 FILE *fpMAKE = nullptr;
2995 if (!makepar) {
2996 // Create the MAKEP file by looping on all *.h files
2997 // delete MAKEP if it already exists
2998#ifdef WIN32
2999 path.Form("%s/makep.cmd",clean_dirname.Data());
3000#else
3001 path.Form("%s/MAKEP",clean_dirname.Data());
3002#endif
3003#ifdef R__WINGCC
3004 fpMAKE = fopen(path,"wb");
3005#else
3006 fpMAKE = fopen(path,"w");
3007#endif
3008 if (!fpMAKE) {
3009 Error("MakeProject", "cannot open file %s", path.Data());
3010 delete list;
3011 filelist->Delete();
3012 delete filelist;
3013 return;
3014 }
3015 }
3016
3017 // Add rootcint/genreflex statement generating ProjectDict.cxx
3018 FILE *ifp = nullptr;
3019 path.Form("%s/%sProjectInstances.h",clean_dirname.Data(),subdirname.Data());
3020#ifdef R__WINGCC
3021 ifp = fopen(path,"wb");
3022#else
3023 ifp = fopen(path,"w");
3024#endif
3025 if (!ifp) {
3026 Error("MakeProject", "cannot open path file %s", path.Data());
3027 delete list;
3028 filelist->Delete();
3029 delete filelist;
3030 fclose(fpMAKE);
3031 return;
3032 }
3033
3034 if (!makepar) {
3035 if (genreflex) {
3036 fprintf(fpMAKE,"genreflex %sProjectHeaders.h -o %sProjectDict.cxx --comments --iocomments %s ",subdirname.Data(),subdirname.Data(),gSystem->GetIncludePath());
3037 path.Form("%s/%sSelection.xml",clean_dirname.Data(),subdirname.Data());
3038 } else {
3039 fprintf(fpMAKE,"rootcint -v1 -f %sProjectDict.cxx %s ", subdirname.Data(), gSystem->GetIncludePath());
3040 path.Form("%s/%sLinkDef.h",clean_dirname.Data(),subdirname.Data());
3041 }
3042 } else {
3043 path.Form("%s/%sLinkDef.h",clean_dirname.Data(),subdirname.Data());
3044 }
3045
3046 // Create the LinkDef.h or xml selection file by looping on all *.h files
3047 // replace any existing file.
3048#ifdef R__WINGCC
3049 FILE *fp = fopen(path,"wb");
3050#else
3051 FILE *fp = fopen(path,"w");
3052#endif
3053 if (!fp) {
3054 Error("MakeProject", "cannot open path file %s", path.Data());
3055 delete list;
3056 filelist->Delete();
3057 delete filelist;
3058 fclose(fpMAKE);
3059 fclose(ifp);
3060 return;
3061 }
3062 if (genreflex) {
3063 fprintf(fp,"<lcgdict>\n");
3064 fprintf(fp,"\n");
3065 } else {
3066 fprintf(fp,"#ifdef __CINT__\n");
3067 fprintf(fp,"\n");
3068 }
3069
3070 TString tmp;
3071 TString instances;
3072 TString selections;
3073 next.Reset();
3074 while ((info = (TStreamerInfo*)next())) {
3075 if (info->IsA() != TStreamerInfo::Class()) {
3076 continue;
3077 }
3078 if (strncmp(info->GetName(), "auto_ptr<", strlen("auto_ptr<")) == 0) {
3079 continue;
3080 }
3081 TClass *cl = TClass::GetClass(info->GetName());
3082 if (cl) {
3083 if (cl->HasInterpreterInfo()) continue; // skip known classes
3084 if (cl->GetSchemaRules()) {
3085 auto rules = cl->GetSchemaRules()->FindRules(cl->GetName(), info->GetClassVersion());
3086 TString strrule;
3087 for(auto rule : rules) {
3088 strrule.Clear();
3089 if (genreflex) {
3090 rule->AsString(strrule,"x");
3091 strrule.Append("\n");
3092 if ( selections.Index(strrule) == kNPOS ) {
3093 selections.Append(strrule);
3094 }
3095 } else {
3096 rule->AsString(strrule);
3097 if (strncmp(strrule.Data(),"type=",5)==0) {
3098 strrule.Remove(0,5);
3099 }
3100 fprintf(fp,"#pragma %s;\n",strrule.Data());
3101 }
3102 }
3103 }
3104
3105 }
3106 if ((info->GetClass() && info->GetClass()->GetCollectionType()) || TClassEdit::IsSTLCont(info->GetName())) {
3107 std::vector<std::string> inside;
3108 int nestedLoc;
3109 TClassEdit::GetSplit( info->GetName(), inside, nestedLoc, TClassEdit::kLong64 );
3110 Int_t stlkind = TClassEdit::STLKind(inside[0]);
3111 TClass *key = TClass::GetClass(inside[1].c_str());
3112 if (key) {
3113 TString what;
3114 switch ( stlkind ) {
3115 case ROOT::kSTLmap:
3116 case ROOT::kSTLmultimap:
3117 if (TClass::GetClass(inside[1].c_str())) {
3118 what = "std::pair<";
3119 what += TMakeProject::UpdateAssociativeToVector( inside[1].c_str() );
3120 what += ",";
3121 what += TMakeProject::UpdateAssociativeToVector( inside[2].c_str() );
3122 if (what[what.Length()-1]=='>') {
3123 what += " >";
3124 } else {
3125 what += ">";
3126 }
3127 if (genreflex) {
3128 tmp.Form("<class name=\"%s\" />\n",what.Data());
3129 if ( selections.Index(tmp) == kNPOS ) {
3130 selections.Append(tmp);
3131 }
3132 tmp.Form("template class %s;\n",what.Data());
3133 if ( instances.Index(tmp) == kNPOS ) {
3134 instances.Append(tmp);
3135 }
3136 } else {
3137 what.ReplaceAll("std::","");
3138 TClass *paircl = TClass::GetClass(what.Data());
3139 if (!paircl || !paircl->HasInterpreterInfo()) {
3140 fprintf(fp,"#pragma link C++ class %s+;\n",what.Data());
3141 }
3142 }
3143 break;
3144 }
3145 default:
3146 if (TClassEdit::IsStdPair(key->GetName())) {
3147 if (genreflex) {
3148 tmp.Form("<class name=\"%s\" />\n",key->GetName());
3149 if ( selections.Index(tmp) == kNPOS ) {
3150 selections.Append(tmp);
3151 }
3152 tmp.Form("template class %s;\n",key->GetName());
3153 if ( instances.Index(tmp) == kNPOS ) {
3154 instances.Append(tmp);
3155 }
3156 } else {
3157 what.ReplaceAll("std::","");
3158 fprintf(fp,"#pragma link C++ class %s+;\n",key->GetName());
3159 }
3160 }
3161 break;
3162 }
3163 }
3164 continue;
3165 }
3166 {
3168 if (genreflex) {
3169 tmp.Form("<class name=\"%s\" />\n",what.Data());
3170 if ( selections.Index(tmp) == kNPOS ) {
3171 selections.Append(tmp);
3172 }
3173 if (what[what.Length()-1] == '>') {
3174 tmp.Form("template class %s;\n",what.Data());
3175 if ( instances.Index(tmp) == kNPOS ) {
3176 instances.Append(tmp);
3177 }
3178 }
3179 } else {
3180 what.ReplaceAll("std::","");
3181 fprintf(fp,"#pragma link C++ class %s+;\n",what.Data());
3182 }
3183 }
3184 if (genreflex) {
3185 // Also request the dictionary for the STL container used as members ...
3186 TIter eliter( info->GetElements() );
3187 TStreamerElement *element;
3188 while( (element = (TStreamerElement*)eliter() ) ) {
3189 if (element->GetClass() && !element->GetClass()->IsLoaded() && element->GetClass()->GetCollectionProxy()) {
3191 tmp.Form("<class name=\"%s\" />\n",what.Data());
3192 if ( selections.Index(tmp) == kNPOS ) {
3193 selections.Append(tmp);
3194 }
3195 tmp.Form("template class %s;\n",what.Data());
3196 if ( instances.Index(tmp) == kNPOS ) {
3197 instances.Append(tmp);
3198 }
3199 }
3200 }
3201 }
3202 }
3203 if (genreflex) {
3204 fprintf(ifp,"#ifndef PROJECT_INSTANCES_H\n");
3205 fprintf(ifp,"#define PROJECT_INSTANCES_H\n");
3206 fprintf(ifp,"%s",instances.Data());
3207 fprintf(ifp,"#endif\n");
3208 fprintf(fp,"%s",selections.Data());
3209 fprintf(fp,"</lcgdict>\n");
3210 } else {
3211 fprintf(fp,"#endif\n");
3212 }
3213 fclose(fp);
3214 fclose(ifp);
3215
3216 if (!makepar) {
3217 // add compilation line
3218 TString sdirname(subdirname);
3219
3221 TString sources = TString::Format("%sProjectSource.cxx ", sdirname.Data());
3222 cmd.ReplaceAll("$SourceFiles",sources.Data());
3223 TString object = TString::Format("%sProjectSource.", sdirname.Data());
3224 object.Append( gSystem->GetObjExt() );
3225 cmd.ReplaceAll("$ObjectFiles", object.Data());
3226 cmd.ReplaceAll("$IncludePath",TString(gSystem->GetIncludePath()) + " -I" + clean_dirname.Data());
3227 cmd.ReplaceAll("$SharedLib",sdirname+"."+gSystem->GetSoExt());
3228 cmd.ReplaceAll("$LinkedLibs",gSystem->GetLibraries("","SDL"));
3229 cmd.ReplaceAll("$LibName",sdirname);
3230 cmd.ReplaceAll("$BuildDir",".");
3231 TString sOpt;
3232 TString rootbuild = ROOTBUILD;
3233 if (rootbuild.Index("debug",0,TString::kIgnoreCase)==kNPOS) {
3234 sOpt = gSystem->GetFlagsOpt();
3235 } else {
3236 sOpt = gSystem->GetFlagsDebug();
3237 }
3238 cmd.ReplaceAll("$Opt", sOpt);
3239
3240 if (genreflex) {
3241 fprintf(fpMAKE,"-s %sSelection.xml \n",subdirname.Data());
3242 } else {
3243 fprintf(fpMAKE,"%sProjectHeaders.h ",subdirname.Data());
3244 fprintf(fpMAKE,"%sLinkDef.h \n",subdirname.Data());
3245 }
3246
3247 fprintf(fpMAKE,"%s\n",cmd.Data());
3248
3249 printf("%s/MAKEP file has been generated\n", clean_dirname.Data());
3250
3251 fclose(fpMAKE);
3252
3253 } else {
3254
3255 // Create the Makefile
3256 TString filemake = TString::Format("%s/Makefile", clean_dirname.Data());
3257 if (MakeProjectParMake(parname, filemake.Data()) != 0) {
3258 Error("MakeProject", "problems creating PAR make file '%s'", filemake.Data());
3259 delete list;
3260 filelist->Delete();
3261 delete filelist;
3262 return;
3263 }
3264 // Get Makefile.arch
3265 TString mkarchsrc = TString::Format("%s/Makefile.arch", TROOT::GetEtcDir().Data());
3266 if (gSystem->ExpandPathName(mkarchsrc))
3267 Warning("MakeProject", "problems expanding '%s'", mkarchsrc.Data());
3268 TString mkarchdst = TString::Format("%s/Makefile.arch", clean_dirname.Data());
3269 if (gSystem->CopyFile(mkarchsrc.Data(), mkarchdst.Data(), kTRUE) != 0) {
3270 Error("MakeProject", "problems retrieving '%s' to '%s'", mkarchsrc.Data(), mkarchdst.Data());
3271 delete list;
3272 filelist->Delete();
3273 delete filelist;
3274 return;
3275 }
3276 // Create the Makefile
3277 TString proofinf = TString::Format("%s/PROOF-INF", clean_dirname.Data());
3278 if (MakeProjectParProofInf(parname, proofinf.Data()) != 0) {
3279 Error("MakeProject", "problems creating BUILD.sh and/or SETUP.C under '%s'", proofinf.Data());
3280 delete list;
3281 filelist->Delete();
3282 delete filelist;
3283 return;
3284 }
3285
3286 // Make sure BUILD.sh is executable and create SETUP.C
3287 TString cmod = TString::Format("chmod +x %s/PROOF-INF/BUILD.sh", clean_dirname.Data());
3288#ifndef WIN32
3289 gSystem->Exec(cmod.Data());
3290#else
3291 // not really needed for Windows but it would work both both Unix and NT
3292 chmod(cmod.Data(), 00700);
3293#endif
3294 Printf("Files Makefile, Makefile.arch, PROOF-INF/BUILD.sh and"
3295 " PROOF-INF/SETUP.C have been generated under '%s'", clean_dirname.Data());
3296
3297 // Generate the PAR file, if not Windows
3298#ifndef WIN32
3299 TString curdir = gSystem->WorkingDirectory();
3300 if (gSystem->ChangeDirectory(pardir)) {
3301 TString cmd = TString::Format("tar czvf %s.par %s", parname.Data(), parname.Data());
3302 gSystem->Exec(cmd.Data());
3303 if (gSystem->ChangeDirectory(curdir)) {
3304 Info("MakeProject", "PAR file %s.par generated", clean_dirname.Data());
3305 } else {
3306 Warning("MakeProject", "problems changing directory back to '%s'", curdir.Data());
3307 }
3308 } else {
3309 Error("MakeProject", "problems changing directory to '%s' - skipping PAR file generation", pardir.Data());
3310 }
3311#else
3312 Warning("MakeProject", "on Windows systems the PAR file cannot be generated out of the package directory!");
3313#endif
3314 }
3315
3316
3317 if (!makepar && !opt.Contains("nocompilation")) {
3318 // now execute the generated script compiling and generating the shared lib
3319 path = gSystem->WorkingDirectory();
3320 gSystem->ChangeDirectory(clean_dirname.Data());
3321#ifndef WIN32
3322 gSystem->Exec("chmod +x MAKEP");
3323 int res = !gSystem->Exec("./MAKEP");
3324#else
3325 // not really needed for Windows but it would work both both Unix and NT
3326 chmod("makep.cmd",00700);
3327 int res = !gSystem->Exec("MAKEP");
3328#endif
3329 gSystem->ChangeDirectory(path);
3330 path.Form("%s/%s.%s",clean_dirname.Data(),subdirname.Data(),gSystem->GetSoExt());
3331 if (res) printf("Shared lib %s has been generated\n",path.Data());
3332
3333 //dynamically link the generated shared lib
3334 if (opt.Contains("++")) {
3335 res = !gSystem->Load(path);
3336 if (res) printf("Shared lib %s has been dynamically linked\n",path.Data());
3337 }
3338 }
3339
3340 delete list;
3341 filelist->Delete();
3342 delete filelist;
3343}
3344
3345////////////////////////////////////////////////////////////////////////////////
3346/// Create makefile at 'filemake' for PAR package 'pack'.
3347///
3348/// Called by MakeProject when option 'par' is given.
3349/// Return 0 on success, -1 on error.
3351Int_t TFile::MakeProjectParMake(const char *pack, const char *filemake)
3352{
3353 // Output file path must be defined
3354 if (!filemake || (filemake && strlen(filemake) <= 0)) {
3355 Error("MakeProjectParMake", "path for output file undefined!");
3356 return -1;
3357 }
3358
3359 // Package name must be defined
3360 if (!pack || (pack && strlen(pack) <= 0)) {
3361 Error("MakeProjectParMake", "package name undefined!");
3362 return -1;
3363 }
3364
3365#ifdef R__WINGCC
3366 FILE *fmk = fopen(filemake, "wb");
3367#else
3368 FILE *fmk = fopen(filemake, "w");
3369#endif
3370 if (!fmk) {
3371 Error("MakeProjectParMake", "cannot create file '%s' (errno: %d)", filemake, TSystem::GetErrno());
3372 return -1;
3373 }
3374
3375 // Fill the file now
3376 fprintf(fmk, "# Makefile for the ROOT test programs.\n");
3377 fprintf(fmk, "# This Makefile shows how to compile and link applications\n");
3378 fprintf(fmk, "# using the ROOT libraries on all supported platforms.\n");
3379 fprintf(fmk, "#\n");
3380 fprintf(fmk, "# Copyright (c) 2000 Rene Brun and Fons Rademakers\n");
3381 fprintf(fmk, "#\n");
3382 fprintf(fmk, "# Author: this makefile has been automatically generated via TFile::MakeProject\n");
3383 fprintf(fmk, "\n");
3384 fprintf(fmk, "include Makefile.arch\n");
3385 fprintf(fmk, "\n");
3386 fprintf(fmk, "#------------------------------------------------------------------------------\n");
3387 fprintf(fmk, "\n");
3388 fprintf(fmk, "PACKO = %sProjectSource.$(ObjSuf)\n", pack);
3389 fprintf(fmk, "PACKS = %sProjectSource.$(SrcSuf) %sProjectDict.$(SrcSuf)\n", pack, pack);
3390 fprintf(fmk, "PACKSO = lib%s.$(DllSuf)\n", pack);
3391 fprintf(fmk, "\n");
3392 fprintf(fmk, "ifeq ($(PLATFORM),win32)\n");
3393 fprintf(fmk, "PACKLIB = lib%s.lib\n", pack);
3394 fprintf(fmk, "else\n");
3395 fprintf(fmk, "PACKLIB = $(PACKSO)\n");
3396 fprintf(fmk, "endif\n");
3397 fprintf(fmk, "\n");
3398 fprintf(fmk, "OBJS = $(PACKO)\n");
3399 fprintf(fmk, "\n");
3400 fprintf(fmk, "PROGRAMS =\n");
3401 fprintf(fmk, "\n");
3402 fprintf(fmk, "#------------------------------------------------------------------------------\n");
3403 fprintf(fmk, "\n");
3404 fprintf(fmk, ".SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)\n");
3405 fprintf(fmk, "\n");
3406 fprintf(fmk, "all: $(PACKLIB)\n");
3407 fprintf(fmk, "\n");
3408 fprintf(fmk, "$(PACKSO): $(PACKO)\n");
3409 fprintf(fmk, "ifeq ($(ARCH),aix)\n");
3410 fprintf(fmk, "\t\t/usr/ibmcxx/bin/makeC++SharedLib $(OutPutOpt) $@ $(LIBS) -p 0 $^\n");
3411 fprintf(fmk, "else\n");
3412 fprintf(fmk, "ifeq ($(ARCH),aix5)\n");
3413 fprintf(fmk, "\t\t/usr/vacpp/bin/makeC++SharedLib $(OutPutOpt) $@ $(LIBS) -p 0 $^\n");
3414 fprintf(fmk, "else\n");
3415 fprintf(fmk, "ifeq ($(PLATFORM),macosx)\n");
3416 fprintf(fmk, "# We need to make both the .dylib and the .so\n");
3417 fprintf(fmk, "\t\t$(LD) $(SOFLAGS)$@ $(LDFLAGS) $^ $(OutPutOpt) $@ $(LIBS)\n");
3418 fprintf(fmk, "ifneq ($(subst $(MACOSX_MINOR),,1234),1234)\n");
3419 fprintf(fmk, "ifeq ($(MACOSX_MINOR),4)\n");
3420 fprintf(fmk, "\t\tln -sf $@ $(subst .$(DllSuf),.so,$@)\n");
3421 fprintf(fmk, "else\n");
3422 fprintf(fmk, "\t\t$(LD) -bundle -undefined $(UNDEFOPT) $(LDFLAGS) $^ \\\n");
3423 fprintf(fmk, "\t\t $(OutPutOpt) $(subst .$(DllSuf),.so,$@)\n");
3424 fprintf(fmk, "endif\n");
3425 fprintf(fmk, "endif\n");
3426 fprintf(fmk, "else\n");
3427 fprintf(fmk, "ifeq ($(PLATFORM),win32)\n");
3428 fprintf(fmk, "\t\tbindexplib $* $^ > $*.def\n");
3429 fprintf(fmk, "\t\tlib -nologo -MACHINE:IX86 $^ -def:$*.def \\\n");
3430 fprintf(fmk, "\t\t $(OutPutOpt)$(PACKLIB)\n");
3431 fprintf(fmk, "\t\t$(LD) $(SOFLAGS) $(LDFLAGS) $^ $*.exp $(LIBS) \\\n");
3432 fprintf(fmk, "\t\t $(OutPutOpt)$@\n");
3433 fprintf(fmk, "else\n");
3434 fprintf(fmk, "\t\t$(LD) $(SOFLAGS) $(LDFLAGS) $^ $(OutPutOpt) $@ $(LIBS) $(EXPLLINKLIBS)\n");
3435 fprintf(fmk, "endif\n");
3436 fprintf(fmk, "endif\n");
3437 fprintf(fmk, "endif\n");
3438 fprintf(fmk, "endif\n");
3439 fprintf(fmk, "\t\t@echo \"$@ done\"\n");
3440 fprintf(fmk, "\n");
3441 fprintf(fmk, "clean:\n");
3442 fprintf(fmk, "\t\t@rm -f $(OBJS) core\n");
3443 fprintf(fmk, "\n");
3444 fprintf(fmk, "distclean: clean\n");
3445 fprintf(fmk, "\t\t@rm -f $(PROGRAMS) $(PACKSO) $(PACKLIB) *Dict.* *.def *.exp \\\n");
3446 fprintf(fmk, "\t\t *.so *.lib *.dll *.d *.log .def so_locations\n");
3447 fprintf(fmk, "\t\t@rm -rf cxx_repository\n");
3448 fprintf(fmk, "\n");
3449 fprintf(fmk, "# Dependencies\n");
3450 fprintf(fmk, "\n");
3451 fprintf(fmk, "%sProjectSource.$(ObjSuf): %sProjectHeaders.h %sLinkDef.h %sProjectDict.$(SrcSuf)\n", pack, pack, pack, pack);
3452 fprintf(fmk, "\n");
3453 fprintf(fmk, "%sProjectDict.$(SrcSuf): %sProjectHeaders.h %sLinkDef.h\n", pack, pack, pack);
3454 fprintf(fmk, "\t\t@echo \"Generating dictionary $@...\"\n");
3455 fprintf(fmk, "\t\t@rootcint -f $@ $^\n");
3456 fprintf(fmk, "\n");
3457 fprintf(fmk, ".$(SrcSuf).$(ObjSuf):\n");
3458 fprintf(fmk, "\t\t$(CXX) $(CXXFLAGS) -c $<\n");
3459 fprintf(fmk, "\n");
3460
3461 // Close the file
3462 fclose(fmk);
3463
3464 // Done
3465 return 0;
3466}
3467
3468////////////////////////////////////////////////////////////////////////////////
3469/// Create BUILD.sh and SETUP.C under 'proofinf' for PAR package 'pack'.
3470/// Called by MakeProject when option 'par' is given.
3471/// Return 0 on success, -1 on error.
3473Int_t TFile::MakeProjectParProofInf(const char *pack, const char *proofinf)
3474{
3475 // Output directory path must be defined ...
3476 if (!proofinf || (proofinf && strlen(proofinf) <= 0)) {
3477 Error("MakeProjectParProofInf", "directory path undefined!");
3478 return -1;
3479 }
3480
3481 // ... and exist and be a directory
3482 Int_t rcst = 0;
3483 FileStat_t st;
3484 if ((rcst = gSystem->GetPathInfo(proofinf, st)) != 0 || !R_ISDIR(st.fMode)) {
3485 Error("MakeProjectParProofInf", "path '%s' %s", proofinf,
3486 ((rcst == 0) ? "is not a directory" : "does not exist"));
3487 return -1;
3488 }
3489
3490 // Package name must be defined
3491 if (!pack || (pack && strlen(pack) <= 0)) {
3492 Error("MakeProjectParProofInf", "package name undefined!");
3493 return -1;
3494 }
3495
3496 TString path;
3497
3498 // The BUILD.sh first
3499 path.Form("%s/BUILD.sh", proofinf);
3500#ifdef R__WINGCC
3501 FILE *f = fopen(path.Data(), "wb");
3502#else
3503 FILE *f = fopen(path.Data(), "w");
3504#endif
3505 if (!f) {
3506 Error("MakeProjectParProofInf", "cannot create file '%s' (errno: %d)",
3507 path.Data(), TSystem::GetErrno());
3508 return -1;
3509 }
3510
3511 fprintf(f, "#! /bin/sh\n");
3512 fprintf(f, "# Build libEvent library.\n");
3513 fprintf(f, "\n");
3514 fprintf(f, "#\n");
3515 fprintf(f, "# The environment variables ROOTPROOFLITE and ROOTPROOFCLIENT can be used to\n");
3516 fprintf(f, "# adapt the script to the calling environment\n");
3517 fprintf(f, "#\n");
3518 fprintf(f, "# if test ! \"x$ROOTPROOFLITE\" = \"x\"; then\n");
3519 fprintf(f, "# echo \"event-BUILD: PROOF-Lite node (session has $ROOTPROOFLITE workers)\"\n");
3520 fprintf(f, "# elif test ! \"x$ROOTPROOFCLIENT\" = \"x\"; then\n");
3521 fprintf(f, "# echo \"event-BUILD: PROOF client\"\n");
3522 fprintf(f, "# else\n");
3523 fprintf(f, "# echo \"event-BUILD: standard PROOF node\"\n");
3524 fprintf(f, "# fi\n");
3525 fprintf(f, "\n");
3526 fprintf(f, "if [ \"\" = \"clean\" ]; then\n");
3527 fprintf(f, " make distclean\n");
3528 fprintf(f, " exit 0\n");
3529 fprintf(f, "fi\n");
3530 fprintf(f, "\n");
3531 fprintf(f, "make\n");
3532 fprintf(f, "rc=$?\n");
3533 fprintf(f, "echo \"rc=$?\"\n");
3534 fprintf(f, "if [ $? != \"0\" ] ; then\n");
3535 fprintf(f, " exit 1\n");
3536 fprintf(f, "fi\n");
3537 fprintf(f, "exit 0\n");
3538
3539 // Close the file
3540 fclose(f);
3541
3542 // Then SETUP.C
3543 path.Form("%s/SETUP.C", proofinf);
3544#ifdef R__WINGCC
3545 f = fopen(path.Data(), "wb");
3546#else
3547 f = fopen(path.Data(), "w");
3548#endif
3549 if (!f) {
3550 Error("MakeProjectParProofInf", "cannot create file '%s' (errno: %d)",
3551 path.Data(), TSystem::GetErrno());
3552 return -1;
3553 }
3554
3555 fprintf(f, "Int_t SETUP()\n");
3556 fprintf(f, "{\n");
3557 fprintf(f, "\n");
3558 fprintf(f, "//\n");
3559 fprintf(f, "// The environment variables ROOTPROOFLITE and ROOTPROOFCLIENT can be used to\n");
3560 fprintf(f, "// adapt the macro to the calling environment\n");
3561 fprintf(f, "//\n");
3562 fprintf(f, "// if (gSystem->Getenv(\"ROOTPROOFLITE\")) {\n");
3563 fprintf(f, "// Printf(\"event-SETUP: PROOF-Lite node (session has %%s workers)\",\n");
3564 fprintf(f, "// gSystem->Getenv(\"ROOTPROOFLITE\"));\n");
3565 fprintf(f, "// } else if (gSystem->Getenv(\"ROOTPROOFCLIENT\")) {\n");
3566 fprintf(f, "// Printf(\"event-SETUP: PROOF client\");\n");
3567 fprintf(f, "// } else {\n");
3568 fprintf(f, "// Printf(\"event-SETUP: standard PROOF node\");\n");
3569 fprintf(f, "// }\n");
3570 fprintf(f, "\n");
3571 fprintf(f, " if (gSystem->Load(\"lib%s\") == -1)\n", pack);
3572 fprintf(f, " return -1;\n");
3573 fprintf(f, " return 0;\n");
3574 fprintf(f, "}\n");
3575 fprintf(f, "\n");
3576
3577 // Close the file
3578 fclose(f);
3579
3580 // Done
3581 return 0;
3582}
3583
3584////////////////////////////////////////////////////////////////////////////////
3585/// Read the list of StreamerInfo from this file.
3586///
3587/// The key with name holding the list of TStreamerInfo objects is read.
3588/// The corresponding TClass objects are updated.
3589/// Note that this function is not called if the static member fgReadInfo is false.
3590/// (see TFile::SetReadStreamerInfo)
3593{
3594 auto listRetcode = GetStreamerInfoListImpl(/*lookupSICache*/ true); // NOLINT: silence clang-tidy warnings
3595 TList *list = listRetcode.fList;
3596 auto retcode = listRetcode.fReturnCode;
3597 if (!list) {
3598 if (retcode) MakeZombie();
3599 return;
3600 }
3601
3602 list->SetOwner(kFALSE);
3603
3604 if (gDebug > 0) Info("ReadStreamerInfo", "called for file %s",GetName());
3605
3606 TStreamerInfo *info;
3607
3608 Int_t version = fVersion;
3609 if (version > 1000000) version -= 1000000;
3610 if (version < 53419 || (59900 < version && version < 59907)) {
3611 // We need to update the fCheckSum field of the TStreamerBase.
3612
3613 // loop on all TStreamerInfo classes
3614 TObjLink *lnk = list->FirstLink();
3615 while (lnk) {
3616 info = (TStreamerInfo*)lnk->GetObject();
3617 if (!info || info->IsA() != TStreamerInfo::Class()) {
3618 lnk = lnk->Next();
3619 continue;
3620 }
3621 TIter next(info->GetElements());
3622 TStreamerElement *element;
3623 while ((element = (TStreamerElement*) next())) {
3624 TStreamerBase *base = dynamic_cast<TStreamerBase*>(element);
3625 if (!base) continue;
3626 if (base->GetBaseCheckSum() != 0) continue;
3627 TStreamerInfo *baseinfo = (TStreamerInfo*)list->FindObject(base->GetName());
3628 if (baseinfo) {
3629 base->SetBaseCheckSum(baseinfo->GetCheckSum());
3630 }
3631 }
3632 lnk = lnk->Next();
3633 }
3634 }
3635
3636 std::vector<Int_t> si_uids;
3637 // loop on all TStreamerInfo classes
3638 for (int mode=0;mode<2; ++mode) {
3639 // In order for the collection proxy to be initialized properly, we need
3640 // to setup the TStreamerInfo for non-stl class before the stl classes.
3641 TObjLink *lnk = list->FirstLink();
3642 while (lnk) {
3643 info = (TStreamerInfo*)lnk->GetObject();
3644 if (!info) {
3645 lnk = lnk->Next();
3646 continue;
3647 }
3648 if (info->IsA() != TStreamerInfo::Class()) {
3649 if (mode==1) {
3650 TObject *obj = (TObject*)info;
3651 if (strcmp(obj->GetName(),"listOfRules")==0) {
3652#if 0
3653 // Completely ignore the rules for now.
3654 TList *listOfRules = (TList*)obj;
3655 TObjLink *rulelnk = listOfRules->FirstLink();
3656 while (rulelnk) {
3657 TObjString *rule = (TObjString*)rulelnk->GetObject();
3658 TClass::AddRule( rule->String().Data() );
3659 rulelnk = rulelnk->Next();
3660 }
3661#endif
3662 } else {
3663 Warning("ReadStreamerInfo","%s has a %s in the list of TStreamerInfo.", GetName(), info->IsA()->GetName());
3664 }
3665 info->SetBit(kCanDelete);
3666 }
3667 lnk = lnk->Next();
3668 continue;
3669 }
3670 // This is a quick way (instead of parsing the name) to see if this is
3671 // the description of an STL container.
3672 if (info->GetElements()==0) {
3673 Warning("ReadStreamerInfo","The StreamerInfo for %s does not have a list of elements.",info->GetName());
3674 lnk = lnk->Next();
3675 continue;
3676 }
3677 TObject *element = info->GetElements()->UncheckedAt(0);
3678 Bool_t isstl = element && strcmp("This",element->GetName())==0;
3679
3680 if ( (!isstl && mode ==0) || (isstl && mode ==1) ) {
3681 // Skip the STL container the first time around
3682 // Skip the regular classes the second time around;
3683 info->BuildCheck(this);
3684 Int_t uid = info->GetNumber();
3685 Int_t asize = fClassIndex->GetSize();
3686 if (uid >= asize && uid <100000) fClassIndex->Set(2*asize);
3687 if (uid >= 0 && uid < fClassIndex->GetSize()) {
3688 si_uids.push_back(uid);
3689 fClassIndex->fArray[uid] = 1;
3690 }
3691 else if (!isstl && !info->GetClass()->IsSyntheticPair()) {
3692 printf("ReadStreamerInfo, class:%s, illegal uid=%d\n",info->GetName(),uid);
3693 }
3694 if (gDebug > 0) printf(" -class: %s version: %d info read at slot %d\n",info->GetName(), info->GetClassVersion(),uid);
3695 }
3696 lnk = lnk->Next();
3697 }
3698 }
3699 fClassIndex->fArray[0] = 0;
3700 list->Clear(); //this will delete all TStreamerInfo objects with kCanDelete bit set
3701 delete list;
3702
3703 // We are done processing the record, let future calls and other threads that it
3704 // has been done.
3705 fgTsSIHashes.Insert(listRetcode.fHash, std::move(si_uids));
3706}
3707
3708////////////////////////////////////////////////////////////////////////////////
3709/// Specify if the streamerinfos must be read at file opening.
3710///
3711/// If fgReadInfo is true (default) TFile::ReadStreamerInfo is called
3712/// when opening the file.
3713/// It may be interesting to set fgReadInfo to false to speedup the file
3714/// opening time or in case libraries containing classes referenced
3715/// by the file have not yet been loaded.
3716/// if fgReadInfo is false, one can still read the StreamerInfo with
3717/// myfile.ReadStreamerInfo();
3720{
3721 fgReadInfo = readinfo;
3722}
3723
3724////////////////////////////////////////////////////////////////////////////////
3725/// If the streamerinfos are to be read at file opening.
3726///
3727/// See TFile::SetReadStreamerInfo for more documentation.
3730{
3731 return fgReadInfo;
3732}
3733
3734////////////////////////////////////////////////////////////////////////////////
3735/// Show the StreamerInfo of all classes written to this file.
3738{
3739 TList *list = GetStreamerInfoList();
3740 if (!list) return;
3741
3742 list->ls();
3743 delete list;
3744}
3745
3746////////////////////////////////////////////////////////////////////////////////
3747/// Check if the ProcessID pidd is already in the file,
3748/// if not, add it and return the index number in the local file list.
3751{
3752 TProcessID *pid = pidd;
3753 if (!pid) pid = TProcessID::GetPID();
3755 Int_t npids = GetNProcessIDs();
3756 for (Int_t i=0;i<npids;i++) {
3757 if (pids->At(i) == pid) return (UShort_t)i;
3758 }
3759
3761 pids->AddAtAndExpand(pid,npids);
3762 pid->IncrementCount();
3763 char name[32];
3764 snprintf(name,32,"ProcessID%d",npids);
3765 this->WriteTObject(pid,name);
3766 this->IncrementProcessIDs();
3767 if (gDebug > 0) {
3768 Info("WriteProcessID", "name=%s, file=%s", name, GetName());
3769 }
3770 return (UShort_t)npids;
3771}
3772
3773
3774////////////////////////////////////////////////////////////////////////////////
3775/// Write the list of TStreamerInfo as a single object in this file
3776/// The class Streamer description for all classes written to this file
3777/// is saved. See class TStreamerInfo.
3780{
3781 //if (!gFile) return;
3782 if (!fWritable) return;
3783 if (!fClassIndex) return;
3784 if (fIsPcmFile) return; // No schema evolution for ROOT PCM files.
3785 if (fClassIndex->fArray[0] == 0
3786 && fSeekInfo != 0) {
3787 // No need to update the index if no new classes added to the file
3788 // but write once an empty StreamerInfo list to mark that there is no need
3789 // for StreamerInfos in this file.
3790 return;
3791 }
3792 if (gDebug > 0) Info("WriteStreamerInfo", "called for file %s",GetName());
3793
3795
3796 // build a temporary list with the marked files
3797 TIter next(gROOT->GetListOfStreamerInfo());
3798 TStreamerInfo *info;
3799 TList list;
3800 TList listOfRules;
3801 listOfRules.SetOwner(kTRUE);
3802 listOfRules.SetName("listOfRules");
3803 std::set<TClass*> classSet;
3804
3805 while ((info = (TStreamerInfo*)next())) {
3806 Int_t uid = info->GetNumber();
3807 if (fClassIndex->fArray[uid]) {
3808 list.Add(info);
3809 if (gDebug > 0) printf(" -class: %s info number %d saved\n",info->GetName(),uid);
3810
3811 // Add the IO customization rules to the list to be saved for the underlying
3812 // class but make sure to add them only once.
3813 TClass *clinfo = info->GetClass();
3814 if (clinfo && clinfo->GetSchemaRules()) {
3815 if ( classSet.find( clinfo ) == classSet.end() ) {
3816 if (gDebug > 0) printf(" -class: %s stored the I/O customization rules\n",info->GetName());
3817
3818 TObjArrayIter it( clinfo->GetSchemaRules()->GetRules() );
3819 ROOT::TSchemaRule *rule;
3820 while( (rule = (ROOT::TSchemaRule*)it.Next()) ) {
3821 TObjString *obj = new TObjString();
3822 rule->AsString(obj->String());
3823 listOfRules.Add(obj);
3824 }
3825 classSet.insert(clinfo);
3826 }
3827 }
3828 }
3829 }
3830
3831 // Write the StreamerInfo list even if it is empty.
3832 fClassIndex->fArray[0] = 2; //to prevent adding classes in TStreamerInfo::TagFile
3833
3834 if (listOfRules.GetEntries()) {
3835 // Only add the list of rules if we have something to say.
3836 list.Add(&listOfRules);
3837 }
3838
3839 //free previous StreamerInfo record
3841 //Create new key
3842 TKey key(&list,"StreamerInfo",GetBestBuffer(), this);
3843 fKeys->Remove(&key);
3844 fSeekInfo = key.GetSeekKey();
3845 fNbytesInfo = key.GetNbytes();
3846 SumBuffer(key.GetObjlen());
3847 key.WriteFile(0);
3848
3849 fClassIndex->fArray[0] = 0;
3850
3851 list.RemoveLast(); // remove the listOfRules.
3852}
3853
3854////////////////////////////////////////////////////////////////////////////////
3855/// Open a file for reading through the file cache.
3856///
3857/// The file will be downloaded to the cache and opened from there.
3858/// If the download fails, it will be opened remotely.
3859/// The file will be downloaded to the directory specified by SetCacheFileDir().
3861TFile *TFile::OpenFromCache(const char *name, Option_t *, const char *ftitle,
3862 Int_t compress, Int_t netopt)
3863{
3864 TFile *f = nullptr;
3865
3866 if (fgCacheFileDir == "") {
3867 ::Warning("TFile::OpenFromCache",
3868 "you want to read through a cache, but you have no valid cache "
3869 "directory set - reading remotely");
3870 ::Info("TFile::OpenFromCache", "set cache directory using TFile::SetCacheFileDir()");
3871 } else {
3872 TUrl fileurl(name);
3873
3874 if ((!strcmp(fileurl.GetProtocol(), "file"))) {
3875 // it makes no sense to read local files through a file cache
3876 if (!fgCacheFileForce)
3877 ::Warning("TFile::OpenFromCache",
3878 "you want to read through a cache, but you are reading "
3879 "local files - CACHEREAD disabled");
3880 } else {
3881 // this is a remote file and worthwhile to be put into the local cache
3882 // now create cachepath to put it
3883 TString cachefilepath;
3884 TString cachefilepathbasedir;
3885 cachefilepath = fgCacheFileDir;
3886 cachefilepath += fileurl.GetFile();
3887 cachefilepathbasedir = gSystem->GetDirName(cachefilepath);
3888 if ((gSystem->mkdir(cachefilepathbasedir, kTRUE) < 0) &&
3889 (gSystem->AccessPathName(cachefilepathbasedir, kFileExists))) {
3890 ::Warning("TFile::OpenFromCache","you want to read through a cache, but I "
3891 "cannot create the directory %s - CACHEREAD disabled",
3892 cachefilepathbasedir.Data());
3893 } else {
3894 // check if this should be a zip file
3895 if (strlen(fileurl.GetAnchor())) {
3896 // remove the anchor and change the target name
3897 cachefilepath += "__";
3898 cachefilepath += fileurl.GetAnchor();
3899 fileurl.SetAnchor("");
3900 }
3901 if (strstr(name,"zip=")) {
3902 // filter out this option and change the target cache name
3903 TString urloptions = fileurl.GetOptions();
3904 TString newoptions;
3905 TObjArray *objOptions = urloptions.Tokenize("&");
3906 Int_t optioncount = 0;
3907 TString zipname;
3908 for (Int_t n = 0; n < objOptions->GetEntries(); n++) {
3909 TString loption = ((TObjString*)objOptions->At(n))->GetName();
3910 TObjArray *objTags = loption.Tokenize("=");
3911 if (objTags->GetEntries() == 2) {
3912 TString key = ((TObjString*)objTags->At(0))->GetName();
3913 TString value = ((TObjString*)objTags->At(1))->GetName();
3914 if (key.CompareTo("zip", TString::kIgnoreCase)) {
3915 if (optioncount!=0) {
3916 newoptions += "&";
3917 }
3918 newoptions += key;
3919 newoptions += "=";
3920 newoptions += value;
3921 ++optioncount;
3922 } else {
3923 zipname = value;
3924 }
3925 }
3926 delete objTags;
3927 }
3928 delete objOptions;
3929 fileurl.SetOptions(newoptions.Data());
3930 cachefilepath += "__";
3931 cachefilepath += zipname;
3932 fileurl.SetAnchor("");
3933 }
3934
3935 Bool_t need2copy = kFALSE;
3936
3937 // check if file is in the cache
3938 Long_t id;
3939 Long64_t size;
3940 Long_t flags;
3941 Long_t modtime;
3942 if (!gSystem->GetPathInfo(cachefilepath, &id, &size, &flags, &modtime)) {
3943 // file is in the cache
3945 char cacheblock[256];
3946 char remotblock[256];
3947 // check the remote file for it's size and compare some magic bytes
3948 TString cfurl;
3949 cfurl = cachefilepath;
3950 cfurl += "?filetype=raw";
3951 TUrl rurl(name);
3952 TString ropt = rurl.GetOptions();
3953 ropt += "&filetype=raw";
3954 rurl.SetOptions(ropt);
3955
3956 Bool_t forcedcache = fgCacheFileForce;
3958
3959 TFile *cachefile = TFile::Open(cfurl, "READ");
3960 TFile *remotfile = TFile::Open(rurl.GetUrl(), "READ");
3961
3962 fgCacheFileForce = forcedcache;
3963
3964 if (!cachefile) {
3965 need2copy = kTRUE;
3966 ::Error("TFile::OpenFromCache",
3967 "cannot open the cache file to check cache consistency");
3968 return nullptr;
3969 }
3970
3971 if (!remotfile) {
3972 ::Error("TFile::OpenFromCache",
3973 "cannot open the remote file to check cache consistency");
3974 return nullptr;
3975 }
3976
3977 cachefile->Seek(0);
3978 remotfile->Seek(0);
3979
3980 if ((!cachefile->ReadBuffer(cacheblock,256)) &&
3981 (!remotfile->ReadBuffer(remotblock,256))) {
3982 if (memcmp(cacheblock, remotblock, 256)) {
3983 ::Warning("TFile::OpenFromCache", "the header of the cache file "
3984 "differs from the remote file - forcing an update");
3985 need2copy = kTRUE;
3986 }
3987 } else {
3988 ::Warning("TFile::OpenFromCache", "the header of the cache and/or "
3989 "remote file are not readable - forcing an update");
3990 need2copy = kTRUE;
3991 }
3992
3993 delete remotfile;
3994 delete cachefile;
3995 }
3996 } else {
3997 need2copy = kTRUE;
3998 }
3999
4000 // try to fetch the file (disable now the forced caching)
4001 Bool_t forcedcache = fgCacheFileForce;
4003 if (need2copy) {
4004 const auto cachefilepathtmp = cachefilepath + std::to_string(gSystem->GetPid()) + ".tmp";
4005 if (!TFile::Cp(name, cachefilepathtmp)) {
4006 ::Warning("TFile::OpenFromCache",
4007 "you want to read through a cache, but I "
4008 "cannot make a cache copy of %s - CACHEREAD disabled",
4009 cachefilepathbasedir.Data());
4010 fgCacheFileForce = forcedcache;
4011 return nullptr;
4012 }
4013 if (gSystem->AccessPathName(cachefilepath)) // then file _does not_ exist (weird convention)
4014 gSystem->Rename(cachefilepathtmp, cachefilepath);
4015 else // another process or thread already wrote a file with the same name while we were copying it
4016 gSystem->Unlink(cachefilepathtmp);
4017 }
4018 fgCacheFileForce = forcedcache;
4019 ::Info("TFile::OpenFromCache", "using local cache copy of %s [%s]", name, cachefilepath.Data());
4020 // finally we have the file and can open it locally
4021 fileurl.SetProtocol("file");
4022 fileurl.SetFile(cachefilepath);
4023
4024 TString tagfile;
4025 tagfile = cachefilepath;
4026 tagfile += ".ROOT.cachefile";
4027 // we symlink this file as a ROOT cached file
4028 gSystem->Symlink(gSystem->BaseName(cachefilepath), tagfile);
4029 return TFile::Open(fileurl.GetUrl(), "READ", ftitle, compress, netopt);
4030 }
4031 }
4032 }
4033
4034 // Failed
4035 return f;
4036}
4037
4038////////////////////////////////////////////////////////////////////////////////
4039/// Create / open a file
4040///
4041/// The type of the file can be either a
4042/// TFile, TNetFile, TWebFile or any TFile derived class for which an
4043/// plugin library handler has been registered with the plugin manager
4044/// (for the plugin manager see the TPluginManager class). The returned
4045/// type of TFile depends on the file name specified by 'url'.
4046/// If 'url' is a '|'-separated list of file URLs, the 'URLs' are tried
4047/// sequentially in the specified order until a successful open.
4048/// If the file starts with "root:", "roots:" or "rootk:" a TNetFile object
4049/// will be returned, with "http:" a TWebFile, with "file:" a local TFile,
4050/// etc. (see the list of TFile plugin handlers in $ROOTSYS/etc/system.rootrc
4051/// for regular expressions that will be checked) and as last a local file will
4052/// be tried.
4053/// Before opening a file via TNetFile a check is made to see if the URL
4054/// specifies a local file. If that is the case the file will be opened
4055/// via a normal TFile. To force the opening of a local file via a
4056/// TNetFile use either TNetFile directly or specify as host "localhost".
4057/// The netopt argument is only used by TNetFile. For the meaning of the
4058/// options and other arguments see the constructors of the individual
4059/// file classes. In case of error, it returns a nullptr.
4060///
4061/// For TFile implementations supporting asynchronous file open, see
4062/// TFile::AsyncOpen(...), it is possible to request a timeout with the
4063/// option <b>`TIMEOUT=<secs>`</b>: the timeout must be specified in seconds and
4064/// it will be internally checked with granularity of one millisec.
4065/// For remote files there is the option: <b>CACHEREAD</b> opens an existing
4066/// file for reading through the file cache. The file will be downloaded to
4067/// the cache and opened from there. If the download fails, it will be opened remotely.
4068/// The file will be downloaded to the directory specified by SetCacheFileDir().
4069///
4070/// *The caller is responsible for deleting the pointer.*
4071/// In READ mode, a nullptr is returned if the file does not exist or cannot be opened.
4072/// In CREATE mode, a nullptr is returned if the file already exists or cannot be created.
4073/// In RECREATE mode, a nullptr is returned if the file can not be created.
4074/// In UPDATE mode, a nullptr is returned if the file cannot be created or opened.
4076TFile *TFile::Open(const char *url, Option_t *options, const char *ftitle,
4077 Int_t compress, Int_t netopt)
4078{
4080 TFile *f = nullptr;
4082
4083 // Check input
4084 if (!url || strlen(url) <= 0) {
4085 ::Error("TFile::Open", "no url specified");
4086 return f;
4087 }
4088
4089 TString expandedUrl(url);
4090 gSystem->ExpandPathName(expandedUrl);
4091
4092#ifdef R__UNIX
4093 // If URL is a file on an EOS FUSE mount, attempt redirection to XRootD protocol.
4094 if (gEnv->GetValue("TFile.CrossProtocolRedirects", 1) == 1) {
4095 TUrl fileurl(expandedUrl, /* default is file */ kTRUE);
4096 if (strcmp(fileurl.GetProtocol(), "file") == 0) {
4097 ssize_t len = getxattr(fileurl.GetFile(), "eos.url.xroot", nullptr, 0);
4098 if (len > 0) {
4099 std::string xurl(len, 0);
4100 if (getxattr(fileurl.GetFile(), "eos.url.xroot", &xurl[0], len) == len) {
4101 if ((f = TFile::Open(xurl.c_str(), options, ftitle, compress, netopt))) {
4102 if (!f->IsZombie()) {
4103 return f;
4104 } else {
4105 delete f;
4106 f = nullptr;
4107 }
4108 }
4109 }
4110 }
4111 }
4112 }
4113#endif
4114
4115 // If a timeout has been specified extract the value and try to apply it (it requires
4116 // support for asynchronous open, though; the following is completely transparent if
4117 // such support if not available for the required protocol)
4118 TString opts(options);
4119 Int_t ito = opts.Index("TIMEOUT=");
4120 if (ito != kNPOS) {
4121 TString sto = opts(ito + strlen("TIMEOUT="), opts.Length());
4122 while (!(sto.IsDigit()) && !(sto.IsNull())) { sto.Remove(sto.Length()-1,1); }
4123 if (!(sto.IsNull())) {
4124 // Timeout in millisecs
4125 Int_t toms = sto.Atoi() * 1000;
4126 if (gDebug > 0) ::Info("TFile::Open", "timeout of %d millisec requested", toms);
4127 // Remove from the options field
4128 sto.Insert(0, "TIMEOUT=");
4129 opts.ReplaceAll(sto, "");
4130 // Asynchronous open
4131 TFileOpenHandle *fh = TFile::AsyncOpen(expandedUrl, opts, ftitle, compress, netopt);
4132 // Check the result in steps of 1 millisec
4134 aos = TFile::GetAsyncOpenStatus(fh);
4135 Int_t xtms = toms;
4136 while (aos == TFile::kAOSInProgress && xtms > 0) {
4137 gSystem->Sleep(1);
4138 xtms -= 1;
4139 aos = TFile::GetAsyncOpenStatus(fh);
4140 }
4141 if (aos == TFile::kAOSNotAsync || aos == TFile::kAOSSuccess) {
4142 // Do open the file now
4143 f = TFile::Open(fh);
4144 if (gDebug > 0) {
4145 if (aos == TFile::kAOSSuccess)
4146 ::Info("TFile::Open", "waited %d millisec for asynchronous open", toms - xtms);
4147 else
4148 ::Info("TFile::Open", "timeout option not supported (requires asynchronous"
4149 " open support)");
4150 }
4151 } else {
4152 if (xtms <= 0)
4153 ::Error("TFile::Open", "timeout expired while opening '%s'", expandedUrl.Data());
4154 // Cleanup the request
4155 SafeDelete(fh);
4156 }
4157 // Done
4158 return f;
4159 } else {
4160 ::Warning("TFile::Open", "incomplete 'TIMEOUT=' option specification - ignored");
4161 opts.ReplaceAll("TIMEOUT=", "");
4162 }
4163 }
4164
4165 // We will use this from now on
4166 const char *option = opts;
4167
4168 // Many URLs? Redirect output and print errors in case of global failure
4169 TString namelist(expandedUrl);
4170 Ssiz_t ip = namelist.Index("|");
4171 Bool_t rediroutput = (ip != kNPOS &&
4172 ip != namelist.Length()-1 && gDebug <= 0) ? kTRUE : kFALSE;
4174 if (rediroutput) {
4175 TString outf = ".TFileOpen_";
4176 FILE *fout = gSystem->TempFileName(outf);
4177 if (fout) {
4178 fclose(fout);
4179 gSystem->RedirectOutput(outf, "w", &rh);
4180 }
4181 }
4182
4183 // Try sequentially all names in 'names'
4184 TString name, n;
4185 Ssiz_t from = 0;
4186 while (namelist.Tokenize(n, from, "|") && !f) {
4187
4188 // check if we read through a file cache
4189 if (!strcasecmp(option, "CACHEREAD") ||
4190 ((!strcasecmp(option,"READ") || !option[0]) && fgCacheFileForce)) {
4191 // Try opening the file from the cache
4192 if ((f = TFile::OpenFromCache(n, option, ftitle, compress, netopt)))
4193 return f;
4194 }
4195
4197
4198 // change names to be recognized by the plugin manager
4199 // e.g. /protocol/path/to/file.root -> protocol:/path/to/file.root
4200 TUrl urlname(n, kTRUE);
4201 name = urlname.GetUrl();
4202 // Check first if a pending async open request matches this one
4205 TFileOpenHandle *fh = nullptr;
4206 while ((fh = (TFileOpenHandle *)nxr()))
4207 if (fh->Matches(name))
4208 return TFile::Open(fh);
4209 }
4210
4211 TString urlOptions(urlname.GetOptions());
4212 if (urlOptions.BeginsWith("pmerge") || urlOptions.Contains("&pmerge") || urlOptions.Contains(" pmerge")) {
4213 type = kMerge;
4214
4215 // Pass the full name including the url options:
4216 f = (TFile*) gROOT->ProcessLineFast(TString::Format("new TParallelMergingFile(\"%s\",\"%s\",\"%s\",%d)",n.Data(),option,ftitle,compress));
4217
4218 } else {
4219 // Resolve the file type; this also adjusts names
4220 TString lfname = gEnv->GetValue("Path.Localroot", "");
4221 type = GetType(name, option, &lfname);
4222
4223 if (type == kLocal) {
4224
4225 // Local files
4226 if (lfname.IsNull()) {
4227 urlname.SetHost("");
4228 urlname.SetProtocol("file");
4229 lfname = urlname.GetUrl();
4230 }
4231 f = new TFile(lfname.Data(), option, ftitle, compress);
4232
4233 } else if (type == kNet) {
4234
4235 // Network files
4236 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name))) {
4237 if (h->LoadPlugin() == -1)
4238 return nullptr;
4239 f = (TFile*) h->ExecPlugin(5, name.Data(), option, ftitle, compress, netopt);
4240 }
4241
4242 } else if (type == kWeb) {
4243
4244 // Web files
4245 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name))) {
4246 if (h->LoadPlugin() == -1)
4247 return nullptr;
4248 f = (TFile*) h->ExecPlugin(2, name.Data(), option);
4249 }
4250
4251 } else if (type == kFile) {
4252
4253 // 'file:' protocol
4254 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
4255 h->LoadPlugin() == 0) {
4256 name.ReplaceAll("file:", "");
4257 f = (TFile*) h->ExecPlugin(4, name.Data(), option, ftitle, compress);
4258 } else
4259 f = new TFile(name.Data(), option, ftitle, compress);
4260
4261 } else {
4262
4263 // no recognized specification: try the plugin manager
4264 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name.Data()))) {
4265 if (h->LoadPlugin() == -1)
4266 return nullptr;
4267 TClass *cl = TClass::GetClass(h->GetClass());
4268 if (cl && cl->InheritsFrom("TNetFile"))
4269 f = (TFile*) h->ExecPlugin(5, name.Data(), option, ftitle, compress, netopt);
4270 else
4271 f = (TFile*) h->ExecPlugin(4, name.Data(), option, ftitle, compress);
4272 } else {
4273 // Just try to open it locally but via TFile::Open, so that we pick-up the correct
4274 // plug-in in the case file name contains information about a special backend (e.g.)
4275 if (strcmp(name, urlname.GetFileAndOptions()) != 0)
4276 f = TFile::Open(urlname.GetFileAndOptions(), option, ftitle, compress);
4277 }
4278 }
4279 }
4280
4281 if (f && f->IsZombie()) {
4282 TString newUrl = f->GetNewUrl();
4283 delete f;
4284 if( newUrl.Length() && (newUrl != name) && gEnv->GetValue("TFile.CrossProtocolRedirects", 1) )
4285 f = TFile::Open( newUrl, option, ftitle, compress );
4286 else
4287 f = nullptr;
4288 }
4289 }
4290
4291 if (rediroutput) {
4292 // Restore output to stdout
4293 gSystem->RedirectOutput(0, "", &rh);
4294 // If we failed print error messages
4295 if (!f)
4296 gSystem->ShowOutput(&rh);
4297 // Remove the file
4298 gSystem->Unlink(rh.fFile);
4299 }
4300
4301 // if the file is writable, non local, and not opened in raw mode
4302 // we create a default write cache of 512 KBytes
4303 if (type != kLocal && type != kFile &&
4304 f && f->IsWritable() && !f->IsRaw()) {
4305 new TFileCacheWrite(f, 1);
4306 }
4307
4308 return f;
4309}
4310
4311////////////////////////////////////////////////////////////////////////////////
4312/// Submit an asynchronous open request.
4313
4314/// See TFile::Open(const char *, ...) for an
4315/// explanation of the arguments. A handler is returned which is to be passed
4316/// to TFile::Open(TFileOpenHandle *) to get the real TFile instance once
4317/// the file is open.
4318/// This call never blocks and it is provided to allow parallel submission
4319/// of file opening operations expected to take a long time.
4320/// TFile::Open(TFileOpenHandle *) may block if the file is not yet ready.
4321/// The sequence
4322///
4323/// TFile::Open(TFile::AsyncOpen(const char *, ...))
4324///
4325/// is equivalent to
4326///
4327/// TFile::Open(const char *, ...)
4328///
4329/// To be effective, the underlying TFile implementation must be able to
4330/// support asynchronous open functionality. Currently, only TXNetFile
4331/// supports it. If the functionality is not implemented, this call acts
4332/// transparently by returning an handle with the arguments for the
4333/// standard synchronous open run by TFile::Open(TFileOpenHandle *).
4334/// The retuned handle will be adopted by TFile after opening completion
4335/// in TFile::Open(TFileOpenHandle *); if opening is not finalized the
4336/// handle must be deleted by the caller.
4339 const char *ftitle, Int_t compress,
4340 Int_t netopt)
4341{
4342 TFileOpenHandle *fh = nullptr;
4343 TFile *f = nullptr;
4344 Bool_t notfound = kTRUE;
4345
4346 // Check input
4347 if (!url || strlen(url) <= 0) {
4348 ::Error("TFile::AsyncOpen", "no url specified");
4349 return fh;
4350 }
4351
4352 // Many URLs? Redirect output and print errors in case of global failure
4353 TString namelist(url);
4354 gSystem->ExpandPathName(namelist);
4355 Ssiz_t ip = namelist.Index("|");
4356 Bool_t rediroutput = (ip != kNPOS &&
4357 ip != namelist.Length()-1 && gDebug <= 0) ? kTRUE : kFALSE;
4359 if (rediroutput) {
4360 TString outf = ".TFileAsyncOpen_";
4361 FILE *fout = gSystem->TempFileName(outf);
4362 if (fout) {
4363 fclose(fout);
4364 gSystem->RedirectOutput(outf, "w", &rh);
4365 }
4366 }
4367
4368 // Try sequentially all names in 'names'
4369 TString name, n;
4370 Ssiz_t from = 0;
4371 while (namelist.Tokenize(n, from, "|") && !f) {
4372
4373 // change names to be recognized by the plugin manager
4374 // e.g. /protocol/path/to/file.root -> protocol:/path/to/file.root
4375 TUrl urlname(n, kTRUE);
4376 name = urlname.GetUrl();
4377
4378 // Resolve the file type; this also adjusts names
4380
4381 TPluginHandler *h = nullptr;
4382
4383 // Here we send the asynchronous request if the functionality is implemented
4384 if (type == kNet) {
4385 // Network files
4386 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
4387 (!strcmp(h->GetClass(),"TXNetFile") || !strcmp(h->GetClass(),"TNetXNGFile"))
4388 && h->LoadPlugin() == 0) {
4389 f = (TFile*) h->ExecPlugin(6, name.Data(), option, ftitle, compress, netopt, kTRUE);
4390 notfound = kFALSE;
4391 }
4392 }
4393 }
4394
4395 if (rediroutput) {
4396 // Restore output to stdout
4397 gSystem->RedirectOutput(0, "", &rh);
4398 // If we failed print error messages
4399 if (!notfound && !f)
4400 gSystem->ShowOutput(&rh);
4401 // Remove the file
4402 gSystem->Unlink(rh.fFile);
4403 }
4404
4405 // Make sure that no error occurred
4406 if (notfound) {
4407 SafeDelete(f);
4408 // Save the arguments in the handler, so that a standard open can be
4409 // attempted later on
4410 fh = new TFileOpenHandle(name, option, ftitle, compress, netopt);
4411 } else if (f) {
4412 // Fill the opaque handler to be use to attach the file later on
4413 fh = new TFileOpenHandle(f);
4414 }
4415
4416 // Record this request
4417 if (fh) {
4418 // Create the lst, if not done already
4422 }
4423
4424 // We are done
4425 return fh;
4426}
4427
4428////////////////////////////////////////////////////////////////////////////////
4429/// Waits for the completion of an asynchronous open request.
4430///
4431/// Returns the pointer to the associated TFile, transferring ownership of the
4432/// handle to the TFile instance.
4435{
4436 TFile *f = nullptr;
4437
4438 // Note that the request may have failed
4439 if (fh && fgAsyncOpenRequests) {
4440 // Remove it from the pending list: we need to do it at this level to avoid
4441 // recursive calls in the standard TFile::Open
4443 // Was asynchronous open functionality implemented?
4444 if ((f = fh->GetFile()) && !(f->IsZombie())) {
4445 // Yes: wait for the completion of the open phase, if needed
4446 Bool_t cr = (!strcmp(f->GetOption(),"CREATE") ||
4447 !strcmp(f->GetOption(),"RECREATE") ||
4448 !strcmp(f->GetOption(),"NEW")) ? kTRUE : kFALSE;
4449 f->Init(cr);
4450 } else {
4451 // No: process a standard open
4452 f = TFile::Open(fh->GetName(), fh->GetOpt(), fh->GetTitle(),
4453 fh->GetCompress(), fh->GetNetOpt());
4454 }
4455
4456 // Adopt the handle instance in the TFile instance so that it gets
4457 // automatically cleaned up
4458 if (f) f->fAsyncHandle = fh;
4459 }
4460
4461 // We are done
4462 return f;
4463}
4464
4465////////////////////////////////////////////////////////////////////////////////
4466/// Interface to system open. All arguments like in POSIX open().
4468Int_t TFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
4469{
4470#if defined(R__WINGCC)
4471 // ALWAYS use binary mode - even cygwin text should be in unix format
4472 // although this is posix default it has to be set explicitly
4473 return ::open(pathname, flags | O_BINARY, mode);
4474#elif defined(R__SEEK64)
4475 return ::open64(pathname, flags, mode);
4476#else
4477 return ::open(pathname, flags, mode);
4478#endif
4479}
4480
4481////////////////////////////////////////////////////////////////////////////////
4482/// Interface to system close. All arguments like in POSIX close().
4485{
4486 if (fd < 0) return 0;
4487 return ::close(fd);
4488}
4489
4490////////////////////////////////////////////////////////////////////////////////
4491/// Interface to system read. All arguments like in POSIX read().
4493Int_t TFile::SysRead(Int_t fd, void *buf, Int_t len)
4494{
4495 return ::read(fd, buf, len);
4496}
4497
4498////////////////////////////////////////////////////////////////////////////////
4499/// Interface to system write. All arguments like in POSIX write().
4501Int_t TFile::SysWrite(Int_t fd, const void *buf, Int_t len)
4502{
4503 return ::write(fd, buf, len);
4504}
4505////////////////////////////////////////////////////////////////////////////////
4506/// Interface to system lseek.
4507///
4508/// All arguments like in POSIX lseek()
4509/// except that the offset and return value are of a type which are
4510/// able to handle 64 bit file systems.
4513{
4514#if defined (R__SEEK64)
4515 return ::lseek64(fd, offset, whence);
4516#elif defined(WIN32)
4517 return ::_lseeki64(fd, offset, whence);
4518#else
4519 return ::lseek(fd, offset, whence);
4520#endif
4521}
4522
4523////////////////////////////////////////////////////////////////////////////////
4524/// Return file stat information.
4525///
4526/// The interface and return value is
4527/// identical to TSystem::GetPathInfo(). The function returns 0 in
4528/// case of success and 1 if the file could not be stat'ed.
4531 Long_t *modtime)
4532{
4533 return gSystem->GetPathInfo(fRealName, id, size, flags, modtime);
4534}
4535
4536////////////////////////////////////////////////////////////////////////////////
4537/// Interface to system fsync. All arguments like in POSIX fsync().
4540{
4541 if (TestBit(kDevNull)) return 0;
4542
4543#ifndef WIN32
4544 return ::fsync(fd);
4545#else
4546 return ::_commit(fd);
4547#endif
4548}
4549
4550////////////////////////////////////////////////////////////////////////////////
4551/// Return the total number of bytes written so far to the file.
4554{
4556}
4557
4558////////////////////////////////////////////////////////////////////////////////
4559/// Static function returning the total number of bytes read from all files.
4562{
4563 return fgBytesRead;
4564}
4565
4566////////////////////////////////////////////////////////////////////////////////
4567/// Static function returning the total number of bytes written to all files.
4568/// Does not take into account what might still be in the write caches.
4571{
4572 return fgBytesWrite;
4573}
4574
4575////////////////////////////////////////////////////////////////////////////////
4576/// Static function returning the total number of read calls from all files.
4579{
4580 return fgReadCalls;
4581}
4582
4583////////////////////////////////////////////////////////////////////////////////
4584/// Static function returning the readahead buffer size.
4587{
4588 return fgReadaheadSize;
4589}
4590
4591//______________________________________________________________________________
4593
4594//______________________________________________________________________________
4596
4597//______________________________________________________________________________
4599
4600//______________________________________________________________________________
4601void TFile::SetFileReadCalls(Int_t readcalls) { fgReadCalls = readcalls; }
4602
4603//______________________________________________________________________________
4605
4606//______________________________________________________________________________
4608
4609////////////////////////////////////////////////////////////////////////////////
4610/// Sets the directory where to locally stage/cache remote files.
4611/// If the directory is not writable by us return kFALSE.
4613Bool_t TFile::SetCacheFileDir(std::string_view cachedir, Bool_t operatedisconnected,
4614 Bool_t forcecacheread )
4615{
4616 TString cached{cachedir};
4617 if (!cached.EndsWith("/"))
4618 cached += "/";
4619
4620 if (gSystem->AccessPathName(cached, kFileExists)) {
4621 // try to create it
4622 gSystem->mkdir(cached, kTRUE);
4623 if (gSystem->AccessPathName(cached, kFileExists)) {
4624 ::Error("TFile::SetCacheFileDir", "no sufficient permissions on cache directory %s or cannot create it", TString(cachedir).Data());
4625 fgCacheFileDir = "";
4626 return kFALSE;
4627 }
4628 gSystem->Chmod(cached, 0700);
4629 }
4631 gSystem->Chmod(cached, 0700);
4632 fgCacheFileDir = cached;
4633 fgCacheFileDisconnected = operatedisconnected;
4634 fgCacheFileForce = forcecacheread;
4635 return kTRUE;
4636}
4637
4638////////////////////////////////////////////////////////////////////////////////
4639/// Get the directory where to locally stage/cache remote files.
4641const char *TFile::GetCacheFileDir()
4642{
4643 return fgCacheFileDir;
4644}
4645
4646////////////////////////////////////////////////////////////////////////////////
4647/// Try to shrink the cache to the desired size.
4648///
4649/// With the clenupinterval you can specify the minimum amount of time after
4650/// the previous cleanup before the cleanup operation is repeated in
4651/// the cache directory
4653Bool_t TFile::ShrinkCacheFileDir(Long64_t shrinksize, Long_t cleanupinterval)
4654{
4655 if (fgCacheFileDir == "") {
4656 return kFALSE;
4657 }
4658
4659 // check the last clean-up in the cache
4660 Long_t id;
4661 Long64_t size;
4662 Long_t flags;
4663 Long_t modtime;
4664
4665 TString cachetagfile = fgCacheFileDir;
4666 cachetagfile += ".tag.ROOT.cache";
4667 if (!gSystem->GetPathInfo(cachetagfile, &id, &size, &flags, &modtime)) {
4668 // check the time passed since last cache cleanup
4669 Long_t lastcleanuptime = ((Long_t)time(0) - modtime);
4670 if (lastcleanuptime < cleanupinterval) {
4671 ::Info("TFile::ShrinkCacheFileDir", "clean-up is skipped - last cleanup %lu seconds ago - you requested %lu", lastcleanuptime, cleanupinterval);
4672 return kTRUE;
4673 }
4674 }
4675
4676 // (re-)create the cache tag file
4677 cachetagfile += "?filetype=raw";
4678 TFile *tagfile = nullptr;
4679
4680 if (!(tagfile = TFile::Open(cachetagfile, "RECREATE"))) {
4681 ::Error("TFile::ShrinkCacheFileDir", "cannot create the cache tag file %s", cachetagfile.Data());
4682 return kFALSE;
4683 }
4684
4685 // the shortest garbage collector in the world - one long line of PERL - unlinks files only,
4686 // if there is a symbolic link with '.ROOT.cachefile' for safety ;-)
4687
4688 TString cmd;
4689#if defined(R__WIN32)
4690 cmd = "echo <TFile::ShrinkCacheFileDir>: cleanup to be implemented";
4691#elif defined(R__MACOSX)
4692 cmd.Form("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);
4693#else
4694 cmd.Form("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);
4695#endif
4696
4697 tagfile->WriteBuffer(cmd, 4096);
4698 delete tagfile;
4699
4700 if ((gSystem->Exec(cmd)) != 0) {
4701 ::Error("TFile::ShrinkCacheFileDir", "error executing clean-up script");
4702 return kFALSE;
4703 }
4704
4705 return kTRUE;
4706}
4707
4708////////////////////////////////////////////////////////////////////////////////
4709/// Sets open timeout time (in ms). Returns previous timeout value.
4712{
4713 UInt_t to = fgOpenTimeout;
4714 fgOpenTimeout = timeout;
4715 return to;
4716}
4717
4718////////////////////////////////////////////////////////////////////////////////
4719/// Returns open timeout (in ms).
4722{
4723 return fgOpenTimeout;
4724}
4725
4726////////////////////////////////////////////////////////////////////////////////
4727/// Sets only staged flag. Returns previous value of flag.
4728/// When true we check before opening the file if it is staged, if not,
4729/// the open fails.
4732{
4734 fgOnlyStaged = onlystaged;
4735 return f;
4736}
4737
4738////////////////////////////////////////////////////////////////////////////////
4739/// Returns staged only flag.
4742{
4743 return fgOnlyStaged;
4744}
4745
4746////////////////////////////////////////////////////////////////////////////////
4747/// Return kTRUE if 'url' matches the coordinates of this file.
4748///
4749/// The check is implementation dependent and may need to be overload
4750/// by each TFile implementation relying on this check.
4751/// The default implementation checks the file name only.
4753Bool_t TFile::Matches(const char *url)
4754{
4755 // Check the full URL, including port and FQDN.
4756 TUrl u(url);
4757
4758 // Check
4759 if (!strcmp(u.GetFile(), fUrl.GetFile())) {
4760 // Check ports
4761 if (u.GetPort() == fUrl.GetPort()) {
4762 if (!strcmp(u.GetHostFQDN(), fUrl.GetHostFQDN())) {
4763 // Ok, coordinates match
4764 return kTRUE;
4765 }
4766 }
4767 }
4768
4769 // Default is not matching
4770 return kFALSE;
4771}
4772
4773////////////////////////////////////////////////////////////////////////////////
4774/// Return kTRUE if this async request matches the open request
4775/// specified by 'url'
4777Bool_t TFileOpenHandle::Matches(const char *url)
4778{
4779 if (fFile) {
4780 return fFile->Matches(url);
4781 } else if (fName.Length() > 0){
4782 // Deep check of URLs
4783 TUrl u(url);
4784 TUrl uref(fName);
4785 if (!strcmp(u.GetFile(), uref.GetFile())) {
4786 // Check ports
4787 if (u.GetPort() == uref.GetPort()) {
4788 // Check also the host name
4789 if (!strcmp(u.GetHostFQDN(), uref.GetHostFQDN())) {
4790 // Ok, coordinates match
4791 return kTRUE;
4792 }
4793 }
4794 }
4795 }
4796
4797 // Default is not matching
4798 return kFALSE;
4799}
4800
4801////////////////////////////////////////////////////////////////////////////////
4802/// Resolve the file type as a function of the protocol field in 'name'
4803///
4804/// If defined, the string 'prefix' is added when testing the locality of
4805/// a 'name' with network-like structure (i.e. root://host//path); if the file
4806/// is local, on return 'prefix' will contain the actual local path of the file.
4809{
4811
4812 TPMERegexp re("^(root|xroot).*", "i");
4813 if (re.Match(name)) {
4814 //
4815 // Should be a network file ...
4816 type = kNet;
4817 // ... but make sure that is not local or that a remote-like connection
4818 // is forced. Treat it as local if:
4819 // i) the url points to the localhost, the file will be opened in
4820 // readonly mode and the current user has read access;
4821 // ii) the specified user is equal to the current user then open local
4822 // TFile.
4823 Bool_t localFile = kFALSE;
4824 TUrl url(name);
4825 //
4826 // Check whether we should try to optimize for local files
4827 Bool_t forceRemote = gEnv->GetValue("Path.ForceRemote", 0);
4828 forceRemote = (forceRemote) ? kTRUE : gEnv->GetValue("TFile.ForceRemote", 0);
4829 TString opts = url.GetOptions();
4830 if (opts.Contains("remote=1"))
4831 forceRemote = kTRUE;
4832 else if (opts.Contains("remote=0"))
4833 forceRemote = kFALSE;
4834 if (!forceRemote) {
4835 // Generic locality test
4836 localFile = gSystem->IsPathLocal(name);
4837 if (localFile) {
4838 // Local path including the prefix
4839 const char *fname = url.GetFileAndOptions();
4840 TString lfname;
4841 if (fname[0] == '/') {
4842 if (prefix)
4843 lfname.Form("%s%s", prefix->Data(), fname);
4844 else
4845 lfname = fname;
4846 } else if (fname[0] == '~' || fname[0] == '$') {
4847 lfname = fname;
4848 } else {
4849 lfname.Form("%s/%s", gSystem->HomeDirectory(), fname);
4850 }
4851 // If option "READ" test existence and access
4852 TString opt = option;
4853 Bool_t read = (opt.IsNull() ||
4854 !opt.CompareTo("READ", TString::kIgnoreCase)) ? kTRUE : kFALSE;
4855 if (read) {
4856 char *fn;
4857 if ((fn = gSystem->ExpandPathName(TUrl(lfname).GetFile()))) {
4859 localFile = kFALSE;
4860 delete [] fn;
4861 }
4862 }
4863 // Return full local path if requested (and if the case)
4864 if (localFile && prefix)
4865 *prefix = lfname;
4866 }
4867 }
4868 //
4869 // Adjust the type according to findings
4870 type = (localFile) ? kLocal : type;
4871 } else if (TPMERegexp("^(http[s]?|s3http[s]?|[a]?s3|gs|gshttp[s]?){1}:", "i").Match(name)) {
4872 //
4873 // Web file
4874 type = kWeb;
4875 } else if (!strncmp(name, "file:", 5)) {
4876 //
4877 // 'file' protocol
4878 type = kFile;
4879 }
4880 // We are done
4881 return type;
4882}
4883
4884////////////////////////////////////////////////////////////////////////////////
4885/// Get status of the async open request related to 'name'.
4888{
4889 // Check the list of pending async open requests
4892 TFileOpenHandle *fh = nullptr;
4893 while ((fh = (TFileOpenHandle *)nxr()))
4894 if (fh->Matches(name))
4895 return TFile::GetAsyncOpenStatus(fh);
4896 }
4897
4898 // Check also the list of files open
4900 TSeqCollection *of = gROOT->GetListOfFiles();
4901 if (of && (of->GetSize() > 0)) {
4902 TIter nxf(of);
4903 TFile *f = nullptr;
4904 while ((f = (TFile *)nxf()))
4905 if (f->Matches(name))
4906 return f->GetAsyncOpenStatus();
4907 }
4908
4909 // Default is synchronous mode
4910 return kAOSNotAsync;
4911}
4912
4913////////////////////////////////////////////////////////////////////////////////
4914/// Get status of the async open request related to 'handle'.
4917{
4918 if (handle && handle->fFile) {
4919 if (!handle->fFile->IsZombie())
4920 return handle->fFile->GetAsyncOpenStatus();
4921 else
4922 return TFile::kAOSFailure;
4923 }
4924
4925 // Default is synchronous mode
4926 return TFile::kAOSNotAsync;
4927}
4928
4929////////////////////////////////////////////////////////////////////////////////
4930/// Get final URL for file being opened asynchronously.
4931/// Returns 0 is the information is not yet available.
4933const TUrl *TFile::GetEndpointUrl(const char* name)
4934{
4935 // Check the list of pending async open requests
4938 TFileOpenHandle *fh = nullptr;
4939 while ((fh = (TFileOpenHandle *)nxr()))
4940 if (fh->Matches(name))
4941 if (fh->fFile)
4942 return fh->fFile->GetEndpointUrl();
4943 }
4944
4945 // Check also the list of files open
4947 TSeqCollection *of = gROOT->GetListOfFiles();
4948 if (of && (of->GetSize() > 0)) {
4949 TIter nxf(of);
4950 TFile *f = nullptr;
4951 while ((f = (TFile *)nxf()))
4952 if (f->Matches(name))
4953 return f->GetEndpointUrl();
4954 }
4955
4956 // Information not yet available
4957 return (const TUrl *)nullptr;
4958}
4959
4960////////////////////////////////////////////////////////////////////////////////
4961/// Print file copy progress.
4963void TFile::CpProgress(Long64_t bytesread, Long64_t size, TStopwatch &watch)
4964{
4965 fprintf(stderr, "[TFile::Cp] Total %.02f MB\t|", (Double_t)size/1048576);
4966
4967 for (int l = 0; l < 20; l++) {
4968 if (size > 0) {
4969 if (l < 20*bytesread/size)
4970 fprintf(stderr, "=");
4971 else if (l == 20*bytesread/size)
4972 fprintf(stderr, ">");
4973 else if (l > 20*bytesread/size)
4974 fprintf(stderr, ".");
4975 } else
4976 fprintf(stderr, "=");
4977 }
4978 // Allow to update the GUI while uploading files
4980 watch.Stop();
4981 Double_t lCopy_time = watch.RealTime();
4982 fprintf(stderr, "| %.02f %% [%.01f MB/s]\r",
4983 100.0*(size?(bytesread/((float)size)):1), (lCopy_time>0.)?bytesread/lCopy_time/1048576.:0.);
4984 watch.Continue();
4985}
4986
4987////////////////////////////////////////////////////////////////////////////////
4988/// Allows to copy this file to the dst URL. Returns kTRUE in case of success,
4989/// kFALSE otherwise.
4991Bool_t TFile::Cp(const char *dst, Bool_t progressbar, UInt_t buffersize)
4992{
4993 Bool_t rmdestiferror = kFALSE;
4994 TStopwatch watch;
4995 Bool_t success = kFALSE;
4996
4997 TUrl dURL(dst, kTRUE);
4998
4999 TString oopt = "RECREATE";
5000 TString ourl = dURL.GetUrl();
5001
5002 // Files will be open in RAW mode
5003 TString raw = "filetype=raw";
5004
5005 // Set optimization options for the destination file
5006 TString opt = dURL.GetOptions();
5007 if (opt != "") opt += "&";
5008 opt += raw;
5009
5010 // AliEn files need to know where the source file is
5011 if (!strcmp(dURL.GetProtocol(), "alien"))
5012 opt += TString::Format("&source=%s", GetName());
5013
5014 dURL.SetOptions(opt);
5015
5016 char *copybuffer = nullptr;
5017
5018 TFile *sfile = this;
5019 TFile *dfile = nullptr;
5020
5021 // "RECREATE" does not work always well with XROOTD
5022 // namely when some pieces of the path are missing;
5023 // we force "NEW" in such a case
5024 if (TFile::GetType(ourl, "") == TFile::kNet) {
5025 if (gSystem->AccessPathName(ourl)) {
5026 oopt = "NEW";
5027 // Force creation of the missing parts of the path
5028 opt += "&mkpath=1";
5029 dURL.SetOptions(opt);
5030 }
5031 }
5032
5033 // Open destination file
5034 if (!(dfile = TFile::Open(dURL.GetUrl(), oopt))) {
5035 ::Error("TFile::Cp", "cannot open destination file %s", dst);
5036 goto copyout;
5037 }
5038
5039 // Probably we created a new file
5040 // We have to remove it in case of errors
5041 rmdestiferror = kTRUE;
5042
5043 sfile->Seek(0);
5044 dfile->Seek(0);
5045
5046 copybuffer = new char[buffersize];
5047 if (!copybuffer) {
5048 ::Error("TFile::Cp", "cannot allocate the copy buffer");
5049 goto copyout;
5050 }
5051
5052 Bool_t readop, writeop;
5053 Long64_t read, written, totalread, filesize, b00;
5054
5055 totalread = 0;
5056 filesize = sfile->GetSize();
5057
5058 watch.Start();
5059
5060 b00 = sfile->GetBytesRead();
5061
5062 do {
5063 if (progressbar) CpProgress(totalread, filesize,watch);
5064
5065 Long64_t b1 = sfile->GetBytesRead() - b00;
5066
5067 Long64_t readsize;
5068 if (filesize - b1 > (Long64_t)buffersize) {
5069 readsize = buffersize;
5070 } else {
5071 readsize = filesize - b1;
5072 }
5073
5074 if (readsize == 0) break;
5075
5076 Long64_t b0 = sfile->GetBytesRead();
5077 sfile->Seek(totalread,TFile::kBeg);
5078 readop = sfile->ReadBuffer(copybuffer, (Int_t)readsize);
5079 read = sfile->GetBytesRead() - b0;
5080 if ((read <= 0) || readop) {
5081 ::Error("TFile::Cp", "cannot read from source file %s. readsize=%lld read=%lld readop=%d",
5082 sfile->GetName(), readsize, read, readop);
5083 goto copyout;
5084 }
5085
5086 Long64_t w0 = dfile->GetBytesWritten();
5087 writeop = dfile->WriteBuffer(copybuffer, (Int_t)read);
5088 written = dfile->GetBytesWritten() - w0;
5089 if ((written != read) || writeop) {
5090 ::Error("TFile::Cp", "cannot write %lld bytes to destination file %s", read, dst);
5091 goto copyout;
5092 }
5093 totalread += read;
5094 } while (read == (Long64_t)buffersize);
5095
5096 if (progressbar) {
5097 CpProgress(totalread, filesize,watch);
5098 fprintf(stderr, "\n");
5099 }
5100
5101 success = kTRUE;
5102
5103copyout:
5104 if (dfile) dfile->Close();
5105
5106 if (dfile) delete dfile;
5107 if (copybuffer) delete[] copybuffer;
5108
5109 if (rmdestiferror && (success != kTRUE))
5110 gSystem->Unlink(dst);
5111
5112 watch.Stop();
5113 watch.Reset();
5114
5115 return success;
5116}
5117
5118////////////////////////////////////////////////////////////////////////////////
5119/// Allows to copy file from src to dst URL. Returns kTRUE in case of success,
5120/// kFALSE otherwise.
5122Bool_t TFile::Cp(const char *src, const char *dst, Bool_t progressbar,
5123 UInt_t buffersize)
5124{
5125 TUrl sURL(src, kTRUE);
5126
5127 // Files will be open in RAW mode
5128 TString raw = "filetype=raw";
5129
5130 // Set optimization options for the source file
5131 TString opt = sURL.GetOptions();
5132 if (opt != "") opt += "&";
5133 opt += raw;
5134 // Netx-related options:
5135 // cachesz = 4*buffersize -> 4 buffers as peak mem usage
5136 // readaheadsz = 2*buffersize -> Keep at max 4*buffersize bytes outstanding when reading
5137 // rmpolicy = 1 -> Remove from the cache the blk with the least offset
5138 opt += TString::Format("&cachesz=%d&readaheadsz=%d&rmpolicy=1", 4*buffersize, 2*buffersize);
5139 sURL.SetOptions(opt);
5140
5141 TFile *sfile = nullptr;
5142
5143 Bool_t success = kFALSE;
5144
5145 // Open source file
5146 if (!(sfile = TFile::Open(sURL.GetUrl(), "READ"))) {
5147 ::Error("TFile::Cp", "cannot open source file %s", src);
5148 } else {
5149 success = sfile->Cp(dst, progressbar, buffersize);
5150 }
5151
5152 if (sfile) {
5153 sfile->Close();
5154 delete sfile;
5155 }
5156
5157 return success;
5158}
5159
5160//______________________________________________________________________________
5161//The next statement is not active anymore on Linux.
5162//Using posix_fadvise introduces a performance penalty (10 %) on optimized files
5163//and in addition it destroys the information of TTreePerfStats
5164#if defined(R__neverLINUX) && !defined(R__WINGCC)
5166{
5167 // Read specified byte range asynchronously. Actually we tell the kernel
5168 // which blocks we are going to read so it can start loading these blocks
5169 // in the buffer cache.
5170
5171 // Shortcut to avoid having to implement dummy ReadBufferAsync() in all
5172 // I/O plugins. Override ReadBufferAsync() in plugins if async is supported.
5173 if (IsA() != TFile::Class())
5174 return kTRUE;
5175
5176 int advice = POSIX_FADV_WILLNEED;
5177 if (len == 0) {
5178 // according POSIX spec if len is zero, all data following offset
5179 // is specified. Nevertheless ROOT uses zero to probe readahead
5180 // capabilities.
5181 advice = POSIX_FADV_NORMAL;
5182 }
5183 Double_t start = 0;
5184 if (gPerfStats) start = TTimeStamp();
5185#if defined(R__SEEK64)
5186 Int_t result = posix_fadvise64(fD, offset, len, advice);
5187#else
5188 Int_t result = posix_fadvise(fD, offset, len, advice);
5189#endif
5190 if (gPerfStats) {
5191 gPerfStats->FileReadEvent(this, len, start);
5192 }
5193 return (result != 0);
5194}
5195#else
5197{
5198 // Not supported yet on non Linux systems.
5199
5200 return kTRUE;
5201}
5202#endif
5203
5204////////////////////////////////////////////////////////////////////////////////
5205/// Max number of bytes to prefetch.
5206///
5207/// By default this is 75% of the
5208/// read cache size. But specific TFile implementations may need to change it
5211{
5212 TFileCacheRead *cr = nullptr;
5213 if ((cr = GetCacheRead())) {
5214 Int_t bytes = cr->GetBufferSize() / 4 * 3;
5215 return ((bytes < 0) ? 0 : bytes);
5216 }
5217 return 0;
5218}
void frombuf(char *&buf, Bool_t *x)
Definition Bytes.h:278
void tobuf(char *&buf, Bool_t x)
Definition Bytes.h:55
#define SafeDelete(p)
Definition RConfig.hxx:525
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define h(i)
Definition RSha256.hxx:106
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
RooAbsTestStatistic * create(const char *name, const char *title, RooAbsReal &real, RooAbsData &adata, const RooArgSet &projDeps, RooAbsTestStatistic::Configuration const &cfg) override
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
short Version_t
Definition RtypesCore.h:65
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
#define gDirectory
Definition TDirectory.h:384
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
const Int_t kBEGIN
Definition TFile.cxx:173
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t bytes
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
#define gInterpreter
R__EXTERN TPluginManager * gPluginMgr
Int_t gDebug
Definition TROOT.cxx:597
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:407
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2481
@ kFileExists
Definition TSystem.h:44
@ kReadPermission
Definition TSystem.h:47
@ kWritePermission
Definition TSystem.h:46
Bool_t R_ISDIR(Int_t mode)
Definition TSystem.h:115
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
R__EXTERN void **(* gThreadTsd)(void *, Int_t)
R__EXTERN TVirtualMonitoringWriter * gMonitoringWriter
#define R__LOCKGUARD(mutex)
#define gPerfStats
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
#define O_BINARY
Definition civetweb.c:912
#define snprintf
Definition civetweb.c:1540
const TMatches FindRules(const TString &source) const
Return all the rules that are about the given 'source' class.
const TObjArray * GetRules() const
This class is a thread-safe associative collection connecting a 256 bits digest/hash to a collection ...
bool Insert(const HashValue &hash, RUidColl &&coll) const
If the hash is there, return false.
static HashValue Hash(char *buf, int len)
Return the hash object corresponding to the buffer.
const RUidColl * Find(const HashValue &hash) const
Return the collection of UID corresponding to the hash if the hash has already been seen or nullptr o...
void AsString(TString &out, const char *options="") const
Add to the string 'out' the string representation of the rule.
const char * GetMemberName() const
virtual Int_t SetCurrentMember()=0
const char * GetArchiveName() const
TArchiveMember * GetMember() const
static TArchiveFile * Open(const char *url, TFile *file)
Return proper archive file handler depending on passed url.
Long64_t GetMemberFilePosition() const
Return position in archive of current member.
virtual Int_t OpenArchive()=0
Long64_t GetDecompressedSize() const
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
Char_t * fArray
Definition TArrayC.h:30
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:105
Int_t GetSize() const
Definition TArray.h:47
Buffer base class used for serializing objects.
Definition TBuffer.h:43
@ kInitialSize
Definition TBuffer.h:78
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
Bool_t IsSyntheticPair() const
Definition TClass.h:521
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2886
Bool_t HasInterpreterInfo() const
Definition TClass.h:410
const ROOT::Detail::TSchemaRuleSet * GetSchemaRules() const
Return the set of the schema rules if any.
Definition TClass.cxx:1932
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5912
static Bool_t AddRule(const char *rule)
Add a schema evolution customization rule.
Definition TClass.cxx:1890
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4874
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2897
Version_t GetClassVersion() const
Definition TClass.h:420
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2968
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
void ls(Option_t *option="") const override
List (ls) all objects in this collection.
void SetName(const char *name)
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TObject * Clone(const char *newname="") const override
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
static void GetDateTime(UInt_t datetime, Int_t &date, Int_t &time)
Static function that returns the date and time.
Definition TDatime.cxx:431
void ReadBuffer(char *&buffer)
Decode Date/Time from output buffer, used by I/O system.
Definition TDatime.cxx:278
A ROOT file is structured in Directories (like a file system).
void Close(Option_t *option="") override
Delete all objects from memory and directory structure itself.
Bool_t cd() override
Change current directory to "this" directory.
Bool_t IsWritable() const override
void Delete(const char *namecycle="") override
Delete Objects or/and keys in a directory.
Int_t AppendKey(TKey *key) override
Insert key in the linked list of keys of this directory.
Int_t ReadKeys(Bool_t forceRead=kTRUE) override
Read the linked list of keys.
TDatime fDatimeM
Date and time of last modification.
void Save() override
Save recursively all directory keys and headers.
Int_t fNbytesKeys
Number of bytes for the keys.
Int_t GetNkeys() const override
Long64_t fSeekKeys
Location of Keys record on file.
TFile * GetFile() const override
Int_t Sizeof() const override
Return the size in bytes of the directory header.
Long64_t fSeekParent
Location of parent directory on file.
void BuildDirectoryFile(TFile *motherFile, TDirectory *motherDir)
Initialise directory to defaults.
Int_t Write(const char *name=nullptr, Int_t opt=0, Int_t bufsize=0) override
Write all objects in memory to disk.
Long64_t fSeekDir
Location of directory on file.
Int_t fNbytesName
Number of bytes in TNamed at creation time.
TDatime fDatimeC
Date and time when directory is created.
Bool_t fWritable
True if directory is writable.
Int_t WriteTObject(const TObject *obj, const char *name=nullptr, Option_t *option="", Int_t bufsize=0) override
Write object obj to this directory.
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
void FillBuffer(char *&buffer) override
Encode directory header into output buffer.
void SetWritable(Bool_t writable=kTRUE) override
Set the new value of fWritable recursively.
TList * fKeys
Pointer to keys list in memory.
void ls(Option_t *option="") const override
List Directory contents.
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
Describe directory structure in memory.
Definition TDirectory.h:45
virtual TList * GetList() const
Definition TDirectory.h:222
void SetName(const char *newname) override
Set the name for directory If the directory name is changed after the directory was written once,...
TUUID fUUID
Definition TDirectory.h:143
TList * fList
Definition TDirectory.h:142
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
A cache when reading files over the network.
virtual Int_t ReadBuffer(char *buf, Long64_t pos, Int_t len)
Read buffer at position pos.
virtual void Close(Option_t *option="")
Close out any threads or asynchronous fetches used by the underlying implementation.
virtual Int_t GetBufferSize() const
TFile * GetFile() const
virtual void SetFile(TFile *file, TFile::ECacheAction action=TFile::kDisconnect)
Set the file using this cache and reset the current blocks (if any).
A cache when writing files over the network.
virtual Bool_t Flush()
Flush the current write buffer to the file.
virtual Int_t ReadBuffer(char *buf, Long64_t pos, Int_t len)
Called by the read cache to check if the requested data is not in the write cache buffer.
virtual Int_t GetBytesInCache() const
virtual Int_t WriteBuffer(const char *buf, Long64_t pos, Int_t len)
Write buffer at position pos in the write buffer.
Class holding info about the file being opened.
Definition TFile.h:363
TFile * fFile
TFile instance of the file being opened.
Definition TFile.h:371
Int_t GetNetOpt() const
Definition TFile.h:390
TFile * GetFile() const
Definition TFile.h:381
const char * GetOpt() const
Definition TFile.h:388
Bool_t Matches(const char *name)
Return kTRUE if this async request matches the open request specified by 'url'.
Definition TFile.cxx:4776
Int_t GetCompress() const
Definition TFile.h:389
A ROOT file is composed of a header, followed by consecutive data records (TKey instances) with a wel...
Definition TFile.h:53
static std::atomic< Long64_t > fgBytesRead
Number of bytes read by all TFile objects.
Definition TFile.h:131
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
Definition TFile.h:89
static void SetFileBytesWritten(Long64_t bytes=0)
Definition TFile.cxx:4597
static Bool_t fgCacheFileForce
Indicates, to force all READ to CACHEREAD.
Definition TFile.h:126
Long64_t fBytesRead
Number of bytes read from this file.
Definition TFile.h:76
virtual TProcessID * ReadProcessID(UShort_t pidf)
The TProcessID with number pidf is read from this file.
Definition TFile.cxx:1937
void ls(Option_t *option="") const override
List file contents.
Definition TFile.cxx:1443
virtual void Seek(Long64_t offset, ERelativeTo pos=kBeg)
Seek to a specific position in the file. Pos it either kBeg, kCur or kEnd.
Definition TFile.cxx:2260
static Bool_t GetOnlyStaged()
Returns staged only flag.
Definition TFile.cxx:4740
static void IncrementFileCounter()
Definition TFile.cxx:4606
static Bool_t ShrinkCacheFileDir(Long64_t shrinkSize, Long_t cleanupInteval=0)
Try to shrink the cache to the desired size.
Definition TFile.cxx:4652
Long64_t fSeekFree
Location on disk of free segments structure.
Definition TFile.h:80
static Int_t fgReadaheadSize
Readahead buffer size.
Definition TFile.h:134
void FillBuffer(char *&buffer) override
Encode file output buffer.
Definition TFile.cxx:1156
Double_t fSum2Buffer
Sum of squares of buffer sizes of objects written so far.
Definition TFile.h:74
static void SetReadaheadSize(Int_t bufsize=256000)
Definition TFile.cxx:4591
static Bool_t fgCacheFileDisconnected
Indicates, we trust in the files in the cache dir without stat on the cached file.
Definition TFile.h:125
const TList * GetStreamerInfoCache()
Returns the cached list of StreamerInfos used in this file.
Definition TFile.cxx:1352
static Bool_t GetReadStreamerInfo()
If the streamerinfos are to be read at file opening.
Definition TFile.cxx:3728
TArchiveFile * fArchive
!Archive file from which we read this file
Definition TFile.h:97
virtual Int_t SysSync(Int_t fd)
Interface to system fsync. All arguments like in POSIX fsync().
Definition TFile.cxx:4538
static TClass * Class()
virtual Int_t ReOpen(Option_t *mode)
Reopen a file with a different access mode.
Definition TFile.cxx:2148
virtual void ReadStreamerInfo()
Read the list of StreamerInfo from this file.
Definition TFile.cxx:3591
virtual Bool_t Matches(const char *name)
Return kTRUE if 'url' matches the coordinates of this file.
Definition TFile.cxx:4752
virtual void SetCacheRead(TFileCacheRead *cache, TObject *tree=nullptr, ECacheAction action=kDisconnect)
Set a pointer to the read cache.
Definition TFile.cxx:2351
TArrayC * fClassIndex
!Index of TStreamerInfo classes written to this file
Definition TFile.h:94
static Long64_t GetFileBytesWritten()
Static function returning the total number of bytes written to all files.
Definition TFile.cxx:4569
virtual InfoListRet GetStreamerInfoListImpl(bool lookupSICache)
See documentation of GetStreamerInfoList for more details.
Definition TFile.cxx:1362
@ kStartBigFile
Definition TFile.h:200
static void SetReadStreamerInfo(Bool_t readinfo=kTRUE)
Specify if the streamerinfos must be read at file opening.
Definition TFile.cxx:3718
Bool_t fNoAnchorInName
!True if we don't want to force the anchor to be appended to the file name
Definition TFile.h:103
static void SetFileBytesRead(Long64_t bytes=0)
Definition TFile.cxx:4594
Long64_t fSeekInfo
Location on disk of StreamerInfo record.
Definition TFile.h:81
void Paint(Option_t *option="") override
Paint all objects in the file.
Definition TFile.cxx:1684
Int_t GetBestBuffer() const
Return the best buffer size of objects on this file.
Definition TFile.cxx:1169
TList * fOpenPhases
!Time info about open phases
Definition TFile.h:113
virtual void SetCompressionLevel(Int_t level=ROOT::RCompressionSetting::ELevel::kUseMin)
See comments for function SetCompressionSettings.
Definition TFile.cxx:2305
TFileCacheWrite * GetCacheWrite() const
Return a pointer to the current write cache.
Definition TFile.cxx:1265
static void SetFileReadCalls(Int_t readcalls=0)
Definition TFile.cxx:4600
static TString fgCacheFileDir
Directory where to locally stage files.
Definition TFile.h:124
virtual Int_t SysRead(Int_t fd, void *buf, Int_t len)
Interface to system read. All arguments like in POSIX read().
Definition TFile.cxx:4492
Int_t fVersion
File format version.
Definition TFile.h:83
void Print(Option_t *option="") const override
Print all objects in the file.
Definition TFile.cxx:1692
static std::atomic< Long64_t > fgFileCounter
Counter for all opened files.
Definition TFile.h:132
virtual EAsyncOpenStatus GetAsyncOpenStatus()
Definition TFile.h:137
void Streamer(TBuffer &) override
Stream a TFile object.
Definition TFile.cxx:2391
static UInt_t GetOpenTimeout()
Returns open timeout (in ms).
Definition TFile.cxx:4720
static void CpProgress(Long64_t bytesread, Long64_t size, TStopwatch &watch)
Print file copy progress.
Definition TFile.cxx:4962
static Bool_t fgOnlyStaged
Before the file is opened, it is checked, that the file is staged, if not, the open fails.
Definition TFile.h:128
virtual Int_t GetNProcessIDs() const
Definition TFile.h:239
Bool_t fMustFlush
!True if the file buffers must be flushed
Definition TFile.h:106
TUrl fUrl
!URL of file
Definition TFile.h:110
Int_t WriteBufferViaCache(const char *buf, Int_t len)
Write buffer via cache.
Definition TFile.cxx:2505
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition TFile.cxx:4560
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
Definition TFile.cxx:1875
virtual TKey * CreateKey(TDirectory *mother, const TObject *obj, const char *name, Int_t bufsize)
Creates key for object and converts data to buffer.
Definition TFile.cxx:1033
virtual void Map()
Definition TFile.h:267
virtual void WriteFree()
Write FREE linked list on the file.
Definition TFile.cxx:2529
static Int_t GetReadaheadSize()
Static function returning the readahead buffer size.
Definition TFile.cxx:4585
~TFile() override
File destructor.
Definition TFile.cxx:556
virtual Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read the nbuf blocks described in arrays pos and len.
Definition TFile.cxx:1807
static Long64_t GetFileCounter()
Definition TFile.cxx:4603
TMap * fCacheReadMap
!Pointer to the read cache (if any)
Definition TFile.h:99
Long64_t fBEGIN
First used byte in file.
Definition TFile.h:78
Int_t MakeProjectParProofInf(const char *packname, const char *proofinfdir)
Create BUILD.sh and SETUP.C under 'proofinf' for PAR package 'pack'.
Definition TFile.cxx:3472
virtual UShort_t WriteProcessID(TProcessID *pid)
Check if the ProcessID pidd is already in the file, if not, add it and return the index number in the...
Definition TFile.cxx:3749
virtual void MakeProject(const char *dirname, const char *classes="*", Option_t *option="new")
Generate source code necessary to access the objects stored in the file.
Definition TFile.cxx:2712
Long64_t fArchiveOffset
!Offset at which file starts in archive
Definition TFile.h:101
@ kEternalTimeout
Definition TFile.h:67
Int_t fNbytesInfo
Number of bytes for StreamerInfo record.
Definition TFile.h:86
virtual Long64_t GetSize() const
Returns the current file size.
Definition TFile.cxx:1333
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition TFile.cxx:1455
TFileOpenHandle * fAsyncHandle
!For proper automatic cleanup
Definition TFile.h:108
static Bool_t SetOnlyStaged(Bool_t onlystaged)
Sets only staged flag.
Definition TFile.cxx:4730
virtual Long64_t GetBytesRead() const
Definition TFile.h:241
virtual Int_t GetErrno() const
Method returning errno.
Definition TFile.cxx:1232
virtual void SetCompressionSettings(Int_t settings=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault)
Used to specify the compression level and algorithm.
Definition TFile.cxx:2324
static Bool_t fgReadInfo
if true (default) ReadStreamerInfo is called when opening a file
Definition TFile.h:135
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition TFile.cxx:606
Long64_t GetRelOffset() const
Definition TFile.h:251
static TFileOpenHandle * AsyncOpen(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Submit an asynchronous open request.
Definition TFile.cxx:4337
virtual void SetCacheWrite(TFileCacheWrite *cache)
Set a pointer to the write cache.
Definition TFile.cxx:2374
TString fOption
File options.
Definition TFile.h:91
virtual Bool_t WriteBuffer(const char *buf, Int_t len)
Write a buffer to the file.
Definition TFile.cxx:2462
void SumBuffer(Int_t bufsize)
Increment statistics for buffer sizes of objects in this file.
Definition TFile.cxx:2403
static const char * GetCacheFileDir()
Get the directory where to locally stage/cache remote files.
Definition TFile.cxx:4640
EAsyncOpenStatus
Asynchronous open request status.
Definition TFile.h:64
@ kAOSSuccess
Definition TFile.h:65
@ kAOSNotAsync
Definition TFile.h:64
@ kAOSInProgress
Definition TFile.h:65
@ kAOSFailure
Definition TFile.h:64
virtual void WriteStreamerInfo()
Write the list of TStreamerInfo as a single object in this file The class Streamer description for al...
Definition TFile.cxx:3778
virtual Long64_t GetBytesWritten() const
Return the total number of bytes written so far to the file.
Definition TFile.cxx:4552
ERelativeTo
Definition TFile.h:199
@ kCur
Definition TFile.h:199
@ kBeg
Definition TFile.h:199
@ kEnd
Definition TFile.h:199
Int_t fCompress
Compression level and algorithm.
Definition TFile.h:84
static TFile *& CurrentFile()
Return the current ROOT file if any.
Definition TFile.cxx:1053
virtual void SetCompressionAlgorithm(Int_t algorithm=ROOT::RCompressionSetting::EAlgorithm::kUseGlobal)
See comments for function SetCompressionSettings.
Definition TFile.cxx:2291
virtual const TUrl * GetEndpointUrl() const
Definition TFile.h:235
Int_t fNbytesFree
Number of bytes for free segments structure.
Definition TFile.h:85
Int_t fD
File descriptor.
Definition TFile.h:82
static constexpr Version_t Class_Version()
Definition TFile.h:347
virtual void ResetErrno() const
Method resetting the errno.
Definition TFile.cxx:1240
Int_t Sizeof() const override
Return the size in bytes of the file header.
Definition TFile.cxx:2383
Bool_t FlushWriteCache()
Flush the write cache if active.
Definition TFile.cxx:1144
virtual void IncrementProcessIDs()
Definition TFile.h:257
Bool_t fIsPcmFile
!True if the file is a ROOT pcm file.
Definition TFile.h:107
TFileCacheRead * fCacheRead
!Pointer to the read cache (if any)
Definition TFile.h:98
virtual Int_t SysClose(Int_t fd)
Interface to system close. All arguments like in POSIX close().
Definition TFile.cxx:4483
TFile()
File default Constructor.
Definition TFile.cxx:191
Char_t fUnits
Number of bytes for file pointers.
Definition TFile.h:92
TObjArray * fProcessIDs
!Array of pointers to TProcessIDs
Definition TFile.h:95
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=nullptr)
Resolve the file type as a function of the protocol field in 'name'.
Definition TFile.cxx:4807
EFileType
File type.
Definition TFile.h:202
@ kWeb
Definition TFile.h:202
@ kDefault
Definition TFile.h:202
@ kLocal
Definition TFile.h:202
@ kMerge
Definition TFile.h:202
@ kNet
Definition TFile.h:202
@ kFile
Definition TFile.h:202
virtual void ShowStreamerInfo()
Show the StreamerInfo of all classes written to this file.
Definition TFile.cxx:3736
virtual Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence)
Interface to system lseek.
Definition TFile.cxx:4511
virtual Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
Return file stat information.
Definition TFile.cxx:4529
virtual Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode)
Interface to system open. All arguments like in POSIX open().
Definition TFile.cxx:4467
ECacheAction
TTreeCache flushing semantics.
Definition TFile.h:70
@ kDoNotDisconnect
Definition TFile.h:70
static UInt_t SetOpenTimeout(UInt_t timeout)
Sets open timeout time (in ms). Returns previous timeout value.
Definition TFile.cxx:4710
virtual void ReadFree()
Read the FREE linked list.
Definition TFile.cxx:1911
virtual Bool_t Cp(const char *dst, Bool_t progressbar=kTRUE, UInt_t buffersize=1000000)
Allows to copy this file to the dst URL.
Definition TFile.cxx:4990
static ROOT::Internal::RConcurrentHashColl fgTsSIHashes
!TS Set of hashes built from read streamer infos
Definition TFile.h:120
Long64_t fBytesReadExtra
Number of extra bytes (overhead) read by the readahead buffer.
Definition TFile.h:77
Long64_t fBytesWrite
Number of bytes written to this file.
Definition TFile.h:75
Bool_t fIsRootFile
!True is this is a ROOT file, raw file otherwise
Definition TFile.h:104
static Bool_t SetCacheFileDir(ROOT::Internal::TStringView cacheDir, Bool_t operateDisconnected=kTRUE, Bool_t forceCacheread=kFALSE)
Definition TFile.h:332
virtual void Flush()
Synchronize a file's in-memory and on-disk states.
Definition TFile.cxx:1127
TList * fFree
Free segments linked list table.
Definition TFile.h:93
virtual Bool_t ReadBufferAsync(Long64_t offs, Int_t len)
Definition TFile.cxx:5195
void Delete(const char *namecycle="") override
Delete object namecycle.
Definition TFile.cxx:1084
Bool_t fInitDone
!True if the file has been initialized
Definition TFile.h:105
virtual void DrawMap(const char *keys="*", Option_t *option="")
Draw map of objects in this file.
Definition TFile.cxx:1114
virtual void MakeFree(Long64_t first, Long64_t last)
Mark unused bytes on the file.
Definition TFile.cxx:1470
TFileCacheWrite * fCacheWrite
!Pointer to the write cache (if any)
Definition TFile.h:100
TString fRealName
Effective real file name (not original url)
Definition TFile.h:90
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition TFile.cxx:2239
Long64_t fOffset
!Seek offset cache
Definition TFile.h:96
static std::atomic< Long64_t > fgBytesWrite
Number of bytes written by all TFile objects.
Definition TFile.h:130
TList * fInfoCache
!Cached list of the streamer infos in this file
Definition TFile.h:112
virtual Int_t GetBytesToPrefetch() const
Max number of bytes to prefetch.
Definition TFile.cxx:5209
static UInt_t fgOpenTimeout
Timeout for open operations in ms - 0 corresponds to blocking i/o.
Definition TFile.h:127
Int_t MakeProjectParMake(const char *packname, const char *filename)
Create makefile at 'filemake' for PAR package 'pack'.
Definition TFile.cxx:3350
Long64_t fEND
Last used byte in file.
Definition TFile.h:79
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:4075
Int_t Write(const char *name=nullptr, Int_t opt=0, Int_t bufsiz=0) override
Write memory objects to this file.
Definition TFile.cxx:2422
EAsyncOpenStatus fAsyncOpenStatus
!Status of an asynchronous open request
Definition TFile.h:109
bool fGlobalRegistration
! if true, bypass use of global lists
Definition TFile.h:115
Double_t fSumBuffer
Sum of buffer sizes of objects written so far.
Definition TFile.h:73
Bool_t fIsArchive
!True if this is a pure archive file
Definition TFile.h:102
TObjArray * GetListOfProcessIDs() const
Definition TFile.h:236
void Draw(Option_t *option="") override
Fill Graphics Structure and Paint.
Definition TFile.cxx:1097
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:936
TClass * IsA() const override
Definition TFile.h:347
static std::atomic< Int_t > fgReadCalls
Number of bytes read from all TFile objects.
Definition TFile.h:133
virtual Int_t Recover()
Attempt to recover file if not correctly closed.
Definition TFile.cxx:2034
virtual TList * GetStreamerInfoList() final
Read the list of TStreamerInfo objects written to this file.
Definition TFile.cxx:1431
virtual void WriteHeader()
Write File Header.
Definition TFile.cxx:2601
@ kRecovered
Definition TFile.h:191
@ kReproducible
Definition TFile.h:197
@ kDevNull
Definition TFile.h:193
@ kHasReferences
Definition TFile.h:192
@ k630forwardCompatibility
Definition TFile.h:190
@ kWriteError
Definition TFile.h:194
@ kBinaryFile
Definition TFile.h:195
static TFile * OpenFromCache(const char *name, Option_t *="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Open a file for reading through the file cache.
Definition TFile.cxx:3860
Int_t fNProcessIDs
Number of TProcessID written to this file.
Definition TFile.h:88
Int_t fWritten
Number of objects written so far.
Definition TFile.h:87
Int_t GetRecordHeader(char *buf, Long64_t first, Int_t maxbytes, Int_t &nbytes, Int_t &objlen, Int_t &keylen)
Read the logical record header starting at a certain postion.
Definition TFile.cxx:1287
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition TFile.cxx:1756
Float_t GetCompressionFactor()
Return the file compression factor.
Definition TFile.cxx:1188
virtual Int_t SysWrite(Int_t fd, const void *buf, Int_t len)
Interface to system write. All arguments like in POSIX write().
Definition TFile.cxx:4500
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
Definition TFile.cxx:4577
TFileCacheRead * GetCacheRead(const TObject *tree=nullptr) const
Return a pointer to the current read cache.
Definition TFile.cxx:1248
Option_t * GetOption() const override
Definition TFile.h:240
static TList * fgAsyncOpenRequests
Definition TFile.h:122
Service class for TFile.
Definition TFree.h:27
Long64_t GetLast() const
Definition TFree.h:41
Int_t Sizeof() const
return number of bytes occupied by this TFree on permanent storage
Definition TFree.cxx:184
virtual void ReadBuffer(char *&buffer)
Decode one free structure from input buffer.
Definition TFree.cxx:167
Long64_t GetFirst() const
Definition TFree.h:40
virtual void FillBuffer(char *&buffer)
Encode fre structure into output buffer.
Definition TFree.cxx:109
TFree * AddFree(TList *lfree, Long64_t first, Long64_t last)
Add a new free segment to the list of free segments.
Definition TFree.cxx:67
static void MakeFunctor(const char *name, const char *type, GlobFunc &func)
Definition TGlobal.h:73
void Reset()
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
void Delete(Option_t *option="") override
Delete an object from the file.
Definition TKey.cxx:538
virtual Long64_t GetSeekKey() const
Definition TKey.h:89
Int_t GetKeylen() const
Definition TKey.h:84
Int_t GetObjlen() const
Definition TKey.h:87
Int_t GetNbytes() const
Definition TKey.h:86
virtual const char * GetClassName() const
Definition TKey.h:75
virtual Bool_t ReadFile()
Read the key structure from the file.
Definition TKey.cxx:1273
void ReadKeyBuffer(char *&buffer)
Decode input buffer.
Definition TKey.cxx:1230
virtual Int_t WriteFile(Int_t cycle=1, TFile *f=nullptr)
Write the encoded object supported by this key.
Definition TKey.cxx:1458
virtual char * GetBuffer() const
Definition TKey.h:78
A doubly linked list.
Definition TList.h:38
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
Definition TList.cxx:250
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:402
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:578
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:822
TObject * Last() const override
Return the last object in the list. Returns 0 when list is empty.
Definition TList.cxx:693
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
virtual TObjLink * FirstLink() const
Definition TList.h:102
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
void RemoveLast() override
Remove the last object of the list.
Definition TList.cxx:909
static void GenerateMissingStreamerInfos(TList *extrainfos, TStreamerElement *element)
Generate an empty StreamerInfo for types that are used in templates parameters but are not known in t...
static TString UpdateAssociativeToVector(const char *name)
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition TMap.h:40
void Add(TObject *obj) override
This function may not be used (but we need to provide it since it is a pure virtual in TCollection).
Definition TMap.cxx:54
TObject * Remove(TObject *key) override
Remove the (key,value) pair with key from the map.
Definition TMap.cxx:296
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition TMap.cxx:236
virtual void FillBuffer(char *&buffer)
Encode TNamed into output buffer.
Definition TNamed.cxx:104
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
virtual Int_t Sizeof() const
Return size of the TNamed part of the TObject.
Definition TNamed.cxx:173
Iterator of object array.
Definition TObjArray.h:117
TObject * Next() override
Return next object in array. Returns 0 when no more objects in array.
An array of TObjects.
Definition TObjArray.h:31
Int_t IndexOf(const TObject *obj) const override
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:457
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition TObject.cxx:1001
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:153
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1015
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:791
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:483
void MakeZombie()
Definition TObject.h:53
void ResetBit(UInt_t f)
Definition TObject.h:198
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition TPRegexp.h:97
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition TPRegexp.cxx:706
Longptr_t ExecPlugin(int nargs)
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition TProcessID.h:74
Int_t IncrementCount()
Increase the reference count to this object.
void Clear(Option_t *option="") override
delete the TObjArray pointing to referenced objects this function is called by TFile::Close("R")
void CheckInit()
Initialize fObjects.
static TObjArray * GetPIDs()
static: returns array of TProcessIDs
static TProcessID * GetSessionProcessID()
static function returning the pointer to the session TProcessID
Int_t DecrementCount()
The reference fCount is used to delete the TProcessID in the TFile destructor when fCount = 0.
static TProcessID * GetPID()
static: returns pointer to current TProcessID
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition TROOT.cxx:2862
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:2870
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3031
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition TROOT.cxx:2745
Sequenceable collection abstract base class.
Stopwatch class.
Definition TStopwatch.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
void Continue()
Resume a stopped stopwatch.
void Stop()
Stop the stopwatch.
void Reset()
Definition TStopwatch.h:52
UInt_t GetBaseCheckSum()
void SetBaseCheckSum(UInt_t cs)
TClass * GetClass() const
Describes a persistent version of a class.
Int_t GetClassVersion() const override
Int_t GenerateHeaderFile(const char *dirname, const TList *subClasses=nullptr, const TList *extrainfos=nullptr) override
Generate header file for the class described by this TStreamerInfo the function is called by TFile::M...
Int_t GetNumber() const override
TClass * IsA() const override
TClass * GetClass() const override
TObjArray * GetElements() const override
UInt_t GetCheckSum() const override
void BuildCheck(TFile *file=nullptr, Bool_t load=kTRUE) override
Check if built and consistent with the class dictionary.
static TClass * Class()
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
void ToLower()
Change string to lower-case.
Definition TString.cxx:1170
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:450
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:661
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1966
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2222
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1221
const char * Data() const
Definition TString.h:380
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition TString.cxx:1808
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
@ kIgnoreCase
Definition TString.h:279
void ToUpper()
Change string to upper case.
Definition TString.cxx:1183
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2242
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:627
Bool_t IsNull() const
Definition TString.h:418
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:576
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2356
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2334
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
virtual void ReadBuffer(char *&buffer)
Read string from I/O buffer.
Definition TString.cxx:1309
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
virtual const char * GetMakeSharedLib() const
Return the command line use to make a shared library.
Definition TSystem.cxx:3933
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=nullptr)
Redirect standard output (stdout, stderr) to the specified file.
Definition TSystem.cxx:1700
virtual void IgnoreInterrupt(Bool_t ignore=kTRUE)
If ignore is true ignore the interrupt signal, else restore previous behaviour.
Definition TSystem.cxx:589
virtual int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition TSystem.cxx:1355
static void ResetErrno()
Static function resetting system error number.
Definition TSystem.cxx:271
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1261
static Int_t GetErrno()
Static function returning system error number.
Definition TSystem.cxx:263
virtual int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition TSystem.cxx:1493
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:832
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:823
virtual int GetPid()
Get process id.
Definition TSystem.cxx:694
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition TSystem.cxx:1328
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3950
virtual void ShowOutput(RedirectHandle_t *h)
Display the content associated with the redirection described by the opaque handle 'h'.
Definition TSystem.cxx:1710
virtual Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in 'path' points to the local file system.
Definition TSystem.cxx:1292
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition TSystem.cxx:893
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:640
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1842
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1385
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1068
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1283
virtual FILE * TempFileName(TString &base, const char *dir=nullptr)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition TSystem.cxx:1484
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:840
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition TSystem.cxx:849
virtual int Rename(const char *from, const char *to)
Rename a file.
Definition TSystem.cxx:1337
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:921
virtual const char * GetFlagsDebug() const
Return the debug flags.
Definition TSystem.cxx:3904
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition TSystem.cxx:938
virtual const char * GetObjExt() const
Get the object file extension.
Definition TSystem.cxx:3998
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:424
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:858
virtual const char * GetLibraries(const char *regexp="", const char *option="", Bool_t isRegexp=kTRUE)
Return a space separated list of loaded shared libraries.
Definition TSystem.cxx:2121
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:874
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition TSystem.cxx:403
virtual const char * GetSoExt() const
Get the shared library extension.
Definition TSystem.cxx:3990
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1019
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1368
virtual const char * GetFlagsOpt() const
Return the optimization flags.
Definition TSystem.cxx:3912
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition TTimeStamp.h:45
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
Definition TUUID.h:42
void ReadBuffer(char *&buffer)
Stream UUID from input buffer.
Definition TUUID.cxx:291
void FillBuffer(char *&buffer)
Stream UUID into output buffer.
Definition TUUID.cxx:275
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetAnchor() const
Definition TUrl.h:70
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition TUrl.cxx:390
void SetAnchor(const char *anchor)
Definition TUrl.h:86
const char * GetFileAndOptions() const
Return the file and its options (the string specified behind the ?).
Definition TUrl.cxx:504
const char * GetFile() const
Definition TUrl.h:69
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
Definition TUrl.cxx:660
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition TUrl.cxx:523
void SetOptions(const char *opt)
Definition TUrl.h:87
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition TUrl.cxx:472
const char * GetOptions() const
Definition TUrl.h:71
void SetHost(const char *host)
Definition TUrl.h:84
const char * GetProtocol() const
Definition TUrl.h:64
void SetFile(const char *file)
Definition TUrl.h:85
Int_t GetPort() const
Definition TUrl.h:78
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
Definition TUrl.cxx:683
virtual Bool_t SendFileReadProgress(TFile *)
virtual Bool_t SendFileCloseEvent(TFile *)
virtual Bool_t SendFileWriteProgress(TFile *)
Abstract Interface class describing Streamer information for one class.
virtual Int_t GetClassVersion() const =0
const Int_t n
Definition legend1.C:16
TF1 * f1
Definition legend1.C:11
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
R__EXTERN TVirtualRWMutex * gCoreMutex
@ kFileThreadSlot
@ kSTLmap
Definition ESTLType.h:33
@ kSTLmultimap
Definition ESTLType.h:34
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:191
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Definition first.py:1
Definition tree.py:1
static const char * what
Definition stlLoader.cc:6
Int_t fMode
Definition TSystem.h:127
@ kUndefined
Undefined compression algorithm (must be kept the last of the list in case a new algorithm is added).
@ kUseMin
Compression level reserved when we are not sure what to use (1 is for the fastest compression)
Definition Compression.h:70
TString fFile
Definition TSystem.h:204
Simple struct of the return value of GetStreamerInfoListImpl.
Definition TFile.h:145
TList * fList
Definition TFile.h:146
th1 Draw()
TLine l
Definition textangle.C:4