Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
roots.cxx
Go to the documentation of this file.
1// @(#)root/main:$Id$
2// Author: G Ganis 10/5/2007
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// //
14// Launching program for remote ROOT sessions //
15// //
16//////////////////////////////////////////////////////////////////////////
17
18#include <cstdio>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <unistd.h>
22#include <cerrno>
23
24#include "TInterpreter.h"
25#include "TROOT.h"
26#include "TApplication.h"
27#include "TPluginManager.h"
28#include "TSystem.h"
29#include "TString.h"
30
31static Int_t MakeCleanupScript(Int_t loglevel);
32static FILE *RedirectOutput(TString &logfile, const char *loc);
33
34static const char *gAppName = "roots";
35
36////////////////////////////////////////////////////////////////////////////////
37/// The main program: start a TApplication which connects back to the client.
38
39int main(int argc, char **argv)
40{
41 // Prepare the application
42 if (argc < 4) {
43 fprintf(stderr, "%s: insufficient input:"
44 " client URL must to be provided\n", gAppName);
45 gSystem->Exit(1);
46 }
47
48 // Parse the debug level
49 int loglevel = -1;
50 TString argdbg(argv[3]);
51 if (argdbg.BeginsWith("-d=")) {
52 argdbg.ReplaceAll("-d=","");
53 loglevel = argdbg.Atoi();
54 }
55 if (loglevel > 0) {
56 fprintf(stderr,"%s: Starting remote session on %s\n", gAppName, gSystem->HostName());
57 if (loglevel > 1) {
58 fprintf(stderr,"%s: argc: %d\n", gAppName, argc);
59 for (Int_t i = 0; i < argc; i++)
60 fprintf(stderr,"%s: argv[%d]: %s\n", gAppName, i, argv[i]);
61 }
62 }
63
64 // Cleanup script
65 if (MakeCleanupScript(loglevel) != 0)
66 fprintf(stderr,"%s: Error: failed to create cleanup script\n", gAppName);
67
68 // Redirect the output
70 FILE *fLog = RedirectOutput(logfile, ((loglevel > 1) ? gAppName : 0));
71 if (fLog) {
72 if (loglevel > 0)
73 fprintf(stderr,"%s: output redirected to %s\n", gAppName, logfile.Data());
74 } else {
75 fprintf(stderr,"%s: problems redirecting output\n", gAppName);
76 gSystem->Exit(1);
77 }
78
79 // Url to contact back
80 TString url = argv[1];
81
82 // Like in batch mode
83 gROOT->SetBatch();
84
85 // Instantiate the TApplication object to be run
86 TPluginHandler *h = nullptr;
87 TApplication *theApp = nullptr;
88 if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","server"))) {
89 if (h->LoadPlugin() == 0) {
90 theApp = (TApplication *) h->ExecPlugin(4, &argc, argv, fLog, logfile.Data());
91 } else {
92 fprintf(stderr, "%s: failed to load plugin for TApplicationServer\n", gAppName);
93 }
94 } else {
95 fprintf(stderr, "%s: failed to find plugin for TApplicationServer\n", gAppName);
96 }
97
98 // Run it
99 if (theApp) {
100 theApp->Run();
101 } else {
102 fprintf(stderr, "%s: failed to instantiate TApplicationServer\n", gAppName);
103 gSystem->Exit(1);
104 }
105
106 // Done
107 gSystem->Exit(0);
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// Redirect stdout to 'logfile'. This log file will be flushed to the
112/// client or master after each command.
113/// On success return a pointer to the open log file. Return 0 on failure.
114
115FILE *RedirectOutput(TString &logfile, const char *loc)
116{
117 if (loc)
118 fprintf(stderr,"%s: RedirectOutput: enter\n", loc);
119
120 // Log file under $TEMP
121 logfile = TString::Format("%s/roots-%d-%d.log", gSystem->TempDirectory(),
122 gSystem->GetUid(), gSystem->GetPid());
123 const char *lfn = logfile.Data();
124 if (loc)
125 fprintf(stderr,"%s: Path to log file: %s\n", loc, lfn);
126
127 if (loc)
128 fprintf(stderr,"%s: RedirectOutput: reopen %s\n", loc, lfn);
129 FILE *flog = freopen(lfn, "w", stdout);
130 if (!flog) {
131 fprintf(stderr,"%s: RedirectOutput: could not freopen stdout\n", loc);
132 return nullptr;
133 }
134
135 if (loc)
136 fprintf(stderr,"%s: RedirectOutput: dup2 ...\n", loc);
137 if ((dup2(fileno(stdout), fileno(stderr))) < 0) {
138 fprintf(stderr,"%s: RedirectOutput: could not redirect stderr\n", loc);
139 return nullptr;
140 }
141
142 if (loc)
143 fprintf(stderr,"%s: RedirectOutput: read open ...\n", loc);
144 FILE *fLog = fopen(lfn, "r");
145 if (!fLog) {
146 fprintf(stderr,"%s: RedirectOutput: could not open logfile %s\n", loc, lfn);
147 return nullptr;
148 }
149
150 if (loc)
151 fprintf(stderr,"%s: RedirectOutput: done!\n", loc);
152 // We are done
153 return fLog;
154}
155
156////////////////////////////////////////////////////////////////////////////////
157/// Create a script that can be executed to cleanup this process in case of
158/// problems. Return 0 on success, -1 in case of any problem.
159
161{
162 // The file path
163 TString cleanup = TString::Format("%s/roots-%d-%d.cleanup", gSystem->TempDirectory(),
164 gSystem->GetUid(), gSystem->GetPid());
165 // Open the file
166 FILE *fc = fopen(cleanup.Data(), "w");
167 if (fc) {
168 fprintf(fc,"#!/bin/sh\n");
169 fprintf(fc,"\n");
170 fprintf(fc,"# Cleanup script for roots process %d\n", gSystem->GetPid());
171 fprintf(fc,"# Usage:\n");
172 fprintf(fc,"# ssh %s@%s %s\n", gSystem->Getenv("USER"), gSystem->HostName(), cleanup.Data());
173 fprintf(fc,"#\n");
174 fprintf(fc,"kill -9 %d", gSystem->GetPid());
175 // Close file
176 fclose(fc);
177 if (chmod(cleanup.Data(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
178 fprintf(stderr,"%s: Error: cannot make script %s executable\n", gAppName, cleanup.Data());
179 unlink(cleanup.Data());
180 return -1;
181 } else {
182 if (loglevel > 1)
183 fprintf(stderr,"%s: Path to cleanup script %s\n", gAppName, cleanup.Data());
184 }
185 } else {
186 fprintf(stderr,"%s: Error: file %s could not be created\n", gAppName, cleanup.Data());
187 return -1;
188 }
189
190 // Done
191 return 0;
192}
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
#define gROOT
Definition TROOT.h:417
externTSystem * gSystem
Definition TSystem.h:582
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
virtual void Run(Bool_t retrn=kFALSE)
Main application eventloop. Calls system dependent eventloop via gSystem.
Basic string class.
Definition TString.h:138
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1994
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:713
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:632
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:2385
int main()
static std::string logfile
static Int_t MakeCleanupScript(Int_t loglevel)
Create a script that can be executed to cleanup this process in case of problems.
Definition roots.cxx:160
static FILE * RedirectOutput(TString &logfile, const char *loc)
Redirect stdout to 'logfile'.
Definition roots.cxx:115
static const char * gAppName
Definition roots.cxx:34