Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libsemanage for openSUSE:Factory checked in at 2025-07-24 18:34:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libsemanage (Old) and /work/SRC/openSUSE:Factory/.libsemanage.new.13279 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libsemanage" Thu Jul 24 18:34:29 2025 rev:68 rq:1295309 version:3.9 Changes: -------- --- /work/SRC/openSUSE:Factory/libsemanage/libsemanage.changes 2025-07-22 12:21:34.931329159 +0200 +++ /work/SRC/openSUSE:Factory/.libsemanage.new.13279/libsemanage.changes 2025-07-24 18:34:32.938369610 +0200 @@ -1,0 +2,9 @@ +Thu Jul 17 15:46:08 UTC 2025 - Johannes Segitz <jseg...@suse.com> + +- Update to version 3.9 + * Improved POSIX compliance (added semanage_basename) + * Add relabel_store config option + * Add semanage_handle_create_with_path + * Add relabel_store config option to semanage.conf + +------------------------------------------------------------------- python-semanage.changes: same change Old: ---- libsemanage-3.8.1.tar.gz libsemanage-3.8.1.tar.gz.asc New: ---- libsemanage-3.9.tar.gz libsemanage-3.9.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libsemanage.spec ++++++ --- /var/tmp/diff_new_pack.oWl08K/_old 2025-07-24 18:34:33.486392281 +0200 +++ /var/tmp/diff_new_pack.oWl08K/_new 2025-07-24 18:34:33.486392281 +0200 @@ -20,7 +20,7 @@ %define libname libsemanage%{soversion} Name: libsemanage -Version: 3.8.1 +Version: 3.9 Release: 0 Summary: SELinux policy management library License: LGPL-2.1-or-later ++++++ python-semanage.spec ++++++ --- /var/tmp/diff_new_pack.oWl08K/_old 2025-07-24 18:34:33.514393439 +0200 +++ /var/tmp/diff_new_pack.oWl08K/_new 2025-07-24 18:34:33.518393605 +0200 @@ -20,12 +20,12 @@ %define soversion 2 %define libname libsemanage%{soversion} -%define libsepol_ver 3.8.1 -%define libselinux_ver 3.8.1 +%define libsepol_ver 3.9 +%define libselinux_ver 3.9 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-semanage -Version: 3.8.1 +Version: 3.9 Release: 0 Summary: Python bindings for SELinux's policy management library License: LGPL-2.1-only ++++++ libsemanage-3.8.1.tar.gz -> libsemanage-3.9.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/VERSION new/libsemanage-3.9/VERSION --- old/libsemanage-3.8.1/VERSION 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/VERSION 2025-07-16 12:55:13.000000000 +0200 @@ -1 +1 @@ -3.8.1 +3.9 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/include/semanage/handle.h new/libsemanage-3.9/include/semanage/handle.h --- old/libsemanage-3.8.1/include/semanage/handle.h 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/include/semanage/handle.h 2025-07-16 12:55:13.000000000 +0200 @@ -30,7 +30,11 @@ struct semanage_handle; typedef struct semanage_handle semanage_handle_t; -/* Create and return a semanage handle. +/* Create and return a semanage handle with a specific config path. + The handle is initially in the disconnected state. */ +semanage_handle_t *semanage_handle_create_with_path(const char *conf_name); + +/* Create and return a semanage handle with the default config path. The handle is initially in the disconnected state. */ extern semanage_handle_t *semanage_handle_create(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/Makefile new/libsemanage-3.9/src/Makefile --- old/libsemanage-3.8.1/src/Makefile 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/Makefile 2025-07-16 12:55:13.000000000 +0200 @@ -58,16 +58,19 @@ -fno-semantic-interposition SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno-shadow \ - -Wno-unused-parameter -Wno-missing-prototypes + -Wno-unused-parameter -Wno-missing-prototypes -Wno-missing-field-initializers -override CFLAGS += -I../include -D_GNU_SOURCE +override CFLAGS += -I../include -I../../libselinux/include -D_GNU_SOURCE RANLIB ?= ranlib SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./ SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ -all: $(LIBA) $(LIBSO) $(LIBPC) +all: $(LIBA) $(LIBPC) +ifneq ($(DISABLE_SHARED),y) +all: $(LIBSO) +endif pywrap: all $(SWIGSO) @@ -90,7 +93,7 @@ $(RANLIB) $@ $(LIBSO): $(LOBJS) - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -lsepol -laudit -lselinux -lbz2 -Wl,-soname,$(LIBSO),--version-script=libsemanage.map,-z,defs + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -L../../libselinux/src -lsepol -laudit -lselinux -lbz2 -Wl,-soname,$(LIBSO),--version-script=libsemanage.map,-z,defs ln -sf $@ $(TARGET) $(LIBPC): $(LIBPC).in ../VERSION @@ -137,11 +140,13 @@ install: all test -d $(DESTDIR)$(LIBDIR) || install -m 755 -d $(DESTDIR)$(LIBDIR) install -m 644 $(LIBA) $(DESTDIR)$(LIBDIR) - install -m 755 $(LIBSO) $(DESTDIR)$(LIBDIR) test -d $(DESTDIR)$(LIBDIR)/pkgconfig || install -m 755 -d $(DESTDIR)$(LIBDIR)/pkgconfig install -m 644 $(LIBPC) $(DESTDIR)$(LIBDIR)/pkgconfig test -f $(DESTDIR)$(DEFAULT_SEMANAGE_CONF_LOCATION) || install -m 644 -D semanage.conf $(DESTDIR)$(DEFAULT_SEMANAGE_CONF_LOCATION) +ifneq ($(DISABLE_SHARED),y) + install -m 755 $(LIBSO) $(DESTDIR)$(LIBDIR) cd $(DESTDIR)$(LIBDIR) && ln -sf $(LIBSO) $(TARGET) +endif install-pywrap: pywrap test -d $(DESTDIR)$(PYTHONLIBDIR) || install -m 755 -d $(DESTDIR)$(PYTHONLIBDIR) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/conf-parse.y new/libsemanage-3.9/src/conf-parse.y --- old/libsemanage-3.8.1/src/conf-parse.y 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/conf-parse.y 2025-07-16 12:55:13.000000000 +0200 @@ -21,6 +21,7 @@ %{ #include "semanage_conf.h" +#include "utilities.h" #include <sepol/policydb.h> #include <selinux/selinux.h> @@ -53,7 +54,7 @@ %} -%name-prefix "semanage_" +%define api.prefix {semanage_} %union { int d; @@ -62,7 +63,7 @@ %token MODULE_STORE VERSION EXPAND_CHECK FILE_MODE SAVE_PREVIOUS SAVE_LINKED TARGET_PLATFORM COMPILER_DIR IGNORE_MODULE_CACHE STORE_ROOT OPTIMIZE_POLICY MULTIPLE_DECLS %token LOAD_POLICY_START SETFILES_START SEFCONTEXT_COMPILE_START DISABLE_GENHOMEDIRCON HANDLE_UNKNOWN USEPASSWD IGNOREDIRS -%token BZIP_BLOCKSIZE BZIP_SMALL REMOVE_HLL +%token BZIP_BLOCKSIZE BZIP_SMALL RELABEL_STORE REMOVE_HLL %token VERIFY_MOD_START VERIFY_LINKED_START VERIFY_KERNEL_START BLOCK_END %token PROG_PATH PROG_ARGS %token <s> ARG @@ -96,6 +97,7 @@ | bzip_blocksize | bzip_small | remove_hll + | relabel_store | optimize_policy | multiple_decls ; @@ -290,6 +292,17 @@ free($3); } +relabel_store: RELABEL_STORE'=' ARG { + if (strcasecmp($3, "false") == 0) { + current_conf->relabel_store = 0; + } else if (strcasecmp($3, "true") == 0) { + current_conf->relabel_store = 1; + } else { + yyerror("relabel_store can only be 'true' or 'false'"); + } + free($3); +} + optimize_policy: OPTIMIZE_POLICY '=' ARG { if (strcasecmp($3, "false") == 0) { current_conf->optimize_policy = 0; @@ -382,7 +395,10 @@ static int semanage_conf_init(semanage_conf_t * conf) { conf->store_type = SEMANAGE_CON_DIRECT; - conf->store_path = strdup(basename(selinux_policy_root())); + const char *policy_root = selinux_policy_root(); + if (policy_root != NULL) { + conf->store_path = strdup(semanage_basename(policy_root)); + } conf->ignoredirs = NULL; conf->store_root_path = strdup("/var/lib/selinux"); conf->compiler_directory_path = strdup("/usr/libexec/selinux/hll"); @@ -396,6 +412,7 @@ conf->bzip_small = 0; conf->ignore_module_cache = 0; conf->remove_hll = 0; + conf->relabel_store = 1; conf->optimize_policy = 1; conf->multiple_decls = 1; @@ -544,8 +561,11 @@ free(current_conf->store_path); if (strcmp(arg, "direct") == 0) { current_conf->store_type = SEMANAGE_CON_DIRECT; - current_conf->store_path = - strdup(basename(selinux_policy_root())); + const char *policy_root = selinux_policy_root(); + if (policy_root != NULL) { + current_conf->store_path = + strdup(semanage_basename(policy_root)); + } current_conf->server_port = -1; } else if (*arg == '/') { current_conf->store_type = SEMANAGE_CON_POLSERV_LOCAL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/conf-scan.l new/libsemanage-3.9/src/conf-scan.l --- old/libsemanage-3.8.1/src/conf-scan.l 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/conf-scan.l 2025-07-16 12:55:13.000000000 +0200 @@ -54,6 +54,7 @@ bzip-blocksize return BZIP_BLOCKSIZE; bzip-small return BZIP_SMALL; remove-hll return REMOVE_HLL; +relabel_store return RELABEL_STORE; optimize-policy return OPTIMIZE_POLICY; multiple-decls return MULTIPLE_DECLS; "[load_policy]" return LOAD_POLICY_START; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/direct_api.c new/libsemanage-3.9/src/direct_api.c --- old/libsemanage-3.8.1/src/direct_api.c 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/direct_api.c 2025-07-16 12:55:13.000000000 +0200 @@ -26,6 +26,7 @@ #include <assert.h> #include <fcntl.h> +#include <libgen.h> #include <stdio.h> #include <stdio_ext.h> #include <stdlib.h> @@ -621,6 +622,23 @@ return 0; } +// Forward error messages to redirected stderr pipe +#define ERR_CHILD_STDERR(handle, ...) \ + { \ + char buf[2048]; \ + int errsv = errno, n; \ + (void)! write_full(err_fd[PIPE_WRITE], "libsemanage.semanage_pipe_data: ", strlen("libsemanage.semanage_pipe_data: ")); \ + n = snprintf(buf, sizeof(buf), __VA_ARGS__); \ + (void)! write_full(err_fd[PIPE_WRITE], buf, n); \ + if (errsv) { \ + errno = errsv; \ + n = snprintf(buf, sizeof(buf), " (%m)."); \ + (void)! write_full(err_fd[PIPE_WRITE], buf, n); \ + } \ + (void)! write_full(err_fd[PIPE_WRITE], "\n", strlen("\n")); \ + (void)! fsync(err_fd[PIPE_WRITE]); \ + } + static int semanage_pipe_data(semanage_handle_t *sh, const char *path, const char *in_data, size_t in_data_len, char **out_data, size_t *out_data_len, char **err_data, size_t *err_data_len) { int input_fd[2] = {-1, -1}; @@ -672,97 +690,100 @@ retval = dup2(input_fd[PIPE_READ], STDIN_FILENO); if (retval == -1) { ERR(sh, "Unable to dup2 input pipe."); - goto cleanup; + goto child_err; } retval = dup2(output_fd[PIPE_WRITE], STDOUT_FILENO); if (retval == -1) { ERR(sh, "Unable to dup2 output pipe."); - goto cleanup; + goto child_err; } retval = dup2(err_fd[PIPE_WRITE], STDERR_FILENO); if (retval == -1) { ERR(sh, "Unable to dup2 error pipe."); - goto cleanup; + goto child_err; } retval = close(input_fd[PIPE_WRITE]); if (retval == -1) { - ERR(sh, "Unable to close input pipe."); - goto cleanup; + ERR_CHILD_STDERR(sh, "Unable to close input pipe."); + goto child_err; } retval = close(output_fd[PIPE_READ]); if (retval == -1) { - ERR(sh, "Unable to close output pipe."); - goto cleanup; + ERR_CHILD_STDERR(sh, "Unable to close output pipe."); + goto child_err; } retval = close(err_fd[PIPE_READ]); if (retval == -1) { - ERR(sh, "Unable to close error pipe."); - goto cleanup; - } - retval = execl(path, path, NULL); - if (retval == -1) { - ERR(sh, "Unable to execute %s.", path); - _exit(EXIT_FAILURE); + ERR_CHILD_STDERR(sh, "Unable to close error pipe."); + goto child_err; } + execl(path, path, NULL); + ERR_CHILD_STDERR(sh, "Unable to execute %s.", path); + +child_err: + _exit(EXIT_FAILURE); } else { + int any_err = 0; + retval = close(input_fd[PIPE_READ]); input_fd[PIPE_READ] = -1; if (retval == -1) { ERR(sh, "Unable to close read end of input pipe."); - goto cleanup; + any_err = 1; } retval = close(output_fd[PIPE_WRITE]); output_fd[PIPE_WRITE] = -1; if (retval == -1) { ERR(sh, "Unable to close write end of output pipe."); - goto cleanup; + any_err = 1; } retval = close(err_fd[PIPE_WRITE]); err_fd[PIPE_WRITE] = -1; if (retval == -1) { ERR(sh, "Unable to close write end of error pipe."); - goto cleanup; + any_err = 1; } retval = write_full(input_fd[PIPE_WRITE], in_data, in_data_len); if (retval == -1) { ERR(sh, "Failed to write data to input pipe."); - goto cleanup; + any_err = 1; } retval = close(input_fd[PIPE_WRITE]); input_fd[PIPE_WRITE] = -1; if (retval == -1) { ERR(sh, "Unable to close write end of input pipe."); - goto cleanup; + any_err = 1; } initial_len = 1 << 17; retval = read_from_pipe_to_data(sh, initial_len, output_fd[PIPE_READ], &data_read, &data_read_len); if (retval != 0) { - goto cleanup; + any_err = 1; } retval = close(output_fd[PIPE_READ]); output_fd[PIPE_READ] = -1; if (retval == -1) { ERR(sh, "Unable to close read end of output pipe."); - goto cleanup; + any_err = 1; } initial_len = 1 << 9; retval = read_from_pipe_to_data(sh, initial_len, err_fd[PIPE_READ], &err_data_read, &err_data_read_len); if (retval != 0) { - goto cleanup; + any_err = 1; } retval = close(err_fd[PIPE_READ]); err_fd[PIPE_READ] = -1; if (retval == -1) { ERR(sh, "Unable to close read end of error pipe."); - goto cleanup; + any_err = 1; } + errno = ENODATA; if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status)) { ERR(sh, "Child process %s did not exit cleanly.", path); retval = -1; @@ -773,6 +794,11 @@ retval = -1; goto cleanup; } + + if (any_err) { + retval = -1; + goto cleanup; + } } retval = 0; @@ -934,9 +960,13 @@ hll_contents.len, &cil_data, &cil_data_len, &err_data, &err_data_len); if (err_data_len > 0) { + int errsv = errno; + + errno = 0; + for (start = end = err_data; end < err_data + err_data_len; end++) { if (*end == '\n') { - ERR(sh, "%s: %.*s.", modinfo->name, (int)(end - start + 1), start); + ERR(sh, "%s: %.*s.", modinfo->name, (int)(end - start), start); start = end + 1; } } @@ -944,6 +974,8 @@ if (end != start) { ERR(sh, "%s: %.*s.", modinfo->name, (int)(end - start), start); } + + errno = errsv; } if (status != 0) { goto cleanup; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/handle.c new/libsemanage-3.9/src/handle.c --- old/libsemanage-3.8.1/src/handle.c 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/handle.c 2025-07-16 12:55:13.000000000 +0200 @@ -59,19 +59,14 @@ return private_semanage_root; } - -semanage_handle_t *semanage_handle_create(void) +semanage_handle_t *semanage_handle_create_with_path(const char *conf_name) { semanage_handle_t *sh = NULL; - char *conf_name = NULL; /* Allocate handle */ if ((sh = calloc(1, sizeof(semanage_handle_t))) == NULL) goto err; - if ((conf_name = semanage_conf_path()) == NULL) - goto err; - if ((sh->conf = semanage_conf_parse(conf_name)) == NULL) goto err; @@ -106,13 +101,30 @@ sh->msg_callback = semanage_msg_default_handler; sh->msg_callback_arg = NULL; + return sh; + + err: + semanage_handle_destroy(sh); + return NULL; +} + +semanage_handle_t *semanage_handle_create(void) +{ + semanage_handle_t *sh = NULL; + char *conf_name = NULL; + + if ((conf_name = semanage_conf_path()) == NULL) + goto err; + + if ((sh = semanage_handle_create_with_path(conf_name)) == NULL) + goto err; + free(conf_name); return sh; err: free(conf_name); - semanage_handle_destroy(sh); return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/libsemanage.map new/libsemanage-3.9/src/libsemanage.map --- old/libsemanage-3.8.1/src/libsemanage.map 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/libsemanage.map 2025-07-16 12:55:13.000000000 +0200 @@ -350,3 +350,7 @@ semanage_module_compute_checksum; semanage_set_check_ext_changes; } LIBSEMANAGE_1.1; + +LIBSEMANAGE_3.9 { + semanage_handle_create_with_path; +} LIBSEMANAGE_3.4; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/libsemanage.pc.in new/libsemanage-3.9/src/libsemanage.pc.in --- old/libsemanage-3.8.1/src/libsemanage.pc.in 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/libsemanage.pc.in 2025-07-16 12:55:13.000000000 +0200 @@ -6,8 +6,8 @@ Name: libsemanage Description: SELinux management library Version: @VERSION@ -URL: http://userspace.selinuxproject.org/ +URL: https://github.com/selinuxproject/selinux/wiki/Releases Requires.private: libselinux libsepol Libs: -L${libdir} -lsemanage -Libs.private: -lbz2 +Libs.private: -laudit -lbz2 Cflags: -I${includedir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/semanage_conf.h new/libsemanage-3.9/src/semanage_conf.h --- old/libsemanage-3.8.1/src/semanage_conf.h 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/semanage_conf.h 2025-07-16 12:55:13.000000000 +0200 @@ -49,6 +49,7 @@ int ignore_module_cache; int optimize_policy; int multiple_decls; + int relabel_store; char *ignoredirs; /* ";" separated of list for genhomedircon to ignore */ struct external_prog *load_policy; struct external_prog *setfiles; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/semanage_store.c new/libsemanage-3.9/src/semanage_store.c --- old/libsemanage-3.8.1/src/semanage_store.c 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/semanage_store.c 2025-07-16 12:55:13.000000000 +0200 @@ -1823,8 +1823,11 @@ cleanup: semanage_release_active_lock(sh); - sehandle = selinux_restorecon_default_handle(); - selinux_restorecon_set_sehandle(sehandle); + + if (sh->conf->relabel_store) { + sehandle = selinux_restorecon_default_handle(); + selinux_restorecon_set_sehandle(sehandle); + } return retval; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/utilities.c new/libsemanage-3.9/src/utilities.c --- old/libsemanage-3.8.1/src/utilities.c 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/utilities.c 2025-07-16 12:55:13.000000000 +0200 @@ -349,3 +349,12 @@ return 0; } + +#ifdef __GNUC__ +__attribute__((nonnull)) +#endif +char *semanage_basename(const char *filename) +{ + char *p = strrchr(filename, '/'); + return p ? p + 1 : (char *)filename; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/src/utilities.h new/libsemanage-3.9/src/utilities.h --- old/libsemanage-3.8.1/src/utilities.h 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/src/utilities.h 2025-07-16 12:55:13.000000000 +0200 @@ -156,4 +156,17 @@ int write_full(int fd, const void *buf, size_t len) WARN_UNUSED; +/** + * Portable implementation of the glibc version of basename(3). + * + * @param filename path to find basename of + * + * @return basename of filename + */ + +#ifdef __GNUC__ +__attribute__((nonnull)) +#endif +char *semanage_basename(const char *filename); + #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsemanage-3.8.1/tests/test_utilities.c new/libsemanage-3.9/tests/test_utilities.c --- old/libsemanage-3.8.1/tests/test_utilities.c 2025-03-05 19:59:06.000000000 +0100 +++ new/libsemanage-3.9/tests/test_utilities.c 2025-07-16 12:55:13.000000000 +0200 @@ -46,6 +46,7 @@ static void test_semanage_str_replace(void); static void test_semanage_findval(void); static void test_slurp_file_filter(void); +static void test_semanage_basename(void); static char fname[] = { 'T', 'E', 'S', 'T', '_', 'T', 'E', 'M', 'P', '_', 'X', 'X', 'X', 'X', @@ -117,6 +118,10 @@ test_slurp_file_filter)) { goto err; } + if (NULL == CU_add_test(suite, "semanage_basename", + test_semanage_basename)) { + goto err; + } return 0; err: CU_cleanup_registry(); @@ -346,3 +351,24 @@ semanage_list_destroy(&data); } + +static void test_semanage_basename(void) +{ + char *basename1 = semanage_basename("/foo/bar"); + CU_ASSERT_STRING_EQUAL(basename1, "bar"); + + char *basename2 = semanage_basename("/foo/bar/"); + CU_ASSERT_STRING_EQUAL(basename2, ""); + + char *basename3 = semanage_basename("/foo.bar"); + CU_ASSERT_STRING_EQUAL(basename3, "foo.bar"); + + char *basename5 = semanage_basename("."); + CU_ASSERT_STRING_EQUAL(basename5, "."); + + char *basename6 = semanage_basename(""); + CU_ASSERT_STRING_EQUAL(basename6, ""); + + char *basename7 = semanage_basename("/"); + CU_ASSERT_STRING_EQUAL(basename7, ""); +}