]> granicus.if.org Git - icinga2/commitdiff
Bugfixes.
authorGunnar Beutner <gunnar@beutner.name>
Sun, 24 Jun 2012 16:44:07 +0000 (18:44 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Sun, 24 Jun 2012 18:11:10 +0000 (20:11 +0200)
22 files changed:
base/tlsclient.cpp
icinga/nagioschecktask.cpp
icinga/nagioschecktask.h
third-party/popen-noshell/README
third-party/popen-noshell/performance_tests/fork-performance [deleted file]
third-party/popen-noshell/performance_tests/fork-performance.c [deleted file]
third-party/popen-noshell/performance_tests/popen_noshell.c [deleted symlink]
third-party/popen-noshell/performance_tests/popen_noshell.h [deleted symlink]
third-party/popen-noshell/performance_tests/run-tests.pl [deleted file]
third-party/popen-noshell/performance_tests/tiny/freebsd/make.sh [deleted file]
third-party/popen-noshell/performance_tests/tiny/freebsd/system.inc [deleted file]
third-party/popen-noshell/performance_tests/tiny/freebsd/tiny.asm [deleted file]
third-party/popen-noshell/performance_tests/tiny/freebsd/tiny2 [deleted file]
third-party/popen-noshell/performance_tests/tiny/linux/make.sh [deleted file]
third-party/popen-noshell/performance_tests/tiny/linux/tiny2 [deleted file]
third-party/popen-noshell/performance_tests/tiny/linux/tiny2.asm [deleted file]
third-party/popen-noshell/performance_tests/tiny2 [deleted symlink]
third-party/popen-noshell/popen_noshell.c
third-party/popen-noshell/popen_noshell.h
third-party/popen-noshell/popen_noshell_examples.c [deleted file]
third-party/popen-noshell/popen_noshell_tests.c [deleted file]
third-party/popen-noshell/popen_noshell_tests.cpp [deleted file]

index 3ac84a96ec1bc2c69d08dff30944216cd381e44b..4c63a9f7ebd5fd485e32a259b633765cafe6f70b 100644 (file)
@@ -246,8 +246,6 @@ int TlsClient::SSLVerifyCertificate(int ok, X509_STORE_CTX *x509Context)
        SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(x509Context, SSL_get_ex_data_X509_STORE_CTX_idx());
        TlsClient *client = (TlsClient *)SSL_get_ex_data(ssl, m_SSLIndex);
 
-       assert(client->GetMutex().active_count);
-
        if (client == NULL)
                return 0;
 
index 800dca309cd3e98cb3ff6fe42c1165d6d8299655..64f20c1772cbb7503aa0faacc6c4f1c2fabb48f4 100644 (file)
@@ -44,10 +44,10 @@ void NagiosCheckTask::CheckThreadProc(void)
        mutex::scoped_lock lock(m_Mutex);
 
        map<int, NagiosCheckTask::Ptr> tasks;
-       const int maxTasks = 16;
+       const int maxTasks = 128;
 
        for (;;) {
-               while (m_Tasks.empty() || tasks.size() >= maxTasks) {
+               while (m_Tasks.empty() || tasks.size() >= MaxChecksPerThread) {
                        lock.unlock();
 
                        map<int, NagiosCheckTask::Ptr>::iterator it, prev;
@@ -202,7 +202,10 @@ void NagiosCheckTask::Register(void)
 {
        CheckTask::RegisterType("nagios", NagiosCheckTask::CreateTask, NagiosCheckTask::FlushQueue);
 
-       int numThreads = max(4, boost::thread::hardware_concurrency());
+       int numThreads = boost::thread::hardware_concurrency();
+
+       if (numThreads < 4)
+               numThreads = 4;
 
        for (int i = 0; i < numThreads; i++) {
                thread t(&NagiosCheckTask::CheckThreadProc);
index 16141857dbb8e2dd737d441055c8f897c7281f32..55643eb16685582f6e2f7392b008b0fa6e38d81a 100644 (file)
@@ -10,6 +10,8 @@ public:
        typedef shared_ptr<NagiosCheckTask> Ptr;
        typedef weak_ptr<NagiosCheckTask> WeakPtr;
 
+       static const int MaxChecksPerThread = 128;
+
        NagiosCheckTask(const Service& service);
 
        virtual void Enqueue(void);
index 586f8781daafde69c2d37dac63933f256f37939b..7a7d4753f93a000943eed80f96a5c1a217541f1e 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * popen_noshell: A faster implementation of popen() and system() for Linux.
  * Copyright (c) 2009 Ivan Zahariev (famzah)
+ * Copyright (c) 2012 Gunnar Beutner
  * Version: 1.0
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,9 +23,5 @@ The package provides the following files:
        * The C implementation of the library:
                popen_noshell.c
                popen_noshell.h
-       * Examples:
-               popen_noshell_examples.c
-       * Unit tests:
-               popen_noshell_tests.c
 
 Compile instructions are included in each file.
diff --git a/third-party/popen-noshell/performance_tests/fork-performance b/third-party/popen-noshell/performance_tests/fork-performance
deleted file mode 100755 (executable)
index 7a3d8ba..0000000
Binary files a/third-party/popen-noshell/performance_tests/fork-performance and /dev/null differ
diff --git a/third-party/popen-noshell/performance_tests/fork-performance.c b/third-party/popen-noshell/performance_tests/fork-performance.c
deleted file mode 100644 (file)
index f9d577b..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * popen_noshell: A faster implementation of popen() and system() for Linux.
- * Copyright (c) 2009 Ivan Zahariev (famzah)
- * Version: 1.0
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses>.
- */
-
-#include <unistd.h>
-#include <err.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-#include <ctype.h>
-#include "popen_noshell.h"
-
-/*
- * This is a performance test program.
- * It invokes the extremely light, statically build binary "./tiny2" which outputs "Hello, world!" and exits.
- *
- * Different approaches for calling "./tiny2" are tried, in order to compare their performance results.
- *
- */
-
-#define USE_LIBC_POPEN 0
-#define USE_NOSHELL_POPEN 1
-
-int use_noshell_compat = 0;
-
-void popen_test(int type) {
-       char *exec_file = "./tiny2";
-       char *arg1 = (char *) NULL;
-       char *argv[] = {exec_file, arg1};
-       FILE *fp;
-       struct popen_noshell_pass_to_pclose pclose_arg;
-       int status;
-       char buf[64];
-
-       if (type) {
-               if (!use_noshell_compat) {
-                       fp = popen_noshell(exec_file, (const char * const *)argv, "r", &pclose_arg, 0);
-               } else {
-                       fp = popen_noshell_compat(exec_file, "r", &pclose_arg);
-                       argv[0] = NULL; // satisfy GCC warnings
-               }
-       } else {
-               fp = popen("./tiny2", "r");
-       }
-       if (!fp) {
-               err(EXIT_FAILURE, "popen()");
-       }
-
-       while (fgets(buf, sizeof(buf)-1, fp)) {
-               if (strcmp(buf, "Hello, world!\n") != 0) {
-                       errx(EXIT_FAILURE, "bad response: %s", buf);
-               }
-       }
-
-       if (type) {
-               status = pclose_noshell(&pclose_arg);
-       } else {
-               status = pclose(fp);
-       }
-       if (status == -1) {
-               err(EXIT_FAILURE, "pclose()");
-       }
-       if (status != 0) {
-               errx(EXIT_FAILURE, "status code is non-zero");
-       }
-}
-
-void fork_test(int type) {
-       pid_t pid;
-       int status;
-
-       if (type) {
-               pid = fork();
-       } else {
-               pid = vfork();
-       }
-       if (pid == -1) {
-               err(EXIT_FAILURE, "fork()");
-       }
-
-       if (pid == 0) { // child
-               execl("./tiny2", "./tiny2", (char *) NULL);
-               _exit(255);
-       }
-
-       // parent process
-       if (waitpid(pid, &status, 0) != pid) {
-               err(EXIT_FAILURE, "waitpid()");
-       }
-       if (status != 0) {
-               errx(EXIT_FAILURE, "status code is non-zero");
-       }
-}
-
-char *allocate_memory(int size_in_mb, int ratio) {
-       char *m;
-       int size;
-       int i;
-
-       size = size_in_mb*1024*1024;
-       m = malloc(sizeof(char) * size);
-       if (!m) {
-               err(EXIT_FAILURE, "malloc()");
-       }
-
-       /* allocate part of the memory, so that we can simulate some memory activity before fork()'ing */
-       if (ratio != 0) {
-               for (i = 0; i < size/ratio; ++i) {
-                       *(m + i) = 'z';
-               }
-       }
-
-       return m;
-}
-
-int safe_atoi(char *s) {
-       int i;
-
-       if (strlen(s) == 0) {
-               errx(EXIT_FAILURE, "safe_atoi(): String is empty");
-       }
-
-       for (i = 0; i < strlen(s); ++i) {
-               if (!isdigit(s[i])) {
-                       errx(EXIT_FAILURE, "safe_atoi(): Non-numeric characters found in string '%s'", s);
-               }
-       }
-
-       return atoi(s);
-}
-
-void parse_argv(int argc, char **argv, int *count, int *allocated_memory_size_in_mb, int *allocated_memory_usage_ratio, int *test_mode) {
-       const struct option long_options[] = {
-               {"count", 1, 0, 1},
-               {"memsize", 1, 0, 2},
-               {"ratio", 1, 0, 3},
-               {"mode", 1, 0, 4},
-               {0, 0, 0, 0}
-       };
-       int c;
-       int usage = 0;
-       int got[4];
-       int optarg_int;
-
-       memset(&got, 0, sizeof(got));
-       while (1) {
-               c = getopt_long(argc, argv, "", &long_options[0], NULL);
-               if (c == -1) { // no more arguments
-                       break;
-               }
-
-               if (c >= 1 && c <= sizeof(got)/sizeof(int)) {
-                       got[c-1] = 1;
-               }
-
-               if (!optarg) {
-                       warnx("You provided no value");
-                       usage = 1;
-                       break;
-               }
-               optarg_int = safe_atoi(optarg);
-
-               switch (c) {
-                       case 1:
-                               *count = optarg_int;
-                               break;
-                       case 2:
-                               *allocated_memory_size_in_mb = optarg_int;
-                               break;
-                       case 3:
-                               *allocated_memory_usage_ratio = optarg_int;
-                               break;
-                       case 4:
-                               *test_mode = optarg_int;
-                               break;
-                       default:
-                               warnx("Bad option");
-                               usage = 1;
-                               break;
-               }
-
-               if (usage) {
-                       break;
-               }
-       }
-
-       for (c = 0; c < sizeof(got)/sizeof(int); ++c) {
-               if (!got[c]) {
-                       warnx("Option #%d not specified", c);
-                       usage = 1;
-               }
-       }
-
-       if (usage) {
-               warnx("Usage: %s ...options - all are required...\n", argv[0]);
-               warnx("\t--count\n\t--memsize [MBytes]\n\t--ratio [0..N, 0=no_usage_of_memory]\n\t--mode [0..7]\n");
-               exit(EXIT_FAILURE);
-       }
-}
-
-int main(int argc, char **argv) {
-       int count;
-       char *m;
-       int allocated_memory_size_in_mb;
-       int allocated_memory_usage_ratio;
-       int test_mode;
-       int wrote = 0;
-
-       count = 30000;
-       allocated_memory_size_in_mb = 20;
-       allocated_memory_usage_ratio = 2; /* the memory usage is 1 divided by the "allocated_memory_usage_ratio", use 0 for "no usage" at all */
-       test_mode = 5;
-
-       parse_argv(argc, argv, &count, &allocated_memory_size_in_mb, &allocated_memory_usage_ratio, &test_mode);
-
-       m = allocate_memory(allocated_memory_size_in_mb, allocated_memory_usage_ratio);
-
-       warnx("Test options: count=%d, memsize=%d, ratio=%d, mode=%d", count, allocated_memory_size_in_mb, allocated_memory_usage_ratio, test_mode);
-
-       while (count--) {
-               switch (test_mode) {
-                       /* the following fork + exec calls do not return the output of their commands */
-                       case 0:
-                               if (!wrote) warnx("fork() + exec(), standard Libc");
-                               fork_test(1);
-                               break;
-                       case 1:
-                               if (!wrote) warnx("vfork() + exec(), standard Libc");
-                               fork_test(0);
-                               break;
-                       case 2:
-                               if (!wrote) warnx("system(), standard Libc");
-                               system("./tiny2 >/dev/null");
-                               break;
-
-                       /* all the below popen() use-cases are tested if they return the correct string in *fp */
-                       case 3:
-                               if (!wrote) warnx("popen(), standard Libc");
-                               popen_test(USE_LIBC_POPEN);
-                               break;
-                       case 4:
-                               use_noshell_compat = 0;
-                               if (!wrote) warnx("the new noshell, debug fork(), compat=%d", use_noshell_compat);
-                               popen_noshell_set_fork_mode(POPEN_NOSHELL_MODE_FORK);
-                               popen_test(USE_NOSHELL_POPEN);
-                               break;
-                       case 5:
-                               use_noshell_compat = 0;
-                               if (!wrote) warnx("the new noshell, default vfork(), compat=%d", use_noshell_compat);
-                               popen_noshell_set_fork_mode(POPEN_NOSHELL_MODE_CLONE);
-                               popen_test(USE_NOSHELL_POPEN);
-                               break;
-                       case 6:
-                               use_noshell_compat = 1;
-                               if (!wrote) warnx("the new noshell, debug fork(), compat=%d", use_noshell_compat);
-                               popen_noshell_set_fork_mode(POPEN_NOSHELL_MODE_FORK);
-                               popen_test(USE_NOSHELL_POPEN);
-                               break;
-                       case 7:
-                               use_noshell_compat = 1;
-                               if (!wrote) warnx("the new noshell, default vfork(), compat=%d", use_noshell_compat);
-                               popen_noshell_set_fork_mode(POPEN_NOSHELL_MODE_CLONE);
-                               popen_test(USE_NOSHELL_POPEN);
-                               break;
-                       default:
-                               errx(EXIT_FAILURE, "Bad mode");
-                               break;
-               }
-               wrote = 1;
-       }
-
-       return 0;
-}
diff --git a/third-party/popen-noshell/performance_tests/popen_noshell.c b/third-party/popen-noshell/performance_tests/popen_noshell.c
deleted file mode 120000 (symlink)
index 10c53de..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../popen_noshell.c
\ No newline at end of file
diff --git a/third-party/popen-noshell/performance_tests/popen_noshell.h b/third-party/popen-noshell/performance_tests/popen_noshell.h
deleted file mode 120000 (symlink)
index 4dc8458..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../popen_noshell.h
\ No newline at end of file
diff --git a/third-party/popen-noshell/performance_tests/run-tests.pl b/third-party/popen-noshell/performance_tests/run-tests.pl
deleted file mode 100755 (executable)
index 00a2028..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-#!/usr/bin/perl
-# popen_noshell: A faster implementation of popen() and system() for Linux.
-# Copyright (c) 2009 Ivan Zahariev (famzah)
-# Version: 1.0
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; under version 3 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses>.
-use strict;
-use warnings;
-
-use Data::Dumper;
-
-my $count = 10000;
-my $memsize = 20;
-my $ratio = 2;
-my $allowed_deviation = 20; # +/- percent
-my $repeat_tests = 3;
-my $uname_args = '-s -r -m'; # or just "-a" :)
-
-my $s;
-my @lines;
-my $line;
-my $i;
-my $options;
-my $caption;
-my $user_t;
-my $sys_t;
-my %results;
-my $k;
-my $mode;
-my $avg_user_t;
-my $avg_sys_t;
-my $success;
-my @sheet = ();
-
-sub parse_die($$) {
-       my ($i, $line) = @_;
-       die("Unable to parse line $i: $line");
-}
-
-if ($repeat_tests < 2) {
-       die('repeat_tests must be at least 2');
-}
-
-$options = undef;
-print "The tests are being performed, this will take some time...\n\n";
-for $mode (0..7) {
-       print(('-'x80)."\n\n");
-       for (1..$repeat_tests) {
-               $s = `gcc -Wall fork-performance.c popen_noshell.c -o fork-performance && time ./fork-performance --count=$count --memsize=$memsize --ratio=$ratio --mode=$mode 2>&1 >/dev/null`;
-               print "$s\n";
-
-               @lines = split(/\n/, $s);
-               $i = 0;
-               $caption = $user_t = $sys_t = undef;
-               foreach $line (@lines) {
-                       ++$i;
-                       if ($i == 1) {
-                               if ($line =~ /^fork-performance: Test options: (.+), mode=\d+$/) {
-                                       if (!defined($options)) {
-                                               $options = $1;
-                                       } else {
-                                               if ($options ne $1) {
-                                                       die("Parsed options is not the same: $options vs. $1");
-                                               }
-                                       }
-                               } else {
-                                       parse_die($i, $line);
-                               }
-                       } elsif ($i == 2) {
-                               if ($line =~ /^fork-performance: (.+)$/) {
-                                       $caption = $1;
-                               } else {
-                                       parse_die($i, $line);
-                               }
-                       } elsif ($i == 3) {
-                               if ($line =~ /(\d+.\d+)\s?user\s+(\d+.\d+)\s?sys(?:tem)?/) {
-                                       $user_t = $1;
-                                       $sys_t = $2;
-                               } else {
-                                       parse_die($i, $line);
-                               }
-                       } elsif ($i == 4) {
-                               # noop
-                       } else {
-                               parse_die($i, $line);
-                       }
-               }
-               if (!defined($options) || !defined($caption) || !defined($user_t) || !defined($sys_t)) {
-                       die('Parsing failed');
-               }
-               $k = $caption;
-               if (!exists($results{$k})) {
-                       $results{$k} = [];
-               }
-               push(@{$results{$k}}, [$user_t, $sys_t]);
-       }
-}
-
-sub print_deviation($$$) {
-       my ($label, $val, $avg_val) = @_;
-       my $deviation;
-       my $retval = 1;
-
-       if ($avg_val == 0) {
-               $deviation = '?? ';
-               $retval = 0;
-       } else {
-               $deviation = (($val / $avg_val) - 1) * 100;
-               $deviation = sprintf('%.0f', $deviation);
-               if (abs($deviation) > $allowed_deviation) {
-                       $retval = 0;
-               }
-       }
-
-       printf("\t%s: %s (%4s%%)%s\n", $label, $val, $deviation, ($retval == 0 ? ' BAD VALUE' : ''));
-
-       return $retval;
-}
-
-$success = 1;
-print("\n\n".('-'x80)."\n");
-print "RAW PERFORMANCE TESTS RESULTS\n";
-print(('-'x80)."\n");
-foreach $k (keys %results) {
-       $avg_user_t = 0;
-       $avg_sys_t = 0;
-       $i = 0;
-       foreach (@{$results{$k}}) {
-               ($user_t, $sys_t) = @{$_};
-               $avg_user_t += $user_t;
-               $avg_sys_t += $sys_t;
-               ++$i;
-       }
-       if ($i != $repeat_tests) {
-               die("Sanity check failed for count: $count vs. $i");
-       }
-       $avg_user_t /= $i;
-       $avg_sys_t  /= $i;
-       $avg_user_t = sprintf('%.2f', $avg_user_t);
-       $avg_sys_t = sprintf('%.2f', $avg_sys_t);
-
-       $s = sprintf("%s | avg_user_t | %s | avg_sys_t | %s | total_t | %s\n", $k, $avg_user_t, $avg_sys_t, ($avg_user_t + $avg_sys_t));
-       push(@sheet, $s);
-       print $s;
-
-       foreach (@{$results{$k}}) {
-               ($user_t, $sys_t) = @{$_};
-
-               $success &= print_deviation('user_t', $user_t, $avg_user_t);
-               $success &= print_deviation('sys_t ', $sys_t, $avg_sys_t);
-       }
-}
-
-print("\n\n".('-'x80)."\n");
-print "PERFORMANCE TESTS REPORT\n";
-print(('-'x80)."\n");
-print "System and setup:\n\t | ".`uname $uname_args`."\t | $options\n";
-print "Here is the data for the graphs:\n";
-foreach (@sheet) {
-       print "\t | ".$_;
-}
-print(('-'x80)."\n");
-
-if (!$success) {
-       print "\nWARNING! Some of the measurements were not accurate enough!\n";
-       print "It is recommended that you re-run the test having the following in mind:\n";
-       print "\t* the machine must be idle and not busy with other tasks\n";
-       print "\t* increase the 'count' to a larger number to have more accurate results\n";
-       print "\t* it is recommended that 'count' is so big, that the user/sys average time is at least bigger than 1.00\n";
-}
diff --git a/third-party/popen-noshell/performance_tests/tiny/freebsd/make.sh b/third-party/popen-noshell/performance_tests/tiny/freebsd/make.sh
deleted file mode 100755 (executable)
index 2cbc393..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-nasm -f elf tiny.asm
-ld -s -o tiny2 tiny.o
diff --git a/third-party/popen-noshell/performance_tests/tiny/freebsd/system.inc b/third-party/popen-noshell/performance_tests/tiny/freebsd/system.inc
deleted file mode 100644 (file)
index d2345d7..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-%define stdin   0
-%define stdout  1
-%define stderr  2
-
-%define    SYS_nosys   0
-%define SYS_exit    1
-%define SYS_fork    2
-%define SYS_read    3
-%define SYS_write   4
-
-section    .text
-align 4
-access.the.bsd.kernel:
-    int 80h
-    ret
-
-%macro system  1
-    mov eax, %1
-    call    access.the.bsd.kernel
-%endmacro
-
-%macro sys.exit    0
-    system  SYS_exit
-%endmacro
-
-%macro  sys.fork    0
-    system  SYS_fork
-%endmacro
-
-%macro  sys.read    0
-    system  SYS_read
-%endmacro
-
-%macro  sys.write   0
-    system  SYS_write
-%endmacro
-
diff --git a/third-party/popen-noshell/performance_tests/tiny/freebsd/tiny.asm b/third-party/popen-noshell/performance_tests/tiny/freebsd/tiny.asm
deleted file mode 100644 (file)
index ef90704..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-; http://www.freebsd.org/doc/en/books/developers-handbook/x86-first-program.html
-
-   %include    'system.inc'
-
-section .data
-hello   db  'Hello, world!', 0Ah
-hbytes  equ $-hello
-
-section .text
-global  _start
-_start:
-push    dword hbytes
-push    dword hello
-push    dword stdout
-sys.write
-
-push    dword 0
-sys.exit
diff --git a/third-party/popen-noshell/performance_tests/tiny/freebsd/tiny2 b/third-party/popen-noshell/performance_tests/tiny/freebsd/tiny2
deleted file mode 100755 (executable)
index 93656c5..0000000
Binary files a/third-party/popen-noshell/performance_tests/tiny/freebsd/tiny2 and /dev/null differ
diff --git a/third-party/popen-noshell/performance_tests/tiny/linux/make.sh b/third-party/popen-noshell/performance_tests/tiny/linux/make.sh
deleted file mode 100755 (executable)
index 4524164..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-nasm -f elf tiny2.asm && ld -s -o tiny2 tiny2.o
diff --git a/third-party/popen-noshell/performance_tests/tiny/linux/tiny2 b/third-party/popen-noshell/performance_tests/tiny/linux/tiny2
deleted file mode 100755 (executable)
index 3893c34..0000000
Binary files a/third-party/popen-noshell/performance_tests/tiny/linux/tiny2 and /dev/null differ
diff --git a/third-party/popen-noshell/performance_tests/tiny/linux/tiny2.asm b/third-party/popen-noshell/performance_tests/tiny/linux/tiny2.asm
deleted file mode 100644 (file)
index 99d1754..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-; Compile with: nasm -f elf tiny2.asm && ld -s -o tiny2 tiny2.o
-;
-; Resource: http://www.faqs.org/docs/Linux-HOWTO/Assembly-HOWTO.html#AEN853
-
-section .data                          ;section declaration
-
-msg     db      "Hello, world!",0xa    ;our dear string
-len     equ     $ - msg                 ;length of our dear string
-
-section .text                          ;section declaration
-
-                       ;we must export the entry point to the ELF linker or
-    global _start      ;loader. They conventionally recognize _start as their
-                       ;entry point. Use ld -e foo to override the default.
-
-_start:
-
-;write our string to stdout
-
-        mov     edx,len ;third argument: message length
-        mov     ecx,msg ;second argument: pointer to message to write
-        mov     ebx,1   ;first argument: file handle (stdout)
-        mov     eax,4   ;system call number (sys_write)
-        int     0x80   ;call kernel
-
-;and exit
-
-       mov     ebx,0   ;first syscall argument: exit code
-        mov     eax,1   ;system call number (sys_exit)
-        int     0x80   ;call kernel
diff --git a/third-party/popen-noshell/performance_tests/tiny2 b/third-party/popen-noshell/performance_tests/tiny2
deleted file mode 120000 (symlink)
index e22eb9b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tiny/linux/tiny2
\ No newline at end of file
index 3125144298b40600fc01983dc53e22f74693683e..737c6049038f89825a9143b830eba587b6aa1947 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * popen_noshell: A faster implementation of popen() and system() for Linux.
  * Copyright (c) 2009 Ivan Zahariev (famzah)
+ * Copyright (c) 2012 Gunnar Beutner
  * Version: 1.0
  *
  * This program is free software; you can redistribute it and/or modify
 #include <stdlib.h>
 #include <inttypes.h>
 
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sched.h>
-#include <linux/sched.h>
-
 /*
  * Wish-list:
  *     1) Make the "ignore_stderr" parameter a mode - ignore, leave unchanged, redirect to stdout (the last is not implemented yet)
                _exit(EVAL); \
        }
 
-int _popen_noshell_fork_mode = POPEN_NOSHELL_MODE_CLONE;
-
-void popen_noshell_set_fork_mode(int mode) { // see "popen_noshell.h" POPEN_NOSHELL_MODE_* constants
-       _popen_noshell_fork_mode = mode;
-}
-
 int popen_noshell_reopen_fd_to_dev_null(int fd) {
        int dev_null_fd;
 
@@ -80,7 +69,7 @@ int popen_noshell_reopen_fd_to_dev_null(int fd) {
        return 0;
 }
 
-int _popen_noshell_close_and_dup(int pipefd[2], int closed_pipefd, int target_fd) {
+static int popen_noshell_close_and_dup(int pipefd[2], int closed_pipefd, int target_fd) {
        int dupped_pipefd;
 
        dupped_pipefd = (closed_pipefd == 0 ? 1 : 0); // get the FD of the other end of the pipe
@@ -102,25 +91,10 @@ int _popen_noshell_close_and_dup(int pipefd[2], int closed_pipefd, int target_fd
        return 0;
 }
 
-void _pclose_noshell_free_clone_arg_memory(struct popen_noshell_clone_arg *func_args) {
-       char **cmd_argv;
-
-       free((char *)func_args->file);
-       cmd_argv = (char **)func_args->argv;
-       while (*cmd_argv) {
-               free(*cmd_argv);
-               ++cmd_argv;
-       }
-       free((char **)func_args->argv);
-       free(func_args);
-}
-
-void _popen_noshell_child_process(
-       /* We need the pointer *arg_ptr only to free whatever we reference if exec() fails and we were fork()'ed (thus memory was copied),
-        * not clone()'d */
-       struct popen_noshell_clone_arg *arg_ptr, /* NULL if we were called by pure fork() (not because of Valgrind) */
-       int pipefd_0, int pipefd_1, int read_pipe, int ignore_stderr, const char *file, const char * const *argv) {
-
+static void popen_noshell_child_process(
+       int pipefd_0, int pipefd_1,
+       int read_pipe, int ignore_stderr,
+       const char *file, const char * const *argv) {
        int closed_child_fd;
        int closed_pipe_fd;
        int dupped_child_fd;
@@ -142,8 +116,8 @@ void _popen_noshell_child_process(
        if (popen_noshell_reopen_fd_to_dev_null(closed_child_fd) != 0) {
                _ERR(255, "popen_noshell_reopen_fd_to_dev_null(%d)", closed_child_fd);
        }
-       if (_popen_noshell_close_and_dup(pipefd, closed_pipe_fd, dupped_child_fd) != 0) {
-               _ERR(255, "_popen_noshell_close_and_dup(%d ,%d)", closed_pipe_fd, dupped_child_fd);
+       if (popen_noshell_close_and_dup(pipefd, closed_pipe_fd, dupped_child_fd) != 0) {
+               _ERR(255, "popen_noshell_close_and_dup(%d ,%d)", closed_pipe_fd, dupped_child_fd);
        }
 
        execvp(file, (char * const *)argv);
@@ -152,14 +126,6 @@ void _popen_noshell_child_process(
 
        warn("exec(\"%s\") inside the child", file);
 
-#ifdef POPEN_NOSHELL_VALGRIND_DEBUG
-       if (arg_ptr) { /* not NULL if we were called by clone() */
-               /* but Valgrind does not support clone(), so we were actually called by fork(), thus memory was copied... */
-               /* free this copied memory; if it was not Valgrind, this memory would have been shared and would belong to the parent! */
-               _pclose_noshell_free_clone_arg_memory(arg_ptr);
-       }
-#endif
-
        if (fflush(stdout) != 0) _ERR(255, "fflush(stdout)");
        if (fflush(stderr) != 0) _ERR(255, "fflush(stderr)");
        close(STDIN_FILENO);
@@ -169,15 +135,6 @@ void _popen_noshell_child_process(
        _exit(255); // call _exit() and not exit(), or you'll have troubles in C++
 }
 
-int popen_noshell_child_process_by_clone(void *raw_arg) {
-       struct popen_noshell_clone_arg *arg;
-
-       arg = (struct popen_noshell_clone_arg *)raw_arg;
-       _popen_noshell_child_process(arg, arg->pipefd_0, arg->pipefd_1, arg->read_pipe, arg->ignore_stderr, arg->file, arg->argv);
-
-       return 0;
-}
-
 char ** popen_noshell_copy_argv(const char * const *argv_orig) {
        int size = 1; /* there is at least one NULL element */
        char **argv;
@@ -206,69 +163,6 @@ char ** popen_noshell_copy_argv(const char * const *argv_orig) {
        return argv_new;
 }
 
-/*
- * Similar to vfork() and threading.
- * Starts a process which behaves like a thread (shares global variables in memory with the parent) but
- * has a different PID and can call exec(), unlike traditional threads which are not allowed to call exec().
- *
- * This fork function is very resource-light because it does not copy any memory from the parent, but shares it.
- *
- * Like standard threads, you have to provide a start function *fn and arguments to it *arg. The life of the
- * new vmfork()'ed process starts from this function.
- *
- * After you have reaped the child via waitpid(), you have to free() the memory at "*memory_to_free_on_child_exit".
- *
- * When the *fn function returns, the child process terminates.  The integer returned by *fn is the exit code for the child process.
- * The child process may also terminate explicitly by calling exit(2) or after receiving a fatal signal.
- *
- * Returns -1 on error. On success returns the PID of the newly created child.
- */
-pid_t popen_noshell_vmfork(int (*fn)(void *), void *arg, void **memory_to_free_on_child_exit) {
-               void *stack, *stack_aligned;
-               pid_t pid;
-
-               stack = malloc(POPEN_NOSHELL_STACK_SIZE + 15);
-               if (!stack) return -1;
-               *memory_to_free_on_child_exit = stack;
-
-               /*
-                * On all supported Linux platforms the stack grows down, except for HP-PARISC.
-                * You can grep the kernel source for "STACK_GROWSUP", in order to get this information.
-                */
-               // stack grows down, set pointer at the end of the block
-               stack_aligned = (void *) ((char * /*byte*/)stack + POPEN_NOSHELL_STACK_SIZE/*bytes*/);
-
-               /*
-                * On all supported platforms by GNU libc, the stack is aligned to 16 bytes, except for the SuperH platform which is aligned to 8 bytes.
-                * You can grep the glibc source for "STACK_ALIGN", in order to get this information.
-                */
-               stack_aligned = (void *) ( ((uintptr_t)stack_aligned+15) & ~ 0x0F ); // align to 16 bytes
-
-               /*
-                * Maybe we could have used posix_memalign() here...
-                * Our implementation seems a bit more portable though - I've read somewhere that posix_memalign() is not supported on all platforms.
-                * The above malloc() + align implementation is taken from:
-                *      http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me
-                */
-               
-#ifndef POPEN_NOSHELL_VALGRIND_DEBUG
-               pid = clone(fn, stack_aligned, CLONE_VM | SIGCHLD, arg);
-#else
-               pid = fork(); // Valgrind does not support arbitrary clone() calls, so we use fork for the tests
-#endif
-               if (pid == -1) return -1;
-
-               if (pid == 0) { // child
-#ifdef POPEN_NOSHELL_VALGRIND_DEBUG
-                       free(stack); // this is a copy because of the fork(), we are not using it at all
-                       _exit(fn(arg)); // if we used fork() because of Valgrind, invoke the child function manually; always use _exit()
-#endif
-                       errx(EXIT_FAILURE, "This must never happen");
-               } // child life ends here, for sure
-
-               return pid;
-}
-
 /*
  * Pipe stream to or from process. Similar to popen(), only much faster.
  *
@@ -309,40 +203,12 @@ FILE *popen_noshell(const char *file, const char * const *argv, const char *type
 
        if (pipe(pipefd) != 0) return NULL;
 
-       if (_popen_noshell_fork_mode) { // use fork()
-
-               pid = fork();
-               if (pid == -1) return NULL;
-               if (pid == 0) {
-                       _popen_noshell_child_process(NULL, pipefd[0], pipefd[1], read_pipe, ignore_stderr, file, argv);
-                       errx(EXIT_FAILURE, "This must never happen");
-               } // child life ends here, for sure
-
-       } else { // use clone()
-
-               struct popen_noshell_clone_arg *arg = NULL;
-
-               arg = (struct popen_noshell_clone_arg*) malloc(sizeof(struct popen_noshell_clone_arg));
-               if (!arg) return NULL;
-
-               /* Copy memory structures, so that nobody can free() our memory while we use it in the child! */
-               arg->pipefd_0 = pipefd[0];
-               arg->pipefd_1 = pipefd[1];
-               arg->read_pipe = read_pipe;
-               arg->ignore_stderr = ignore_stderr;
-               arg->file = strdup(file);
-               if (!arg->file) return NULL;
-               arg->argv = (const char * const *)popen_noshell_copy_argv(argv);
-               if (!arg->argv) return NULL;
-
-               pclose_arg->free_clone_mem = 1;
-               pclose_arg->func_args = arg;
-               pclose_arg->stack = NULL; // we will populate it below
-
-               pid = popen_noshell_vmfork(&popen_noshell_child_process_by_clone, arg, &(pclose_arg->stack));
-               if (pid == -1) return NULL;
-
-       } // done: using clone()
+       pid = vfork();
+       if (pid == -1) return NULL;
+       if (pid == 0) {
+               popen_noshell_child_process(pipefd[0], pipefd[1], read_pipe, ignore_stderr, file, argv);
+               errx(EXIT_FAILURE, "This must never happen");
+       } // child life ends here, for sure
 
        /* parent process */
 
@@ -373,7 +239,7 @@ int popen_noshell_add_ptr_to_argv(char ***argv, int *count, char *start) {
                return 0;
 }
 
-int _popen_noshell_add_token(char ***argv, int *count, char *start, char *command, int *j) {
+static int popen_noshell_add_token(char ***argv, int *count, char *start, char *command, int *j) {
        if (start != NULL && command + *j - 1 - start >= 0) {
                command[*j] = '\0'; // terminate the token in memory
                *j += 1;
@@ -387,7 +253,7 @@ int _popen_noshell_add_token(char ***argv, int *count, char *start, char *comman
        return 0;
 }
 
-#define _popen_noshell_split_return_NULL { if (argv != NULL) free(argv); if (command != NULL) free(command); return NULL; }
+#define popen_noshell_split_return_NULL { if (argv != NULL) free(argv); if (command != NULL) free(command); return NULL; }
 char ** popen_noshell_split_command_to_argv(const char *command_original, char **free_this_buf) {
        char *command;
        size_t i, len;
@@ -395,7 +261,7 @@ char ** popen_noshell_split_command_to_argv(const char *command_original, char *
        char c;
        char **argv = NULL;
        int count = 0;
-       const char _popen_bash_meta_characters[] = "!\\$`\n|&;()<>";
+       const char popen_bash_meta_characters[] = "!\\$`\n|&;()<>";
        int in_sq = 0;
        int in_dq = 0;
        int j = 0;
@@ -404,7 +270,7 @@ char ** popen_noshell_split_command_to_argv(const char *command_original, char *
 #endif
 
        command = (char *)calloc(strlen(command_original) + 1, sizeof(char));
-       if (!command) _popen_noshell_split_return_NULL;
+       if (!command) popen_noshell_split_return_NULL;
 
        *free_this_buf = command;
 
@@ -414,9 +280,9 @@ char ** popen_noshell_split_command_to_argv(const char *command_original, char *
                if (!start) start = command + j;
                c = command_original[i];
 
-               if (index(_popen_bash_meta_characters, c) != NULL) {
+               if (index(popen_bash_meta_characters, c) != NULL) {
                        errno = EINVAL;
-                       _popen_noshell_split_return_NULL;
+                       popen_noshell_split_return_NULL;
                }
 
                if (c == ' ' || c == '\t') {
@@ -426,8 +292,8 @@ char ** popen_noshell_split_command_to_argv(const char *command_original, char *
                        }
 
                        // new token
-                       if (_popen_noshell_add_token(&argv, &count, start, command, &j) != 0) {
-                               _popen_noshell_split_return_NULL;
+                       if (popen_noshell_add_token(&argv, &count, start, command, &j) != 0) {
+                               popen_noshell_split_return_NULL;
                        }
                        start = NULL;
                        continue;
@@ -446,20 +312,20 @@ char ** popen_noshell_split_command_to_argv(const char *command_original, char *
        }
        if (in_sq || in_dq) { // unmatched single/double quote
                errno = EINVAL;
-               _popen_noshell_split_return_NULL;
+               popen_noshell_split_return_NULL;
        }
 
-       if (_popen_noshell_add_token(&argv, &count, start, command, &j) != 0) {
-               _popen_noshell_split_return_NULL;
+       if (popen_noshell_add_token(&argv, &count, start, command, &j) != 0) {
+               popen_noshell_split_return_NULL;
        }
 
        if (count == 0) {
                errno = EINVAL;
-               _popen_noshell_split_return_NULL;
+               popen_noshell_split_return_NULL;
        }
 
        if (popen_noshell_add_ptr_to_argv(&argv, &count, NULL) != 0) { // NULL-terminate the list
-               _popen_noshell_split_return_NULL;
+               popen_noshell_split_return_NULL;
        }
 
 #ifdef POPEN_NOSHELL_DEBUG
@@ -491,7 +357,7 @@ char ** popen_noshell_split_command_to_argv(const char *command_original, char *
  * This is simpler than popen_noshell() but is more INSECURE.
  * Since shells have very complicated expansion, quoting and word splitting algorithms, we do NOT try to re-implement them here.
  * This function does NOT support any special characters. It will immediately return an error if such symbols are encountered in "command".
- * The "command" is split only by space and tab delimiters. The special symbols are pre-defined in _popen_bash_meta_characters[].
+ * The "command" is split only by space and tab delimiters. The special symbols are pre-defined in popen_bash_meta_characters[].
  * The only special characters supported are single and double quotes. You can enclose arguments in quotes and they should be splitted correctly.
  *
  * If possible, use popen_noshell() because of its better security.
@@ -542,10 +408,5 @@ int pclose_noshell(struct popen_noshell_pass_to_pclose *arg) {
                return -1;
        }
 
-       if (arg->free_clone_mem) {
-               free(arg->stack);
-               _pclose_noshell_free_clone_arg_memory(arg->func_args);
-       }
-
        return status;
 }
index 795dc8ad0398b6d961a567b56ed04bbeed1d57ec..0b47d3a51a4f37e8928aa1cb6ea6ed4ce12b395c 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * popen_noshell: A faster implementation of popen() and system() for Linux.
  * Copyright (c) 2009 Ivan Zahariev (famzah)
+ * Copyright (c) 2012 Gunnar Beutner
  * Version: 1.0
  *
  * This program is free software; you can redistribute it and/or modify
@@ -27,28 +28,9 @@ extern "C" {
 #include <sys/types.h>
 #include <unistd.h>
 
-/* stack for the child process before it does exec() */
-#define POPEN_NOSHELL_STACK_SIZE 8*1024*1024 /* currently most Linux distros set this to 8 MBytes */
-
-/* constants to use with popen_noshell_set_fork_mode() */
-#define POPEN_NOSHELL_MODE_CLONE 0 /* default, faster */
-#define POPEN_NOSHELL_MODE_FORK 1 /* slower */
-
-struct popen_noshell_clone_arg {
-       int pipefd_0;
-       int pipefd_1;
-       int read_pipe;
-       int ignore_stderr;
-       const char *file;
-       const char * const *argv;
-};
-
 struct popen_noshell_pass_to_pclose {
        FILE *fp;
        pid_t pid;
-       int free_clone_mem;
-       void *stack;
-       struct popen_noshell_clone_arg *func_args;
 };
 
 /***************************
@@ -64,12 +46,6 @@ FILE *popen_noshell_compat(const char *command, const char *type, struct popen_n
 /* call this when you have finished reading and writing from/to the child process */
 int pclose_noshell(struct popen_noshell_pass_to_pclose *arg); /* the pclose() equivalent */
 
-/* this is the innovative faster vmfork() which shares memory with the parent and is very resource-light; see the source code for documentation */
-pid_t popen_noshell_vmfork(int (*fn)(void *), void *arg, void **memory_to_free_on_child_exit);
-
-/* used only for benchmarking purposes */
-void popen_noshell_set_fork_mode(int mode);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/third-party/popen-noshell/popen_noshell_examples.c b/third-party/popen-noshell/popen_noshell_examples.c
deleted file mode 100644 (file)
index b2b20e4..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * popen_noshell: A faster implementation of popen() and system() for Linux.
- * Copyright (c) 2009 Ivan Zahariev (famzah)
- * Version: 1.0
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses>.
- */
-
-#include "popen_noshell.h"
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <alloca.h>
-
-/***********************************
- * popen_noshell use-case examples *
- ***********************************
- *
- * Compile and test via:
- *     gcc -Wall popen_noshell.c popen_noshell_examples.c -o popen_noshell_examples && ./popen_noshell_examples
- *
- * If you want to profile using Valgrind, then compile and run via:
- *     gcc -Wall -g -DPOPEN_NOSHELL_VALGRIND_DEBUG popen_noshell.c popen_noshell_examples.c -o popen_noshell_examples && \
- *        valgrind -q --tool=memcheck --leak-check=yes --show-reachable=yes --track-fds=yes ./popen_noshell_examples
- */
-
-void satisfy_open_FDs_leak_detection_and_exit() {
-       /* satisfy Valgrind FDs leak detection for the parent process */
-       if (fflush(stdout) != 0) err(EXIT_FAILURE, "fflush(stdout)");
-       if (fflush(stderr) != 0) err(EXIT_FAILURE, "fflush(stderr)");
-       close(STDIN_FILENO);
-       close(STDOUT_FILENO);
-       close(STDERR_FILENO);
-
-       exit(0);
-}
-
-void example_reading(int use_compat) {
-       FILE *fp;
-       char buf[256];
-       int status;
-       struct popen_noshell_pass_to_pclose pclose_arg;
-
-       char *cmd = "ls -la /proc/self/fd"; /* used only by popen_noshell_compat(), we discourage this type of providing a command */
-
-       /* the command arguments used by popen_noshell() */
-       char *exec_file = "ls";
-       char *arg1 = "-la";
-       char *arg2 = "/proc/self/fd";
-       char *arg3 = (char *) NULL; /* last element */
-       char *argv[] = {exec_file, arg1, arg2, arg3}; /* NOTE! The first argv[] must be the executed *exec_file itself */
-       
-       if (use_compat) {
-               fp = popen_noshell_compat(cmd, "r", &pclose_arg);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell_compat()");
-               }
-       } else {
-               fp = popen_noshell(exec_file, (const char * const *)argv, "r", &pclose_arg, 0);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell()");
-               }
-       }
-
-       while (fgets(buf, sizeof(buf)-1, fp)) {
-               printf("Got line: %s", buf);
-       }
-
-       status = pclose_noshell(&pclose_arg);
-       if (status == -1) {
-               err(EXIT_FAILURE, "pclose_noshell()");
-       } else {
-               printf("The status of the child is %d. Note that this is not only the exit code. See man waitpid().\n", status);
-       }
-}
-
-void example_writing(int use_compat) {
-       FILE *fp;
-       int status;
-       struct popen_noshell_pass_to_pclose pclose_arg;
-
-       char *cmd = "tee -a /tmp/popen-noshell.txt"; /* used only by popen_noshell_compat(), we discourage this type of providing a command */
-
-       /* the command arguments used by popen_noshell() */
-       char *exec_file = "tee";
-       char *arg1 = "-a";
-       char *arg2 = "/tmp/popen-noshell.txt";
-       char *arg3 = (char *) NULL; /* last element */
-       char *argv[] = {exec_file, arg1, arg2, arg3}; /* NOTE! The first argv[] must be the executed *exec_file itself */
-       
-       if (use_compat) {
-               fp = popen_noshell_compat(cmd, "w", &pclose_arg);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell_compat()");
-               }
-       } else {
-               fp = popen_noshell(exec_file, (const char * const *)argv, "w", &pclose_arg, 0);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell()");
-               }
-       }
-
-       if (fprintf(fp, "This is a test line, my pid is %d\n", (int)getpid()) < 0) {
-               err(EXIT_FAILURE, "fprintf()");
-       }
-
-       status = pclose_noshell(&pclose_arg);
-       if (status == -1) {
-               err(EXIT_FAILURE, "pclose_noshell()");
-       } else {
-               printf("The status of the child is %d. Note that this is not only the exit code. See man waitpid().\n", status);
-       }
-       
-       printf("Done, you can see the results by executing: cat %s\n", arg2);
-}
-
-int main() {
-       int try_compat;
-       int try_read;
-
-       /*
-        * Tune these options as you need.
-        */
-       try_compat = 0; /* or the more secure, but incompatible version of popen_noshell */
-       try_read = 1;   /* or write */
-
-       if (try_read) {
-               example_reading(try_compat);
-       } else {
-               example_writing(try_compat);
-       }
-
-       satisfy_open_FDs_leak_detection_and_exit();
-
-       return 0;
-}
diff --git a/third-party/popen-noshell/popen_noshell_tests.c b/third-party/popen-noshell/popen_noshell_tests.c
deleted file mode 100644 (file)
index cde0bc6..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * popen_noshell: A faster implementation of popen() and system() for Linux.
- * Copyright (c) 2009 Ivan Zahariev (famzah)
- * Version: 1.0
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses>.
- */
-
-#include "popen_noshell.h"
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <alloca.h>
-
-/***************************************************
- * popen_noshell C unit test and use-case examples *
- ***************************************************
- *
- * Compile and test via:
- *     gcc -Wall popen_noshell.c popen_noshell_tests.c -o popen_noshell_tests && ./popen_noshell_tests
- *
- * Compile for debugging by Valgrind via:
- *     gcc -Wall -g -DPOPEN_NOSHELL_VALGRIND_DEBUG popen_noshell.c popen_noshell_tests.c -o popen_noshell_tests
- * Then start under Valgrind via:
- *     valgrind -q --tool=memcheck --leak-check=yes --show-reachable=yes --track-fds=yes ./popen_noshell_tests
- * If you want to filter Valgrind false reports about 0 opened file descriptors, add the following at the end:
- *     2>&1|egrep -v '^==[[:digit:]]{1,5}==( | FILE DESCRIPTORS: 0 open at exit.)$'
- */
-
-int do_unit_tests_ignore_stderr;
-
-void satisfy_open_FDs_leak_detection_and_exit() {
-       /* satisfy Valgrind FDs leak detection for the parent process */
-       if (fflush(stdout) != 0) err(EXIT_FAILURE, "fflush(stdout)");
-       if (fflush(stderr) != 0) err(EXIT_FAILURE, "fflush(stderr)");
-       close(STDIN_FILENO);
-       close(STDOUT_FILENO);
-       close(STDERR_FILENO);
-
-       exit(0);
-}
-
-void assert_string(char *expected, char *got, const char *assert_desc) {
-       if (strcmp(expected, got) != 0) errx(EXIT_FAILURE, "%s: Expected '%s', got '%s'", assert_desc, expected, got);
-}
-
-void assert_int(int expected, int got, const char *assert_desc) {
-       if (expected != got) errx(EXIT_FAILURE, "%s: Expected %d, got %d", assert_desc, expected, got);
-}
-
-void assert_status_not_internal_error(int status) {
-       assert_int(1, status >= 0, "assert_status_not_internal_error");
-}
-
-void assert_status_signal(int signal, int status) {
-       assert_status_not_internal_error(status);
-       assert_int(signal, status & 127, "assert_status_signal");
-}
-
-void assert_status_exit_code(int code, int status) {
-       assert_status_not_internal_error(status);
-       assert_status_signal(0, status);
-       assert_int(code, status >> 8, "assert_status_exit_code");
-}
-
-void example_reading(int use_compat) {
-       FILE *fp;
-       char buf[256];
-       int status;
-       struct popen_noshell_pass_to_pclose pclose_arg;
-
-       char *cmd = "ls -la /proc/self/fd"; /* used only by popen_noshell_compat(), we discourage this type of providing a command */
-
-       /* the command arguments used by popen_noshell() */
-       char *exec_file = "ls";
-       char *arg1 = "-la";
-       char *arg2 = "/proc/self/fd";
-       char *arg3 = (char *) NULL; /* last element */
-       char *argv[] = {exec_file, arg1, arg2, arg3}; /* NOTE! The first argv[] must be the executed *exec_file itself */
-       
-       if (use_compat) {
-               fp = popen_noshell_compat(cmd, "r", &pclose_arg);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell_compat()");
-               }
-       } else {
-               fp = popen_noshell(exec_file, (const char * const *)argv, "r", &pclose_arg, 0);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell()");
-               }
-       }
-
-       while (fgets(buf, sizeof(buf)-1, fp)) {
-               printf("Got line: %s", buf);
-       }
-
-       status = pclose_noshell(&pclose_arg);
-       if (status == -1) {
-               err(EXIT_FAILURE, "pclose_noshell()");
-       } else {
-               printf("The status of the child is %d. Note that this is not only the exit code. See man waitpid().\n", status);
-       }
-}
-
-void example_writing(int use_compat) {
-       FILE *fp;
-       int status;
-       struct popen_noshell_pass_to_pclose pclose_arg;
-
-       char *cmd = "tee -a /tmp/popen-noshell.txt"; /* used only by popen_noshell_compat(), we discourage this type of providing a command */
-
-       /* the command arguments used by popen_noshell() */
-       char *exec_file = "tee";
-       char *arg1 = "-a";
-       char *arg2 = "/tmp/popen-noshell.txt";
-       char *arg3 = (char *) NULL; /* last element */
-       char *argv[] = {exec_file, arg1, arg2, arg3}; /* NOTE! The first argv[] must be the executed *exec_file itself */
-       
-       if (use_compat) {
-               fp = popen_noshell_compat(cmd, "w", &pclose_arg);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell_compat()");
-               }
-       } else {
-               fp = popen_noshell(exec_file, (const char * const *)argv, "w", &pclose_arg, 0);
-               if (!fp) {
-                       err(EXIT_FAILURE, "popen_noshell()");
-               }
-       }
-
-       if (fprintf(fp, "This is a test line, my pid is %d\n", (int)getpid()) < 0) {
-               err(EXIT_FAILURE, "fprintf()");
-       }
-
-       status = pclose_noshell(&pclose_arg);
-       if (status == -1) {
-               err(EXIT_FAILURE, "pclose_noshell()");
-       } else {
-               printf("The status of the child is %d. Note that this is not only the exit code. See man waitpid().\n", status);
-       }
-       
-       printf("Done, you can see the results by executing: cat %s\n", arg2);
-}
-
-void unit_test(int reading, char *argv[], char *expected_string, int expected_signal, int expected_exit_code) {
-       FILE *fp;
-       char buf[256];
-       int status;
-       struct popen_noshell_pass_to_pclose pclose_arg;
-       char *received;
-       size_t received_size;
-
-       fp = popen_noshell(argv[0], (const char * const *)argv, reading ? "r" : "w", &pclose_arg, do_unit_tests_ignore_stderr);
-       if (!fp) err(EXIT_FAILURE, "popen_noshell");
-
-       if (reading) {
-               received_size = strlen(expected_string) + 256; // so that we can store a bit longer strings that we expected and discover the mismatch
-               received = alloca(received_size); // use alloca() or else the fork()'ed child will generate a Valgrind memory leak warning if exec() fails
-               if (!received) err(EXIT_FAILURE, "alloca");
-               memset(received, 0, received_size); // ensure a terminating null
-
-               while (fgets(buf, sizeof(buf) - 1, fp)) {
-                       strncat(received, buf, received_size - strlen(received) - 2);
-               }
-
-               assert_string(expected_string, received, "Received string");
-       }
-
-       status = pclose_noshell(&pclose_arg);
-       if (status == -1) {
-               err(EXIT_FAILURE, "pclose_noshell()");
-       } else {
-               if (expected_signal != 0) {
-                       assert_status_signal(expected_signal, status);
-               } else {
-                       assert_status_exit_code(expected_exit_code, status);
-               }
-       }
-
-       //free(received); // memory allocated by alloca() cannot be free()'d
-}
-
-void do_unit_tests() {
-       int test_num = 0;
-       int more_to_test = 1;
-       char *bin_bash = "/bin/bash";
-       char *bin_true = "/bin/true";
-       char *bin_cat  = "/bin/cat";
-       char *bin_echo = "/bin/echo";
-
-       do {
-               ++test_num;
-               switch (test_num) {
-                       case 1: {
-                               char *argv[] = {"/", NULL};
-                               unit_test(1, argv, "", 0, 255); // failed to execute binary (status code is -1, STDOUT is empty, STDERR text)
-                               break;
-                       }
-                       case 2: {
-                               char *argv[] = {bin_bash, "-c", "ulimit -t 1 && while [ 1 ]; do let COUNTER=COUNTER+1; done;", NULL};
-                               unit_test(1, argv, "", 9, 5); // process signalled with 9 due to CPU limit (STDOUT/ERR are empty)
-                               break;
-                       }
-                       case 3: {
-                               char *argv[] = {bin_bash, "-c", "sleep 1; exit 1", NULL};
-                               unit_test(1, argv, "", 0, 1); // process exited with value 1   (STDOUT/ERR are empty)
-                               break;
-                       }
-                       case 4: {
-                               char *argv[] = {bin_bash, "-c", "exit 255", NULL};
-                               unit_test(1, argv, "", 0, 255); // process exited with value 255 (STDOUT/ERR are empty)
-                               break;
-                       }
-                       case 5: {
-                               char *argv[] = {bin_bash, "-c", "echo \"some err string\" 1>&2; exit 111", NULL};
-                               unit_test(1, argv, "", 0, 111); // process exited with value 111 (STDERR text, STDOUT is empty)
-                               break;
-                       }
-                       case 6: {
-                               char *argv[] = {bin_bash, "-c", "echo -en \"some err\\nstring v2\" 1>&2; echo -en \"some\\ngood text\"; exit 0", NULL};
-                               unit_test(1, argv, "some\ngood text", 0, 0); // process exited with value 0 (STDERR text, STDOUT text)
-                               break;
-                       }
-                       case 7: {
-                               char *argv[] = {bin_bash, "-c", "echo -e \"\" 1>&2; echo -e \"\"; exit 3", NULL};
-                               unit_test(1, argv, "\n", 0, 3); // process exited with value 3 (STDERR text, STDOUT text)
-                               break;
-                       }
-                       case 8: {
-                               char *argv[] = {bin_bash, NULL};
-                               unit_test(1, argv, "", 0, 0); // process exited with value 0 (single argument, STDOUT/ERR are empty)
-                               break;
-                       }
-                       case 9: {
-                               char *argv[] = {bin_true, NULL};
-                               unit_test(1, argv, "", 0, 0); // process exited with value 0 (single argument, STDOUT/ERR are empty)
-                               break;
-                       }
-                       case 10: {
-                               char *argv[] = {bin_cat, NULL}; // cat expects an input from STDIN
-                               unit_test(1, argv, "", 0, 0); // process exited with value 0 (single argument, STDOUT/ERR are empty)
-                               break;
-                       }
-                       case 11: {
-                               char *argv[] = {bin_echo, NULL};
-                               unit_test(1, argv, "\n", 0, 0); // process exited with value 0 (single argument, STDERR is empty, STDOUT text)
-                               break;
-                       }
-                       default:
-                               more_to_test = 0;
-                               break;
-               }
-       } while (more_to_test);
-
-       assert_int(11, test_num - 1, "Test count");
-}
-
-void proceed_to_unit_tests_and_exit() {
-       popen_noshell_set_fork_mode(POPEN_NOSHELL_MODE_CLONE); /* the default one */
-       do_unit_tests();
-       popen_noshell_set_fork_mode(POPEN_NOSHELL_MODE_FORK);
-       do_unit_tests();
-
-       printf("Tests passed OK.\n");
-
-       satisfy_open_FDs_leak_detection_and_exit();
-}
-
-int main() {
-       do_unit_tests_ignore_stderr = 1; /* do we ignore STDERR from the executed commands? */
-       proceed_to_unit_tests_and_exit();
-       satisfy_open_FDs_leak_detection_and_exit();
-
-       return 0;
-}
diff --git a/third-party/popen-noshell/popen_noshell_tests.cpp b/third-party/popen-noshell/popen_noshell_tests.cpp
deleted file mode 100644 (file)
index f6ab754..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * popen_noshell: A faster implementation of popen() and system() for Linux.
- * Copyright (c) 2009 Ivan Zahariev (famzah)
- * Credits for the C++ test cases go to David Coz
- * Version: 1.0
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses>.
- */
-
-#include "popen_noshell.h"
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <alloca.h>
-
-/*****************************************************
- * popen_noshell C++ unit test and use-case examples *
- *****************************************************
- *
- * Compile and test via:
- *     g++ -Wall popen_noshell.c popen_noshell_tests.cpp -o popen_noshell_tests_cpp && ./popen_noshell_tests_cpp
- */
-
-#define DUMMY_SIZE 10000
-
-// Just a dummy structure that allocates memory at startup and releases it 
-// when exit() is called.
-
-struct Dummy {
-  Dummy() {
-    val = new char[DUMMY_SIZE];
-  }
-  ~Dummy() {
-    delete[] val;
-    val = NULL;
-  }
-  char* val;
-};
-
-static Dummy dummy;
-
-int main() {
-  FILE *fp;
-  char buf[256];
-  int status;
-  struct popen_noshell_pass_to_pclose pclose_arg;
-
-  popen_noshell_set_fork_mode(POPEN_NOSHELL_MODE_CLONE);
-
-  // We provide an invalid command, so that the child calls exit().
-  // Child's exit() will result in destruction of global objects, while these
-  // objects belong to the parent!
-  // Therefore, if the parent uses them after child's exit(), it is likely to
-  // lead to a crash.
-  
-  //char *exec_file = (char *) "ls";
-  char *exec_file = (char *) "lsaaa";
-  char *arg1 = (char *) "-la";
-  char *arg2 = (char *) "/proc/self/fd";
-  char *arg3 = (char *) NULL; /* last element */
-  char *argv[] = {exec_file, arg1, arg2, arg3}; /* NOTE! The first argv[] must be the executed *exec_file itself */
-
-  fp = popen_noshell(argv[0], (const char * const *)argv, "r", &pclose_arg, 0);
-  if (!fp) {
-    err(EXIT_FAILURE, "popen_noshell()");
-  }
-
-  while (fgets(buf, sizeof(buf)-1, fp)) {
-    printf("Got line: %s", buf);
-  }
-
-  status = pclose_noshell(&pclose_arg);
-  if (status == -1) {
-    err(EXIT_FAILURE, "pclose_noshell()");
-  } else {
-    printf("The status of the child is %d. Note that this is not only the exit code. See man waitpid().\n", status);
-  }
-
-  // Trying to access our global variable stuff.
-  // If exit() is used in the child process, dummy.val = 0 and we have a crash.
-  // With _exit(), dummy.val is still valid.
-
-  // printf("Accessing dummy stuff. dummy.val=%p\n", dummy.val);
-  memset(dummy.val, 42, DUMMY_SIZE);
-  printf("\nTests passed OK.\n");
-
-  return 0;
-}