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