Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
IOHandler.cxx
Go to the documentation of this file.
1// Author: Danilo Piparo, Omar Zapata, Enric Tejedor 16/12/2015
2
3/*************************************************************************
4 * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#include <Python.h>
12
13#include <fcntl.h>
14#ifdef _MSC_VER // Visual Studio
15#include <winsock2.h>
16#include <io.h>
17#pragma comment(lib, "Ws2_32.lib")
18#define pipe(fds) _pipe(fds, 1048575, _O_BINARY)
19#define read _read
20#define dup _dup
21#define dup2 _dup2
22#define STDIN_FILENO 0
23#define STDOUT_FILENO 1
24#define STDERR_FILENO 2
25#else
26#include <unistd.h>
27#endif
28#include <string>
29#include <iostream>
30#include "TInterpreter.h"
31
32//////////////////////////
33// MODULE FUNCTIONALITY //
34//////////////////////////
35
37private:
38 bool fCapturing = false;
39 std::string fStdoutpipe;
40 std::string fStderrpipe;
41 int fStdout_pipe[2] = {0, 0};
42 int fStderr_pipe[2] = {0, 0};
45
46public:
48 void Poll();
49 void InitCapture();
50 void EndCapture();
51 void Clear();
52 std::string &GetStdout();
53 std::string &GetStderr();
54};
55
56#ifndef F_LINUX_SPECIFIC_BASE
57#define F_LINUX_SPECIFIC_BASE 1024
58#endif
59#ifndef F_SETPIPE_SZ
60#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
61#endif
62
63constexpr long MAX_PIPE_SIZE = 1048575;
64
66
67static void PollImpl(FILE *stdStream, int *pipeHandle, std::string &pipeContent)
68{
69 fflush(stdStream);
70#ifdef _MSC_VER
71 char buffer[60000] = "";
72 struct _stat st;
73 _fstat(pipeHandle[0], &st);
74 if (st.st_size) {
75 _read(pipeHandle[0], buffer, 60000);
76 pipeContent += buffer;
77 }
78#else
79 int buf_read;
80 char ch;
81 while (true) {
82 buf_read = read(pipeHandle[0], &ch, 1);
83 if (buf_read == 1) {
84 pipeContent += ch;
85 } else
86 break;
87 }
88#endif
89}
90
92{
95}
96
97static void InitCaptureImpl(int &savedStdStream, int *pipeHandle, int FILENO)
98{
99 savedStdStream = dup(FILENO);
100 if (pipe(pipeHandle) != 0) {
101 return;
102 }
103#ifndef _MSC_VER
104 long flags_stdout = fcntl(pipeHandle[0], F_GETFL);
105 if (flags_stdout == -1)
106 return;
107 flags_stdout |= O_NONBLOCK;
108 fcntl(pipeHandle[0], F_SETFL, flags_stdout);
109 fcntl(pipeHandle[0], F_SETPIPE_SZ, MAX_PIPE_SIZE);
110#endif
111 dup2(pipeHandle[1], FILENO);
112}
113
115{
116 if (!fCapturing) {
119 fCapturing = true;
120 }
121}
122
124{
125 if (fCapturing) {
126 Poll();
127 dup2(fSaved_stdout, STDOUT_FILENO);
128 dup2(fSaved_stderr, STDERR_FILENO);
129 close(fSaved_stdout);
130 close(fSaved_stderr);
131 close(fStdout_pipe[0]);
132 close(fStdout_pipe[1]);
133 close(fStderr_pipe[0]);
134 close(fStderr_pipe[1]);
135 fCapturing = false;
136 }
137}
138
140{
141 fStdoutpipe = "";
142 fStderrpipe = "";
143}
144
146{
147 return fStdoutpipe;
148}
149
151{
152 return fStderrpipe;
153}
154
156
157bool JupyROOTExecutorImpl(const char *code)
158{
159 auto status = false;
160 try {
161 auto err = TInterpreter::kNoError;
162 if (gInterpreter->ProcessLine(code, &err)) {
163 status = true;
164 }
165
166 if (err == TInterpreter::kProcessing) {
167 gInterpreter->ProcessLine(".@");
168 gInterpreter->ProcessLine("cerr << \"Unbalanced braces. This cell was not processed.\" << endl;");
169 }
170 } catch (...) {
171 status = true;
172 }
173
174 return status;
175}
176
177bool JupyROOTDeclarerImpl(const char *code)
178{
179 auto status = false;
180 try {
181 if (gInterpreter->Declare(code)) {
182 status = true;
183 }
184 } catch (...) {
185 status = true;
186 }
187 return status;
188}
189
191{
192 const char *code;
193 if (!PyArg_ParseTuple(args, "s", &code))
194 return NULL;
195
196 auto res = JupyROOTExecutorImpl(code);
197
198 return PyLong_FromLong(res);
199}
200
202{
203 const char *code;
204 if (!PyArg_ParseTuple(args, "s", &code))
205 return NULL;
206
207 auto res = JupyROOTDeclarerImpl(code);
208
209 return PyLong_FromLong(res);
210}
211
213{
216}
217
219{
222 // Fixes for ROOT-7999
223 gInterpreter->ProcessLine("SetErrorHandler((ErrorHandlerFunc_t)&DefaultErrorHandler);");
224 }
225
227}
228
230{
233}
234
236{
239}
240
242{
245}
246
248{
249 auto out = JupyROOTExecutorHandler_ptr->GetStdout().c_str();
250 return PyUnicode_FromString(out);
251}
252
254{
255 auto err = JupyROOTExecutorHandler_ptr->GetStderr().c_str();
256 return PyUnicode_FromString(err);
257}
258
260{
263
266
268}
#define Py_RETURN_NONE
Definition CPyCppyy.h:268
PyObject * JupyROOTExecutorHandler_Ctor(PyObject *, PyObject *)
PyObject * JupyROOTDeclarer(PyObject *, PyObject *args)
static void InitCaptureImpl(int &savedStdStream, int *pipeHandle, int FILENO)
Definition IOHandler.cxx:97
JupyROOTExecutorHandler * JupyROOTExecutorHandler_ptr
constexpr long MAX_PIPE_SIZE
Definition IOHandler.cxx:63
PyObject * JupyROOTExecutorHandler_GetStdout(PyObject *, PyObject *)
#define F_SETPIPE_SZ
Definition IOHandler.cxx:60
bool JupyROOTDeclarerImpl(const char *code)
static void PollImpl(FILE *stdStream, int *pipeHandle, std::string &pipeContent)
Definition IOHandler.cxx:67
bool JupyROOTExecutorImpl(const char *code)
PyObject * JupyROOTExecutor(PyObject *, PyObject *args)
PyObject * JupyROOTExecutorHandler_EndCapture(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_Poll(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_Clear(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_GetStderr(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_InitCapture(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_Dtor(PyObject *, PyObject *)
_object PyObject
#define gInterpreter
std::string & GetStderr()
std::string & GetStdout()