comparison src/helper.cpp @ 49:51a8fe0a03cf

Suspend/resume stdout (as in the Piper simple server) to avoid plugins' own stdout blatherings from interfering with our "return values"
author Chris Cannam
date Tue, 02 Oct 2018 11:55:03 +0100
parents d7ec0b2a8802
children 5f91094e5680
comparison
equal deleted inserted replaced
48:2e8a5f665a07 49:51a8fe0a03cf
79 static const char programName[] = "vamp-plugin-load-checker"; 79 static const char programName[] = "vamp-plugin-load-checker";
80 80
81 #ifdef _WIN32 81 #ifdef _WIN32
82 #include <windows.h> 82 #include <windows.h>
83 #include <process.h> 83 #include <process.h>
84 #endif 84 #include <io.h>
85 #else
86 #include <unistd.h>
87 #endif
88
89 #include <fcntl.h>
85 90
86 #include <string> 91 #include <string>
87 #include <iostream> 92 #include <iostream>
88 93
89 #ifdef _WIN32 94 #ifdef _WIN32
271 DLCLOSE(handle); 276 DLCLOSE(handle);
272 277
273 return result; 278 return result;
274 } 279 }
275 280
281 // We write our output to stdout, but want to ensure that the plugin
282 // doesn't write anything itself. To do this we open a null file
283 // descriptor and dup2() it into place of stdout in the gaps between
284 // our own output activity.
285
286 static int normalFd = -1;
287 static int suspendedFd = -1;
288
289 static void initFds()
290 {
291 #ifdef _WIN32
292 normalFd = _dup(1);
293 suspendedFd = _open("NUL", _O_WRONLY);
294 #else
295 normalFd = dup(1);
296 suspendedFd = open("/dev/null", O_WRONLY);
297 #endif
298
299 if (normalFd < 0 || suspendedFd < 0) {
300 throw runtime_error("Failed to initialise fds for stdio suspend/resume");
301 }
302 }
303
304 static void suspendOutput()
305 {
306 #ifdef _WIN32
307 _dup2(suspendedFd, 1);
308 #else
309 dup2(suspendedFd, 1);
310 #endif
311 }
312
313 static void resumeOutput()
314 {
315 fflush(stdout);
316 #ifdef _WIN32
317 _dup2(normalFd, 1);
318 #else
319 dup2(normalFd, 1);
320 #endif
321 }
322
276 int main(int argc, char **argv) 323 int main(int argc, char **argv)
277 { 324 {
278 bool allGood = true; 325 bool allGood = true;
279 string soname; 326 string soname;
280 327
311 // block the program until the user clicked it away and then 358 // block the program until the user clicked it away and then
312 // fail anyway. 359 // fail anyway.
313 SetErrorMode(SEM_FAILCRITICALERRORS); 360 SetErrorMode(SEM_FAILCRITICALERRORS);
314 #endif 361 #endif
315 362
363 initFds();
364 suspendOutput();
365
316 while (getline(cin, soname)) { 366 while (getline(cin, soname)) {
317 Result result = check(soname, descriptor); 367 Result result = check(soname, descriptor);
368 resumeOutput();
318 if (result.code == PluginCheckCode::SUCCESS) { 369 if (result.code == PluginCheckCode::SUCCESS) {
319 cout << "SUCCESS|" << soname << "|" << endl; 370 cout << "SUCCESS|" << soname << "|" << endl;
320 } else { 371 } else {
321 if (result.message == "") { 372 if (result.message == "") {
322 cout << "FAILURE|" << soname 373 cout << "FAILURE|" << soname
326 << "|" << result.message << " [" 377 << "|" << result.message << " ["
327 << int(result.code) << "]" << endl; 378 << int(result.code) << "]" << endl;
328 } 379 }
329 allGood = false; 380 allGood = false;
330 } 381 }
382 suspendOutput();
331 } 383 }
332 384
333 return allGood ? 0 : 1; 385 return allGood ? 0 : 1;
334 } 386 }