Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

674 lines
18KB

  1. /*
  2. * Carla Pipe utils based on lv2fil UI code
  3. * Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
  4. * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. */
  18. #ifndef CARLA_PIPE_UTILS_HPP_INCLUDED
  19. #define CARLA_PIPE_UTILS_HPP_INCLUDED
  20. #include "CarlaMutex.hpp"
  21. #include "CarlaString.hpp"
  22. #include <cerrno>
  23. #include <clocale>
  24. #include <fcntl.h>
  25. #include <signal.h>
  26. #include <sys/wait.h>
  27. #define WAIT_START_TIMEOUT 3000 /* ms */
  28. #define WAIT_ZOMBIE_TIMEOUT 3000 /* ms */
  29. #define WAIT_STEP 100 /* ms */
  30. // -----------------------------------------------------------------------
  31. struct ScopedLocale {
  32. const char* locale;
  33. ScopedLocale() noexcept
  34. : locale(carla_strdup_safe(::setlocale(LC_NUMERIC, nullptr)))
  35. {
  36. ::setlocale(LC_NUMERIC, "C");
  37. }
  38. ~ScopedLocale() noexcept
  39. {
  40. if (locale != nullptr)
  41. {
  42. ::setlocale(LC_NUMERIC, locale);
  43. delete[] locale;
  44. locale = nullptr;
  45. }
  46. }
  47. CARLA_DECLARE_NON_COPY_STRUCT(ScopedLocale)
  48. CARLA_PREVENT_HEAP_ALLOCATION
  49. };
  50. // -----------------------------------------------------------------------
  51. class CarlaPipeServer
  52. {
  53. protected:
  54. CarlaPipeServer()
  55. : fWriteLock(),
  56. fPipeRecv(-1),
  57. fPipeSend(-1),
  58. fIsReading(false),
  59. fPid(-1),
  60. fTmpStr()
  61. {
  62. carla_debug("CarlaPipeServer::CarlaPipeServer()");
  63. carla_zeroChar(fTmpBuf, 0xff+1);
  64. }
  65. // -------------------------------------------------------------------
  66. public:
  67. virtual ~CarlaPipeServer()
  68. {
  69. carla_debug("CarlaPipeServer::~CarlaPipeServer()");
  70. stop();
  71. }
  72. bool isOk() const noexcept
  73. {
  74. return (fPipeRecv != -1 && fPipeSend != -1 && fPid != -1);
  75. }
  76. bool start(const char* const filename, const char* const arg1, const char* const arg2) noexcept
  77. {
  78. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  79. CARLA_SAFE_ASSERT_RETURN(arg1 != nullptr, false);
  80. CARLA_SAFE_ASSERT_RETURN(arg2 != nullptr, false);
  81. carla_debug("CarlaPipeServer::start(\"%s\", \"%s\", \"%s\")", filename, arg1, arg2);
  82. const CarlaMutexLocker cml(fWriteLock);
  83. //----------------------------------------------------------------
  84. const char* argv[6];
  85. //----------------------------------------------------------------
  86. // argv[0] => filename
  87. argv[0] = filename;
  88. //----------------------------------------------------------------
  89. // argv[1-2] => args
  90. argv[1] = arg1;
  91. argv[2] = arg2;
  92. //----------------------------------------------------------------
  93. // argv[3-4] => pipes
  94. int pipe1[2]; // written by host process, read by plugin UI process
  95. int pipe2[2]; // written by plugin UI process, read by host process
  96. if (::pipe(pipe1) != 0)
  97. {
  98. fail("pipe1 creation failed");
  99. return false;
  100. }
  101. if (::pipe(pipe2) != 0)
  102. {
  103. try { ::close(pipe1[0]); } catch (...) {}
  104. try { ::close(pipe1[1]); } catch (...) {}
  105. fail("pipe2 creation failed");
  106. return false;
  107. }
  108. char pipeRecv[100+1];
  109. char pipeSend[100+1];
  110. std::snprintf(pipeRecv, 100, "%d", pipe1[0]); // [0] means reading end
  111. std::snprintf(pipeSend, 100, "%d", pipe2[1]); // [1] means writting end
  112. pipeRecv[100] = '\0';
  113. pipeSend[100] = '\0';
  114. argv[3] = pipeRecv; // reading end
  115. argv[4] = pipeSend; // writting end
  116. //----------------------------------------------------------------
  117. // argv[5] => null
  118. argv[5] = nullptr;
  119. //----------------------------------------------------------------
  120. // fork
  121. int ret = -1;
  122. if ((! fork_exec(argv, &ret)) || ret == -1)
  123. {
  124. try { ::close(pipe1[0]); } catch (...) {}
  125. try { ::close(pipe1[1]); } catch (...) {}
  126. try { ::close(pipe2[0]); } catch (...) {}
  127. try { ::close(pipe2[1]); } catch (...) {}
  128. fail("fork_exec() failed");
  129. return false;
  130. }
  131. fPid = ret;
  132. // fork duplicated the handles, close pipe ends that are used by the child process
  133. try { ::close(pipe1[0]); } catch(...) {}
  134. try { ::close(pipe2[1]); } catch(...) {}
  135. fPipeSend = pipe1[1]; // [1] means writting end
  136. fPipeRecv = pipe2[0]; // [0] means reading end
  137. // set non-block
  138. try {
  139. ret = ::fcntl(fPipeRecv, F_SETFL, ::fcntl(fPipeRecv, F_GETFL) | O_NONBLOCK);
  140. } catch (...) {
  141. ret = -1;
  142. fail("failed to set pipe as non-block");
  143. }
  144. //----------------------------------------------------------------
  145. // wait a while for child process to confirm it is alive
  146. if (ret != -1)
  147. {
  148. char ch;
  149. ssize_t ret2;
  150. for (int i=0; ;)
  151. {
  152. try {
  153. ret2 = ::read(fPipeRecv, &ch, 1);
  154. }
  155. catch (...) {
  156. fail("failed to read from pipe");
  157. break;
  158. }
  159. switch (ret2)
  160. {
  161. case -1:
  162. if (errno == EAGAIN)
  163. {
  164. if (i < WAIT_START_TIMEOUT / WAIT_STEP)
  165. {
  166. carla_msleep(WAIT_STEP);
  167. ++i;
  168. continue;
  169. }
  170. carla_stderr("we have waited for child with pid %d to appear for %.1f seconds and we are giving up", int(fPid), float(WAIT_START_TIMEOUT)/1000.0f);
  171. }
  172. else
  173. {
  174. CarlaString error(std::strerror(errno));
  175. carla_stderr("read() failed: %s", error.buffer());
  176. }
  177. break;
  178. case 1:
  179. if (ch == '\n') {
  180. // success
  181. return true;
  182. }
  183. carla_stderr("read() has wrong first char '%c'", ch);
  184. break;
  185. default:
  186. carla_stderr("read() returned %i", int(ret2));
  187. break;
  188. }
  189. break;
  190. }
  191. }
  192. carla_stderr("force killing misbehaved child %i (start)", int(fPid));
  193. if (kill(fPid, SIGKILL) == -1)
  194. {
  195. CarlaString error(std::strerror(errno));
  196. carla_stderr("kill() failed: %s (start)\n", error.buffer());
  197. }
  198. // wait a while child to exit, we dont like zombie processes
  199. wait_child(fPid);
  200. // close pipes
  201. try { ::close(fPipeRecv); } catch (...) {}
  202. try { ::close(fPipeSend); } catch (...) {}
  203. fPipeRecv = -1;
  204. fPipeSend = -1;
  205. fPid = -1;
  206. return false;
  207. }
  208. void stop() noexcept
  209. {
  210. carla_debug("CarlaPipeServer::stop()");
  211. if (fPipeSend == -1 || fPipeRecv == -1 || fPid == -1)
  212. return;
  213. const CarlaMutexLocker cml(fWriteLock);
  214. try {
  215. ssize_t ignore = ::write(fPipeSend, "quit\n", 5);
  216. (void)ignore;
  217. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::stop");
  218. waitChildClose();
  219. try { ::close(fPipeRecv); } catch (...) {}
  220. try { ::close(fPipeSend); } catch (...) {}
  221. fPipeRecv = -1;
  222. fPipeSend = -1;
  223. fPid = -1;
  224. }
  225. void idle()
  226. {
  227. const char* locale = nullptr;
  228. for (;;)
  229. {
  230. const char* const msg(readline());
  231. if (msg == nullptr)
  232. break;
  233. if (locale == nullptr)
  234. {
  235. locale = carla_strdup(::setlocale(LC_NUMERIC, nullptr));
  236. ::setlocale(LC_NUMERIC, "C");
  237. }
  238. fIsReading = true;
  239. msgReceived(msg);
  240. fIsReading = false;
  241. delete[] msg;
  242. }
  243. if (locale != nullptr)
  244. {
  245. ::setlocale(LC_NUMERIC, locale);
  246. delete[] locale;
  247. }
  248. }
  249. // -------------------------------------------------------------------
  250. bool readNextLineAsBool(bool& value) noexcept
  251. {
  252. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  253. if (const char* const msg = readline())
  254. {
  255. value = (std::strcmp(msg, "true") == 0);
  256. delete[] msg;
  257. return true;
  258. }
  259. return false;
  260. }
  261. bool readNextLineAsInt(int32_t& value) noexcept
  262. {
  263. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  264. if (const char* const msg = readline())
  265. {
  266. value = std::atoi(msg);
  267. delete[] msg;
  268. return true;
  269. }
  270. return false;
  271. }
  272. bool readNextLineAsUInt(uint32_t& value) noexcept
  273. {
  274. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  275. if (const char* const msg = readline())
  276. {
  277. int32_t tmp = std::atoi(msg);
  278. delete[] msg;
  279. if (tmp >= 0)
  280. {
  281. value = static_cast<uint32_t>(tmp);
  282. return true;
  283. }
  284. }
  285. return false;
  286. }
  287. bool readNextLineAsLong(int64_t& value) noexcept
  288. {
  289. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  290. if (const char* const msg = readline())
  291. {
  292. value = std::atol(msg);
  293. delete[] msg;
  294. return true;
  295. }
  296. return false;
  297. }
  298. bool readNextLineAsULong(uint64_t& value) noexcept
  299. {
  300. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  301. if (const char* const msg = readline())
  302. {
  303. int64_t tmp = std::atol(msg);
  304. delete[] msg;
  305. if (tmp >= 0)
  306. {
  307. value = static_cast<uint64_t>(tmp);
  308. return true;
  309. }
  310. }
  311. return false;
  312. }
  313. bool readNextLineAsFloat(float& value) noexcept
  314. {
  315. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  316. if (const char* const msg = readline())
  317. {
  318. const bool ret(std::sscanf(msg, "%f", &value) == 1);
  319. delete[] msg;
  320. return ret;
  321. }
  322. return false;
  323. }
  324. bool readNextLineAsString(const char*& value) noexcept
  325. {
  326. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  327. if (const char* const msg = readline())
  328. {
  329. value = msg;
  330. return true;
  331. }
  332. return false;
  333. }
  334. // -------------------------------------------------------------------
  335. // must be locked before calling
  336. void writeMsg(const char* const msg) const noexcept
  337. {
  338. CARLA_SAFE_ASSERT_RETURN(fPipeSend != -1,);
  339. // TESTING remove later
  340. const bool wasLocked(! fWriteLock.tryLock());
  341. CARLA_SAFE_ASSERT_RETURN(wasLocked, fWriteLock.unlock());
  342. try {
  343. ssize_t ignore = ::write(fPipeSend, msg, std::strlen(msg));
  344. (void)ignore;
  345. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::writeMsg");
  346. }
  347. void writeMsg(const char* const msg, size_t size) const noexcept
  348. {
  349. CARLA_SAFE_ASSERT_RETURN(fPipeSend != -1,);
  350. // TESTING remove later
  351. const bool wasLocked(! fWriteLock.tryLock());
  352. CARLA_SAFE_ASSERT_RETURN(wasLocked, fWriteLock.unlock());
  353. try {
  354. ssize_t ignore = ::write(fPipeSend, msg, size);
  355. (void)ignore;
  356. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::writeMsg");
  357. }
  358. void writeAndFixMsg(const char* const msg) noexcept
  359. {
  360. CARLA_SAFE_ASSERT_RETURN(fPipeSend != -1,);
  361. // TESTING remove later
  362. const bool wasLocked(! fWriteLock.tryLock());
  363. CARLA_SAFE_ASSERT_RETURN(wasLocked, fWriteLock.unlock());
  364. const size_t size(msg != nullptr ? std::strlen(msg) : 0);
  365. char fixedMsg[size+2];
  366. if (size > 0)
  367. {
  368. std::strcpy(fixedMsg, msg);
  369. for (size_t i=0; i < size; ++i)
  370. {
  371. if (fixedMsg[i] == '\n')
  372. fixedMsg[i] = '\r';
  373. }
  374. if (fixedMsg[size-1] == '\r')
  375. {
  376. fixedMsg[size-1] = '\n';
  377. fixedMsg[size] = '\0';
  378. fixedMsg[size+1] = '\0';
  379. }
  380. else
  381. {
  382. fixedMsg[size] = '\n';
  383. fixedMsg[size+1] = '\0';
  384. }
  385. }
  386. else
  387. {
  388. fixedMsg[0] = '\n';
  389. fixedMsg[1] = '\0';
  390. }
  391. try {
  392. ssize_t ignore = ::write(fPipeSend, fixedMsg, size+1);
  393. (void)ignore;
  394. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::writeAndFixMsg");
  395. }
  396. // -------------------------------------------------------------------
  397. void waitChildClose() noexcept
  398. {
  399. if (! wait_child(fPid))
  400. {
  401. carla_stderr2("force killing misbehaved child %i (exit)", int(fPid));
  402. if (kill(fPid, SIGKILL) == -1)
  403. carla_stderr2("kill() failed: %s (exit)", std::strerror(errno));
  404. else
  405. wait_child(fPid);
  406. }
  407. }
  408. // -------------------------------------------------------------------
  409. protected:
  410. // common write lock
  411. CarlaMutex fWriteLock;
  412. // to possibly send errors somewhere
  413. virtual void fail(const char* const error)
  414. {
  415. carla_stderr2(error);
  416. }
  417. // returns true if msg handled
  418. virtual bool msgReceived(const char* const msg) noexcept = 0;
  419. // -------------------------------------------------------------------
  420. private:
  421. int fPipeRecv; // the pipe end that is used for receiving messages from UI
  422. int fPipeSend; // the pipe end that is used for sending messages to UI
  423. bool fIsReading;
  424. pid_t fPid;
  425. char fTmpBuf[0xff+1];
  426. CarlaString fTmpStr;
  427. // -------------------------------------------------------------------
  428. const char* readline() noexcept
  429. {
  430. char ch;
  431. char* ptr = fTmpBuf;
  432. ssize_t ret;
  433. fTmpStr.clear();
  434. for (int i=0; i < 0xff; ++i)
  435. {
  436. try {
  437. ret = ::read(fPipeRecv, &ch, 1);
  438. }
  439. catch (...) {
  440. break;
  441. }
  442. if (ret == 1 && ch != '\n')
  443. {
  444. if (ch == '\r')
  445. ch = '\n';
  446. *ptr++ = ch;
  447. if (i+1 == 0xff)
  448. {
  449. i = 0;
  450. ptr = fTmpBuf;
  451. fTmpStr += fTmpBuf;
  452. }
  453. continue;
  454. }
  455. if (fTmpStr.isNotEmpty() || ptr != fTmpBuf)
  456. {
  457. if (ptr != fTmpBuf)
  458. {
  459. *ptr = '\0';
  460. fTmpStr += fTmpBuf;
  461. }
  462. try {
  463. return fTmpStr.dup();
  464. }
  465. catch(...) {
  466. return nullptr;
  467. }
  468. }
  469. break;
  470. }
  471. return nullptr;
  472. }
  473. // -------------------------------------------------------------------
  474. static bool fork_exec(const char* const argv[6], int* const retp) noexcept
  475. {
  476. const pid_t ret = *retp = vfork();
  477. switch (ret)
  478. {
  479. case 0: // child process
  480. execvp(argv[0], const_cast<char* const*>(argv));
  481. carla_stderr2("exec failed: %s", std::strerror(errno));
  482. _exit(0); // this is not noexcept safe but doesn't matter anyway
  483. return false;
  484. case -1: // error
  485. carla_stderr2("fork() failed: %s", std::strerror(errno));
  486. _exit(0); // this is not noexcept safe but doesn't matter anyway
  487. return false;
  488. }
  489. return true;
  490. }
  491. static bool wait_child(const pid_t pid) noexcept
  492. {
  493. if (pid <= 0)
  494. {
  495. carla_stderr2("Can't wait for pid %i", int(pid));
  496. return false;
  497. }
  498. pid_t ret;
  499. for (int i=0, maxTime=WAIT_ZOMBIE_TIMEOUT/WAIT_STEP; i < maxTime; ++i)
  500. {
  501. try {
  502. ret = ::waitpid(pid, nullptr, WNOHANG);
  503. } CARLA_SAFE_EXCEPTION_BREAK("wait_child");
  504. if (ret != 0)
  505. {
  506. if (ret == pid)
  507. return true;
  508. if (ret == -1)
  509. {
  510. if (errno == ECHILD)
  511. return true;
  512. CarlaString error(std::strerror(errno));
  513. carla_stderr2("waitpid(%i) failed: %s", int(pid), error.buffer());
  514. return false;
  515. }
  516. carla_stderr2("we waited for child pid %i to exit but we got pid %i instead", int(pid), int(ret));
  517. return false;
  518. }
  519. carla_msleep(WAIT_STEP); /* wait 100 ms */
  520. }
  521. carla_stderr2("we waited for child with pid %i to exit for %.1f seconds and we are giving up", int(pid), float(WAIT_START_TIMEOUT)/1000.0f);
  522. return false;
  523. }
  524. };
  525. // -----------------------------------------------------------------------
  526. #endif // CARLA_PIPE_UTILS_HPP_INCLUDED