Logo ROOT   6.16/01
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
22bool JupyROOTExecutorImpl(const char *code);
23bool JupyROOTDeclarerImpl(const char *code);
24
25class JupyROOTExecutorHandler {
26private:
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;
34public:
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
52constexpr long MAX_PIPE_SIZE = 1048575;
53
54JupyROOTExecutorHandler::JupyROOTExecutorHandler() {}
55
56
57static 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
70void JupyROOTExecutorHandler::Poll()
71{
72 PollImpl(stdout, fStdout_pipe, fStdoutpipe);
73 PollImpl(stderr, fStderr_pipe, fStderrpipe);
74}
75
76static 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
96void 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
105void 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
115void JupyROOTExecutorHandler::Clear()
116{
117 fStdoutpipe = "";
118 fStderrpipe = "";
119}
120
121std::string &JupyROOTExecutorHandler::GetStdout()
122{
123 return fStdoutpipe;
124}
125
126std::string &JupyROOTExecutorHandler::GetStderr()
127{
128 return fStderrpipe;
129}
130
131JupyROOTExecutorHandler *JupyROOTExecutorHandler_ptr = nullptr;
132
133////////////////////////////////////////////////////////////////////////////////
134bool 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
154bool 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
167extern "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 {
181 }
182
184 {
186 JupyROOTExecutorHandler_ptr = new JupyROOTExecutorHandler();
187 // Fixes for ROOT-7999
188 gInterpreter->ProcessLine("SetErrorHandler((ErrorHandlerFunc_t)&DefaultErrorHandler);");
189 }
190 }
191
193 {
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;
222 }
223
224}
int JupyROOTDeclarer(const char *code)
Definition: IOHandler.cxx:173
void JupyROOTExecutorHandler_Dtor()
Definition: IOHandler.cxx:217
void JupyROOTExecutorHandler_InitCapture()
Definition: IOHandler.cxx:202
static void InitCaptureImpl(int &savedStdStream, int *pipeHandle, int FILENO)
Definition: IOHandler.cxx:76
JupyROOTExecutorHandler * JupyROOTExecutorHandler_ptr
Definition: IOHandler.cxx:131
void JupyROOTExecutorHandler_Poll()
Definition: IOHandler.cxx:192
int JupyROOTExecutor(const char *code)
Definition: IOHandler.cxx:169
constexpr long MAX_PIPE_SIZE
Definition: IOHandler.cxx:52
const char * JupyROOTExecutorHandler_GetStderr()
Definition: IOHandler.cxx:212
void JupyROOTExecutorHandler_Ctor()
Definition: IOHandler.cxx:183
#define F_SETPIPE_SZ
Definition: IOHandler.cxx:49
bool JupyROOTDeclarerImpl(const char *code)
Definition: IOHandler.cxx:154
static void PollImpl(FILE *stdStream, int *pipeHandle, std::string &pipeContent)
Definition: IOHandler.cxx:57
bool JupyROOTExecutorImpl(const char *code)
Definition: IOHandler.cxx:134
const char * JupyROOTExecutorHandler_GetStdout()
Definition: IOHandler.cxx:207
void JupyROOTExecutorHandler_Clear()
Definition: IOHandler.cxx:178
void JupyROOTExecutorHandler_EndCapture()
Definition: IOHandler.cxx:197
#define gInterpreter
Definition: TInterpreter.h:538