Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libstorage-ng for openSUSE:Factory checked in at 2023-10-24 20:07:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libstorage-ng (Old) and /work/SRC/openSUSE:Factory/.libstorage-ng.new.24901 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libstorage-ng" Tue Oct 24 20:07:01 2023 rev:241 rq:1119612 version:4.5.151 Changes: -------- --- /work/SRC/openSUSE:Factory/libstorage-ng/libstorage-ng.changes 2023-10-22 21:01:03.831553649 +0200 +++ /work/SRC/openSUSE:Factory/.libstorage-ng.new.24901/libstorage-ng.changes 2023-10-24 20:07:04.213717180 +0200 @@ -1,0 +2,14 @@ +Mon Oct 23 11:04:31 UTC 2023 - aschn...@suse.com + +- merge gh#openSUSE/libstorage-ng#957 +- extended testsuite +- 4.5.151 + +-------------------------------------------------------------------- +Mon Oct 23 10:15:40 UTC 2023 - aschn...@suse.com + +- merge gh#openSUSE/libstorage-ng#956 +- improved error handling in SystemCmd +- 4.5.150 + +-------------------------------------------------------------------- Old: ---- libstorage-ng-4.5.149.tar.xz New: ---- libstorage-ng-4.5.151.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libstorage-ng.spec ++++++ --- /var/tmp/diff_new_pack.qL9xOa/_old 2023-10-24 20:07:05.037747139 +0200 +++ /var/tmp/diff_new_pack.qL9xOa/_new 2023-10-24 20:07:05.037747139 +0200 @@ -18,7 +18,7 @@ %define libname %{name}1 Name: libstorage-ng -Version: 4.5.149 +Version: 4.5.151 Release: 0 Summary: Library for storage management License: GPL-2.0-only ++++++ libstorage-ng-4.5.149.tar.xz -> libstorage-ng-4.5.151.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.149/LIBVERSION new/libstorage-ng-4.5.151/LIBVERSION --- old/libstorage-ng-4.5.149/LIBVERSION 2023-10-20 18:47:00.000000000 +0200 +++ new/libstorage-ng-4.5.151/LIBVERSION 2023-10-23 13:04:31.000000000 +0200 @@ -1 +1 @@ -1.95.0 +1.95.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.149/VERSION new/libstorage-ng-4.5.151/VERSION --- old/libstorage-ng-4.5.149/VERSION 2023-10-20 18:47:00.000000000 +0200 +++ new/libstorage-ng-4.5.151/VERSION 2023-10-23 13:04:31.000000000 +0200 @@ -1 +1 @@ -4.5.149 +4.5.151 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.149/storage/Utils/SystemCmd.cc new/libstorage-ng-4.5.151/storage/Utils/SystemCmd.cc --- old/libstorage-ng-4.5.149/storage/Utils/SystemCmd.cc 2023-10-20 18:47:00.000000000 +0200 +++ new/libstorage-ng-4.5.151/storage/Utils/SystemCmd.cc 2023-10-23 13:04:31.000000000 +0200 @@ -217,18 +217,6 @@ } - void - SystemCmd::closeOpenFds() const - { - int max_fd = getdtablesize(); - - for ( int fd = 3; fd < max_fd; fd++ ) - { - close(fd); - } - } - - int SystemCmd::execute() { @@ -338,39 +326,35 @@ } y2deb("sout:" << _pfds[1].fd << " serr:" << _pfds[2].fd); + const int max_fd = getdtablesize(); + const TmpForExec args_p(make_args()); const TmpForExec env_p(make_env()); switch( (_cmdPid=fork()) ) { case 0: // child process + { + // Do not use exit() here. Use _exit() instead. + + // Only use asyncâsignalâsafe functions here, see fork(2) and + // signal-safety(7). if ( dup2( sin[0], STDIN_FILENO )<0 ) - { - SYSCALL_FAILED_NOTHROW( "dup2 stdin failed in child process" ); - } + _exit(125); if ( dup2( sout[1], STDOUT_FILENO )<0 ) - { - SYSCALL_FAILED_NOTHROW( "dup2 stdout failed in child process" ); - } + _exit(125); if ( dup2( serr[1], STDERR_FILENO )<0 ) - { - SYSCALL_FAILED_NOTHROW( "dup2 stderr failed in child process" ); - } + _exit(125); if ( close( sin[1] )<0 ) - { - SYSCALL_FAILED_NOTHROW( "close( stdin ) failed in child process" ); - } + _exit(125); if ( close( sout[0] )<0 ) - { - SYSCALL_FAILED_NOTHROW( "close( stdout ) failed in child process" ); - } + _exit(125); if ( close( serr[0] )<0 ) - { - SYSCALL_FAILED_NOTHROW( "close( stderr ) failed in child process" ); - } + _exit(125); - closeOpenFds(); + for (int fd = 3; fd < max_fd; ++fd) + close(fd); if (args().empty()) { @@ -381,22 +365,29 @@ _cmdRet = execvpe(args()[0].c_str(), args_p.get(), env_p.get()); } - // execle() should not return. If we get here, it failed. - // Throwing an exception here would not make any sense, however: - // We are in the forked child process, and there is nothing - // to return to that could make use of an exception. - y2err("execle() failed: THIS SHOULD NOT HAPPEN \"SH_BIN\" Ret:" << - _cmdRet << " errno: " << errno); - y2err( "Exiting child process" ); - _exit(127); // same as "command not found" in the shell - break; + // If we get here the exec has failed. Depending on errno we return an + // error code like the shell does ('sh -c ...'). Unfortunately it is + // not possible in the parent to distinguish whether exec or the + // program returned the code (e.g. 127). So far that does not seem to + // be needed. If ever needed the "self-pipe trick" could be used. + + if (errno == ENOENT) + _exit(SHELL_RET_COMMAND_NOT_FOUND); + if (errno == ENOEXEC || errno == EACCES || errno == EISDIR) + _exit(SHELL_RET_COMMAND_NOT_EXECUTABLE); + _exit(125); + } + break; case -1: + { _cmdRet = -1; SYSCALL_FAILED( "fork() failed" ); - break; + } + break; default: // parent process + { if ( close( sin[0] ) < 0 ) { SYSCALL_FAILED_NOTHROW( "close( stdin ) in parent failed" ); @@ -430,8 +421,8 @@ doWait( _cmdRet ); y2mil("stopwatch " << stopwatch << " for \"" << display_command() << "\""); - - break; + } + break; } } else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.149/storage/Utils/SystemCmd.h new/libstorage-ng-4.5.151/storage/Utils/SystemCmd.h --- old/libstorage-ng-4.5.149/storage/Utils/SystemCmd.h 2023-10-20 18:47:00.000000000 +0200 +++ new/libstorage-ng-4.5.151/storage/Utils/SystemCmd.h 2023-10-23 13:04:31.000000000 +0200 @@ -225,7 +225,6 @@ void init(); void cleanup(); void invalidate(); - void closeOpenFds() const; int doExecute(); bool doWait(int& cmdRet_ret); void checkOutput(); @@ -275,17 +274,14 @@ /** * Constructs the args for the child process. * - * Must not be called after exec since allocating the memory - * for the vector is not allowed then (in a multithreaded - * program), see fork(2) and signal-safety(7). So simply call - * it right before fork. + * Not asyncâsignalâsafe, see fork(2) and signal-safety(7). */ TmpForExec make_args() const; /** * Constructs the environment for the child process. * - * Same not as for make_args(). + * Not asyncâsignalâsafe, see fork(2) and signal-safety(7). */ TmpForExec make_env() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libstorage-ng-4.5.149/testsuite/Utils/systemcmd.cc new/libstorage-ng-4.5.151/testsuite/Utils/systemcmd.cc --- old/libstorage-ng-4.5.149/testsuite/Utils/systemcmd.cc 2023-10-20 18:47:00.000000000 +0200 +++ new/libstorage-ng-4.5.151/testsuite/Utils/systemcmd.cc 2023-10-23 13:04:31.000000000 +0200 @@ -2,7 +2,6 @@ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE libstorage -#include <boost/version.hpp> #include <boost/test/unit_test.hpp> #include <boost/algorithm/string.hpp> @@ -13,6 +12,7 @@ #include "storage/Utils/Exception.h" #include "storage/Utils/Mockup.h" #include "storage/Utils/SystemCmd.h" +#include "storage/Utils/StorageDefines.h" using namespace std; @@ -105,14 +105,14 @@ } -BOOST_AUTO_TEST_CASE(pipe_stdin) +BOOST_AUTO_TEST_CASE(pipe_stdin_cmd) { vector<string> stdout = { "Hello, cruel world", "I'm leaving you today" }; - SystemCmd::Options cmd_options("cat"); + SystemCmd::Options cmd_options(CAT_BIN); cmd_options.stdin_text = "Hello, cruel world\nI'm leaving you today"; SystemCmd cmd(cmd_options); @@ -121,7 +121,23 @@ } -BOOST_AUTO_TEST_CASE(retcode_42) +BOOST_AUTO_TEST_CASE(pipe_stdin_args) +{ + vector<string> stdout = { + "Hello, cruel world", + "I'm leaving you today" + }; + + SystemCmd::Options cmd_options({ CAT_BIN }); + cmd_options.stdin_text = "Hello, cruel world\nI'm leaving you today"; + + SystemCmd cmd(cmd_options); + + BOOST_CHECK_EQUAL(join(cmd.stdout()), join(stdout)); +} + + +BOOST_AUTO_TEST_CASE(retcode_42_cmd) { SystemCmd cmd("../helpers/retcode 42"); @@ -129,6 +145,14 @@ } +BOOST_AUTO_TEST_CASE(retcode_42_args) +{ + SystemCmd cmd({ "../helpers/retcode", "42" }); + + BOOST_CHECK(cmd.retcode() == 42); +} + + BOOST_AUTO_TEST_CASE(non_existent_no_throw) { BOOST_CHECK_NO_THROW({ @@ -138,9 +162,16 @@ } -BOOST_AUTO_TEST_CASE(non_existent_throw) +BOOST_AUTO_TEST_CASE(non_existent_throw_cmd) +{ + BOOST_CHECK_THROW({ SystemCmd cmd("/bin/wrglbrmpf", SystemCmd::ThrowBehaviour::DoThrow); }, + CommandNotFoundException); +} + + +BOOST_AUTO_TEST_CASE(non_existent_throw_args) { - BOOST_CHECK_THROW({SystemCmd cmd("/bin/wrglbrmpf", SystemCmd::ThrowBehaviour::DoThrow);}, + BOOST_CHECK_THROW({ SystemCmd cmd({ "/bin/wrglbrmpf" }, SystemCmd::ThrowBehaviour::DoThrow); }, CommandNotFoundException); } @@ -154,13 +185,20 @@ } -BOOST_AUTO_TEST_CASE(segfault_throw) +BOOST_AUTO_TEST_CASE(segfault_throw_cmd) { BOOST_CHECK_THROW({SystemCmd cmd("../helpers/segfaulter", SystemCmd::ThrowBehaviour::DoThrow);}, SystemCmdException); } +BOOST_AUTO_TEST_CASE(segfault_throw_args) +{ + BOOST_CHECK_THROW({ SystemCmd cmd({ "../helpers/segfaulter" }, SystemCmd::ThrowBehaviour::DoThrow); }, + SystemCmdException); +} + + BOOST_AUTO_TEST_CASE(non_exec_no_throw) { BOOST_CHECK_NO_THROW({ @@ -170,9 +208,16 @@ } -BOOST_AUTO_TEST_CASE(non_exec_throw) +BOOST_AUTO_TEST_CASE(non_exec_throw_cmd) +{ + BOOST_CHECK_THROW({ SystemCmd cmd("../helpers/segfaulter.cc", SystemCmd::ThrowBehaviour::DoThrow); }, + SystemCmdException); +} + + +BOOST_AUTO_TEST_CASE(non_exec_throw_args) { - BOOST_CHECK_THROW({SystemCmd cmd( "../helpers/segfaulter.cc", SystemCmd::ThrowBehaviour::DoThrow);}, + BOOST_CHECK_THROW({ SystemCmd cmd({ "../helpers/segfaulter.cc" }, SystemCmd::ThrowBehaviour::DoThrow); }, SystemCmdException); }