YARP
Yet Another Robot Platform
RunReadWrite.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #ifndef YARP_RUN_IMPL_RUNREADWRITE_H
11 #define YARP_RUN_IMPL_RUNREADWRITE_H
12 
13 #include <string>
14 #include <yarp/os/Port.h>
15 #include <yarp/os/Thread.h>
16 #include <yarp/os/PortReader.h>
17 #include <string>
18 #include <yarp/os/Network.h>
21 
22 #include <cstdlib>
23 #include <fcntl.h>
24 
25 #if defined(_WIN32)
26 #include <windows.h>
27 #include <process.h>
28 #include <io.h>
29 #else
30 #include <unistd.h>
31 #endif
32 
34 
35 class RunStdio
36 {
37 public:
38  virtual ~RunStdio(){}
39  virtual void exit()=0;
40 };
41 
42 /*
43 class RunTerminator : public yarp::os::Thread
44 {
45 public:
46  RunTerminator(RunStdio* pStdio)
47  {
48  mStdio=pStdio;
49  CreatePipe(&hReadPipe, &hWritePipe, nullptr, 0);
50  }
51 
52  ~RunTerminator()
53  {
54  CloseHandle(hReadPipe);
55  CloseHandle(hWritePipe);
56  }
57 
58  void run()
59  {
60  DWORD nr;
61  char dummy[24];
62  ReadFile(hReadPipe, dummy, 1, &nr, nullptr);
63  RUNLOG("mStdio->exit()")
64  mStdio->exit();
65  }
66 
67  void exit()
68  {
69  DWORD nw;
70  WriteFile(hWritePipe, "*", 1, &nw, nullptr);
71  }
72 
73 protected:
74  HANDLE hReadPipe, hWritePipe;
75  RunStdio* mStdio;
76 };
77 */
78 
80 #if !defined(_WIN32)
81  : public yarp::os::Thread
82 #endif
83 {
84 public:
86  {
87  mStdio=pStdio;
88 #if !defined(_WIN32)
89  int pipe_block[2];
90  int warn_suppress = yarp::run::impl::pipe(pipe_block);
91  YARP_UNUSED(warn_suppress);
92  fwait=fdopen(pipe_block[0], "r");
93  fpost=fdopen(pipe_block[1], "w");
94 #endif
95  }
96 
97 #if defined(_WIN32)
98  void start(){}
99 #endif
100 
102  {
103 #if !defined(_WIN32)
104  fclose(fwait);
105  fclose(fpost);
106 #endif
107  }
108 
109  void run()
110 #if !defined(_WIN32)
111  override
112 #endif
113  {
114 #if !defined(_WIN32)
115  char dummy[24];
116  char* warn_suppress = fgets(dummy, 16, fwait);
117  YARP_UNUSED(warn_suppress);
118  RUNLOG("mStdio->exit()")
119  mStdio->exit();
120 #endif
121  }
122 
123  void exit()
124  {
125 #if defined(_WIN32)
126  mStdio->exit();
127 #else
128  fprintf(fpost, "SHKIATTETE!\n");
129  fflush(fpost);
130 #endif
131  }
132 
133 protected:
134  FILE *fwait, *fpost;
136 };
137 
139 
140 class RunWrite : public RunStdio
141 {
142 public:
143  RunWrite(std::string& portName, std::string& loggerName)
144  {
145  mVerbose=true;
146 
147  char buff[16];
148  sprintf(buff, "/%d", getpid());
149  wPortName=portName+buff;
150  wLoggerName=loggerName;
151 
152  /*
153  //persistent connection to the logger, off by default
154  yarp::os::ContactStyle style;
155  style.persistent=true;
156  yarp::os::Network::connect(wPortName.c_str(), loggerName.c_str(), style);
157  */
158 
159  mRunning=true;
160  }
161 
162  RunWrite(std::string& portName)
163  {
164  mVerbose=false;
165 
166  wPortName=portName+"/stdout";
167 
168  mRunning=true;
169  }
170 
172 
173  int loop();
174 
175  void exit() override
176  {
177  RUNLOG("<<<exit()")
178 
179  mRunning=false;
180  wPort.close();
181 
182 #if defined(_WIN32)
183  RUNLOG(">>>exit()")
184  ::exit(0);
185 #else
186  int term_pipe[2];
187  int warn_suppress = yarp::run::impl::pipe(term_pipe);
188  YARP_UNUSED(warn_suppress);
189  yarp::run::impl::dup2(term_pipe[0], STDIN_FILENO);
190  FILE* file_term_pipe=fdopen(term_pipe[1], "w");
191  fprintf(file_term_pipe, "SHKIATTETE!\n");
192  fflush(file_term_pipe);
193  fclose(file_term_pipe);
194  RUNLOG(">>>exit()")
195 #endif
196  }
197 
198 protected:
199  bool mRunning;
200  bool mVerbose;
201 
202  std::string wPortName;
203  std::string wLoggerName;
205 };
206 
208 
209 class RunRead : public RunStdio
210 {
211 public:
212  RunRead(std::string &portName)
213  {
214  rPortName=portName+"/stdin";
215 
216  mRunning=true;
217  }
219 
220  int loop();
221 
222  void exit() override
223  {
224  RUNLOG("<<<exit()")
225 
226  mRunning=false;
227 
228  rPort.interrupt();
229 
230  RUNLOG(">>>exit()")
231  }
232 
233 protected:
234  bool mRunning;
235 
236  std::string rPortName;
238 };
239 
241 
242 class RunReadWrite : public RunStdio, public yarp::os::Thread
243 {
244 public:
245  RunReadWrite(std::string &portsName, std::string &fpName, std::string &lpName)
246  {
247  UUID=portsName;
248  wPortName=portsName+"/stdio:o";
249  rPortName=portsName+"/stdio:i";
250  mRunning=true;
251 
252  if (fpName!="")
253  {
254  char buff[16];
255  sprintf(buff, "/%d", getpid());
256  mForwarded=true;
257  fPortName=fpName+buff;
258 
260  style.persistent=true;
261  yarp::os::Network::connect(fPortName.c_str(), lpName.c_str(), style);
262  }
263  else
264  {
265  mForwarded=false;
266  }
267  }
268 
270 
271  void run() override;
272  int loop();
273 
274  void exit() override
275  {
276  RUNLOG("<<<exit()")
277 
278  mRunning=false;
279 
280  rPort.interrupt();
281 
282 #if defined(_WIN32)
283  for (int t=0; t<10; ++t) yarp::os::SystemClock::delaySystem(1.0);
284 #endif
285  RUNLOG(">>>exit()")
286  }
287 
288 protected:
289  bool mRunning;
291 
292  std::string UUID;
293  std::string wPortName;
294  std::string rPortName;
295  std::string fPortName;
299 };
300 
301 #endif // YARP_RUN_IMPL_RUNREADWRITE_H
float t
#define RUNLOG(msg)
std::string rPortName
Definition: RunReadWrite.h:294
std::string UUID
Definition: RunReadWrite.h:292
std::string wPortName
Definition: RunReadWrite.h:293
RunReadWrite(std::string &portsName, std::string &fpName, std::string &lpName)
Definition: RunReadWrite.h:245
void exit() override
Definition: RunReadWrite.h:274
yarp::os::Port fPort
Definition: RunReadWrite.h:298
yarp::os::Port rPort
Definition: RunReadWrite.h:297
void run() override
Main body of the new thread.
std::string fPortName
Definition: RunReadWrite.h:295
yarp::os::Port wPort
Definition: RunReadWrite.h:296
void exit() override
Definition: RunReadWrite.h:222
RunRead(std::string &portName)
Definition: RunReadWrite.h:212
int loop()
yarp::os::Port rPort
Definition: RunReadWrite.h:237
bool mRunning
Definition: RunReadWrite.h:234
std::string rPortName
Definition: RunReadWrite.h:236
virtual ~RunStdio()
Definition: RunReadWrite.h:38
virtual void exit()=0
void run() override
Main body of the new thread.
Definition: RunReadWrite.h:109
RunStdio * mStdio
Definition: RunReadWrite.h:135
RunTerminator(RunStdio *pStdio)
Definition: RunReadWrite.h:85
yarp::os::Port wPort
Definition: RunReadWrite.h:204
std::string wLoggerName
Definition: RunReadWrite.h:203
bool mRunning
Definition: RunReadWrite.h:199
RunWrite(std::string &portName)
Definition: RunReadWrite.h:162
std::string wPortName
Definition: RunReadWrite.h:202
bool mVerbose
Definition: RunReadWrite.h:200
void exit() override
Definition: RunReadWrite.h:175
RunWrite(std::string &portName, std::string &loggerName)
Definition: RunReadWrite.h:143
int loop()
Preferences for how to communicate with a contact.
Definition: ContactStyle.h:27
bool persistent
Specify whether a requested connection should be persistent.
Definition: ContactStyle.h:66
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
Definition: Network.cpp:685
A mini-server for network communication.
Definition: Port.h:50
void interrupt() override
Interrupt any current reads or writes attached to the port.
Definition: Port.cpp:377
void close() override
Stop port activity.
Definition: Port.cpp:357
static void delaySystem(double seconds)
Definition: SystemClock.cpp:32
An abstraction for a thread of execution.
Definition: Thread.h:25
bool start()
Start the new thread running.
Definition: Thread.cpp:96
int getpid()
Portable wrapper for the getppid() function.
Definition: Os.cpp:94
#define YARP_UNUSED(var)
Definition: api.h:159