You mentioned in another thread (which has followups cut off as it is over 3 months old) that you would like to invoke the subprocesses with a lower priority. I hacked up the utility below for myself just now for some other project, but had Crunchie in mind as a potential application while I was writing it. Should be easy to add in:
Code:
// Compiled on Windows using the free compiler, LCC. Should work with
// most other Windows-based C compilers too.
// See:
// http://xona.com/2004/07/22.html
// http://episteme.arstechnica.com/groupee/forums/a/tpc/f/99609816/m/365007825731/inc/-1
// http://www.jpsoft.com/help/index.htm?start.htm
// (and http://www.jpsoft.com/help/index.htm?detach.htm )
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
// Windows uses the wrong name:
#define strcasecmp stricmp
// procedure does not print any error messages, allowing us to
// invoke it both from command-line code and from GUI code.
// Error conditions not extensively tested.
int priosystem(char *exefile, char *process_name, char *priority) {
#define SLOP 32
char *formatstr = "%s /c start \"%s\" /%s \"%s\"";
char *allowed[] = {
"Realtime", "High", "AboveNormal", "Normal", "BelowNormal", "Low",
NULL
};
char *command, *comspec;
int prio = 0;
int rc; // result of system() call.
// priority: Realtime, High, AboveNormal, Normal, BelowNormal, Low.
// 24 13 10 8 6 4
for (;;) {
if (allowed[prio] == NULL) {
// programmer error
return -2; // BAD PRIORITY STRING
}
if (strcasecmp(priority, allowed[prio]) == 0) break;
prio += 1;
}
{
FILE *test;
int c;
comspec = getenv("ComSpec");
if (comspec == NULL) {
// relatively safe fallback
comspec = "C:\\WINDOWS\\system32\\cmd.exe"; // DO NOT "free(comspec)"!
}
test = fopen(comspec, "rb");
if (test == NULL) {
return -3; // BAD COMMAND INTERPRETER - no %COMSPEC%, no C:...
}
c = fgetc(test);
if (c == EOF || ferror(test)) {
fclose(test);
return -4; // BAD COMMAND INTERPRETER FILE?
}
fclose(test);
}
command = malloc(strlen(formatstr) +
strlen(exefile) +
strlen(process_name) +
strlen(priority) +
SLOP);
if (command == NULL) {
// you're screwed. Probably even a printf will fail if we have this little RAM left.
return -1; // GROSSLY INSUFFICIENT MEMORY
}
// NOTE: as with system(), using this command makes you vulnerable to
// data injection hacks, if someone supplies a bad parameter or messes with COMSPEC
// So use only when the parameters are under you control.
sprintf(command, formatstr,
comspec,
process_name,
allowed[prio],
exefile);
rc = system(command);
free(command);
return rc;
#undef SLOP
}
#ifdef PRIOTEST_MAIN
int main(int argc, char **argv)
{
int rc;
fprintf(stderr, "TEST STARTING\n"); fflush(stderr);
rc = priosystem("notepad.exe", "Notepad (Low prio)", "belownormal");
fprintf(stderr, "SYSTEM RETURNS\n"); fflush(stderr);
switch (rc) {
case 0: break;
case -1: // no memory at all
fprintf(stderr, "FATAL: no mem\n"); exit(1);
case -2: // bad prio string
fprintf(stderr, "Error: bad priority string\n"); exit(2);
case -3: // bad CLI or no comspec
fprintf(stderr, "Failure: cannot determine which CMD.EXE to use\n"); exit(3);
case -4: // bad CLI
fprintf(stderr, "Failure: CMD.EXE bad perms or file corrupt - %s\n", strerror(errno));
exit(4);
default:
fprintf(stderr, "Failure: %s\n", strerror(errno));
}
exit(0);
/* NOT REACHED */
return 1;
}
#endif