Hello community,

here is the log from the commit of package cpulimit for openSUSE:Factory 
checked in at 2018-02-19 13:03:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cpulimit (Old)
 and      /work/SRC/openSUSE:Factory/.cpulimit.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cpulimit"

Mon Feb 19 13:03:32 2018 rev:2 rq:577907 version:2.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/cpulimit/cpulimit.changes        2015-01-08 
23:01:44.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.cpulimit.new/cpulimit.changes   2018-02-19 
13:04:10.759128089 +0100
@@ -1,0 +2,18 @@
+Sun Feb 18 08:34:12 UTC 2018 - avin...@opensuse.org
+
+- new upstream version 2.5
+  * Added some protection against causing a fork bomb when the
+    throttled process is a parent to LimitCPU.
+- includes 2.4
+  * Introduced ability to watch children of the target process. This
+    means forks of the process we are throttling can also be
+    throttled, using the "-m" or "--monitor-forks" flags.
+- includes 2.3
+  * Applied patch to man page which fixes -s description.
+  * Added --foreground, -f flag for launching target programs in the
+    foreground. LimitCPU then waits for the target process to exit.
+    Should be useful in scripts.
+- rebase cpulimit-2.2-do_not_forget_version.patch
+- cleanup with spec-cleaner
+
+-------------------------------------------------------------------

Old:
----
  cpulimit-2.2.tar.gz

New:
----
  cpulimit-2.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cpulimit.spec ++++++
--- /var/tmp/diff_new_pack.cKKSmU/_old  2018-02-19 13:04:12.107079477 +0100
+++ /var/tmp/diff_new_pack.cKKSmU/_new  2018-02-19 13:04:12.115079188 +0100
@@ -2,7 +2,7 @@
 #
 # spec file for package cpulimit
 #
-# Copyright (c) 2012-2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,18 +18,17 @@
 
 
 Name:           cpulimit
-Version:        2.2
+Version:        2.5
 Release:        0
 Summary:        Limit the CPU Usage of a Process
 License:        GPL-2.0+
 Group:          System/Monitoring
 Url:            http://limitcpu.sourceforge.net/
-Source0:        
http://prdownloads.sourceforge.net/limitcpu/cpulimit-%{version}.tar.gz
+Source0:        
http://prdownloads.sourceforge.net/limitcpu/%{name}-%{version}.tar.gz
 Patch0:                %{name}-2.2-do_not_forget_version.patch
 BuildRequires:  gcc
 BuildRequires:  glibc-devel
 BuildRequires:  make
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
 %description
 LimitCPU is a program to throttle the CPU cycles used by other applications.
@@ -47,21 +46,15 @@
 %patch0 -p1
 
 %build
-make %{?_smp_flags} \
-    PREFIX="%{_prefix}" \
+make %{?_smp_mflags} \
     CFLAGS="%{optflags}"
 
 %install
-install -D -m0755 %{name} "%{buildroot}%{_bindir}/%{name}"
-install -D -m0644 %{name}.1 "%{buildroot}%{_mandir}/man1/%{name}.1"
-
-%clean
-%{?buildroot:rm -rf %{buildroot}}
+%make_install PREFIX=%{buildroot}/%{_prefix}
 
 %files
-%defattr(-,root,root)
 %doc LICENSE CHANGELOG README TODO
 %{_bindir}/%{name}
-%doc %{_mandir}/man1/%{name}.1%{ext_man}
+%{_mandir}/man1/%{name}.1%{ext_man}
 
 %changelog

++++++ cpulimit-2.2-do_not_forget_version.patch ++++++
--- /var/tmp/diff_new_pack.cKKSmU/_old  2018-02-19 13:04:12.139078323 +0100
+++ /var/tmp/diff_new_pack.cKKSmU/_new  2018-02-19 13:04:12.139078323 +0100
@@ -1,12 +1,11 @@
-diff -uNr old-cpulimit-2.2/cpulimit.c cpulimit-2.2/cpulimit.c
---- old-cpulimit-2.2/cpulimit.c        2014-12-26 10:24:53.788487238 +0100
-+++ cpulimit-2.2/cpulimit.c    2014-12-26 10:25:17.024096912 +0100
+--- a/cpulimit.c       2014-12-26 10:24:53.788487238 +0100
++++ b/cpulimit.c       2014-12-26 10:25:17.024096912 +0100
 @@ -80,7 +80,7 @@
  #endif
  
  #ifndef VERSION
--#define VERSION 2.1
-+#define VERSION 2.2
+-#define VERSION 2.4
++#define VERSION 2.5
  #endif
  
  //pid of the controlled process

++++++ cpulimit-2.2.tar.gz -> cpulimit-2.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cpulimit-2.2/CHANGELOG new/cpulimit-2.5/CHANGELOG
--- old/cpulimit-2.2/CHANGELOG  2014-05-24 00:09:14.000000000 +0200
+++ new/cpulimit-2.5/CHANGELOG  2017-03-27 19:03:18.000000000 +0200
@@ -1,3 +1,24 @@
+========== Changes in 2.5 =================
+
+* Added some protection against causing a fork bomb
+  when the throttled process is a parent to LimitCPU.
+  Patch provided by Johann Felix.
+
+========== Changes in 2.4 =================
+
+* Introduced ability to watch children of the target
+  process. This means forks of the process we are throttling
+  can also be throttled, using the "-m" or "--monitor-forks" flags.
+
+=========== Changes in 2.3 ================
+
+* Applied patch to man page which fixes -s description.
+
+* Added --foreground, -f flag for launching target programs in
+  the foreground. LimitCPU then waits for the target process to exit.
+  Should be useful in scripts. Closes Debian bug #836027.
+
+
 =========== Changes in 2.2 ================
 
 * Escaped double-dashed in manual page to avoid
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cpulimit-2.2/Makefile new/cpulimit-2.5/Makefile
--- old/cpulimit-2.2/Makefile   2014-05-22 23:20:06.000000000 +0200
+++ new/cpulimit-2.5/Makefile   2017-03-27 19:01:48.000000000 +0200
@@ -1,4 +1,4 @@
-VERSION?=2.2
+VERSION?=2.5
 PREFIX?=/usr
 CFLAGS?=-Wall -O2 -DVERSION=$(VERSION)
 CC?=gcc
@@ -15,7 +15,7 @@
        $(CC) -o cpulimit cpulimit.c -lrt -DFREEBSD $(CFLAGS) $(CPPFLAGS) 
$(LDFLAGS)
 
 cpulimit: cpulimit.c
-       $(CC) -o cpulimit cpulimit.c -lrt -DLINUX $(CFLAGS) $(CPPFLAGS) 
$(LDFLAGS)
+       $(CC) -o cpulimit cpulimit.c -pthread -lrt -DLINUX $(CFLAGS) 
$(CPPFLAGS) $(LDFLAGS)
 
 tests:
        $(MAKE) -C test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cpulimit-2.2/README new/cpulimit-2.5/README
--- old/cpulimit-2.2/README     2014-05-24 00:17:00.000000000 +0200
+++ new/cpulimit-2.5/README     2016-11-19 23:23:20.000000000 +0100
@@ -22,7 +22,7 @@
 file named LICENSE.
 
 Copyright 2005, Angelo Marletta <marlon...@hotmail.com>
-Copyright 2011-2014, Jesse Smith <jessefrgsm...@yahoo.ca>
+Copyright 2011-2016, Jesse Smith <jessefrgsm...@yahoo.ca>
 
 
 
@@ -181,6 +181,13 @@
 
 cpulimit -l 25 -p 1234 --signal=15
 
+LimitCPU can be used to watch not only one target process, but also
+child processes the target spawns. This means new processs the
+target creates will also be throttled. By default, LimitCPU
+only watches one target process and ignores children, but monitoring
+children can be enabled using the "-m" or "--monitor-forks" flag.
+
+cpulimit -l 25 -p 1234 -m
 
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cpulimit-2.2/TODO new/cpulimit-2.5/TODO
--- old/cpulimit-2.2/TODO       2014-04-07 01:39:56.000000000 +0200
+++ new/cpulimit-2.5/TODO       2016-11-19 23:23:20.000000000 +0100
@@ -1,3 +1 @@
-- light and scalable algorithm for subprocesses detection and limitation
-
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cpulimit-2.2/cpulimit.1 new/cpulimit-2.5/cpulimit.1
--- old/cpulimit-2.2/cpulimit.1 2014-05-24 00:16:02.000000000 +0200
+++ new/cpulimit-2.5/cpulimit.1 2016-11-19 23:23:20.000000000 +0100
@@ -22,6 +22,9 @@
 \fB\-b\fR, \fB\-\-background\fR
 run cpulimit in the background, freeing up the terminal
 .TP
+\fB\-f\fR, \fB\-\-foreground\fR
+run cpulimit in foreground while waiting for launched process to finish
+.TP
 \fB\-c\fR, \fB\-\-cpu\fR
 specify the number of CPU cores available. Usually this is detected for us.
 .TP
@@ -34,6 +37,9 @@
 \fB\-k\fR, \fB\-\-kill\fR
 kill target process instead of throttling its CPU usage
 .TP
+\fB\-m\fR, \fB\-\-monitor\-forks\fR
+watch and throttle child processes of the target process
+.TP
 \fB\-r\fR, \fB\-\-restore\fR
 restore a process killed using the \-k flag.
 .TP
@@ -90,7 +96,7 @@
 Launch the Firefox program and kill it if the process goes
 over 20% CPU usage.
 .TP
-\[sh] \fBcpulimit \-l 20 \-p 1234 -s SIGTERM
+\[sh] \fBcpulimit \-l 20 \-p 1234 \-s SIGTERM
 Throttle process 1234 at 20% CPU usage. If cpulimit is forced to exit, 
 it sends the watched process the SIGTERM signal.
 .SH NOTES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cpulimit-2.2/cpulimit.c new/cpulimit-2.5/cpulimit.c
--- old/cpulimit-2.2/cpulimit.c 2014-05-25 17:09:17.000000000 +0200
+++ new/cpulimit-2.5/cpulimit.c 2017-03-27 18:59:11.000000000 +0200
@@ -56,6 +56,11 @@
 #include <sys/user.h>
 #endif
 
+#ifdef LINUX
+#include <dirent.h>
+#define PROC_FILENAME 64
+#define LINE_LENGTH 256
+#endif
 
 //kernel time resolution (inverse of one jiffy interval) in Hertz
 //i don't know how to detect it, then define to the default (not very clean!)
@@ -80,7 +85,7 @@
 #endif
 
 #ifndef VERSION
-#define VERSION 2.1
+#define VERSION 2.4
 #endif
 
 //pid of the controlled process
@@ -123,6 +128,29 @@
 }
 
 
+#ifdef LINUX
+#include <pthread.h>
+
+typedef struct
+{
+   pid_t child;   // the child of our target process
+   pid_t monitor; // the LimitCPU fork monitoring the child
+   void *next; 
+} CHILD;
+
+int quitting = FALSE;           // Have we receive a quit signal
+int monitor_children = FALSE;   // are we monitoring children of target
+
+// Data passed to the monitor thread
+typedef struct
+{
+   int limit;           // per cent limit to place on a process
+   char *this_program;  // copy of argv[0]
+} PROGRAM_DATA;
+
+#endif
+
+
 
 int Check_Us(pid_t target_pid)
 {
@@ -325,13 +353,38 @@
 void quit(int sig) {
        //let the process continue if we are stopped
        kill(pid, send_signal);
+        #ifdef LINUX
+        if (monitor_children)
+        {
+            quitting = TRUE;
+            printf("Asking children to quit...\n");
+            sleep(2);                // wait for thread clean-up
+        }
+        #endif
        printf("Exiting...\n");
        exit(0);
 }
 
+// Handle a child process quitting
+void Child_Done(int sig)
+{
+   pid_t caught_child;
+   caught_child = waitpid(-1, NULL, WNOHANG);
+   if (verbose)
+   {
+      printf("Caught child process: %d\n", (int) caught_child);
+      printf("%d\n", errno);
+   }
+   // If this was the one process we were watching, we can quit now.
+   if (caught_child == pid)
+   {
+      printf("Child process is finished, exiting...\n");
+      exit(0);
+   }
+}
+
 
 #ifdef FREEBSD
-//get jiffies count from /proc filesystem
 int getjiffies(int pid)
 {
    kvm_t *my_kernel = NULL;
@@ -359,6 +412,7 @@
 #endif
 
 #ifdef LINUX
+//get jiffies count from /proc filesystem
 int getjiffies(int pid) {
        static char stat[20];
        static char buffer[1024];
@@ -500,6 +554,248 @@
 
 
 
+#ifdef LINUX
+// This following functions are for detecting and limiting child
+// processes on Linux.
+
+// This function adds a new child process to our list of child processes.
+CHILD *Add_Child(CHILD *all_children, pid_t new_pid)
+{
+    CHILD *new_child = (CHILD *) calloc(sizeof(CHILD), 1);
+    CHILD *current;
+
+    if (! new_child)
+       return all_children;
+
+    new_child->next = NULL;
+    new_child->child = new_pid;
+    new_child->monitor = 0;
+
+    if (all_children)
+    {
+        current = all_children;
+        while (current->next)
+           current = current->next;
+        current->next = new_child;
+        return all_children;
+    }
+    else   // this is the first node
+       return new_child;
+}
+
+
+
+// This function removes a child PID node.
+CHILD *Remove_Child(CHILD *all_children, pid_t old_pid)
+{
+    CHILD *current, *previous = NULL;
+    int found = FALSE;
+
+    current = all_children;
+    while ( (! found) && (current) )
+    {
+        if (current->child == old_pid)
+        {
+           if (previous)
+               previous->next = current->next;
+           else
+             all_children = current->next;
+           
+           free(current);
+           found = TRUE;
+        }
+        else
+        {
+            previous = current;
+            current = current->next;
+        }
+     }
+     return all_children;
+}
+
+
+// This function cleans up all remaining child nodes.
+void Clean_Up_Children(CHILD *all_children)
+{
+   CHILD *current, *next;
+
+   current = all_children;
+   while (current)
+   {
+      next = current->next;
+      free(current);
+      current = next;
+   }
+}
+
+
+// This function searches the linked list for a matching PID.
+// It returns NULL if no match is found and a pointer to the
+// node is a match is located.
+CHILD *Find_Child(CHILD *children, pid_t target)
+{
+   CHILD *current;
+   int found = FALSE;
+
+   current = children;
+   while ( (!found) && (current) )
+   {
+      if (current->child == target)
+        found = TRUE;
+      else
+        current = current->next;
+   }
+   return current;
+}
+
+
+
+// This function returns a list of process IDs of children
+// of the given process (PID). It does this by searching the /proc
+// file system and looking in the /proc/pid/status file for the PPid field.
+// A linked list of child PIDs is returned on success or NULL on failure or
+// if no child PIDs are found.
+CHILD *Find_Child_PIDs(CHILD *all_children, pid_t parent_pid)
+{
+    int found = FALSE;
+    DIR *proc;
+    struct dirent *proc_entry;
+    char filename[PROC_FILENAME];
+    FILE *status_file;
+    char *reading_file;
+    char line[256];
+    pid_t new_ppid;
+    int current_pid;
+
+    proc = opendir("/proc");
+    if (! proc)
+       return all_children;
+
+    proc_entry = readdir(proc);
+    while (proc_entry)
+    {
+        snprintf(filename, PROC_FILENAME, "/proc/%s/status", 
proc_entry->d_name);
+        status_file = fopen(filename, "r");
+        if (status_file)
+        {
+           found = FALSE;
+           reading_file = fgets(line, LINE_LENGTH, status_file);
+           while ( (! found) && (reading_file) )
+           {
+             if (! strncmp(line, "PPid:", 5) )
+             {
+                 sscanf(&(line[6]), "%d", &new_ppid);
+                 if (new_ppid == parent_pid && current_pid != getpid() )
+                 {
+                     sscanf(proc_entry->d_name, "%d", &current_pid);
+                     if (! Find_Child(all_children, current_pid) )
+                        all_children = Add_Child(all_children, current_pid);
+                 }
+                 found = TRUE;
+             }
+             else
+                reading_file = fgets(line, LINE_LENGTH, status_file);
+           }   // done reading status file
+          
+           fclose(status_file);
+        }
+        proc_entry = readdir(proc);
+    }   // done reading proc file system
+    closedir(proc);
+    return all_children;
+}
+
+
+// This function (which should probably be called as a thread) monitors the
+// system for child processes of the current target process. When a new
+// child of the target is located, it is added to the CHILD list.
+// New children result in a new fork of this program being spawned to
+// monitor the child process and its children.
+
+void *Monitor_Children(void *all_data)
+{
+   CHILD *all_children = NULL;
+   CHILD *current;
+   PROGRAM_DATA *program_data = (PROGRAM_DATA *) all_data;
+
+   while (! quitting )
+   {
+      // Check for new child processes
+      all_children = Find_Child_PIDs(all_children, pid);
+
+      // Find any children without monitors and create a monitoring process
+      // Clean out old processes while we are looking
+      current = all_children;
+      while (current)
+      {
+         // First see if the child process is still running. If not,
+         // we can remote its node.
+         if (current->child)
+         {
+             char filename[PROC_FILENAME];
+             DIR *child_directory;
+             snprintf(filename, PROC_FILENAME, "/proc/%d", current->child);
+             child_directory = opendir(filename);
+             if (child_directory)
+                closedir(child_directory);
+             else
+             {
+                if (verbose)
+                  printf("Child process %d done, cleaning up.\n",
+                          (int) current->child);
+                all_children = Remove_Child(all_children, current->child);
+             }
+         }  // end of clean up children processes no longer running
+
+         // The child process is still running, but it might not have
+         // a monitor. Create a new monitoring process.
+         if ( (current->child) && (! current->monitor) )
+         {
+              pid_t returned_pid;
+
+              if (verbose)
+                 printf("Creating monitoring process for %d\n",
+                        (int) current->child);
+
+              returned_pid = fork();
+              if (returned_pid > 0)
+              {
+                 // parent
+                 current->monitor = returned_pid;
+              }
+              else if (returned_pid == 0)
+              {
+                 // child
+                 char limit_amount[16];
+                 char process_identifier[16];
+                 snprintf(limit_amount, 16, "%d", (int) program_data->limit);
+                 snprintf(process_identifier, 16, "%d", current->child);
+                 if (verbose)
+                    printf("Starting monitor with: %s -l %s -p %s -z -m\n",
+                            program_data->this_program, limit_amount,
+                            process_identifier);
+                 execl(program_data->this_program, program_data->this_program,
+                       "-l", limit_amount, "-p", process_identifier, 
+                       "-z", "-m", (char *) NULL);
+              }
+              
+         }    // end of creating a new monitor
+         if (verbose)
+         {
+             printf("Watching child: %d with %d\n", 
+                   (int) current->child, (int) current->monitor);
+         }
+         current = current->next;
+      }
+      sleep(1);
+   }  // end LimitCPU is still running
+   pthread_exit(NULL);
+}
+
+#endif       // end of monitoring children processes on Linux
+
+
+
 void print_usage(FILE *stream,int exit_code) {
         fprintf(stream, "CPUlimit version %1.1f\n", VERSION);
        fprintf(stream, "Usage: %s TARGET [OPTIONS...] [-- 
PROGRAM]\n",program_name);
@@ -512,10 +808,14 @@
         fprintf(stream, "                         executable program file\n");
        fprintf(stream, "   OPTIONS\n");
         fprintf(stream, "      -b  --background   run in background\n");
+        fprintf(stream, "      -f  --foreground   launch target process in 
foreground and wait for it to exit\n");
         fprintf(stream, "      -c  --cpu=N        override the detection of 
CPUs on the machine.\n");
        fprintf(stream, "      -l, --limit=N      percentage of cpu allowed 
from 1 up.\n");
         fprintf(stream, "                         Usually 1 - %d00, but can be 
higher\n", NCPU);
         fprintf(stream, "                         on multi-core CPUs 
(mandatory)\n");
+        #ifdef LINUX
+        fprintf(stream, "      -m, --monitor-forks  Watch children/forks of 
the target process\n");
+        #endif
         fprintf(stream, "      -q, --quiet        run in quiet mode (only 
print errors).\n");
         fprintf(stream, "      -k, --kill         kill processes going over 
their limit\n");
         fprintf(stream, "                         instead of just throttling 
them.\n");
@@ -585,7 +885,12 @@
        //parse arguments
        int next_option;
        /* A string listing valid short options letters. */
-       const char* short_options="p:e:P:l:c:s:bqkrvzh";
+        #ifdef LINUX
+       const char* short_options="p:e:P:l:c:s:bfqkmrvzh";
+        PROGRAM_DATA program_data;
+        #else
+       const char* short_options="p:e:P:l:c:s:bfqkrvzh";
+        #endif
        /* An array describing valid long options. */
        const struct option long_options[] = {
                { "pid", required_argument, NULL, 'p' },
@@ -593,17 +898,21 @@
                { "path", required_argument, NULL, 'P' },
                { "limit", required_argument, NULL, 'l' },
                 { "background", no_argument, NULL, 'b' },
+                { "foreground", no_argument, NULL, 'f' },
                 { "quiet", no_argument, NULL, 'q' },
                { "verbose", no_argument, NULL, 'v' },
                { "lazy", no_argument, NULL, 'z' },
                { "help", no_argument, NULL, 'h' },
                 { "cpu", required_argument, NULL, 'c'},
                 { "signal", required_argument, NULL, 's'},
+                #ifdef LINUX
+                { "monitor-forks", no_argument, NULL, 'm'},
+                #endif
                { NULL, 0, NULL, 0 }
        };
        //argument variables
        const char *exe=NULL;
-       const char *path=NULL;
+        const char *path=NULL;
        int perclimit=0;
        int pid_ok = FALSE;
        int process_ok = FALSE;
@@ -611,6 +920,8 @@
         int last_known_argument = 0;
         int kill_process = FALSE;   // kill process instead of stopping it
         int restore_process = FALSE;  // restore killed process
+        int run_child_in_background = TRUE;  // run cpulimit in background 
when 
+                                             //  we launch new process
         // struct rlimit maxlimit;
 
         NCPU = get_ncpu();
@@ -623,6 +934,11 @@
                                 run_in_background = TRUE;
                                 last_known_argument++;
                                 break;
+                        case 'f':
+                                run_child_in_background = FALSE;
+                                run_in_background = FALSE;
+                                last_known_argument++;
+                                break;
                        case 'p':
                                pid=atoi(optarg);
                                 if (pid)   // valid PID
@@ -663,6 +979,12 @@
                                 kill_process = TRUE;
                                 last_known_argument++;
                                 break;
+                        #ifdef LINUX
+                        case 'm':
+                                monitor_children = TRUE;
+                                last_known_argument++;
+                                break;
+                        #endif
                         case 'r':
                                 restore_process = TRUE;
                                 last_known_argument++;
@@ -699,6 +1021,7 @@
                }
        } while(next_option != -1);
 
+        signal(SIGCHLD, Child_Done);
 
         // try to launch a program passed on the command line
         // But only if we do not already have a PID to watch
@@ -737,39 +1060,34 @@
               // a running head start to avoid death at start-up
               if (kill_process)
                  sleep(5);
-     
-              limit_pid = fork();
-              if (limit_pid == 0)   // child
+    
+              /* The following block assumes we want to run cpulimit in the
+                 background. This is the default behaviour.
+              */ 
+              if (run_child_in_background)
               {
-                 pid = forked_pid;    // the first child
-                 lazy = TRUE;
-                 pid_ok = TRUE;
-                 if (verbose)
-                   printf("Throttling process %d\n", (int) pid);
-              }
-              else    // parent
-                exit(0);
-           }
+                 limit_pid = fork();
+                 if (limit_pid == 0)   // child cpulimit process running in 
background
+                 {
+                    pid = forked_pid;    // the first child, target process
+                    lazy = TRUE;
+                    pid_ok = TRUE;
+                    if (verbose)
+                      printf("Throttling process %d\n", (int) pid);
+                 }
+                 else    // parent cpulimit process which can quit
+                   exit(0);
+              }  // end of running in background
+              else
+              {
+                  pid = forked_pid;
+                  lazy = TRUE;
+                  pid_ok = TRUE;
+                  run_in_background = FALSE;
+              }  // end of running in foreground
+
+           }  // end of parent that launched target
 
-           /*
-           else if (forked_pid == 0)   // child
-           {
-               lazy = TRUE;
-               pid_ok = TRUE;
-               pid = getppid();
-               if (verbose)
-                  printf("Throttling process %d\n", (int) pid);
-           }
-           else // parent
-           {
-               execvp(argv[last_known_argument], 
-                      &(argv[last_known_argument]));
-               
-               // we should never return  
-               exit(2);
-           }
-           */
-           
         }      // end of launching child process
 
        if (!process_ok && !pid_ok) {
@@ -820,50 +1138,6 @@
            printf("%d CPUs detected.\n", NCPU);
 
         increase_priority();
-/*
-Instead of all this big block of code to detect and change
-priority settings, let us just use the increase_priority()
-function. It is a little more simple and takes a more
-gradual approach, rather than "all or nothing".
--- Jesse
-
-       if (setpriority(PRIO_PROCESS, my_pid,-20)!=0) {
-       //if that failed, check if we have a limit 
-        // by how much we can raise the priority
-#ifdef RLIMIT_NICE 
-//check if non-root can even make changes 
-// (ifdef because it's only available in linux >= 2.6.13)
-               nice_lim=getpriority(PRIO_PROCESS, my_pid);
-               getrlimit(RLIMIT_NICE, &maxlimit);
-
-//if we can do better then current
-               if( (20 - (signed)maxlimit.rlim_cur) < nice_lim &&  
-                   setpriority(PRIO_PROCESS, my_pid,
-                    20 - (signed)maxlimit.rlim_cur)==0 //and it actually works
-                 ) {
-
-                       //if we can do better, but not by much, warn about it
-                       if( (nice_lim - (20 - (signed)maxlimit.rlim_cur)) < 9) 
-                        {
-                       printf("Warning, can only increase priority by %d.\n",  
                              nice_lim - (20 - (signed)maxlimit.rlim_cur));
-                       }
-                        //our new limit
-                       nice_lim = 20 - (signed)maxlimit.rlim_cur; 
-
-               } else 
-// otherwise don't try to change priority. 
-// The below will also run if it's not possible 
-// for non-root to change priority
-#endif
-               {
-                       printf("Warning: cannot renice.\nTo work better you 
should run this program as root, or adjust RLIMIT_NICE.\nFor example in 
/etc/security/limits.conf add a line with: * - nice -10\n\n");
-                       nice_lim=INT_MAX;
-               }
-       } else {
-               nice_lim=-20;
-       }
-*/
-
 
        //time quantum in microseconds. it's splitted in a working period and a 
sleeping one
        int period=100000;
@@ -896,6 +1170,23 @@
 
        float pcpu_avg=0;
 
+        // On Linux we can monitor child processes of the target
+        #ifdef LINUX
+        if (monitor_children)
+        {
+           pthread_t my_thread;
+           int thread_status;
+           if (verbose)
+              printf("Starting fork monitoring thread...\n");
+           program_data.this_program = argv[0];
+           program_data.limit = perclimit;
+           thread_status = pthread_create(&my_thread, NULL, 
+                                          Monitor_Children, &program_data);
+           if ( (thread_status) && (verbose) )
+              printf("Creating fork monitoring thread failed.\n");
+        }
+        #endif
+
        //here we should already have high priority, for time precision
        while(1) {
 
@@ -945,9 +1236,9 @@
                         // printf("Continue\n");
                        //resume process
                        if (kill(pid,SIGCONT)!=0) {
-                if (!quiet)
+                             if (!quiet)
                                fprintf(stderr,"Process %d dead!\n",pid);
-                               if (lazy) exit(2);
+                            if (lazy) exit(2);
                                //wait until our process appears
                                goto wait_for_process;
                        }
@@ -1024,16 +1315,16 @@
                              }
                          }
                      }
-                     // do not kll process, just throttle it
+                     // do not kill process, just throttle it
                      else
                      {
 
                         // printf("Stop\n");
                        //stop process, it has worked enough
                        if (kill(pid,SIGSTOP)!=0) {
-                if (!quiet)
+                            if (!quiet)
                                fprintf(stderr,"Process %d dead!\n", pid);
-                               if (lazy) exit(2);
+                           if (lazy) exit(2);
                                //wait until our process appears
                                goto wait_for_process;
                        }


Reply via email to