1 //#define _WIN32_WINNT 0x0500
8 #include "ResolveLocker.h"
9 extern int ResolveLocker(USER_OPTIONS *attachOption);
10 extern void GetLockerInfo(char *Locker, char *Path);
11 #endif /* HAVE_HESOID */
13 #define MAX_THREADS 100
21 extern void LogStats(char *FileName, int ToLog, int Iteration, int NumberOfProcesses, int NumberOfThreads,
22 char *HostName, int ProcessNumber, struct cmd_struct CommandInfo[],
23 char *CommandLine, char *TargetDirectory);
24 extern int UpdateMasterLog(char *FileName, struct cmd_struct CommandInfo[]);
25 extern int BuildMasterStatLog(char *FileName, char *MoveFileName, int NumberOfProcesses,
26 int NumberOfThreads, char *CommandLine, int LoopCount,
27 char *TargetDirectory, int ProcessNumber);
28 extern void LogMessage(int ProcessNumber, char *HostName, char *FileName, char *message, int LogID);
30 DWORD WINAPI StressTestThread(LPVOID lpThreadParameter);
31 int getopt(int, char**, char*);
32 DWORD FindProcessCount(char *ProcessName, HANDLE JobHandle);
33 void show_results(char *CommandLine, char *TargetDirectory, struct cmd_struct CommandInfo[],
34 char *HostName, int NumberOfThreads, int CurrentLoop, int LogID);
36 char *ClientText = "streamfiles.txt";
37 char PathToSecondDir[256];
38 int ThreadStatus[MAX_HANDLES];
40 int BufferSize = 256*1024;
48 HANDLE FileMutexHandle;
49 HANDLE ChronMutexHandle;
51 HANDLE ShutDownEventHandle;
52 HANDLE PauseEventHandle;
53 HANDLE ContinueEventHandle;
54 EXIT_STATUS ExitStatus[MAX_HANDLES];
56 double create_procs(char *Hostname, char *CommandLine, char *TargetDirectory,
57 char *AfsLocker, char *Locker, char *HostName,
58 int NumberOfThreads, int CurrentLoop, int LogID)
65 HANDLE hEventHandle[MAX_HANDLES];
66 HANDLE hThreadHandle[MAX_HANDLES];
67 DWORD dwThreadID[MAX_HANDLES];
68 struct cmd_struct *CommandInfo;
69 CRITICAL_SECTION CriticalSection;
70 PARAMETERLIST *pParameterList[MAX_HANDLES];
72 USER_OPTIONS attachOption;
75 InitializeCriticalSection(&CriticalSection);
76 for (i = 0; i < MAX_HANDLES; i++)
78 hEventHandle[i] = NULL;
79 hThreadHandle[i] = NULL;
80 pParameterList[i] = NULL;
85 CommandInfo = calloc(1, sizeof(struct cmd_struct) * (CMD_MAX_CMD + 1) * NumberOfThreads);
88 for (i = 0; i < NumberOfThreads; i++)
92 if (ThreadStatus[count] == 0)
95 sprintf(EventName, "%d%sEvent%05d", ProcessID, HostName, count);
96 hEventHandle[count] = CreateEvent(NULL, FALSE, FALSE, EventName);
97 if (hEventHandle[count] == NULL)
99 ResetEvent(hEventHandle[count]);
101 pParameterList[count] = calloc(1, sizeof(PARAMETERLIST));
102 pParameterList[count]->ProcessNumber = count;
103 pParameterList[count]->CommandInfo = (struct cmd_struct *)(CommandInfo + (i * (CMD_MAX_CMD + 1)));
104 pParameterList[count]->BufferSize = BufferSize;
105 pParameterList[count]->PrintStats = PrintStats;
106 pParameterList[count]->CurrentLoop = CurrentLoop;
107 pParameterList[count]->AfsTrace = AfsTrace;
108 pParameterList[count]->TargetDirectory = TargetDirectory;
109 pParameterList[count]->pExitStatus = &ExitStatus[i];
110 pParameterList[count]->pThreadStatus = &ThreadStatus[i];
111 pParameterList[count]->CommandLine = CommandLine;
112 pParameterList[count]->ClientText = ClientText;
113 pParameterList[count]->PathToSecondDir = PathToSecondDir;
114 pParameterList[count]->AfsLocker = AfsLocker;
115 pParameterList[count]->HostName = HostName;
116 pParameterList[count]->ProcessID = ProcessID;;
117 pParameterList[count]->LogID = LogID;;
119 ThreadStatus[count] = 0;
120 hThreadHandle[count] = CreateThread(NULL, 0, &StressTestThread, (LPVOID)pParameterList[count], CREATE_SUSPENDED, &dwThreadID[count]);
121 if (hThreadHandle[count] != NULL)
123 ResumeThread(hThreadHandle[count]);
124 ThreadStatus[count] = 1;
129 CloseHandle(hEventHandle[count]);
130 if (pParameterList[count] != NULL)
131 free(pParameterList[count]);
132 pParameterList[count] = NULL;
133 hThreadHandle[count] = NULL;
134 hEventHandle[count] = NULL;
139 for (i = 0; i < MAX_HANDLES; i++)
141 if (hEventHandle[i] != NULL)
149 memset(&attachOption, '\0', sizeof(attachOption));
150 strcpy(attachOption.Locker, Locker);
151 strcpy(attachOption.type, "locker");
152 if (rc = ResolveLocker(&attachOption))
154 if (!stricmp(attachOption.type, "AFS"))
156 printf("Unable to attach locker %s - AFS is not supported\n", Locker);
159 strcpy(AfsLocker, attachOption.SubMount);
160 memset(&attachOption, '\0', sizeof(attachOption));
161 strcpy(attachOption.Locker, Locker);
162 strcpy(attachOption.type, "locker");
163 if (rc = attach(attachOption, 0, 0, Locker))
165 printf("Unable to attach locker %s\n", Locker);
170 #endif /* HAVE_HESOID */
172 status = WaitForMultipleObjects(count, hEventHandle, TRUE, INFINITE);
173 for (i = 0; i < MAX_HANDLES; i++)
175 if (hEventHandle[i] != NULL)
176 CloseHandle(hEventHandle[i]);
177 if (pParameterList[i] != NULL)
178 free(pParameterList[i]);
179 pParameterList[i] = NULL;
180 hEventHandle[i] = NULL;
183 for (i = 0; i < NumberOfThreads; i++)
188 if (strlen(ExitStatus[i].Reason))
190 sprintf(temp, "Thread %0d exited with reason: %s", i, ExitStatus[i].Reason);
194 sprintf(temp, "Thread %0d completed\n", i);
198 sprintf(FileName, "Thread_%05d.log", i);
199 LogMessage(i, HostName, FileName, temp, LogID);
200 sprintf(temp, "Ended Iteration %0d\n\n", CurrentLoop);
201 LogMessage(i, HostName, FileName, temp, LogID);
202 CloseHandle(hEventHandle[i]);
204 show_results(CommandLine, TargetDirectory, CommandInfo, HostName, NumberOfThreads, CurrentLoop, LogID);
206 DeleteCriticalSection(&CriticalSection);
211 static void usage(void)
214 fprintf(stderr, "usage: wintorture [options]\n");
215 fprintf(stderr, "where options can be:\n");
216 fprintf(stderr, "\t-b Create a chronological log.\n");
217 fprintf(stderr, "\t-c <txt> Specifies the script txt file to use.\n");
218 fprintf(stderr, "\t-e End thread processing on an error.\n");
219 fprintf(stderr, "\t-f <name> Target directory name.\n");
220 fprintf(stderr, "\t-i <num> Number of iterations of the stress test to run.\n");
221 fprintf(stderr, "\t This option will override the -m option.\n");
223 fprintf(stderr, "\t-l <path> AFS locker or AFS submount in which to create the target directory.\n");
224 #endif /* HAVE_HESOID */
225 fprintf(stderr, "\t-m <num> The number of minutes to run the stress test.\n");
226 fprintf(stderr, "\t This option will override the -i option.\n");
227 fprintf(stderr, "\t-n <num> The number of threads to run.\n");
228 fprintf(stderr, "\t-p <path> UNC path to second directory.\n");
229 fprintf(stderr, "\t-s Output stats.\n");
230 fprintf(stderr, "\t-t Do AFS trace logging.\n");
231 fprintf(stderr, "\t-u <UNC> UNC path to target directory.\n");
232 fprintf(stderr, "\t-v Turn on verbose mode.\n");
233 fprintf(stderr, "\nNOTE: The switches are not case sensitive. You\n");
234 fprintf(stderr, "\n may use either upper or lower case letters.\n\n");
237 void show_results(char *CommandLine, char *TargetDirectory, struct cmd_struct *CommandInfo,
238 char *HostName, int NumberOfThreads, int CurrentLoop, int LogID)
240 struct cmd_struct TotalCommandInfo[CMD_MAX_CMD + 1];
243 unsigned grand_total = 0;
245 char WorkingDirectory[512];
246 struct cmd_struct *FinalCmdInfo;
248 for (j = 0; j <= CMD_MAX_CMD; j++) {
249 TotalCommandInfo[j].count = 0;
250 TotalCommandInfo[j].min_sec = 0;
251 TotalCommandInfo[j].max_sec = 0;
252 TotalCommandInfo[j].MilliSeconds = 0;
253 TotalCommandInfo[j].total_sec = 0;
254 TotalCommandInfo[j].total_sum_of_squares = 0;
255 TotalCommandInfo[j].ErrorCount = 0;
256 TotalCommandInfo[j].ErrorTime = 0;
259 memset(ExitStatus, '\0', sizeof(ExitStatus[0]) * MAX_HANDLES);
261 for (j = 0; j < NumberOfThreads; j++)
263 FinalCmdInfo = CommandInfo + (j * (CMD_MAX_CMD + 1));
265 for (i = 0; i <= CMD_MAX_CMD; i++)
267 TotalCommandInfo[i].count += FinalCmdInfo[i].count;
268 TotalCommandInfo[i].total_sec += FinalCmdInfo[i].total_sec;
269 TotalCommandInfo[i].total_sum_of_squares += FinalCmdInfo[i].total_sum_of_squares;
270 TotalCommandInfo[i].ErrorCount += FinalCmdInfo[i].ErrorCount;
271 TotalCommandInfo[i].ErrorTime += FinalCmdInfo[i].ErrorTime;
272 grand_total += FinalCmdInfo[j].total_sec;
273 if (!TotalCommandInfo[i].min_sec || (TotalCommandInfo[i].min_sec > FinalCmdInfo[i].min_sec))
274 TotalCommandInfo[i].min_sec = FinalCmdInfo[i].min_sec;
275 if (TotalCommandInfo[i].max_sec < FinalCmdInfo[i].max_sec)
276 TotalCommandInfo[i].max_sec = FinalCmdInfo[i].max_sec;
281 memset(WorkingDirectory, '\0', sizeof(WorkingDirectory));
282 GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
283 sprintf(FileName, "%s\\log%05d\\%s\\ProcessStats.log", WorkingDirectory, LogID, HostName);
286 LogStats(FileName, 0, CurrentLoop, 1, NumberOfThreads, HostName, -1, TotalCommandInfo,
287 CommandLine, TargetDirectory);
288 LogStats(FileName, 1, CurrentLoop, 1, NumberOfThreads, HostName, -1, TotalCommandInfo,
289 CommandLine, TargetDirectory);
291 sprintf(FileName, "%s\\log%05d\\%s", WorkingDirectory, LogID, "MasterStatLog.log");
292 UpdateMasterLog(FileName, TotalCommandInfo);
293 sprintf(FileName, "%s\\log%05d\\%s\\%s", WorkingDirectory, LogID, HostName, "MasterProcessStatLog.log");
294 UpdateMasterLog(FileName, TotalCommandInfo);
298 int main(int argc, char *argv[])
303 int NumberOfIterations;
304 int StressTestUsed = 0;
308 int NumberOfProcesses;
324 char MoveFileName[256];
328 char WorkingDirectory[512];
329 char CommandLine[512];
330 char TargetDirectory[512];
334 SYSTEMTIME SystemTime;
335 SYSTEMTIME LocalTime;
336 TIME_ZONE_INFORMATION TimeZoneInformation;
337 HANDLE ExitMutexHandle;
341 memset(HostName, '\0', sizeof(HostName));
342 memset(PathToSecondDir, '\0', sizeof(PathToSecondDir));
343 memset(Locker, '\0', sizeof(Locker));
345 NumberOfIterations = 0;
352 NumberOfProcesses = 1;
357 while ((opt = getopt(argc, argv, "A:a:BbC:c:D:d:EeF:f:G:g:I:i:L:l:M:m:N:n:P:p:SsTtU:u:Vv")) != EOF)
376 NumberOfProcesses = atoi(optarg);
384 strcpy(HostName, optarg);
385 for (i = 0; i < (int)strlen(HostName); i++)
387 if ((HostName[i] == '\\') || (HostName[i] == '/'))
389 printf("\nInvalid -F usage...Subdirectories not allowed\n\n");
398 LogID = atoi(optarg);
403 NumberOfIterations = atoi(optarg);
404 if (NumberOfIterations < 0)
405 NumberOfIterations = 0;
410 strcpy(Locker, optarg);
413 #endif /* HAVE_HESOID */
416 NumberOfIterations = 0;
417 SecondsToRun = atoi(optarg) * 60;
418 if (SecondsToRun < 0)
423 NumberOfThreads = atoi(optarg);
427 strcpy(PathToSecondDir, optarg);
428 for(p = PathToSecondDir; *p; p++)
445 strcpy(Locker, optarg);
458 if (strlen(HostName) == 0)
460 printf("You must use the -f option to specify a target directory\n\n");
464 if (strlen(Locker) == 0)
466 printf("You must use either the -u or the -l option\n\n");
471 memset(CommandLine, '\0', sizeof(CommandLine));
472 for (i = 1; i < argc; i++)
476 if (!stricmp(argv[i], "-f"))
480 strcpy(temp, argv[i + 1]);
481 temp[strlen(temp) - 5] = '\0';
482 strcat(CommandLine, argv[i]);
483 strcat(CommandLine, " ");
484 strcat(CommandLine, temp);
485 strcat(CommandLine, " ");
490 strcat(CommandLine, argv[i]);
491 strcat(CommandLine, " ");
497 if (strlen(Locker) == 0)
504 for(p = Locker; *p; p++)
515 sprintf(AfsLocker, "\\\\afs\\%s", Locker);
516 memset(buffer, '\0', sizeof(buffer));
517 GetLockerInfo(Locker, buffer);
518 if (strlen(buffer) != 0)
520 sPtr = strstr(buffer, "/afs/");
521 sPtr += strlen("/afs/");
522 strcpy(TargetDirectory, sPtr);
523 sPtr = strchr(TargetDirectory, ' ');
526 while ((sPtr = strchr(TargetDirectory, '/')) != NULL)
531 strcpy(TargetDirectory, Locker);
536 #endif /* HAVE_HESOID */
537 strcpy(AfsLocker, Locker);
538 if (!strnicmp(Locker, "\\\\afs\\", strlen("\\\\afs\\")))
539 strcpy(TargetDirectory, &Locker[strlen("\\\\afs\\")]);
541 strcpy(TargetDirectory, Locker);
544 #endif /* HAVE_HESOID */
551 ExitMutexHandle = CreateMutex(NULL, FALSE, "AfsExitEvent");
552 ChronMutexHandle = CreateMutex(NULL, FALSE, "WinTortureChronMutex");
553 MutexHandle = CreateMutex(NULL, FALSE, "WinTortureMutex");
554 FileMutexHandle = CreateMutex(NULL, FALSE, "WinTortureFileMutex");
555 OSMutexHandle = CreateMutex(NULL, FALSE, "WinTortureOSMutex");
557 for (i = 0; i < MAX_THREADS; i++)
562 sprintf(JobName, "%s%05d", "JOB", LogID);
563 JobHandle = CreateJobObject(NULL, JobName);
564 rc = AssignProcessToJobObject(JobHandle, GetCurrentProcess());
566 GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
567 sprintf(FileName, "%s\\log%05d", WorkingDirectory, LogID);
568 CreateDirectory(FileName, NULL);
569 sprintf(FileName, "%s\\test", WorkingDirectory);
570 CreateDirectory(FileName, NULL);
573 sprintf(FileName, "%s\\log%05d\\Chron.log", WorkingDirectory, LogID);
574 DeleteFile(FileName);
577 sprintf(FileName, "%s\\log%05d\\%s", WorkingDirectory, LogID, HostName);
578 sprintf(command, "rmdir /S /Q %s > %s\\test\\test", FileName, WorkingDirectory);
581 ShutDownEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsShutdownEvent");
582 PauseEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsPauseEvent");
583 ContinueEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsContinueEvent");
587 if ((NumberOfIterations == 0) && (SecondsToRun == 0))
588 NumberOfIterations = 1;
589 else if (SecondsToRun != 0)
591 SecondsToRun += StartTime;
596 if (SecondsToRun != 0)
599 if (StartTime > (time_t)SecondsToRun)
604 if (NumberOfIterations != 0)
606 if (LoopCount >= NumberOfIterations)
611 if (rc = WaitForSingleObject(ShutDownEventHandle, 0) == WAIT_OBJECT_0)
616 CurrentLoop = LoopCount;
619 printf("\nIteration %d started at: %s\n", LoopCount, tbuffer);
620 create_procs(HostName, CommandLine, TargetDirectory, AfsLocker, Locker,
621 HostName, NumberOfThreads, CurrentLoop, LogID);
623 printf("Iteration %d ended at: %s\n", LoopCount, tbuffer);
625 printf("Iteration %d lapse time: %ld seconds\n", LoopCount, EndTime - StartTime);
626 TotalTime += EndTime - StartTime;
627 sprintf(FileName, "%s\\log%05d\\IterationCount", WorkingDirectory, LogID);
628 WaitForSingleObject(MutexHandle, 20 * 1000);
629 if ((fp = fopen(FileName, "r")) != NULL)
631 fgets(buffer, sizeof(buffer), fp);
632 IterationCount = atoi(buffer);
636 fp = fopen(FileName, "w");
637 fprintf(fp, "%d\n", IterationCount);
639 ReleaseMutex(MutexHandle);
642 for (i = 0; i < MAX_THREADS; i++)
644 if (ThreadStatus[i] == 1)
649 if (i >= MAX_THREADS)
653 for (i = 0; i < MAX_THREADS; i++)
655 if (ThreadStatus[i] == 0)
663 printf("\nSleeping for 3 minutes for error recovery\n\n");
664 Sleep(3 * 60 * 1000);
670 sprintf(FileName, ".\\log%05d\\%s\\Master.log", LogID, HostName);
671 Mfp = fopen(FileName, "w+");
672 fprintf(Mfp, "Average Iteration Time = %.02f minutes\n\n", ((float)TotalTime/(float)(LoopCount))/60.0);
673 for (i = 0; i < NumberOfThreads; i++)
675 sprintf(FileName, ".\\log%05d\\%s\\Thread_%05d.log", LogID, HostName, i);
676 fp = fopen(FileName, "r");
679 fprintf(Mfp, "START OF THREAD %d\n\n", i);
680 while (fgets(buffer, 512, fp) != NULL)
682 fprintf(Mfp, "%s", buffer);
685 fprintf(Mfp, "END OF THREAD %d\n\n", i);
690 memset(WorkingDirectory, '\0', sizeof(WorkingDirectory));
691 GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
693 sprintf(FileName, "%s\\log%05d\\%s\\%s", WorkingDirectory, LogID, HostName, "MasterProcessStatLog.log");
694 sprintf(MoveFileName, "%s\\log%05d\\%s\\%s", WorkingDirectory, LogID, HostName, "MasterProcessStatLogRaw.log");
695 BuildMasterStatLog(FileName, MoveFileName, NumberOfProcesses, NumberOfThreads, CommandLine, LoopCount,
696 TargetDirectory, -1);
698 // sprintf(DateTime, "%s-%04d%02d%02d-%02d%02d%02d", HostName,
703 // LocalTime.wMinute,
704 // LocalTime.wSecond);
705 // sprintf(command, "rename %s\\log%05d\\%s %s", WorkingDirectory, LogID, HostName, DateTime);
706 // rc = system(command);
708 WaitForSingleObject(ExitMutexHandle, 20 * 1000);
711 GetSystemTime(&SystemTime);
712 GetTimeZoneInformation(&TimeZoneInformation);
713 SystemTimeToTzSpecificLocalTime(&TimeZoneInformation, &SystemTime, &LocalTime);
715 NumberOfProcesses = 0;
716 sprintf(FileName, "%s\\log%05d\\ProcessCount", WorkingDirectory, LogID);
717 if ((fp = fopen(FileName, "r")) != NULL)
719 fgets(buffer, sizeof(buffer), fp);
720 NumberOfProcesses = atoi(buffer);
724 fp = fopen(FileName, "w");
725 fprintf(fp, "%d\n", NumberOfProcesses);
728 if (FindProcessCount("wintorture.exe", JobHandle) == 1)
730 NumberOfProcesses = 0;
731 sprintf(FileName, "%s\\log%05d\\ProcessCount", WorkingDirectory, LogID);
732 sprintf(MoveFileName, "%s\\log%05d\\ProcessCountRaw", WorkingDirectory, LogID);
733 if ((fp = fopen(FileName, "r")) != NULL)
735 fgets(buffer, sizeof(buffer), fp);
736 NumberOfProcesses = atoi(buffer);
738 MoveFile(FileName, MoveFileName);
742 sprintf(FileName, "%s\\log%05d\\IterationCount", WorkingDirectory, LogID);
743 sprintf(MoveFileName, "%s\\log%05d\\IterationCountRaw", WorkingDirectory, LogID);
744 if ((fp = fopen(FileName, "r")) != NULL)
746 fgets(buffer, sizeof(buffer), fp);
747 IterationCount = atoi(buffer);
749 MoveFile(FileName, MoveFileName);
752 sprintf(FileName, "%s\\log%05d\\%s", WorkingDirectory, LogID, "MasterStatLog.log");
753 sprintf(MoveFileName, "%s\\log%05d\\%s", WorkingDirectory, LogID, "MasterStatLogRaw.log");
754 BuildMasterStatLog(FileName, MoveFileName, NumberOfProcesses, NumberOfThreads,
755 CommandLine, IterationCount, TargetDirectory, -2);
756 sprintf(DateTime, "%s%05d-%04d%02d%02d-%02d%02d%02d", "log",
764 sprintf(command, "rename %s\\log%05d %s", WorkingDirectory, LogID, DateTime);
765 rc = system(command);
766 ResetEvent(ShutDownEventHandle);
767 ResetEvent(PauseEventHandle);
768 ResetEvent(ContinueEventHandle);
769 CloseHandle(ShutDownEventHandle);
770 CloseHandle(PauseEventHandle);
771 CloseHandle(ContinueEventHandle);
775 ReleaseMutex(ExitMutexHandle);
776 CloseHandle(JobHandle);
780 int ProcessNameAndID(DWORD processID, char *ProcessName, HANDLE JobHandle)
782 char szProcessName[1024] = "unknown";
784 char WorkingDirectory[512];
788 memset(WorkingDirectory, '\0', sizeof(WorkingDirectory));
789 GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
790 strcat(WorkingDirectory, "\\");
792 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
798 if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
800 memset(szProcessName, '\0', sizeof(szProcessName));
801 GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName));
802 if (!stricmp(szProcessName, ProcessName))
804 memset(FileName, '\0', sizeof(FileName));
805 if (GetModuleFileNameEx(hProcess, hMod, FileName, sizeof(FileName) - 1))
807 if (!strnicmp(WorkingDirectory, FileName, strlen(WorkingDirectory)))
815 CloseHandle(hProcess);
819 DWORD FindProcessCount(char *ProcessName, HANDLE JobHandle)
821 DWORD aProcesses[8092];
827 JOBOBJECT_BASIC_PROCESS_ID_LIST IdList;
829 rc = QueryInformationJobObject(JobHandle, JobObjectBasicProcessIdList, &IdList, sizeof(IdList), NULL);
830 return(IdList.NumberOfAssignedProcesses);
832 if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
836 cProcesses = cbNeeded / sizeof(DWORD);
838 for (i = 0; i < cProcesses; i++)
841 // Count += ProcessNameAndID(aProcesses[i], ProcessName, JobHandle);
847 char *_progname(char *nargv0)
851 tmp = strrchr(nargv0, '/');
859 #define BADCH (int)'?'
860 #define BADARG (int)':'
863 int getopt(int nargc, char *nargv[], char *ostr)
865 static char *__progname = 0;
866 static char *place = EMSG; /* option letter processing */
867 char *oli; /* option letter list index */
869 __progname = __progname?__progname:_progname(*nargv);
871 if (optreset || !*place)
874 if (optind >= nargc || *(place = nargv[optind]) != '-')
879 if (place[1] && *++place == '-' && place[1] == '\0')
886 if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr, optopt)))
888 if (optopt == (int)'-')
892 if (opterr && *ostr != ':')
893 (void)fprintf(stderr, "%s: illegal option -- %c\n", __progname, optopt);
906 else if (nargc <= ++optind)
912 (void)fprintf(stderr, "%s: option requires an argument -- %c\n", __progname, optopt);
916 optarg = nargv[optind];