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