Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package libalternatives for openSUSE:Factory
checked in at 2026-08-15 22:39:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libalternatives (Old)
and /work/SRC/openSUSE:Factory/.libalternatives.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libalternatives"
Sat Aug 15 22:39:30 2026 rev:8 rq:1371067 version:2.0+0.4f22c01
Changes:
--------
--- /work/SRC/openSUSE:Factory/libalternatives/libalternatives.changes
2025-04-11 16:46:24.650295483 +0200
+++
/work/SRC/openSUSE:Factory/.libalternatives.new.1258/libalternatives.changes
2026-08-15 22:39:30.938240841 +0200
@@ -1,0 +2,21 @@
+Thu Aug 13 16:12:39 UTC 2026 - Adam Majer <[email protected]>
+
+- Update to version v2.0+0.4f22c01:
+ * add missing test
+ * Capture saved_errno correctly
+ * Check for null pointer
+ * reset argv0 to original if execve() fails
+ * Clarify value of argv0
+ * Return errno from failed exec()
+ * Use basename for argv[0] resolution
+ * Update unit test
+ * Document behaviour changes - KeepArgv0 is default
+ * Correct pointer in corner case
+ * Add UpdateArgv0 option
+ * Clarify priority as increasing with integer size
+
+- Functionality change: KeepArgv0 is default option unless
+ another is specified. Functionality should now be same as with
+ symlinks (bsc#1262785)
+
+-------------------------------------------------------------------
Old:
----
libalternatives-v1.2+31.da24cd4.tar.zst
New:
----
libalternatives-v2.0+0.4f22c01.tar.zst
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libalternatives.spec ++++++
--- /var/tmp/diff_new_pack.f2It9J/_old 2026-08-15 22:39:31.655266087 +0200
+++ /var/tmp/diff_new_pack.f2It9J/_new 2026-08-15 22:39:31.657266157 +0200
@@ -1,7 +1,7 @@
#
# spec file for package libalternatives
#
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%define sover 1
Name: libalternatives
-Version: 1.2+31.da24cd4
+Version: 2.0+0.4f22c01
Release: 0
Summary: Helper for executing preferred application based on user
preferences
License: Apache-2.0
++++++ _service ++++++
--- /var/tmp/diff_new_pack.f2It9J/_old 2026-08-15 22:39:31.697267566 +0200
+++ /var/tmp/diff_new_pack.f2It9J/_new 2026-08-15 22:39:31.702267742 +0200
@@ -3,7 +3,7 @@
<param name="scm">git</param>
<param name="url">https://github.com/openSUSE/libalternatives.git</param>
<param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@.%h</param>
- <param name="revision">da24cd4</param>
+ <param name="revision">v2.0</param>
<param name="changesgenerate">enable</param>
</service>
<service mode="manual" name="recompress">
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.f2It9J/_old 2026-08-15 22:39:31.738269009 +0200
+++ /var/tmp/diff_new_pack.f2It9J/_new 2026-08-15 22:39:31.742269150 +0200
@@ -1,6 +1,5 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/openSUSE/libalternatives.git</param>
- <param
name="changesrevision">da24cd4ceee23d93ebfecbf1d527515e06ca6998</param></service></servicedata>
-(No newline at EOF)
+ <param
name="changesrevision">4f22c017e3249441c8d383c34fdacf77f1d7ba17</param></service></servicedata>
++++++ libalternatives-v1.2+31.da24cd4.tar.zst ->
libalternatives-v2.0+0.4f22c01.tar.zst ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libalternatives-v1.2+31.da24cd4/README.md
new/libalternatives-v2.0+0.4f22c01/README.md
--- old/libalternatives-v1.2+31.da24cd4/README.md 2023-10-10
14:11:24.000000000 +0200
+++ new/libalternatives-v2.0+0.4f22c01/README.md 2026-08-13
18:08:08.000000000 +0200
@@ -34,7 +34,7 @@
is executed directly. Which executable is executed depends on the
available alternatives installed on the system and the system and/or
user configuration files. By default, the preferred alternative with the
-highest priority is executed. If an alternative is selected by the user
+highest priority (larger positive integer) is executed. If an alternative is
selected by the user
or the system administrator, this alternative will be executed instead.
If the user or system selection is unavailable, the system will fall
back to the default, highest priority, installed alternative.
@@ -51,7 +51,7 @@
where
+ *binary* is the name of the alternative provided
-+ *pref* is a numeric priority
++ *pref* is a numeric priority, larger integer is higher preference
The config file must be of the following format:
@@ -71,22 +71,28 @@
Argv[0]
-------
-In normal cases, argv[0] contains name of the executed target
-by the *alts* binary. In the example below, this would be *vim*. If the
-called process needs the name of for argv[0], set the option
-*options=KeepArgv0* in the config file.
+In normal cases, argv[0] retaines the path of original binary or symlink
+to the *alts* binary. When UpdateArgv0 is specified, the argv[0] will be
+set to the absolute path of binary executed by *alts*, so this would be
+*/usr/bin/vim*.
-Note: Only these two options for argv[0] are available. Some called processes
expect other names which cannot be handled by libalternatives.
+Note: Only these two options for argv[0] are available. Some called processes
expect
+other names which cannot be handled by libalternatives without helper binaries.
For example:
binary=/usr/bin/vim
man=vim.1
- options=KeepArgv0
+ options=UpdateArgv0
*alts* is also the configuration utility that allows system or user
override of the default binary. See *alts(1)* for details.
+**Change Of Behaviour**: Previously, argv0 would be set to basename of the
+binary being executed. To be better compatible with symlinks, this behaviour
+required UpdateArv0 Option to be specified. Without that option, KeepArgv0
+is assumed by default.
+
Groups
------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libalternatives-v1.2+31.da24cd4/doc/alts.1
new/libalternatives-v2.0+0.4f22c01/doc/alts.1
--- old/libalternatives-v1.2+31.da24cd4/doc/alts.1 2023-10-10
14:11:24.000000000 +0200
+++ new/libalternatives-v2.0+0.4f22c01/doc/alts.1 2026-08-13
18:08:08.000000000 +0200
@@ -41,6 +41,8 @@
-s -- system override, default for root users
-n -- program to override with a given priority alternative
+priority is defined as a positive integer, where larger number is preferred
over smaller number
+
.SH SEE ALSO
update-alternatives(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/libalternatives-v1.2+31.da24cd4/src/libalternatives.c
new/libalternatives-v2.0+0.4f22c01/src/libalternatives.c
--- old/libalternatives-v1.2+31.da24cd4/src/libalternatives.c 2023-10-10
14:11:24.000000000 +0200
+++ new/libalternatives-v2.0+0.4f22c01/src/libalternatives.c 2026-08-13
18:08:08.000000000 +0200
@@ -669,18 +669,25 @@
PUBLIC_FUNC
int libalts_exec_default(char *argv[])
{
- argv[0]=basename(argv[0]);
+ if (argv == NULL || argv[0] == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
- struct AlternativeLink *alts;
+ char *orig_argv0 = argv[0];
+ struct AlternativeLink *alts, *orig_alts;
checkEnvDebug();
- loadAlternatives(argv[0], &alts);
+ loadAlternatives(basename(argv[0]), &alts);
+ orig_alts = alts;
+ int saved_errno = ENOENT;
if (alts) {
while (alts->type != ALTLINK_EOL) {
if (alts->type == ALTLINK_BINARY) {
- if ((alts->options & ALTLINK_OPTIONS_KEEPARGV0)
== 0)
+ if ((alts->options &
ALTLINK_OPTIONS_UPDATEARGV0) != 0)
argv[0] = (char*)alts->target;
execv(alts->target, argv);
+ saved_errno = errno;
perror("Failed to execute target.");
break;
}
@@ -690,9 +697,13 @@
if (IS_DEBUG)
fprintf(stderr, "execDefault() failed with target %s\n", (alts
? alts->target : NULL));
- if (alts)
- libalts_free_alternatives_ptr(&alts);
- errno = ENOENT;
+
+ argv[0] = orig_argv0;
+ if (orig_alts)
+ libalts_free_alternatives_ptr(&orig_alts);
+
+ errno = saved_errno;
+
return -1;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/libalternatives-v1.2+31.da24cd4/src/libalternatives.h
new/libalternatives-v2.0+0.4f22c01/src/libalternatives.h
--- old/libalternatives-v1.2+31.da24cd4/src/libalternatives.h 2023-10-10
14:11:24.000000000 +0200
+++ new/libalternatives-v2.0+0.4f22c01/src/libalternatives.h 2026-08-13
18:08:08.000000000 +0200
@@ -34,6 +34,7 @@
{
ALTLINK_OPTIONS_NONE = 0,
ALTLINK_OPTIONS_KEEPARGV0 = 1,
+ ALTLINK_OPTIONS_UPDATEARGV0 = 2,
};
struct AlternativeLink
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libalternatives-v1.2+31.da24cd4/src/options_parser.c
new/libalternatives-v2.0+0.4f22c01/src/options_parser.c
--- old/libalternatives-v1.2+31.da24cd4/src/options_parser.c 2023-10-10
14:11:24.000000000 +0200
+++ new/libalternatives-v2.0+0.4f22c01/src/options_parser.c 2026-08-13
18:08:08.000000000 +0200
@@ -251,6 +251,35 @@
return state->parser_func(data, len, state);
}
+static int parser_asssertOption_UpdateArgv0(const char *data, size_t len,
struct OptionsParserState *state)
+{
+ if (len == 0)
+ return 0;
+
+ const char token[] = "UpdateArgv0";
+ u_int32_t pos = state->parser_func_param;
+ u_int32_t max_pos_to_match = MIN(sizeof(token)-1, pos+len);
+
+ while (pos < max_pos_to_match && *data == token[pos]) {
+ pos++;
+ data++;
+ len--;
+ }
+
+ if (pos == max_pos_to_match) {
+ if (pos == sizeof(token)-1) {
+ state->parser_func =
parser_skipWhitespaceBeforeCommaAndOption;
+ state->options |= ALTLINK_OPTIONS_UPDATEARGV0;
+ }
+ else
+ state->parser_func_param = pos;
+ }
+ else
+ state->parser_func = parser_alreadyErrorNoResumePossible;
+
+ return state->parser_func(data, len, state);
+}
+
static int parser_parseOptions(const char *data, size_t len, struct
OptionsParserState *state)
{
if (len == 0)
@@ -261,6 +290,10 @@
state->parser_func = parser_asssertOption_KeepArgv0;
state->parser_func_param = 1;
break;
+ case 'U':
+ state->parser_func = parser_asssertOption_UpdateArgv0;
+ state->parser_func_param = 1;
+ break;
case '\n':
case '\r':
state->parser_func = parser_searchToken;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/libalternatives-v1.2+31.da24cd4/test/alternatives_tests.c
new/libalternatives-v2.0+0.4f22c01/test/alternatives_tests.c
--- old/libalternatives-v1.2+31.da24cd4/test/alternatives_tests.c
2023-10-10 14:11:24.000000000 +0200
+++ new/libalternatives-v2.0+0.4f22c01/test/alternatives_tests.c
2026-08-13 18:08:08.000000000 +0200
@@ -467,6 +467,16 @@
CU_ASSERT_EQUAL(errno, ENOENT);
}
+static void failedExecOfEmptyArgv()
+{
+ CU_ASSERT_EQUAL(libalts_exec_default(NULL), -1);
+ CU_ASSERT_EQUAL(errno, EINVAL);
+
+ char *empty_argv[] = { NULL };
+ CU_ASSERT_EQUAL(libalts_exec_default(empty_argv), -1);
+ CU_ASSERT_EQUAL(errno, EINVAL);
+}
+
static void validExecCommand()
{
char *command_false[] = { "/usr/path/test42", NULL };
@@ -509,7 +519,7 @@
static void validExecCommandReplacedArgv0()
{
- char *command_replace_argv[] = { "/usr/path/area48",
"argv_replaced_helper", NULL };
+ char *command_replace_argv[] = { "/usr/path/area48", "area48", NULL };
pid_t child_pid = fork();
int status = 1000;
@@ -527,6 +537,26 @@
}
}
+static void validExecCommandUpdateArgv0()
+{
+ char *command_update_argv[] = { "/usr/path/area49",
"argv_replaced_helper", NULL };
+ pid_t child_pid = fork();
+ int status = 1000;
+
+ switch (child_pid) {
+ case -1:
+ CU_ASSERT_FATAL(-1);
+ return;
+ case 0:
+ libalts_exec_default(command_update_argv);
+ exit(100);
+ default:
+ CU_ASSERT_EQUAL_FATAL(wait(&status), child_pid);
+ CU_ASSERT(WIFEXITED(status));
+ CU_ASSERT_EQUAL(WEXITSTATUS(status), 0);
+ }
+}
+
void addAlternativesAppTests()
{
CU_pSuite suite = CU_add_suite_with_setup_and_teardown("Alternative App
Tests", setupTests, cleanupTests, storeErrorCount, printOutputOnErrorIncrease);
@@ -545,7 +575,9 @@
suite = CU_add_suite_with_setup_and_teardown("Default Exec Tests",
setupExecTests, cleanupExecTests, storeErrorCount, printOutputOnErrorIncrease);
CU_ADD_TEST(suite, failedExecOfUnknown);
+ CU_ADD_TEST(suite, failedExecOfEmptyArgv);
CU_ADD_TEST(suite, validExecCommand);
CU_ADD_TEST(suite, validExecCommandKeepArgv0);
CU_ADD_TEST(suite, validExecCommandReplacedArgv0);
+ CU_ADD_TEST(suite, validExecCommandUpdateArgv0);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/libalternatives-v1.2+31.da24cd4/test/options_parser_tests.c
new/libalternatives-v2.0+0.4f22c01/test/options_parser_tests.c
--- old/libalternatives-v1.2+31.da24cd4/test/options_parser_tests.c
2023-10-10 14:11:24.000000000 +0200
+++ new/libalternatives-v2.0+0.4f22c01/test/options_parser_tests.c
2026-08-13 18:08:08.000000000 +0200
@@ -253,6 +253,17 @@
CU_ASSERT_EQUAL(result->options, ALTLINK_OPTIONS_KEEPARGV0);
}
+static void parseWithUpdateArgv0Option()
+{
+ const char data[] = "binary=/usr/bin/ls\noptions=UpdateArgv0";
+
+ CU_ASSERT_PTR_NOT_NULL(state = initOptionsParser());
+ CU_ASSERT_EQUAL(parseOptionsData(data, sizeof(data)-1, state), 0);
+ CU_ASSERT_PTR_NOT_NULL(result = doneOptionsParser(10, state));
+
+ CU_ASSERT_EQUAL(result->options, ALTLINK_OPTIONS_UPDATEARGV0);
+}
+
static void parseLongGroupsLine()
{
const char data[] =
"binary=testing\ngroup=vi,vim,ex,gex,edit,view,rview,eview,vimdiff,gvimdiff, 1
,2,3,4,5,10";
@@ -305,5 +316,6 @@
CU_ADD_TEST(tests, parsesMultipleGroupsAsLatestGroupList);
CU_ADD_TEST(tests, parseWithBadOptions);
CU_ADD_TEST(tests, parseWithGoodOptions);
+ CU_ADD_TEST(tests, parseWithUpdateArgv0Option);
CU_ADD_TEST(tests, parseLongGroupsLine);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/libalternatives-v1.2+31.da24cd4/test/test_exec/area49/10.conf
new/libalternatives-v2.0+0.4f22c01/test/test_exec/area49/10.conf
--- old/libalternatives-v1.2+31.da24cd4/test/test_exec/area49/10.conf
1970-01-01 01:00:00.000000000 +0100
+++ new/libalternatives-v2.0+0.4f22c01/test/test_exec/area49/10.conf
2026-08-13 18:08:08.000000000 +0200
@@ -0,0 +1,3 @@
+man=test
+binary=./build/test/argv_replaced_helper
+options=UpdateArgv0
\ No newline at end of file