|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include <stdio.h> |
|
6 #include <stdlib.h> |
|
7 #include "iniparser.h" |
|
8 |
|
9 #ifdef _WIN32 |
|
10 #include <windows.h> |
|
11 #include <tchar.h> |
|
12 |
|
13 extern int iniparser_getint(dictionary *d, char *key, int notfound); |
|
14 extern char *iniparser_getstring(dictionary *d, char *key, char *def); |
|
15 |
|
16 // This is the windows launcher function |
|
17 int launchWindows(int children, int maxtime) { |
|
18 _TCHAR cmdline[50]; |
|
19 STARTUPINFO startup; |
|
20 PROCESS_INFORMATION procinfo; |
|
21 BOOL rv = 0; |
|
22 |
|
23 _stprintf(cmdline, _T("proclaunch.exe %d %d"), children, maxtime); |
|
24 ZeroMemory(&startup, sizeof(STARTUPINFO)); |
|
25 startup.cb = sizeof(STARTUPINFO); |
|
26 |
|
27 ZeroMemory(&procinfo, sizeof(PROCESS_INFORMATION)); |
|
28 |
|
29 printf("Launching process!\n"); |
|
30 rv = CreateProcess(NULL, |
|
31 cmdline, |
|
32 NULL, |
|
33 NULL, |
|
34 FALSE, |
|
35 0, |
|
36 NULL, |
|
37 NULL, |
|
38 &startup, |
|
39 &procinfo); |
|
40 |
|
41 if (!rv) { |
|
42 DWORD dw = GetLastError(); |
|
43 printf("error: %d\n", dw); |
|
44 } |
|
45 CloseHandle(procinfo.hProcess); |
|
46 CloseHandle(procinfo.hThread); |
|
47 return 0; |
|
48 } |
|
49 #endif |
|
50 |
|
51 int main(int argc, char **argv) { |
|
52 int children = 0; |
|
53 int maxtime = 0; |
|
54 int passedtime = 0; |
|
55 dictionary *dict = NULL; |
|
56 |
|
57 // Command line handling |
|
58 if (argc == 1 || (0 == strcmp(argv[1], "-h")) || (0 == strcmp(argv[1], "--help"))) { |
|
59 printf("ProcLauncher takes an ini file. Specify the ini file as the only\n"); |
|
60 printf("parameter of the command line:\n"); |
|
61 printf("proclauncher my.ini\n\n"); |
|
62 printf("The ini file has the form:\n"); |
|
63 printf("[main]\n"); |
|
64 printf("children=child1,child2 ; These comma separated values are sections\n"); |
|
65 printf("maxtime=60 ; Max time this process lives\n"); |
|
66 printf("[child1] ; Here is a child section\n"); |
|
67 printf("children=3 ; You can have grandchildren: this spawns 3 of them for child1\n"); |
|
68 printf("maxtime=30 ; Max time, note it's in seconds. If this time\n"); |
|
69 printf(" ; is > main:maxtime then the child process will be\n"); |
|
70 printf(" ; killed when the parent exits. Also, grandchildren\n"); |
|
71 printf("[child2] ; inherit this maxtime and can't change it.\n"); |
|
72 printf("maxtime=25 ; You can call these sections whatever you want\n"); |
|
73 printf("children=0 ; as long as you reference them in a children attribute\n"); |
|
74 printf("....\n"); |
|
75 return 0; |
|
76 } else if (argc == 2) { |
|
77 // This is ini file mode: |
|
78 // proclauncher <inifile> |
|
79 dict = iniparser_load(argv[1]); |
|
80 |
|
81 } else if (argc == 3) { |
|
82 // Then we've been called in child process launching mode: |
|
83 // proclauncher <children> <maxtime> |
|
84 children = atoi(argv[1]); |
|
85 maxtime = atoi(argv[2]); |
|
86 } |
|
87 |
|
88 if (dict) { |
|
89 /* Dict operation */ |
|
90 char *childlist = iniparser_getstring(dict, "main:children", NULL); |
|
91 maxtime = iniparser_getint(dict, (char*)"main:maxtime", 10);; |
|
92 if (childlist) { |
|
93 int c = 0, m = 10; |
|
94 char childkey[50], maxkey[50]; |
|
95 char cmd[25]; |
|
96 char *token = strtok(childlist, ","); |
|
97 |
|
98 while (token) { |
|
99 // Reset defaults |
|
100 memset(childkey, 0, 50); |
|
101 memset(maxkey, 0, 50); |
|
102 memset(cmd, 0, 25); |
|
103 c = 0; |
|
104 m = 10; |
|
105 |
|
106 sprintf(childkey, "%s:children", token); |
|
107 sprintf(maxkey, "%s:maxtime", token); |
|
108 c = iniparser_getint(dict, childkey, 0); |
|
109 m = iniparser_getint(dict, maxkey, 10); |
|
110 |
|
111 // Launch the child process |
|
112 #ifdef _WIN32 |
|
113 launchWindows(c, m); |
|
114 #else |
|
115 sprintf(cmd, "./proclaunch %d %d &", c, m); |
|
116 system(cmd); |
|
117 #endif |
|
118 |
|
119 // Get the next child entry |
|
120 token = strtok(NULL, ","); |
|
121 } |
|
122 } |
|
123 iniparser_freedict(dict); |
|
124 } else { |
|
125 // Child Process operation - put on your recursive thinking cap |
|
126 char cmd[25]; |
|
127 // This is launching grandchildren, there are no great grandchildren, so we |
|
128 // pass in a 0 for the children to spawn. |
|
129 #ifdef _WIN32 |
|
130 while(children > 0) { |
|
131 launchWindows(0, maxtime); |
|
132 children--; |
|
133 } |
|
134 #else |
|
135 sprintf(cmd, "./proclaunch %d %d &", 0, maxtime); |
|
136 printf("Launching child process: %s\n", cmd); |
|
137 while (children > 0) { |
|
138 system(cmd); |
|
139 children--; |
|
140 } |
|
141 #endif |
|
142 } |
|
143 |
|
144 /* Now we have launched all the children. Let's wait for max time before returning |
|
145 This does pseudo busy waiting just to appear active */ |
|
146 while (passedtime < maxtime) { |
|
147 #ifdef _WIN32 |
|
148 Sleep(1000); |
|
149 #else |
|
150 sleep(1); |
|
151 #endif |
|
152 passedtime++; |
|
153 } |
|
154 exit(0); |
|
155 return 0; |
|
156 } |