--- Makefile +++ Makefile 2006-05-16 17:16:01.000000000 +0200 @@ -21,7 +21,7 @@ startpar: $(OBJS) install: startpar $(INSTALL) -d $(DESTDIR)$(sbindir) $(DESTDIR)$(man8dir) - $(INSTALL) -s startpar $(DESTDIR)$(sbindir)/. + $(INSTALL) startpar $(DESTDIR)$(sbindir)/. $(INSTALL_DATA) startpar.8 $(DESTDIR)$(man8dir)/. clean: --- proc.c +++ proc.c 2006-05-16 18:10:47.000000000 +0200 @@ -45,30 +45,29 @@ static unsigned long int scan_one(const int read_proc(unsigned long int * const prcs_run, unsigned long int * const prcs_blked) { - static char StatBuf[32*1024]; + char StatBuf[2048], *ptr = &StatBuf[0]; unsigned long int running, blocked; - ssize_t n; - int fd; + ssize_t len; + size_t skip; + FILE *stat; *prcs_run = 0; *prcs_blked = 0; - if ((fd = open( "/proc/stat", O_RDONLY )) < 0) { + if ((stat = fopen("/proc/stat", "r")) == (FILE*)0) { fprintf(stderr, "ERROR: could not open /proc/stat: %s\n", strerror(errno)); return 1; } - n = read( fd, StatBuf, (sizeof(StatBuf) - 1)); - close(fd); - if (n < 40) { - if (n < 0) { - fprintf(stderr, "ERROR: could not read /proc/stat: %s\n", strerror(errno)); - return 1; - } - fprintf(stderr, "ERROR: no enough data in /proc/stat?\n"); - return 1; + len = sizeof(StatBuf); + while ((len > 0) && (fgets(ptr, len, stat))) { + if (ptr[0] != 'p') + continue; + skip = strlen(ptr); + len -= skip; + ptr += skip; } - StatBuf[n] = 0; + fclose(stat); running = scan_one(StatBuf, "procs_running"); blocked = scan_one(StatBuf, "procs_blocked"); --- startpar.c +++ startpar.c 2007-05-11 12:07:21.215446308 +0200 @@ -127,6 +127,19 @@ void waitsplash() splashpid = 0; } +void closeall(void) +{ + int s; + + if (!prgs) + return; + for (s = 0; s < par; s++) + if (prgs[s].fd) + close(prgs[s].fd); + close(pidpipe[0]); + close(pidpipe[1]); +} + void callsplash(int n, char *path, char *action) { char *p; @@ -169,24 +182,11 @@ void callsplash(int n, char *path, char } close(1); dup(2); + closeall(); execl("/sbin/splash", "splash", "-p", sbuf, "-t", tbuf, splashcfg, (char *)0); _exit(1); } - -void closeall(void) -{ - int s; - - if (!prgs) - return; - for (s = 0; s < par; s++) - if (prgs[s].fd) - close(prgs[s].fd); - close(pidpipe[0]); - close(pidpipe[1]); -} - void writebuf(struct prg *p) { char *b = p->buf; @@ -360,6 +360,7 @@ int run_single(char *prg, int spl) close(1); dup(2); + closeall(); if (run_mode) { char path[128]; @@ -510,6 +511,7 @@ void usage(int status) int main(int argc, char **argv) { + volatile int broken; int timo = -1; int gtimo = -1; int r, c, i, s, last, num; @@ -706,6 +708,7 @@ int main(int argc, char **argv) exit(1); } + broken = 0; /* Detect broken hardware */ gettimeofday(&glastio, 0); limit = checklimit(inpar, (run_mode) ? run_mode : "stop"); lastlim.tv_sec = glastio.tv_sec; @@ -721,6 +724,7 @@ int main(int argc, char **argv) last = -1; maxfd = -1; active = 0; + pid = 0; diff = ((now.tv_sec - lastlim.tv_sec) * 1000) + ((now.tv_usec - lastlim.tv_usec)/ 1000); @@ -795,8 +799,7 @@ int main(int argc, char **argv) } /* for (s = 0; s < par; s++) */ - if (s < limit && num < argc) - continue; /* start new processes */ + broken++; /* no endless loops due broken systems */ if (interactive_task) { @@ -809,9 +812,14 @@ int main(int argc, char **argv) p->pid = 0; p->fd = 0; interactive_task = NULL; + broken = 0; /* run_single() uses waitpid() */ continue; } } + + if ((active < limit) && (num < argc) && (broken < argc)) + continue; /* try to start new processes */ + if (active == 0) { if (num < argc) @@ -828,16 +836,25 @@ int main(int argc, char **argv) if (active == 1 && last >= 0) { p = prgs + last; - writebuf(p); - continue; + if ((pid = waitpid(p->pid, &r, maxfd < 0 ? 0 : WNOHANG)) == 0) + { + writebuf(p); + continue; + } + broken = 0; } FD_SET(pidpipe[0], &rset); /* drain the pidpipe */ - while ((r = read(pidpipe[0], pipebuf, sizeof pipebuf)) > 0) + while ((c = read(pidpipe[0], pipebuf, sizeof pipebuf)) > 0) ; - pid = waitpid(-1, &r, maxfd < 0 ? 0 : WNOHANG); + if (pid == 0) + { + pid = waitpid(-1, &r, maxfd < 0 ? 0 : WNOHANG); + broken = 0; + } + if (pid > 0) { if (pid == splashpid) @@ -874,7 +891,7 @@ int main(int argc, char **argv) } break; } - } + } /* for (s = 0; s < par; s++) */ continue; } @@ -993,9 +1010,9 @@ int main(int argc, char **argv) } p->lastio.tv_sec = now.tv_sec; p->lastio.tv_usec = now.tv_usec; - } + } /* for (s = 0; s < par; s++) */ } - } + } /* for (;;) */ finished: waitsplash();