GRSISort
Created by P.C. Bender
Developement Team: P.C. Bender, R. Dunlop, V. Bildstein
An extension of the ROOT analysis Framework
grsisort.cxx
Go to the documentation of this file.
1 #include <cstdio>
2 #include <string>
3 #include <sys/stat.h>
4 #include <netdb.h>
5 #include <iostream>
6 #include <stdexcept>
7 #include <pwd.h>
8 
9 #include "TEnv.h"
10 #include "TPluginManager.h"
11 #include "TGRSIint.h"
12 
13 #include "GVersion.h"
14 #include "TThread.h"
15 
16 #ifdef __APPLE__
17 #define HAVE_UTMPX_H
18 #define UTMP_NO_ADDR
19 #ifndef ut_user
20 #define ut_user ut_name
21 #endif
22 #ifndef UTMP_FILE
23 #define UTMP_FILE "/etc/utmp"
24 #endif
25 #endif
26 
27 #ifdef HAVE_UTMPX_H
28 #include <utmpx.h>
29 #define STRUCT_UTMP struct utmpx
30 #else
31 #if defined(__linux) && defined(__powerpc) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 90)
32 extern "C" {
33 #endif
34 #include <utmp.h>
35 #define STRUCT_UTMP struct utmp
36 #endif
37 
39 
40 void SetGRSIEnv();
42 static int ReadUtmp();
43 static STRUCT_UTMP* SearchEntry(int /*n*/, const char* /*tty*/);
44 static void SetDisplay();
45 
46 TStopwatch* gStopwatch;
47 
49 {
50  // Be polite when you leave.
51  double realTime = gStopwatch->RealTime();
52  int hour = static_cast<int>(realTime / 3600);
53  realTime -= hour * 3600;
54  int min = static_cast<int>(realTime / 60);
55  realTime -= min * 60;
56  std::cout<<DMAGENTA<<std::endl
57  <<"bye,bye\t"<<DCYAN<<getpwuid(getuid())->pw_name<<RESET_COLOR<<" after "<<hour<<":"
58  <<std::setfill('0')<<std::setw(2)<<min<<":"<<std::setprecision(3)<<std::fixed<<realTime
59  <<" h:m:s"<<std::endl;
60 }
61 
62 int main(int argc, char** argv)
63 {
64  gStopwatch = new TStopwatch;
65  std::atexit(atexitHandler);
66 
67  try {
68  TThread::Initialize();
69  TObject::SetObjectStat(false);
70 
71  // Find the grsisort environment variable so that we can read in .grsirc
72  SetDisplay();
73  SetGRSIEnv();
75  TGRSIint* input = nullptr;
76 
77  // Create an instance of the grsi interpreter so that we can run root-like interpretive mode
78  input = TGRSIint::instance(argc, argv);
79  input->SetReturnFromRun(true);
80  // Run the code!
81  input->Run(true);
82  } catch(grsi::exit_exception& e) {
83  std::cerr<<e.message<<std::endl;
84  // Close files and clean up properly here
85  } catch(std::runtime_error& e) {
86  std::cerr<<e.what()<<std::endl;
87  std::cout<<"Don't know how to handle this error, exiting "<<argv[0]<<"!"<<std::endl;
88  }
89 
90  return 0;
91 }
92 
93 void SetGRSIEnv()
94 {
95  std::string grsi_path = getenv("GRSISYS"); // Finds the GRSISYS path to be used by other parts of the grsisort code
96  if(grsi_path.length() > 0) {
97  grsi_path += "/";
98  }
99  // Read in grsirc in the GRSISYS directory to set user defined options on grsisort startup
100  grsi_path += ".grsirc";
101  gEnv->ReadFile(grsi_path.c_str(), kEnvChange);
102 }
103 
105 {
106  // gPluginMgr->AddHandler("GRootCanvas","grsi","GRootCanvas"
107  gPluginMgr->AddHandler("TGuiFactory", "root", "GROOTGuiFactory", "Gui", "GROOTGuiFactory()");
108  gPluginMgr->AddHandler("TBrowserImp", "GRootBrowser", "GRootBrowser", "Gui",
109  "NewBrowser(TBrowser *,const char *,Int_t,Int_t,UInt_t,UInt_t");
110  gPluginMgr->AddHandler("TBrowserImp", "GRootBrowser", "GRootBrowser", "Gui",
111  "NewBrowser(TBrowser *,const char *,Int_t,Int_t");
112 }
113 
114 static int ReadUtmp()
115 {
116  FILE* utmp;
117  struct stat file_stats;
118  size_t n_read, size;
119 
120  gUtmpContents = nullptr;
121 
122  utmp = fopen(UTMP_FILE, "r");
123  if(utmp == nullptr) {
124  return 0;
125  }
126 
127  fstat(fileno(utmp), &file_stats);
128  size = file_stats.st_size;
129  if(size <= 0) {
130  fclose(utmp);
131  return 0;
132  }
133 
134  gUtmpContents = static_cast<STRUCT_UTMP*>(malloc(size));
135  if(gUtmpContents == nullptr) {
136  fclose(utmp);
137  return 0;
138  }
139 
140  n_read = fread(gUtmpContents, 1, size, utmp);
141  if(ferror(utmp) == 0) {
142  if(fclose(utmp) != EOF && n_read == size) {
143  return size / sizeof(STRUCT_UTMP);
144  }
145  } else {
146  fclose(utmp);
147  }
148 
149  free(gUtmpContents);
150  gUtmpContents = nullptr;
151  return 0;
152 }
153 
154 static STRUCT_UTMP* SearchEntry(int n, const char* tty)
155 {
157  while((n--) != 0) {
158  if((ue->ut_name[0] != 0) && (strncmp(tty, ue->ut_line, sizeof(ue->ut_line)) == 0)) {
159  return ue;
160  }
161  ue++;
162  }
163  return nullptr;
164 }
165 
166 static void SetDisplay()
167 {
168  // Set DISPLAY environment variable.
169 
170  if(getenv("DISPLAY") == nullptr) {
171  char* tty = ttyname(0); // device user is logged in on
172  if(tty != nullptr) {
173  tty += 5; // remove "/dev/"
174  STRUCT_UTMP* utmp_entry = SearchEntry(ReadUtmp(), tty);
175  if(utmp_entry != nullptr) {
176  size_t length = sizeof(utmp_entry->ut_host);
177  auto* display = new char[length + 15];
178  auto* host = new char[length + 1];
179  strncpy(host, utmp_entry->ut_host, length); // instead of using size of utmp_entry->ut_host to prevent warning from gcc 9.1
180  host[sizeof(utmp_entry->ut_host)] = 0;
181  if(host[0] != 0) {
182  if(strchr(host, ':') != nullptr) {
183  sprintf(display, "DISPLAY=%s", host);
184  fprintf(stderr, "*** DISPLAY not set, setting it to %s\n", host);
185  } else {
186  sprintf(display, "DISPLAY=%s:0.0", host);
187  fprintf(stderr, "*** DISPLAY not set, setting it to %s:0.0\n", host);
188  }
189  putenv(display);
190 #ifndef UTMP_NO_ADDR
191  } else if(utmp_entry->ut_addr != 0) {
192  struct hostent* he;
193  if((he = gethostbyaddr(reinterpret_cast<const char*>(&utmp_entry->ut_addr), sizeof(utmp_entry->ut_addr),
194  AF_INET)) != nullptr) {
195  sprintf(display, "DISPLAY=%s:0.0", he->h_name);
196  fprintf(stderr, "*** DISPLAY not set, setting it to %s:0.0\n", he->h_name);
197  putenv(display);
198  } else {
199  delete[] display; // if display is not used, we can delete it
200  }
201 #endif
202  } else {
203  delete[] display; // if display is not used, we can delete it
204  }
205  delete[] host;
206  // display cannot be deleted otherwise the env var is deleted too
207  }
208  free(gUtmpContents);
209  }
210  }
211 }
static STRUCT_UTMP * SearchEntry(int, const char *)
Definition: grsisort.cxx:154
TStopwatch * gStopwatch
Definition: grsisort.cxx:46
#define RESET_COLOR
Definition: Globals.h:4
#define STRUCT_UTMP
Definition: grsisort.cxx:35
#define DCYAN
Definition: Globals.h:20
int main(int argc, char **argv)
Definition: grsisort.cxx:62
static TGRSIint * instance(int argc=0, char **argv=nullptr, void *options=nullptr, int numOptions=-1, bool noLogo=false, const char *appClassName="grsisort")
Definition: TGRSIint.cxx:54
static STRUCT_UTMP * gUtmpContents
Definition: grsisort.cxx:38
void atexitHandler()
Definition: grsisort.cxx:48
void SetGRSIEnv()
Definition: grsisort.cxx:93
static int ReadUtmp()
Definition: grsisort.cxx:114
void SetGRSIPluginHandlers()
Definition: grsisort.cxx:104
#define DMAGENTA
Definition: Globals.h:19
static void SetDisplay()
Definition: grsisort.cxx:166
const char * message
Definition: Globals.h:93