{"id":2760,"date":"2017-04-10T15:12:29","date_gmt":"2017-04-10T15:12:29","guid":{"rendered":"https:\/\/raspberry-projects.com\/pi\/?p=2760"},"modified":"2019-05-22T16:16:20","modified_gmt":"2019-05-22T16:16:20","slug":"running-a-command-line-tool-on-a-child-thread","status":"publish","type":"post","link":"https:\/\/raspberry-projects.com\/pi\/programming-in-c\/threads\/running-a-command-line-tool-on-a-child-thread","title":{"rendered":"Running a command line tool on a child thread"},"content":{"rendered":"\n<p>The following example&nbsp;runs hcidump on a child thread. &nbsp;This happens to be a bluetooth&nbsp;bluez tool which continuously outputs events as it seens them. This code allows this to happen on a child thread with the output passed back to the main application thread using a named pipe. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Create the pipe and the child thread process <\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;iostream>\n#include &lt;fcntl.h>\n#include &lt;unistd.h>\n\nint our_input_fifo_filestream = -1;\n\n\t\/\/--------------------------------------\n\t\/\/----- CREATE A FIFO \/ NAMED PIPE -----\n\t\/\/--------------------------------------\n\tint result;\n\n\tprintf(\"Making FIFO...\\n\");\n\tresult = mkfifo(OUR_INPUT_FIFO_NAME, 0777);\t\t\/\/(This will fail if the fifo already exists in the system from the app previously running, this is fine)\n\tif (result == 0)\n\t{\n\t\t\/\/FIFO CREATED\n\t\tprintf(\"New FIFO created: %s\\n\", OUR_INPUT_FIFO_NAME);\n\t}\n\n\tprintf(\"Process %d opening FIFO %s\\n\", getpid(), OUR_INPUT_FIFO_NAME);\n\tour_input_fifo_filestream = open(OUR_INPUT_FIFO_NAME, (O_RDONLY | O_NONBLOCK));\n\t\t\t\t\t\/\/Possible flags:\n\t\t\t\t\t\/\/\tO_RDONLY - Open for reading only.\n\t\t\t\t\t\/\/\tO_WRONLY - Open for writing only.\n\t\t\t\t\t\/\/\tO_NDELAY \/ O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status\n\t\t\t\t\t\/\/\t\t\t\t\t\t\t\t\t\t\tif there is no input immediately available (instead of blocking). Likewise, write requests can also return\n\t\t\t\t\t\/\/\t\t\t\t\t\t\t\t\t\t\timmediately with a failure status if the output can't be written immediately.\n\tif (our_input_fifo_filestream != -1)\n\t\tprintf(\"Opened input FIFO: %i\\n\", our_input_fifo_filestream);\n\n\n\t\/\/----------------------------------------------\n\t\/\/----- RUN HCIDUMP ON A BACKGROUND THREAD -----\n\t\/\/----------------------------------------------\n\tint pid2 = fork();\n\tif(pid2 == 0)\n\t{\n\t\t\/\/----- THIS IS THE CHILD THREAD -----\n\t\t\/\/cout &lt;&lt; \"I am the child\" &lt;&lt; endl;\n\n\t\tFILE* pipe2 = popen(\"sudo hcidump\", \"r\");\t\t\/\/Send the command, popen exits immediately \n\t\tif (pipe2)\n\t\t{\n\t\t\t\/\/----- THIS CHILD THREAD WILL RUN FOREVER -----\n\t\t\tcout &lt;&lt; \"Bluetooth hcidump child thread started\" &lt;&lt; endl;\n\n\t\t\t\/\/Create an output filestream for this child thread\n\t\t\tint our_output_fifo_filestream = -1;\n\t\t\tour_output_fifo_filestream = open(OUR_INPUT_FIFO_NAME, (O_WRONLY | O_NONBLOCK));\n\t\t\t\t\t\t\t\t\/\/Possible flags:\n\t\t\t\t\t\t\t\t\/\/\tO_RDONLY - Open for reading only.\n\t\t\t\t\t\t\t\t\/\/\tO_WRONLY - Open for writing only.\n\t\t\t\t\t\t\t\t\/\/\tO_NDELAY \/ O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status\n\t\t\t\t\t\t\t\t\/\/\t\t\t\t\t\t\t\t\t\t\tif there is no input immediately available (instead of blocking). Likewise, write requests can also return\n\t\t\t\t\t\t\t\t\/\/\t\t\t\t\t\t\t\t\t\t\timmediately with a failure status if the output can't be written immediately.\n\t\t\tif (our_output_fifo_filestream != -1)\n\t\t\t\tcout &lt;&lt; \"Opened output FIFO: \" &lt;&lt; our_output_fifo_filestream &lt;&lt; endl;\n\n\t\t\tchar buffer2[128];\n\t\t\twhile(!feof(pipe2))\t\t\t\t\t\t\/\/Wait for the output resulting from the command\n\t\t\t{\n\t\t\t\tif(fgets(buffer2, 128, pipe2) != NULL)\n\t\t\t\t{\n\t\t\t\t\twrite(our_output_fifo_filestream, (void*)buffer2, strlen(buffer2));\t\n\t\t\t\t\t\/\/cout &lt;&lt; buffer2 &lt;&lt; endl;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcout &lt;&lt; \"Bluetooth hcidump child thread ending\" &lt;&lt; endl;\n\t\t\tpclose(pipe2);\n\t\t}\n\t\t_exit(0);\t\t\/\/Don't forget to exit!\n\t}\n\telse\n\t{\n\t\t\/\/cout &lt;&lt; \"I am the parent\\n\" &lt;&lt; endl;\n\t\twait();\t\t\/\/Optional if you want to wait on the child thread, remove if not\n\t}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Reading the output from the main application thread <\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>\t\/\/---------------------------------------------\n\t\/\/----- CHECK FIFO FOR ANY RECEIVED BYTES -----\n\t\/\/---------------------------------------------\n\t\/\/ Read up to 255 characters from the port if they are there\n\tif (our_input_fifo_filestream != -1)\n\t{\n\t\tunsigned char buffer3[256];\n\t\tint length3 = read(our_input_fifo_filestream, (void*)buffer3, 255);\t\t\/\/Filestream, buffer to store in, number of bytes to read (max)\n\t\tif (length3 &lt; 0)\n\t\t{\n\t\t\t\/\/An error occured (this can happen)\n\t\t}\n\t\telse if (length3 == 0)\n\t\t{\n\t\t\t\/\/No data waiting\n\t\t}\n\t\telse\n\t\t{\n\t\t\t\/\/Bytes received\n\t\t\tbuffer3[length3] = '\\0';\n\t\t\tcout &lt;&lt; buffer3 &lt;&lt; endl;\n\t\t}\n\t}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The following example&nbsp;runs hcidump on a child thread. &nbsp;This happens to be a bluetooth&nbsp;bluez tool which continuously outputs events as it seens them. This code allows this to happen on a child thread with the output passed back to the main application thread using a named pipe. Create the pipe and the child thread process [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[83],"tags":[],"class_list":["post-2760","post","type-post","status-publish","format-standard","hentry","category-threads"],"_links":{"self":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/2760","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/comments?post=2760"}],"version-history":[{"count":7,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/2760\/revisions"}],"predecessor-version":[{"id":3072,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/2760\/revisions\/3072"}],"wp:attachment":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/media?parent=2760"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/categories?post=2760"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/tags?post=2760"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}