Logo ROOT   6.10/09
Reference Guide
IOHandler.cxx
Go to the documentation of this file.
1 // Author: Danilo Piparo, Omar Zapata 16/12/2015
2 
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <string>
6 #include <iostream>
7 #include "TInterpreter.h"
8 
9 bool JupyROOTExecutorImpl(const char *code);
10 bool JupyROOTDeclarerImpl(const char *code);
11 
12 class JupyROOTExecutorHandler {
13 private:
14  bool fCapturing = false;
15  std::string fStdoutpipe;
16  std::string fStderrpipe;
17  int fStdout_pipe[2] = {0,0};
18  int fStderr_pipe[2] = {0,0};
19  int fSaved_stderr = 0;
20  int fSaved_stdout = 0;
21 public:
22  JupyROOTExecutorHandler();
23  void Poll();
24  void InitCapture();
25  void EndCapture();
26  void Clear();
27  std::string &GetStdout();
28  std::string &GetStderr();
29 };
30 
31 
32 #ifndef F_LINUX_SPECIFIC_BASE
33 #define F_LINUX_SPECIFIC_BASE 1024
34 #endif
35 #ifndef F_SETPIPE_SZ
36 #define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
37 #endif
38 
39 constexpr long MAX_PIPE_SIZE = 1048575;
40 
41 JupyROOTExecutorHandler::JupyROOTExecutorHandler() {}
42 
43 
44 static void PollImpl(FILE *stdStream, int *pipeHandle, std::string &pipeContent)
45 {
46  int buf_read;
47  char ch;
48  fflush(stdStream);
49  while (true) {
50  buf_read = read(pipeHandle[0], &ch, 1);
51  if (buf_read == 1) {
52  pipeContent += ch;
53  } else break;
54  }
55 }
56 
57 void JupyROOTExecutorHandler::Poll()
58 {
59  PollImpl(stdout, fStdout_pipe, fStdoutpipe);
60  PollImpl(stderr, fStderr_pipe, fStderrpipe);
61 }
62 
63 static void InitCaptureImpl(int &savedStdStream, int *pipeHandle, int FILENO)
64 {
65  savedStdStream = dup(FILENO);
66  if (pipe(pipeHandle) != 0) {
67  return;
68  }
69  long flags_stdout = fcntl(pipeHandle[0], F_GETFL);
70  if (flags_stdout == -1) return;
71  flags_stdout |= O_NONBLOCK;
72  fcntl(pipeHandle[0], F_SETFL, flags_stdout);
73  fcntl(pipeHandle[0], F_SETPIPE_SZ, MAX_PIPE_SIZE);
74  dup2(pipeHandle[1], FILENO);
75  close(pipeHandle[1]);
76 }
77 
78 void JupyROOTExecutorHandler::InitCapture()
79 {
80  if (!fCapturing) {
81  InitCaptureImpl(fSaved_stdout, fStdout_pipe, STDOUT_FILENO);
82  InitCaptureImpl(fSaved_stderr, fStderr_pipe, STDERR_FILENO);
83  fCapturing = true;
84  }
85 }
86 
87 void JupyROOTExecutorHandler::EndCapture()
88 {
89  if (fCapturing) {
90  Poll();
91  dup2(fSaved_stdout, STDOUT_FILENO);
92  dup2(fSaved_stderr, STDERR_FILENO);
93  fCapturing = false;
94  }
95 }
96 
97 void JupyROOTExecutorHandler::Clear()
98 {
99  fStdoutpipe = "";
100  fStderrpipe = "";
101 }
102 
103 std::string &JupyROOTExecutorHandler::GetStdout()
104 {
105  return fStdoutpipe;
106 }
107 
108 std::string &JupyROOTExecutorHandler::GetStderr()
109 {
110  return fStderrpipe;
111 }
112 
113 JupyROOTExecutorHandler *JupyROOTExecutorHandler_ptr = nullptr;
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 bool JupyROOTExecutorImpl(const char *code)
117 {
118  auto status = false;
119  try {
120  auto err = TInterpreter::kNoError;
121  if (gInterpreter->ProcessLine(code, &err)) {
122  status = true;
123  }
124 
125  if (err == TInterpreter::kProcessing) {
126  gInterpreter->ProcessLine(".@");
127  gInterpreter->ProcessLine("cerr << \"Unbalanced braces. This cell was not processed.\" << endl;");
128  }
129  } catch (...) {
130  status = true;
131  }
132 
133  return status;
134 }
135 
136 bool JupyROOTDeclarerImpl(const char *code)
137 {
138  auto status = false;
139  try {
140  if (gInterpreter->Declare(code)) {
141  status = true;
142  }
143  } catch (...) {
144  status = true;
145  }
146  return status;
147 }
148 
149 extern "C" {
150 
151  int JupyROOTExecutor(const char *code)
152  {
153  return JupyROOTExecutorImpl(code);
154  }
155  int JupyROOTDeclarer(const char *code)
156  {
157  return JupyROOTDeclarerImpl(code);
158  }
159 
161  {
162  JupyROOTExecutorHandler_ptr->Clear();
163  }
164 
166  {
167  if (!JupyROOTExecutorHandler_ptr) {
168  JupyROOTExecutorHandler_ptr = new JupyROOTExecutorHandler();
169  // Fixes for ROOT-7999
170  gInterpreter->ProcessLine("SetErrorHandler((ErrorHandlerFunc_t)&DefaultErrorHandler);");
171  }
172  }
173 
175  {
176  JupyROOTExecutorHandler_ptr->Poll();
177  }
178 
180  {
181  JupyROOTExecutorHandler_ptr->EndCapture();
182  }
183 
185  {
186  JupyROOTExecutorHandler_ptr->InitCapture();
187  }
188 
190  {
191  return JupyROOTExecutorHandler_ptr->GetStdout().c_str();
192  }
193 
195  {
196  return JupyROOTExecutorHandler_ptr->GetStderr().c_str();
197  }
198 
200  {
201  if (!JupyROOTExecutorHandler_ptr) return;
203  JupyROOTExecutorHandler_ptr = nullptr;
204  }
205 
206 }
bool JupyROOTExecutorImpl(const char *code)
Definition: IOHandler.cxx:116
double read(const std::string &file_name)
reading
#define gInterpreter
Definition: TInterpreter.h:499
void JupyROOTExecutorHandler_Clear()
Definition: IOHandler.cxx:160
#define F_SETPIPE_SZ
Definition: IOHandler.cxx:36
static void InitCaptureImpl(int &savedStdStream, int *pipeHandle, int FILENO)
Definition: IOHandler.cxx:63
constexpr long MAX_PIPE_SIZE
Definition: IOHandler.cxx:39
const char * JupyROOTExecutorHandler_GetStdout()
Definition: IOHandler.cxx:189
void JupyROOTExecutorHandler_Ctor()
Definition: IOHandler.cxx:165
void JupyROOTExecutorHandler_EndCapture()
Definition: IOHandler.cxx:179
int JupyROOTExecutor(const char *code)
Definition: IOHandler.cxx:151
static void PollImpl(FILE *stdStream, int *pipeHandle, std::string &pipeContent)
Definition: IOHandler.cxx:44
JupyROOTExecutorHandler * JupyROOTExecutorHandler_ptr
Definition: IOHandler.cxx:113
int JupyROOTDeclarer(const char *code)
Definition: IOHandler.cxx:155
bool JupyROOTDeclarerImpl(const char *code)
Definition: IOHandler.cxx:136
void JupyROOTExecutorHandler_Poll()
Definition: IOHandler.cxx:174
void JupyROOTExecutorHandler_Dtor()
Definition: IOHandler.cxx:199
const char * JupyROOTExecutorHandler_GetStderr()
Definition: IOHandler.cxx:194
void JupyROOTExecutorHandler_InitCapture()
Definition: IOHandler.cxx:184