| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
| * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include "iniparser.h" |
| |
| #ifdef _WIN32 |
| #include <windows.h> |
| #include <tchar.h> |
| |
| extern int iniparser_getint(dictionary *d, char *key, int notfound); |
| extern char *iniparser_getstring(dictionary *d, char *key, char *def); |
| |
| // This is the windows launcher function |
| int launchWindows(int children, int maxtime) { |
| _TCHAR cmdline[50]; |
| STARTUPINFO startup; |
| PROCESS_INFORMATION procinfo; |
| BOOL rv = 0; |
| |
| _stprintf(cmdline, _T("proclaunch.exe %d %d"), children, maxtime); |
| ZeroMemory(&startup, sizeof(STARTUPINFO)); |
| startup.cb = sizeof(STARTUPINFO); |
| |
| ZeroMemory(&procinfo, sizeof(PROCESS_INFORMATION)); |
| |
| printf("Launching process!\n"); |
| rv = CreateProcess(NULL, |
| cmdline, |
| NULL, |
| NULL, |
| FALSE, |
| 0, |
| NULL, |
| NULL, |
| &startup, |
| &procinfo); |
| |
| if (!rv) { |
| DWORD dw = GetLastError(); |
| printf("error: %d\n", dw); |
| } |
| CloseHandle(procinfo.hProcess); |
| CloseHandle(procinfo.hThread); |
| return 0; |
| } |
| #endif |
| |
| int main(int argc, char **argv) { |
| int children = 0; |
| int maxtime = 0; |
| int passedtime = 0; |
| dictionary *dict = NULL; |
| |
| // Command line handling |
| if (argc == 1 || (0 == strcmp(argv[1], "-h")) || (0 == strcmp(argv[1], "--help"))) { |
| printf("ProcLauncher takes an ini file. Specify the ini file as the only\n"); |
| printf("parameter of the command line:\n"); |
| printf("proclauncher my.ini\n\n"); |
| printf("The ini file has the form:\n"); |
| printf("[main]\n"); |
| printf("children=child1,child2 ; These comma separated values are sections\n"); |
| printf("maxtime=60 ; Max time this process lives\n"); |
| printf("[child1] ; Here is a child section\n"); |
| printf("children=3 ; You can have grandchildren: this spawns 3 of them for child1\n"); |
| printf("maxtime=30 ; Max time, note it's in seconds. If this time\n"); |
| printf(" ; is > main:maxtime then the child process will be\n"); |
| printf(" ; killed when the parent exits. Also, grandchildren\n"); |
| printf("[child2] ; inherit this maxtime and can't change it.\n"); |
| printf("maxtime=25 ; You can call these sections whatever you want\n"); |
| printf("children=0 ; as long as you reference them in a children attribute\n"); |
| printf("....\n"); |
| return 0; |
| } else if (argc == 2) { |
| // This is ini file mode: |
| // proclauncher <inifile> |
| dict = iniparser_load(argv[1]); |
| |
| } else if (argc == 3) { |
| // Then we've been called in child process launching mode: |
| // proclauncher <children> <maxtime> |
| children = atoi(argv[1]); |
| maxtime = atoi(argv[2]); |
| } |
| |
| if (dict) { |
| /* Dict operation */ |
| char *childlist = iniparser_getstring(dict, "main:children", NULL); |
| maxtime = iniparser_getint(dict, (char*)"main:maxtime", 10);; |
| if (childlist) { |
| int c = 0, m = 10; |
| char childkey[50], maxkey[50]; |
| char cmd[25]; |
| char *token = strtok(childlist, ","); |
| |
| while (token) { |
| // Reset defaults |
| memset(childkey, 0, 50); |
| memset(maxkey, 0, 50); |
| memset(cmd, 0, 25); |
| c = 0; |
| m = 10; |
| |
| sprintf(childkey, "%s:children", token); |
| sprintf(maxkey, "%s:maxtime", token); |
| c = iniparser_getint(dict, childkey, 0); |
| m = iniparser_getint(dict, maxkey, 10); |
| |
| // Launch the child process |
| #ifdef _WIN32 |
| launchWindows(c, m); |
| #else |
| sprintf(cmd, "./proclaunch %d %d &", c, m); |
| system(cmd); |
| #endif |
| |
| // Get the next child entry |
| token = strtok(NULL, ","); |
| } |
| } |
| iniparser_freedict(dict); |
| } else { |
| // Child Process operation - put on your recursive thinking cap |
| char cmd[25]; |
| // This is launching grandchildren, there are no great grandchildren, so we |
| // pass in a 0 for the children to spawn. |
| #ifdef _WIN32 |
| while(children > 0) { |
| launchWindows(0, maxtime); |
| children--; |
| } |
| #else |
| sprintf(cmd, "./proclaunch %d %d &", 0, maxtime); |
| printf("Launching child process: %s\n", cmd); |
| while (children > 0) { |
| system(cmd); |
| children--; |
| } |
| #endif |
| } |
| |
| /* Now we have launched all the children. Let's wait for max time before returning |
| This does pseudo busy waiting just to appear active */ |
| while (passedtime < maxtime) { |
| #ifdef _WIN32 |
| Sleep(1000); |
| #else |
| sleep(1); |
| #endif |
| passedtime++; |
| } |
| exit(0); |
| return 0; |
| } |