{"id":178,"date":"2011-01-20T02:47:16","date_gmt":"2011-01-20T07:47:16","guid":{"rendered":"http:\/\/littlesvr.ca\/grumble\/?p=178"},"modified":"2012-12-05T00:51:53","modified_gmt":"2012-12-05T05:51:53","slug":"createprocess-for-linux","status":"publish","type":"post","link":"http:\/\/littlesvr.ca\/grumble\/2011\/01\/20\/createprocess-for-linux\/","title":{"rendered":"CreateProcess for Linux"},"content":{"rendered":"<p>Do you remember the first time someone told you about fork()\/exec() for Linux? Do you remember beeing completely confused? I do, and it&#8217;s an ongoing pain in the ass for me &#8211; every time I want to call something simple without blocking and without worrying about pipes or the structure of exec()\/execl()\/execlp() parameters, or the return of the fork() call.<\/p>\n<p>Finally I had enough and wrote my own CreateProcess function. It will seem trivial for any Linux C programmer, but in my experience it&#8217;s not simple enough. This or something like it should have been part of the standard library, just like printf() is.<\/p>\n<p>Feel free to use it for whatever you want, minding the GPL v2 licence:<\/p>\n<ul>\n<li><a href=\"http:\/\/littlesvr.ca\/grumble\/wp-content\/uploads\/2011\/01\/CreateProcess.c\">CreateProcess.c<\/a><\/li>\n<li><a href=\"http:\/\/littlesvr.ca\/grumble\/wp-content\/uploads\/2011\/01\/CreateProcess.h\">CreateProcess.h<\/a><\/li>\n<\/ul>\n<pre>\/******************************************************************************\r\n*   CreateProcess\r\n*\r\n*\u00a0\u00a0 Copyright (C) 2010 Andrew Smith\r\n*\r\n*   This program is free software: you can redistribute it and\/or modify\r\n*   it under the terms of the GNU General Public License as published by\r\n*   the Free Software Foundation, version 2 of the License only, not\r\n*   any earlier or later version.\r\n*\r\n*   You should have received a copy of the GNU General Public License\r\n*   along with this program.  If not, see &lt;http:\/\/www.gnu.org\/licenses\/&gt;.\r\n*\/\r\n\r\n\/******************************************************************************\r\n*  CreateProcess function: a simple way for Linux\/Unix to call programs\r\n* without blocking and without the complications of fork()\/exec() which\r\n* normal people shouldn't need to understand :)\r\n*\r\n*  Usage example:\r\n\r\n#include \"CreateProcess.h\"\r\n\r\nint main(void)\r\n{\r\n    \/\/ Call it like this:\r\n    CreateProcess(\"ls\", \"-a -l --sort=size\");\r\n\r\n    \/\/ Or like this:\r\n    CreateProcess(\"date\", NULL);\r\n\r\n    \/\/ Note that the second call does not wait for the first to finish\r\n    \/\/ as system() would\r\n\r\n    return 0;\r\n}\r\n\r\n* Enjoy!\r\n* - Andrew Smith\r\n*\/\r\n\r\n#include &lt;stdio.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;stdbool.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\npid_t CreateProcess(const char* command, const char* parametersIn)\r\n{\r\n    const int maxNumArgs = 1024;\r\n    const char* args[maxNumArgs];\r\n    char* parameters = NULL;\r\n\r\n    memset(args, 0, (sizeof(char*) * maxNumArgs));\r\n    args[0] = command;\r\n\r\n    if(parametersIn != NULL)\r\n    {\r\n        parameters = strdup(parametersIn);\r\n        int strLen = strlen(parameters);\r\n\r\n        int numParameters = 1;\r\n        bool expectNextParam = true;\r\n        int i;\r\n        for(i = 0; i &lt; strLen; i++)\r\n        {\r\n            if(parameters[i] == ' ' || parameters[i] == '\\t' ||\r\n               parameters[i] == '\\n')\r\n            {\r\n                expectNextParam = true;\r\n                parameters[i] = '\\0';\r\n            }\r\n            else if(expectNextParam)\r\n            {\r\n                args[numParameters] = &amp;(parameters[i]);\r\n                numParameters++;\r\n                expectNextParam = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    pid_t pid = fork();\r\n    if(pid == 0)\r\n    {\r\n        execvp(command, (char**)args);\r\n        _exit(1);\r\n    }\r\n\r\n    if(parameters != NULL)\r\n        free(parameters);\r\n\r\n    return pid;\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Do you remember the first time someone told you about fork()\/exec() for Linux? Do you remember beeing completely confused? I do, and it&#8217;s an ongoing pain in the ass for me &#8211; every time I want to call something simple without blocking and without worrying about pipes or the structure of exec()\/execl()\/execlp() parameters, or the &hellip; <\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4],"tags":[],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-andrew","4":"post-178","6":"format-standard","7":"category-opensource","8":"category-safeforseneca"},"_links":{"self":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts\/178","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/comments?post=178"}],"version-history":[{"count":7,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts\/178\/revisions"}],"predecessor-version":[{"id":605,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/posts\/178\/revisions\/605"}],"wp:attachment":[{"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/media?parent=178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/categories?post=178"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/littlesvr.ca\/grumble\/wp-json\/wp\/v2\/tags?post=178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}