roots.cxx

Go to the documentation of this file.
00001 // @(#)root/main:$Id: roots.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: G Ganis 10/5/2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // Launching program for remote ROOT sessions                           //
00015 //                                                                      //
00016 //////////////////////////////////////////////////////////////////////////
00017 
00018 #include <stdio.h>
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <unistd.h>
00022 #include <errno.h>
00023 
00024 #include "TInterpreter.h"
00025 #include "TROOT.h"
00026 #include "TApplication.h"
00027 #include "TPluginManager.h"
00028 #include "TSystem.h"
00029 #include "TString.h"
00030 
00031 static Int_t MakeCleanupScript(Int_t loglevel);
00032 static FILE *RedirectOutput(TString &logfile, const char *loc);
00033 
00034 static const char *gAppName = "roots";
00035 
00036 //______________________________________________________________________________
00037 int main(int argc, char **argv)
00038 {
00039    // The main program: start a TApplication which connects back to the client.
00040 
00041    // Prepare the application
00042    if (argc < 4) {
00043       fprintf(stderr, "%s: insufficient input:"
00044                       " client URL must to be provided\n", gAppName);
00045       gSystem->Exit(1);
00046    }
00047 
00048    // Parse the debug level
00049    int loglevel = -1;
00050    TString argdbg(argv[3]);
00051    if (argdbg.BeginsWith("-d=")) {
00052       argdbg.ReplaceAll("-d=","");
00053       loglevel = argdbg.Atoi();
00054    }
00055    if (loglevel > 0) {
00056       fprintf(stderr,"%s: Starting remote session on %s\n", gAppName, gSystem->HostName());
00057       if (loglevel > 1) {
00058          fprintf(stderr,"%s:    argc: %d\n", gAppName, argc);
00059          for (Int_t i = 0; i < argc; i++)
00060             fprintf(stderr,"%s:    argv[%d]: %s\n", gAppName, i, argv[i]);
00061       }
00062    }
00063 
00064    // Cleanup script
00065    if (MakeCleanupScript(loglevel) != 0)
00066       fprintf(stderr,"%s: Error: failed to create cleanup script\n", gAppName);
00067 
00068    // Redirect the output
00069    TString logfile;
00070    FILE *fLog = RedirectOutput(logfile, ((loglevel > 1) ? gAppName : 0));
00071    if (fLog) {
00072       if (loglevel > 0)
00073          fprintf(stderr,"%s: output redirected to %s\n", gAppName, logfile.Data());
00074    } else {
00075       fprintf(stderr,"%s: problems redirecting output\n", gAppName);
00076       gSystem->Exit(1);
00077    }
00078 
00079    // Url to contact back
00080    TString url = argv[1];
00081 
00082    // Like in batch mode
00083    gROOT->SetBatch();
00084 
00085    // Enable autoloading
00086    gInterpreter->EnableAutoLoading();
00087 
00088    // Instantiate the TApplication object to be run
00089    TPluginHandler *h = 0;
00090    TApplication *theApp = 0;
00091    if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","server"))) {
00092       if (h->LoadPlugin() == 0) {
00093          theApp = (TApplication *) h->ExecPlugin(4, &argc, argv, fLog, logfile.Data());
00094       } else {
00095          fprintf(stderr, "%s: failed to load plugin for TApplicationServer\n", gAppName);
00096       }
00097    } else {
00098       fprintf(stderr, "%s: failed to find plugin for TApplicationServer\n", gAppName);
00099    }
00100 
00101    // Run it
00102    if (theApp) {
00103       theApp->Run();
00104    } else {
00105       fprintf(stderr, "%s: failed to instantiate TApplicationServer\n", gAppName);
00106       gSystem->Exit(1);
00107    }
00108 
00109    // Done
00110    gSystem->Exit(0);
00111 }
00112 
00113 //______________________________________________________________________________
00114 FILE *RedirectOutput(TString &logfile, const char *loc)
00115 {
00116    // Redirect stdout to 'logfile'. This log file will be flushed to the
00117    // client or master after each command.
00118    // On success return a pointer to the open log file. Return 0 on failure.
00119 
00120    if (loc)
00121       fprintf(stderr,"%s: RedirectOutput: enter\n", loc);
00122 
00123    // Log file under $TEMP
00124    logfile = Form("%s/roots-%d-%d.log", gSystem->TempDirectory(),
00125                                         gSystem->GetUid(), gSystem->GetPid());
00126    const char *lfn = logfile.Data();
00127    if (loc)
00128       fprintf(stderr,"%s: Path to log file: %s\n", loc, lfn);
00129 
00130    if (loc)
00131       fprintf(stderr,"%s: RedirectOutput: reopen %s\n", loc, lfn);
00132    FILE *flog = freopen(lfn, "w", stdout);
00133    if (!flog) {
00134       fprintf(stderr,"%s: RedirectOutput: could not freopen stdout\n", loc);
00135       return 0;
00136    }
00137 
00138    if (loc)
00139       fprintf(stderr,"%s: RedirectOutput: dup2 ...\n", loc);
00140    if ((dup2(fileno(stdout), fileno(stderr))) < 0) {
00141       fprintf(stderr,"%s: RedirectOutput: could not redirect stderr\n", loc);
00142       return 0;
00143    }
00144 
00145    if (loc)
00146       fprintf(stderr,"%s: RedirectOutput: read open ...\n", loc);
00147    FILE *fLog = fopen(lfn, "r");
00148    if (!fLog) {
00149       fprintf(stderr,"%s: RedirectOutput: could not open logfile %s\n", loc, lfn);
00150       return 0;
00151    }
00152 
00153    if (loc)
00154       fprintf(stderr,"%s: RedirectOutput: done!\n", loc);
00155    // We are done
00156    return fLog;
00157 }
00158 
00159 //______________________________________________________________________________
00160 Int_t MakeCleanupScript(Int_t loglevel)
00161 {
00162    // Create a script that can be executed to cleanup this process in case of
00163    // problems. Return 0 on success, -1 in case of any problem.
00164 
00165    // The file path
00166    TString cleanup = Form("%s/roots-%d-%d.cleanup", gSystem->TempDirectory(),
00167                                                     gSystem->GetUid(), gSystem->GetPid());
00168    // Open the file
00169    FILE *fc = fopen(cleanup.Data(), "w");
00170    if (fc) {
00171       fprintf(fc,"#!/bin/sh\n");
00172       fprintf(fc,"\n");
00173       fprintf(fc,"# Cleanup script for roots process %d\n", gSystem->GetPid());
00174       fprintf(fc,"# Usage:\n");
00175       fprintf(fc,"#   ssh %s@%s %s\n", gSystem->Getenv("USER"), gSystem->HostName(), cleanup.Data());
00176       fprintf(fc,"#\n");
00177       fprintf(fc,"kill -9 %d", gSystem->GetPid());
00178       // Close file
00179       fclose(fc);
00180       if (chmod(cleanup.Data(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
00181          fprintf(stderr,"%s: Error: cannot make script %s executable\n", gAppName, cleanup.Data());
00182          unlink(cleanup.Data());
00183          return -1;
00184       } else {
00185          if (loglevel > 1)
00186             fprintf(stderr,"%s: Path to cleanup script %s\n", gAppName, cleanup.Data());
00187       }
00188    } else {
00189       fprintf(stderr,"%s: Error: file %s could not be created\n", gAppName, cleanup.Data());
00190       return -1;
00191    }
00192 
00193    // Done
00194    return 0;
00195 }

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