Hello community, here is the log from the commit of package sysvinit checked in at Fri Jul 18 22:37:47 CEST 2008. -------- --- sysvinit/sysvinit.changes 2008-06-17 17:42:27.000000000 +0200 +++ sysvinit/sysvinit.changes 2008-07-18 17:16:32.713584000 +0200 @@ -1,0 +2,13 @@ +Fri Jul 18 17:15:48 CEST 2008 - werner@suse.de + +- Make a new startpar version 0.52 + * Should know about .depend.halt of new insserv + +------------------------------------------------------------------- +Fri Jul 4 16:03:15 CEST 2008 - werner@suse.de + +- Fix a long standing bug in startpar introduced by implementing + the make like behaviour (bnc#394926) +- Make a new startpar version 0.51 + +------------------------------------------------------------------- Old: ---- startpar-0.50.dif startpar-0.50.tar.bz2 New: ---- startpar-0.52.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sysvinit.spec ++++++ --- /var/tmp/diff_new_pack.x29256/_old 2008-07-18 22:35:29.000000000 +0200 +++ /var/tmp/diff_new_pack.x29256/_new 2008-07-18 22:35:29.000000000 +0200 @@ -17,20 +17,20 @@ %define KPVER 2.13 %define SCVER 1.09 %define SIVER 2.86 -%define START 0.50 +%define START 0.52 License: GPL v2 or later Group: System/Base PreReq: coreutils AutoReqProv: on Version: 2.86 -Release: 150 +Release: 154 Summary: SysV-Style init BuildRoot: %{_tmppath}/%{name}-%{version}-build Source: sysvinit-2.86.tar.bz2 Source2: killproc-2.13.tar.bz2 Source3: powerd-2.0.2.tar.bz2 Source4: showconsole-1.09.tar.bz2 -Source5: startpar-0.50.tar.bz2 +Source5: startpar-0.52.tar.bz2 Source6: rc.powerd Source7: sysvinit-rpmlintrc Patch: sysvinit-2.86.dif @@ -46,7 +46,7 @@ Patch11: sysvinit-2.86-race.patch Patch12: sysvinit-2.86-lib64.patch Patch13: sysvinit-2.82-multiline.patch -Patch14: startpar-0.50.dif +#Patch14: startpar-0.52.dif Patch15: sysvinit-2.86-usage-message.patch Patch16: sysvinit-2.86-full-time.patch Patch17: sysvinit-2.86-hddown.patch @@ -94,7 +94,7 @@ %patch -P 10 popd pushd ../startpar-%{START} -%patch -P 14 +#%patch -P 14 popd %_fixowner . %_fixgroup . @@ -285,6 +285,13 @@ %doc %{_mandir}/man8/startpar.8.gz %changelog +* Fri Jul 18 2008 werner@suse.de +- Make a new startpar version 0.52 + * Should know about .depend.halt of new insserv +* Fri Jul 04 2008 werner@suse.de +- Fix a long standing bug in startpar introduced by implementing + the make like behaviour (bnc#394926) +- Make a new startpar version 0.51 * Fri Jun 13 2008 werner@suse.de - Let blogd detect changes of screen size, set new size pty pair, and if process group is not init send a SIGWINCH (bnc#259577) ++++++ startpar-0.50.tar.bz2 -> startpar-0.52.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/startpar-0.50/COPYING new/startpar-0.52/COPYING --- old/startpar-0.50/COPYING 2003-06-17 13:56:37.000000000 +0200 +++ new/startpar-0.52/COPYING 2008-01-07 15:43:31.000000000 +0100 @@ -2,7 +2,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -304,8 +304,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + along with this program; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/startpar-0.50/makeboot.c new/startpar-0.52/makeboot.c --- old/startpar-0.50/makeboot.c 2007-06-18 15:32:18.000000000 +0200 +++ new/startpar-0.52/makeboot.c 2008-07-18 11:15:21.000000000 +0200 @@ -288,6 +288,8 @@ char buf[4] = "rc0"; if (! strcmp(action, "boot")) { filter_files("boot", 'S', 0); + } else if (! strcmp(action, "halt")) { + filter_files("boot", 'K', 0); } else if (! strcmp(action, "start")) { buf[2] = *prev; filter_files(buf, 'K', 1); @@ -339,6 +341,10 @@ best = node; } } + if (best) { + blogger("service %s", best->name); + best->status = T_RUNNING; + } return best; } @@ -412,3 +418,36 @@ node->name, node->status, node->num_deps, node->interactive, node->importance); } #endif + +#ifdef TEST +void *xcalloc(size_t nmemb, size_t size) +{ + void *r; + if ((r = (void *)calloc(nmemb, size)) == 0) { + fprintf(stderr, "calloc: out of memory\n"); + exit(1); + } + return r; +} + +int main(int argc, char **argv) +{ + struct makenode *nodevec; + char makefile[64]; + + if (argc != 2) + goto out; + nodevec = xcalloc(1, sizeof(*nodevec)); + + snprintf(makefile, sizeof(makefile), "depend.%s", argv[1]); + parse_makefile(makefile); + check_run_files(argv[1], "5", "6"); +out: + while ((nodevec = pickup_task())) { + fprintf(stdout, "%s\n", nodevec->name); + finish_task(nodevec); + } + + return 0; +} +#endif diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/startpar-0.50/Makefile new/startpar-0.52/Makefile --- old/startpar-0.50/Makefile 2007-06-18 14:37:41.000000000 +0200 +++ new/startpar-0.52/Makefile 2008-07-18 13:01:56.000000000 +0200 @@ -1,4 +1,4 @@ -VERSION = 0.50 +VERSION = 0.52 INSTALL = install -m 755 INSTALL_DATA = install -m 644 @@ -7,7 +7,10 @@ mandir = /usr/share/man man8dir = $(mandir)/man8 -OBJS = startpar.o makeboot.o proc.o +SRCS = startpar.c makeboot.c proc.c +HDRS = makeboot.h proc.h +REST = COPYING Makefile startpar.8 +OBJS = $(SRCS:.c=.o) CC = gcc OPTFLAGS = -O2 -g -Wall -W @@ -26,3 +29,11 @@ clean: rm -f startpar $(OBJS) + +dest: clean + mkdir -p startpar-$(VERSION) + for file in $(SRCS) $(HDRS) $(REST) ; do \ + cp -p $$file startpar-$(VERSION)/; \ + done + tar -cps -jf startpar-$(VERSION).tar.bz2 startpar-$(VERSION)/* + rm -rf startpar-$(VERSION)/ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/startpar-0.50/proc.c new/startpar-0.52/proc.c --- old/startpar-0.50/proc.c 2007-06-18 14:03:33.000000000 +0200 +++ new/startpar-0.52/proc.c 2008-01-07 15:43:31.000000000 +0100 @@ -13,8 +13,8 @@ * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING); if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301, USA. * **************************************************************** */ @@ -69,6 +69,7 @@ } fclose(stat); + /* These fields are not present in /proc/stat for 2.4 kernels */ running = scan_one(StatBuf, "procs_running"); blocked = scan_one(StatBuf, "procs_blocked"); diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/startpar-0.50/proc.h new/startpar-0.52/proc.h --- old/startpar-0.50/proc.h 2005-09-15 17:21:03.000000000 +0200 +++ new/startpar-0.52/proc.h 2008-01-07 15:43:31.000000000 +0100 @@ -12,8 +12,8 @@ * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING); if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301, USA. * **************************************************************** */ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/startpar-0.50/startpar.8 new/startpar-0.52/startpar.8 --- old/startpar-0.50/startpar.8 2007-06-18 14:10:40.000000000 +0200 +++ new/startpar-0.52/startpar.8 2008-01-07 15:43:31.000000000 +0100 @@ -85,11 +85,11 @@ .IR boot ", " start ", and " stop for reading .IR .depend.boot " or " .depend.start " or " .depend.stop -repectivly in the directory +respectively in the directory .IR /etc/init.d/ . By scanning the boot and runlevel directories in .I /etc/init.d/ -it then executes the appropiate scripts in parallel. +it then executes the appropriate scripts in parallel. .SH FILES .I /etc/init.d/.depend.boot @@ -101,7 +101,7 @@ .SH SEE ALSO .BR init.d (7), .BR insserv (8), -.BR startproc (8) +.BR startproc (8). .SH COPYRIGHT 2003,2004 SuSE Linux AG, Nuernberg, Germany. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/startpar-0.50/startpar.c new/startpar-0.52/startpar.c --- old/startpar-0.50/startpar.c 2007-06-18 14:34:30.000000000 +0200 +++ new/startpar-0.52/startpar.c 2008-07-18 13:25:50.000000000 +0200 @@ -12,8 +12,8 @@ * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING); if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301, USA. * **************************************************************** */ @@ -40,6 +40,8 @@ #include "makeboot.h" #include "proc.h" +#define timerdiff(n,l) (__extension__ ({ (((n).tv_sec-(l).tv_sec)*1000)+(((n).tv_usec-(l).tv_usec)/1000); })) + typedef enum _boolean {false, true} boolean; extern char *optarg; extern int optind; @@ -48,8 +50,13 @@ static char *myname; static struct termios tio; static struct winsize wz; -static int wzok; +static struct { + char env_row[128]; + char env_col[128]; +} sz; +static sig_atomic_t wzok; static char *arg; +static boolean isstart; static struct sigaction sa; static struct timeval glastio; static struct timeval now; @@ -72,7 +79,7 @@ static struct prg *prgs; static int inpar, par; static int pidpipe[2]; -static int iorate = 800; +static double iorate = 800.0; void *xcalloc(size_t nmemb, size_t size) { @@ -124,7 +131,9 @@ int status; if (!splashpid) return; - waitpid(splashpid, &status, 0); + do { + waitpid(splashpid, &status, 0); + } while (errno == EINTR); splashpid = 0; } @@ -181,8 +190,8 @@ splashpid = pid; return; } - close(1); - dup(2); + while (dup2(2, 1) < 0 && (errno == EINTR)) + ; closeall(); execl("/sbin/splash", "splash", "-p", sbuf, "-t", tbuf, splashcfg, (char *)0); _exit(1); @@ -204,11 +213,10 @@ p->len -= r; b += r; } - glastio.tv_sec = now.tv_sec; - glastio.tv_usec = now.tv_usec; + glastio = now; } -static int checksystem(const int par, const char *mode, const boolean limit) +static int checksystem(const int par, const boolean start, const boolean limit) { const int pg_size = sysconf(_SC_PAGESIZE); const long int minphys_bytes = (sysconf(_SC_LONG_BIT) > 32L) ? (2<<22) : (2<<21); @@ -223,7 +231,7 @@ if (pg_size < 0) return par; - if (mode && strcmp(mode, "stop") == 0) + if (!start) minphys_pg = avphys_pg; else minphys_pg = minphys_bytes / pg_size; @@ -240,8 +248,8 @@ if (read_proc(&prcs_run, &prcs_blked)) return par; - newpar = (par*numcpu) - prcs_run + 1; /* +1 for startpar its self */ - newpar -= (prcs_blked * iorate); /* I/O load reduction */ + newpar = (par*numcpu) - prcs_run + 1; /* +1 for startpar its self */ + newpar -= (int)(((double)prcs_blked)*iorate); /* I/O load reduction */ #if DEBUG fprintf(stderr, "checksystem par=%d newpar=%d (prcs_run=%u) %ld\n", par, newpar, prcs_run, time(0)); @@ -253,14 +261,14 @@ return newpar; } -static inline int checklimit(const int par, const char *mode) +static inline int checklimit(const int par, const boolean start) { - return checksystem(par, mode, true); + return checksystem(par, start, true); } -static inline int checkpar(const int par, const char *mode) +static inline int checkpar(const int par, const boolean start) { - return checksystem(par, mode, false); + return checksystem(par, start, false); } void run(struct prg *p) @@ -301,39 +309,45 @@ (void)signal(SIGQUIT, SIG_DFL); (void)signal(SIGSEGV, SIG_DFL); (void)signal(SIGTERM, SIG_DFL); + (void)signal(SIGCHLD, SIG_DFL); if (setpgid(0, 0)) perror("setpgid"); if (m && p->fd) { - close(1); + while (close(1) < 0 && (errno == EINTR)) + ; if (open(m, O_RDWR) != 1) { perror(m); _exit(1); } - close(2); - dup(1); + while (dup2(1, 2) < 0 && (errno == EINTR)) + ; tio.c_oflag &= ~OPOST; if (tcsetattr(1, TCSANOW, &tio)) perror("tcsetattr"); - if (wzok && ioctl(0, TIOCSWINSZ, &wz)) - perror("TIOCSWINSZ"); + if (wzok) + ioctl(1, TIOCSWINSZ, &wz); + putenv(sz.env_row); + putenv(sz.env_col); } else { - close(1); - dup(2); + while (dup2(2, 1) < 0 && (errno == EINTR)) + ; } closeall(); - if (run_mode) { - char path[128]; - snprintf(path, sizeof(path), "/etc/init.d/%s", p->name); - execlp(path, path, arg, (char *)0); - } else if (arg) + if (run_mode) + { + char path[128]; + snprintf(path, sizeof(path), "/etc/init.d/%s", p->name); + execlp(path, path, arg, (char *)0); + } + else if (arg) execlp(p->name, p->name, arg, (char *)0); else execlp(p->name, p->name, (char *)0); @@ -359,9 +373,10 @@ (void)signal(SIGQUIT, SIG_DFL); (void)signal(SIGSEGV, SIG_DFL); (void)signal(SIGTERM, SIG_DFL); + (void)signal(SIGCHLD, SIG_DFL); - close(1); - dup(2); + while (dup2(2, 1) < 0 && (errno == EINTR)) + ; closeall(); if (run_mode) { @@ -377,7 +392,7 @@ _exit(1); } - while (waitpid(pid, &r, 0) == (pid_t)-1) + while ((waitpid(pid, &r, 0) == (pid_t)-1) && (errno == EINTR)) ; callsplash(spl, prg, arg); return WIFEXITED(r) ? WEXITSTATUS(r) : (WIFSIGNALED(r) ? 1 : 255); @@ -420,8 +435,7 @@ (void)memcpy(gtimo_buf + gtimo_buflen, p->buf, p->len); gtimo_buflen += p->len; p->len = 0; - glastio.tv_sec = now.tv_sec; - glastio.tv_usec = now.tv_usec; + glastio = now; } void flushbuf(void) @@ -475,10 +489,10 @@ { if ((r = fork()) == 0) { - close(0); - dup(p->fd); - close(1); - dup(2); + while (dup2(p->fd, 0) < 0 && (errno == EINTR)) + ; + while (dup2(2, 1) < 0 && (errno == EINTR)) + ; closeall(); execlp(myname, myname, "-f", "--", p->name, NULL); do_forward(); @@ -490,12 +504,25 @@ p->fd = 0; } -void sigchld(int sig __attribute__ ((unused))) +static void sigchld(int sig __attribute__ ((unused))) { char c = 0; write(pidpipe[1], &c, 1); } +static void sigwinch(int sig __attribute__ ((unused))) +{ + if (ioctl(0, TIOCGWINSZ, &wz) < 0) + { + wzok = 0; + return; + } + if (wz.ws_row == 0) wz.ws_row = 24; + if (wz.ws_col == 0) wz.ws_col = 80; + snprintf(sz.env_row, sizeof(sz.env_row), "LINES=%d", wz.ws_row); + snprintf(sz.env_col, sizeof(sz.env_col), "COLUMNS=%d", wz.ws_col); +} + void usage(int status) { fprintf(stderr, "usage: startpar [options] [-a arg] prgs\n"); @@ -513,25 +540,24 @@ int main(int argc, char **argv) { - volatile int broken; - int timo = -1; int gtimo = -1; - int r, c, i, s, last, num; + int timo = -1; + int isgtimo; + int forw = 0; + int c, i, num; + int limit; int *resvec; - int maxfd; fd_set rset; struct timeval tv; struct prg *p; - pid_t pid; - int forw = 0; char pipebuf[16]; - int isgtimo; struct prg *gtimo_running = 0; struct prg *interactive_task = NULL; - int active, limit; - char *prev_level = NULL, *run_level = NULL; + char *prev_level = getenv("PREVLEVEL"); + char *run_level = getenv("RUNLEVEL"); char *splashopt = 0; + (void)signal(SIGCHLD, SIG_DFL); numcpu = sysconf(_SC_NPROCESSORS_ONLN); myname = argv[0]; @@ -573,9 +599,9 @@ usage(0); break; case 'i': - iorate = atoi(optarg); - if (iorate <= 0) - iorate = 800; + iorate = atof(optarg); + if (iorate < 0.0) + iorate = 800.0; break; default: usage(1); @@ -609,6 +635,8 @@ char makefile[64]; if (!strcmp(run_mode, "boot")) arg = "start"; + else if (!strcmp(run_mode, "halt")) + arg = "stop"; else if (!strcmp(run_mode, "start") || !strcmp(run_mode, "stop")) { arg = run_mode; @@ -628,6 +656,7 @@ check_run_files(run_mode, prev_level, run_level); argc = tree_entries; /* number of handled scripts */ + isstart = !strcmp(arg, "start"); if (argc == 0) exit(0); @@ -639,7 +668,7 @@ inpar = par; /* the original argument of parallel procs per cpu */ - par = checkpar(inpar, run_mode); /* the number of parallel procs on all cpu's */ + par = checkpar(inpar, isstart); /* the number of parallel procs on all cpu's */ if (par > argc) /* not more than the number of all scripts */ par = argc; @@ -651,6 +680,9 @@ if (par < 0) usage(1); + if (arg) + isstart = !strcmp(arg, "start"); + if (argc == 0) exit(0); @@ -661,7 +693,7 @@ inpar = par; /* the original argument of parallel procs per cpu */ - par = checkpar(inpar, "stop"); /* the number of parallel procs on all cpu's */ + par = checkpar(inpar, isstart); /* the number of parallel procs on all cpu's */ if (par > argc) /* not more than the number of all scripts */ par = argc; @@ -674,12 +706,13 @@ if (argc == 1) { - if (run_mode) { - *nodevec = pickup_task(); - if (*nodevec) { - *resvec = run_single((*nodevec)->name, calcsplash(0, 1, splashopt)); - finish_task(*nodevec); - } + if (run_mode) + { + if ((*nodevec = pickup_task())) + { + *resvec = run_single((*nodevec)->name, calcsplash(0, 1, splashopt)); + finish_task(*nodevec); + } } else *resvec = run_single(*argv, calcsplash(0, 1, splashopt)); goto finished; @@ -691,6 +724,15 @@ if (!gtimo_buf) gtimo_bufsize = 0; /* Accept error due memory shortage */ + sa.sa_handler = sigwinch; + sa.sa_flags = SA_RESTART|SA_NODEFER; + (void)sigemptyset(&sa.sa_mask); + if (sigaction(SIGWINCH, &sa, 0)) + { + perror("sigwinch sigaction"); + exit(1); + } + if (tcgetattr(0, &tio)) { perror("tcgetattr"); @@ -698,6 +740,13 @@ } if (ioctl(0, TIOCGWINSZ, &wz) == 0) wzok = 1; + if (wz.ws_row == 0) wz.ws_row = 24; + if (wz.ws_col == 0) wz.ws_col = 80; + + strcat(&sz.env_row[0], "LINES="); + strcat(&sz.env_col[0], "COLUMNS="); + snprintf(sz.env_row, sizeof(sz.env_row), "LINES=%d", wz.ws_row); + snprintf(sz.env_col, sizeof(sz.env_col), "COLUMNS=%d", wz.ws_col); if (pipe(pidpipe)) { @@ -715,58 +764,56 @@ exit(1); } - broken = 0; /* Detect broken hardware */ gettimeofday(&glastio, 0); - limit = checklimit(inpar, (run_mode) ? run_mode : "stop"); - lastlim.tv_sec = glastio.tv_sec; - lastlim.tv_usec = glastio.tv_usec; + limit = checklimit(inpar, isstart); + lastlim = glastio; for (;;) { + int active = 0; + int maxfd = -1; + int last = -1; + pid_t pid = 0; + int r = 0, s; long diff; gettimeofday(&now, 0); FD_ZERO(&rset); - tv.tv_sec = now.tv_sec; - tv.tv_usec = now.tv_usec; - last = -1; - maxfd = -1; - active = 0; - pid = 0; - - diff = ((now.tv_sec - lastlim.tv_sec) * 1000) + - ((now.tv_usec - lastlim.tv_usec)/ 1000); - if (diff >= 300 || diff < 0) + tv = now; + + if ((diff = timerdiff(now, lastlim)) >= 300 || diff < 0) { #if DEBUG fprintf(stderr, "%d: doing checklimit after %ldms %ld\n", getpid(), diff, time(0)); #endif - limit = checklimit(inpar, (run_mode) ? run_mode : "stop"); - if (limit > argc) + if ((limit = checklimit(inpar, isstart)) > argc) limit = argc; /* not more than the number of all scripts */ - lastlim.tv_sec = now.tv_sec; - lastlim.tv_usec = now.tv_usec; + lastlim = now; diff = 0; } #if DEBUG - fprintf(stderr, "par = %d, inpar = %d, limit = %d (diff=%ld)\n", par, inpar, limit, diff); + fprintf(stderr, "par=%d, inpar=%d, limit=%d (diff=%ld)\n", par, inpar, limit, diff); #endif - for (s = 0; s < par; s++) + for (s = 0; s < par; s++) /* never leave this with break!! */ { + account: /* for the new process below */ p = prgs + s; if (p == interactive_task) - continue; /* don't handle this here */ + continue; /* don't count this here */ if (p->fd || p->pid) active++; /* count all running procs */ if (p->fd == 0) { - if (p->pid == 0 && num < argc && !interactive_task) + if (interactive_task) + continue; /* dont't start new processes */ + if (num >= argc) + continue; /* nothing to do */ + if (p->pid == 0) { if (active >= limit) - break; /* load balancing */ + continue; /* load balancing */ if (run_mode) { - nodevec[num] = pickup_task(); - if (! nodevec[num]) + if ((nodevec[num] = pickup_task()) == NULL) continue; if (nodevec[num]->interactive) interactive_task = p; @@ -777,17 +824,17 @@ p->splashadd = calcsplash(num, argc, splashopt); p->num = num++; if (interactive_task) - break; + continue; /* don't start this here */ run(p); - active++; /* remember this _new_ proc!!! */ if (p->pid == 0) { resvec[p->num] = 1; if (run_mode) finish_task(nodevec[p->num]); - active--; /* fork in run() failed, sigh! */ } - break; + gettimeofday(&now, 0); + tv = now; + goto account; /* take the new process into account */ } continue; } @@ -796,18 +843,13 @@ maxfd = p->fd; if (p->len == 0) continue; - if ((last < 0) || (tv.tv_sec > p->lastio.tv_sec) || - (tv.tv_sec == p->lastio.tv_sec && tv.tv_usec > p->lastio.tv_usec)) + if ((last < 0) || timercmp(&tv,&p->lastio,>)) { last = s; - tv.tv_sec = p->lastio.tv_sec; - tv.tv_usec = p->lastio.tv_usec; + tv = p->lastio; } - } /* for (s = 0; s < par; s++) */ - broken++; /* no endless loops due broken systems */ - if (interactive_task) { if (active == 0) @@ -819,36 +861,31 @@ 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) fprintf(stderr, "ERROR: not all processed (%d of %d)\n", num, argc); #if DEBUG - if ((pid = waitpid(-1, &r, maxfd < 0 ? 0 : WNOHANG)) > 0) + if ((pid = waitpid(-1, &r, (maxfd < 0 ? 0 : WNOHANG)|WUNTRACED)) > 0) fprintf(stderr, "ERROR: not all processes are checked\n"); #endif break; } -#if 0 +#if DEBUG fprintf(stderr, "active = %d\n", active); #endif if (active == 1 && last >= 0) { p = prgs + last; - if ((pid = waitpid(p->pid, &r, maxfd < 0 ? 0 : WNOHANG)) == 0) + if ((pid = waitpid(p->pid, &r, (maxfd < 0 ? 0 : WNOHANG)|WUNTRACED)) == 0) { writebuf(p); continue; } - broken = 0; } FD_SET(pidpipe[0], &rset); @@ -857,10 +894,7 @@ ; if (pid == 0) - { - pid = waitpid(-1, &r, maxfd < 0 ? 0 : WNOHANG); - broken = 0; - } + pid = waitpid(-1, &r, (maxfd < 0 ? 0 : WNOHANG)|WUNTRACED); if (pid > 0) { @@ -871,6 +905,16 @@ p = prgs + s; if (p->pid == pid) { + if (WIFSTOPPED(r)) + { + if (WSTOPSIG(r) == SIGTTIN) + { + pid_t pg = getpgid(pid); + if (pg > 0) + killpg(pg, SIGCONT); + } + continue; + } callsplash(p->splashadd, p->name, arg); resvec[p->num] = WIFEXITED(r) ? WEXITSTATUS(r) : (WIFSIGNALED(r) ? 1 : 255); if (run_mode) @@ -911,12 +955,11 @@ isgtimo = 0; if (gtimo >= 0 && !gtimo_running && last >= 0 && prgs[last].pid) { - const long glsec = glastio.tv_sec + gtimo; - if ((timo < 0) || (tv.tv_sec > glsec) || - (tv.tv_sec == glsec && tv.tv_usec > glastio.tv_usec)) + struct timeval gl = glastio; + gl.tv_sec += gtimo; + if ((timo < 0) || timercmp(&tv,&gl,>)) { - tv.tv_sec = glastio.tv_sec; - tv.tv_usec = glastio.tv_usec; + tv = glastio; tv.tv_sec += gtimo; isgtimo = 1; } @@ -1015,8 +1058,7 @@ memmove(p->buf, p->buf + p->len, sizeof(p->buf) - p->len); p->len = sizeof(p->buf) - p->len; } - p->lastio.tv_sec = now.tv_sec; - p->lastio.tv_usec = now.tv_usec; + p->lastio = now; } /* for (s = 0; s < par; s++) */ } } /* for (;;) */ @@ -1036,9 +1078,13 @@ exit (1); } #endif +#if VERBOSE printf(i ? " %d" : "%d", resvec[i]); +#endif /* VERBOSE */ } +#if VERBOSE printf("\n"); +#endif /* VERBOSE */ } return 0; } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org