2020-11-09 13:23:58 +09:00
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2015-04-10 19:10:00 +02:00
2019-10-31 11:07:23 +09:00
# include <fcntl.h>
2021-09-30 11:19:34 +02:00
# include <linux/oom.h>
2016-06-14 23:52:29 +02:00
# include <sys/mount.h>
2016-02-22 18:36:54 +01:00
# include <sys/personality.h>
2016-06-14 23:52:29 +02:00
# include <sys/prctl.h>
2015-04-10 19:10:00 +02:00
# include <sys/stat.h>
2015-10-24 22:58:24 +02:00
# include <sys/types.h>
2015-04-10 19:10:00 +02:00
# include <sys/wait.h>
# include <unistd.h>
2017-10-03 10:41:51 +02:00
# if HAVE_VALGRIND_VALGRIND_H
2016-06-19 23:43:35 +00:00
# include <valgrind/valgrind.h>
# endif
2015-04-10 19:10:00 +02:00
2015-10-27 03:01:06 +01:00
# include "alloc-util.h"
2016-02-22 18:36:54 +01:00
# include "architecture.h"
2021-04-01 16:46:01 +02:00
# include "dirent-util.h"
2021-07-07 15:57:51 +02:00
# include "errno-list.h"
# include "errno-util.h"
2016-06-14 23:52:29 +02:00
# include "fd-util.h"
2021-11-24 15:24:55 +01:00
# include "ioprio-util.h"
2015-04-10 19:10:00 +02:00
# include "log.h"
# include "macro.h"
2019-10-31 11:07:23 +09:00
# include "missing_sched.h"
# include "missing_syscall.h"
2016-06-12 19:51:11 -04:00
# include "parse-util.h"
2015-10-24 22:58:24 +02:00
# include "process-util.h"
2021-07-07 15:57:51 +02:00
# include "procfs-util.h"
2020-01-02 17:33:51 +01:00
# include "rlimit-util.h"
2017-12-22 13:08:14 +01:00
# include "signal-util.h"
2016-06-12 19:42:51 -04:00
# include "stdio-util.h"
2015-10-24 22:58:24 +02:00
# include "string-util.h"
2015-04-10 23:15:59 +02:00
# include "terminal-util.h"
2018-09-13 14:31:13 +02:00
# include "tests.h"
2020-01-02 17:33:51 +01:00
# include "user-util.h"
2015-10-24 22:58:24 +02:00
# include "util.h"
# include "virt.h"
2015-04-10 19:10:00 +02:00
2021-11-24 12:11:17 +01:00
static void test_get_process_comm_one ( pid_t pid ) {
2015-04-10 19:10:00 +02:00
struct stat st ;
2016-07-18 22:31:34 +02:00
_cleanup_free_ char * a = NULL , * c = NULL , * d = NULL , * f = NULL , * i = NULL ;
2015-04-10 19:10:00 +02:00
_cleanup_free_ char * env = NULL ;
2017-12-14 19:02:29 +01:00
char path [ STRLEN ( " /proc//comm " ) + DECIMAL_STR_MAX ( pid_t ) ] ;
2015-04-10 19:10:00 +02:00
pid_t e ;
uid_t u ;
gid_t g ;
dev_t h ;
int r ;
2021-04-02 11:35:23 +02:00
log_info ( " /* %s */ " , __func__ ) ;
2016-06-12 19:42:51 -04:00
xsprintf ( path , " /proc/ " PID_FMT " /comm " , pid ) ;
if ( stat ( path , & st ) = = 0 ) {
assert_se ( get_process_comm ( pid , & a ) > = 0 ) ;
log_info ( " PID " PID_FMT " comm: '%s' " , pid , a ) ;
2015-04-29 21:40:54 +02:00
} else
2016-06-12 19:42:51 -04:00
log_warning ( " %s not exist. " , path ) ;
2015-04-10 19:10:00 +02:00
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( pid , 0 , PROCESS_CMDLINE_COMM_FALLBACK , & c ) > = 0 ) ;
2016-06-12 19:42:51 -04:00
log_info ( " PID " PID_FMT " cmdline: '%s' " , pid , c ) ;
2015-04-10 19:10:00 +02:00
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( pid , 8 , 0 , & d ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
log_info ( " PID " PID_FMT " cmdline truncated to 8: '%s' " , pid , d ) ;
free ( d ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( pid , 1 , 0 , & d ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
log_info ( " PID " PID_FMT " cmdline truncated to 1: '%s' " , pid , d ) ;
2015-04-10 19:10:00 +02:00
2021-07-07 15:57:51 +02:00
r = get_process_ppid ( pid , & e ) ;
assert_se ( pid = = 1 ? r = = - EADDRNOTAVAIL : r > = 0 ) ;
if ( r > = 0 ) {
log_info ( " PID " PID_FMT " PPID: " PID_FMT , pid , e ) ;
assert_se ( e > 0 ) ;
}
2015-04-10 19:10:00 +02:00
2016-06-12 19:42:51 -04:00
assert_se ( is_kernel_thread ( pid ) = = 0 | | pid ! = 1 ) ;
2015-04-10 19:10:00 +02:00
2016-06-12 19:42:51 -04:00
r = get_process_exe ( pid , & f ) ;
2015-04-10 19:10:00 +02:00
assert_se ( r > = 0 | | r = = - EACCES ) ;
2016-06-12 19:42:51 -04:00
log_info ( " PID " PID_FMT " exe: '%s' " , pid , strna ( f ) ) ;
2015-04-10 19:10:00 +02:00
2016-06-12 19:42:51 -04:00
assert_se ( get_process_uid ( pid , & u ) = = 0 ) ;
log_info ( " PID " PID_FMT " UID: " UID_FMT , pid , u ) ;
2015-04-10 19:10:00 +02:00
2016-06-12 19:42:51 -04:00
assert_se ( get_process_gid ( pid , & g ) = = 0 ) ;
log_info ( " PID " PID_FMT " GID: " GID_FMT , pid , g ) ;
2015-04-10 19:10:00 +02:00
2016-06-12 19:42:51 -04:00
r = get_process_environ ( pid , & env ) ;
2015-04-10 19:10:00 +02:00
assert_se ( r > = 0 | | r = = - EACCES ) ;
2016-06-12 19:42:51 -04:00
log_info ( " PID " PID_FMT " strlen(environ): %zi " , pid , env ? ( ssize_t ) strlen ( env ) : ( ssize_t ) - errno ) ;
2015-04-10 19:10:00 +02:00
2015-09-07 13:42:47 +02:00
if ( ! detect_container ( ) )
2016-06-12 19:42:51 -04:00
assert_se ( get_ctty_devnr ( pid , & h ) = = - ENXIO | | pid ! = 1 ) ;
2015-04-10 19:10:00 +02:00
2018-02-16 07:03:13 +01:00
( void ) getenv_for_pid ( pid , " PATH " , & i ) ;
2016-06-12 19:42:51 -04:00
log_info ( " PID " PID_FMT " $PATH: '%s' " , pid , strna ( i ) ) ;
2015-04-10 19:10:00 +02:00
}
2021-11-24 12:11:17 +01:00
TEST ( get_process_comm ) {
if ( saved_argc > 1 ) {
pid_t pid = 0 ;
( void ) parse_pid ( saved_argv [ 1 ] , & pid ) ;
test_get_process_comm_one ( pid ) ;
} else {
TEST_REQ_RUNNING_SYSTEMD ( test_get_process_comm_one ( 1 ) ) ;
test_get_process_comm_one ( getpid ( ) ) ;
}
}
2021-04-01 16:46:01 +02:00
static void test_get_process_cmdline_one ( pid_t pid ) {
_cleanup_free_ char * c = NULL , * d = NULL , * e = NULL , * f = NULL , * g = NULL , * h = NULL ;
int r ;
r = get_process_cmdline ( pid , SIZE_MAX , 0 , & c ) ;
log_info ( " PID " PID_FMT " : %s " , pid , r > = 0 ? c : errno_to_name ( r ) ) ;
r = get_process_cmdline ( pid , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & d ) ;
log_info ( " %s " , r > = 0 ? d : errno_to_name ( r ) ) ;
r = get_process_cmdline ( pid , SIZE_MAX , PROCESS_CMDLINE_QUOTE , & e ) ;
log_info ( " %s " , r > = 0 ? e : errno_to_name ( r ) ) ;
r = get_process_cmdline ( pid , SIZE_MAX , PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_COMM_FALLBACK , & f ) ;
log_info ( " %s " , r > = 0 ? f : errno_to_name ( r ) ) ;
r = get_process_cmdline ( pid , SIZE_MAX , PROCESS_CMDLINE_QUOTE_POSIX , & g ) ;
log_info ( " %s " , r > = 0 ? g : errno_to_name ( r ) ) ;
r = get_process_cmdline ( pid , SIZE_MAX , PROCESS_CMDLINE_QUOTE_POSIX | PROCESS_CMDLINE_COMM_FALLBACK , & h ) ;
log_info ( " %s " , r > = 0 ? h : errno_to_name ( r ) ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( get_process_cmdline ) {
2021-04-01 16:46:01 +02:00
_cleanup_closedir_ DIR * d = NULL ;
assert_se ( d = opendir ( " /proc " ) ) ;
FOREACH_DIRENT ( de , d , return ) {
pid_t pid ;
if ( de - > d_type ! = DT_DIR )
continue ;
if ( parse_pid ( de - > d_name , & pid ) < 0 )
continue ;
test_get_process_cmdline_one ( pid ) ;
}
}
2018-05-16 21:50:35 -04:00
static void test_get_process_comm_escape_one ( const char * input , const char * output ) {
_cleanup_free_ char * n = NULL ;
2021-04-02 11:35:23 +02:00
log_debug ( " input: <%s> — output: <%s> " , input , output ) ;
2018-05-16 21:50:35 -04:00
assert_se ( prctl ( PR_SET_NAME , input ) > = 0 ) ;
assert_se ( get_process_comm ( 0 , & n ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " got: <%s> " , n ) ;
2018-05-16 21:50:35 -04:00
assert_se ( streq_ptr ( n , output ) ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( get_process_comm_escape ) {
2018-05-16 21:50:35 -04:00
_cleanup_free_ char * saved = NULL ;
assert_se ( get_process_comm ( 0 , & saved ) > = 0 ) ;
test_get_process_comm_escape_one ( " " , " " ) ;
test_get_process_comm_escape_one ( " foo " , " foo " ) ;
test_get_process_comm_escape_one ( " 012345678901234 " , " 012345678901234 " ) ;
test_get_process_comm_escape_one ( " 0123456789012345 " , " 012345678901234 " ) ;
2019-05-15 11:55:59 +02:00
test_get_process_comm_escape_one ( " äöüß " , " \\ 303 \\ 244 \\ 303 \\ 266 \\ 303 \\ 274 \\ 303 \\ 237 " ) ;
test_get_process_comm_escape_one ( " xäöüß " , " x \\ 303 \\ 244 \\ 303 \\ 266 \\ 303 \\ 274 \\ 303 \\ 237 " ) ;
test_get_process_comm_escape_one ( " xxäöüß " , " xx \\ 303 \\ 244 \\ 303 \\ 266 \\ 303 \\ 274 \\ 303 \\ 237 " ) ;
test_get_process_comm_escape_one ( " xxxäöüß " , " xxx \\ 303 \\ 244 \\ 303 \\ 266 \\ 303 \\ 274 \\ 303 \\ 237 " ) ;
test_get_process_comm_escape_one ( " xxxxäöüß " , " xxxx \\ 303 \\ 244 \\ 303 \\ 266 \\ 303 \\ 274 \\ 303 \\ 237 " ) ;
test_get_process_comm_escape_one ( " xxxxxäöüß " , " xxxxx \\ 303 \\ 244 \\ 303 \\ 266 \\ 303 \\ 274 \\ 303 \\ 237 " ) ;
2018-05-16 21:50:35 -04:00
assert_se ( prctl ( PR_SET_NAME , saved ) > = 0 ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( pid_is_unwaited ) {
2015-04-10 19:10:00 +02:00
pid_t pid ;
pid = fork ( ) ;
assert_se ( pid > = 0 ) ;
if ( pid = = 0 ) {
_exit ( EXIT_SUCCESS ) ;
} else {
int status ;
waitpid ( pid , & status , 0 ) ;
assert_se ( ! pid_is_unwaited ( pid ) ) ;
}
2017-07-20 16:19:18 +02:00
assert_se ( pid_is_unwaited ( getpid_cached ( ) ) ) ;
2015-04-10 19:10:00 +02:00
assert_se ( ! pid_is_unwaited ( - 1 ) ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( pid_is_alive ) {
2015-04-10 19:10:00 +02:00
pid_t pid ;
pid = fork ( ) ;
assert_se ( pid > = 0 ) ;
if ( pid = = 0 ) {
_exit ( EXIT_SUCCESS ) ;
} else {
int status ;
waitpid ( pid , & status , 0 ) ;
assert_se ( ! pid_is_alive ( pid ) ) ;
}
2017-07-20 16:19:18 +02:00
assert_se ( pid_is_alive ( getpid_cached ( ) ) ) ;
2015-04-10 19:10:00 +02:00
assert_se ( ! pid_is_alive ( - 1 ) ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( personality ) {
2016-02-22 18:36:54 +01:00
assert_se ( personality_to_string ( PER_LINUX ) ) ;
assert_se ( ! personality_to_string ( PERSONALITY_INVALID ) ) ;
assert_se ( streq ( personality_to_string ( PER_LINUX ) , architecture_to_string ( native_architecture ( ) ) ) ) ;
assert_se ( personality_from_string ( personality_to_string ( PER_LINUX ) ) = = PER_LINUX ) ;
assert_se ( personality_from_string ( architecture_to_string ( native_architecture ( ) ) ) = = PER_LINUX ) ;
# ifdef __x86_64__
assert_se ( streq_ptr ( personality_to_string ( PER_LINUX ) , " x86-64 " ) ) ;
assert_se ( streq_ptr ( personality_to_string ( PER_LINUX32 ) , " x86 " ) ) ;
assert_se ( personality_from_string ( " x86-64 " ) = = PER_LINUX ) ;
assert_se ( personality_from_string ( " x86 " ) = = PER_LINUX32 ) ;
assert_se ( personality_from_string ( " ia64 " ) = = PERSONALITY_INVALID ) ;
assert_se ( personality_from_string ( NULL ) = = PERSONALITY_INVALID ) ;
assert_se ( personality_from_string ( personality_to_string ( PER_LINUX32 ) ) = = PER_LINUX32 ) ;
# endif
}
2021-11-24 12:11:17 +01:00
TEST ( get_process_cmdline_harder ) {
2016-06-14 23:52:29 +02:00
char path [ ] = " /tmp/test-cmdlineXXXXXX " ;
_cleanup_close_ int fd = - 1 ;
_cleanup_free_ char * line = NULL ;
pid_t pid ;
2018-09-20 16:09:05 +09:00
if ( geteuid ( ) ! = 0 ) {
log_info ( " Skipping %s: not root " , __func__ ) ;
2016-06-14 23:52:29 +02:00
return ;
2018-09-20 16:09:05 +09:00
}
2016-06-14 23:52:29 +02:00
2018-10-24 16:53:14 +02:00
if ( ! have_namespaces ( ) ) {
log_notice ( " Testing without namespaces, skipping %s " , __func__ ) ;
return ;
}
2017-10-03 10:41:51 +02:00
# if HAVE_VALGRIND_VALGRIND_H
2016-06-19 23:43:35 +00:00
/* valgrind patches open(/proc//cmdline)
* so , test_get_process_cmdline_harder fails always
* See https : //github.com/systemd/systemd/pull/3555#issuecomment-226564908 */
2018-09-20 16:09:05 +09:00
if ( RUNNING_ON_VALGRIND ) {
log_info ( " Skipping %s: running on valgrind " , __func__ ) ;
2016-06-19 23:43:35 +00:00
return ;
2018-09-20 16:09:05 +09:00
}
2016-06-19 23:43:35 +00:00
# endif
2016-06-14 23:52:29 +02:00
pid = fork ( ) ;
if ( pid > 0 ) {
siginfo_t si ;
( void ) wait_for_terminate ( pid , & si ) ;
assert_se ( si . si_code = = CLD_EXITED ) ;
assert_se ( si . si_status = = 0 ) ;
return ;
}
assert_se ( pid = = 0 ) ;
assert_se ( unshare ( CLONE_NEWNS ) > = 0 ) ;
2018-07-19 10:24:07 +00:00
if ( mount ( NULL , " / " , NULL , MS_SLAVE | MS_REC , NULL ) < 0 ) {
log_warning_errno ( errno , " mount(..., \" / \" , MS_SLAVE|MS_REC, ...) failed: %m " ) ;
assert_se ( IN_SET ( errno , EPERM , EACCES ) ) ;
return ;
}
2018-03-09 01:10:42 +00:00
2016-06-14 23:52:29 +02:00
fd = mkostemp ( path , O_CLOEXEC ) ;
assert_se ( fd > = 0 ) ;
2016-11-17 20:57:22 -05:00
2018-07-19 10:24:07 +00:00
/* Note that we don't unmount the following bind-mount at the end of the test because the kernel
* will clear up its / proc / PID / hierarchy automatically as soon as the test stops . */
2016-11-17 20:57:22 -05:00
if ( mount ( path , " /proc/self/cmdline " , " bind " , MS_BIND , NULL ) < 0 ) {
/* This happens under selinux… Abort the test in this case. */
log_warning_errno ( errno , " mount(..., \" /proc/self/cmdline \" , \" bind \" , ...) failed: %m " ) ;
2018-07-19 10:24:07 +00:00
assert_se ( IN_SET ( errno , EPERM , EACCES ) ) ;
2016-11-17 20:57:22 -05:00
return ;
}
2021-03-23 00:49:28 -07:00
/* Set RLIMIT_STACK to infinity to test we don't try to allocate unncessarily large values to read
* the cmdline . */
if ( setrlimit ( RLIMIT_STACK , & RLIMIT_MAKE_CONST ( RLIM_INFINITY ) ) < 0 )
log_warning ( " Testing without RLIMIT_STACK=infinity " ) ;
2016-06-14 23:52:29 +02:00
assert_se ( unlink ( path ) > = 0 ) ;
assert_se ( prctl ( PR_SET_NAME , " testa " ) > = 0 ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , 0 , & line ) = = - ENOENT ) ;
2016-06-14 23:52:29 +02:00
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [testa] " ) ) ;
line = mfree ( line ) ;
2021-03-30 19:42:36 +02:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2021-03-30 19:42:36 +02:00
assert_se ( streq ( line , " \" [testa] \" " ) ) ; /* quoting is enabled here */
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 0 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 1 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " … " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 2 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 3 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [t… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 4 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [te… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 5 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [tes… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 6 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [test… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 7 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [testa] " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 8 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [testa] " ) ) ;
line = mfree ( line ) ;
2021-03-30 19:42:36 +02:00
/* Test with multiple arguments that don't require quoting */
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( write ( fd , " foo \0 bar " , 8 ) = = 8 ) ;
2016-06-14 23:52:29 +02:00
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , 0 , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar " ) ) ;
line = mfree ( line ) ;
assert_se ( write ( fd , " quux " , 4 ) = = 4 ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , 0 , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 1 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 2 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " f… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 3 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " fo… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 4 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 5 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 6 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo b… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 7 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo ba… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 8 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo bar… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 9 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo bar … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 10 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo bar q… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 11 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo bar qu… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 12 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 13 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 14 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 1000 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
assert_se ( ftruncate ( fd , 0 ) > = 0 ) ;
assert_se ( prctl ( PR_SET_NAME , " aaaa bbbb cccc " ) > = 0 ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , 0 , & line ) = = - ENOENT ) ;
2016-06-14 23:52:29 +02:00
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [aaaa bbbb cccc] " ) ) ;
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 10 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [aaaa bbb… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 11 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [aaaa bbbb… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-03 11:46:11 +01:00
assert_se ( get_process_cmdline ( 0 , 12 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " '%s' " , line ) ;
Rework cmdline printing to use unicode
The functions to retrieve and print process cmdlines were based on the
assumption that they contain printable ASCII, and everything else
should be filtered out. That assumption doesn't hold in today's world,
where people are free to use unicode everywhere.
This replaces the custom cmdline reading code with a more generic approach
using utf8_escape_non_printable_full().
For kernel threads, truncation is done on the parenthesized name, so we'll
get "[worker]", "[worker…]", …, "[w…]", "[…", "…" as we reduce the number of
available columns.
This implementation is most likely slower for very long cmdlines, but I don't
think this is very important. The common case is to have short commandlines,
and should print those properly. Absurdly long cmdlines are the exception,
which needs to be handled correctly and safely, but speed is not too important.
Fixes #12532.
v2:
- use size_t for the number of columns. This change propagates into various
other functions that call get_process_cmdline(), increasing the size of the
patch, but the changes are rather trivial.
2019-05-15 11:20:26 +02:00
assert_se ( streq ( line , " [aaaa bbbb … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2021-03-30 19:42:36 +02:00
/* Test with multiple arguments that do require quoting */
# define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0"
2021-11-01 09:01:40 +09:00
# define EXPECT1 "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\""
# define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
2021-03-30 19:42:36 +02:00
assert_se ( lseek ( fd , SEEK_SET , 0 ) = = 0 ) ;
assert_se ( write ( fd , CMDLINE1 , sizeof CMDLINE1 ) = = sizeof CMDLINE1 ) ;
assert_se ( ftruncate ( fd , sizeof CMDLINE1 ) = = 0 ) ;
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_QUOTE , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " got: ==%s== " , line ) ;
log_debug ( " exp: ==%s== " , EXPECT1 ) ;
2021-03-30 19:42:36 +02:00
assert_se ( streq ( line , EXPECT1 ) ) ;
line = mfree ( line ) ;
2021-03-11 00:10:02 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_QUOTE_POSIX , & line ) > = 0 ) ;
log_debug ( " got: ==%s== " , line ) ;
log_debug ( " exp: ==%s== " , EXPECT1p ) ;
assert_se ( streq ( line , EXPECT1p ) ) ;
line = mfree ( line ) ;
2021-03-30 19:42:36 +02:00
# define CMDLINE2 "foo\0\1\2\3\0\0"
2021-11-01 09:01:40 +09:00
# define EXPECT2 "foo \"\\001\\002\\003\""
# define EXPECT2p "foo $'\\001\\002\\003'"
2021-03-30 19:42:36 +02:00
assert_se ( lseek ( fd , SEEK_SET , 0 ) = = 0 ) ;
assert_se ( write ( fd , CMDLINE2 , sizeof CMDLINE2 ) = = sizeof CMDLINE2 ) ;
assert_se ( ftruncate ( fd , sizeof CMDLINE2 ) = = 0 ) ;
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_QUOTE , & line ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " got: ==%s== " , line ) ;
log_debug ( " exp: ==%s== " , EXPECT2 ) ;
2021-03-30 19:42:36 +02:00
assert_se ( streq ( line , EXPECT2 ) ) ;
line = mfree ( line ) ;
2021-03-11 00:10:02 +01:00
assert_se ( get_process_cmdline ( 0 , SIZE_MAX , PROCESS_CMDLINE_QUOTE_POSIX , & line ) > = 0 ) ;
log_debug ( " got: ==%s== " , line ) ;
log_debug ( " exp: ==%s== " , EXPECT2p ) ;
assert_se ( streq ( line , EXPECT2p ) ) ;
line = mfree ( line ) ;
2016-06-14 23:52:29 +02:00
safe_close ( fd ) ;
2017-12-22 13:24:40 +01:00
_exit ( EXIT_SUCCESS ) ;
2016-06-14 23:52:29 +02:00
}
2017-08-03 22:31:46 +02:00
static void test_rename_process_now ( const char * p , int ret ) {
2016-12-06 20:29:07 +01:00
_cleanup_free_ char * comm = NULL , * cmdline = NULL ;
int r ;
2021-04-02 11:35:23 +02:00
log_info ( " /* %s */ " , __func__ ) ;
2016-12-06 20:29:07 +01:00
r = rename_process ( p ) ;
assert_se ( r = = ret | |
( ret = = 0 & & r > = 0 ) | |
( ret > 0 & & r > 0 ) ) ;
2021-04-02 11:35:23 +02:00
log_debug_errno ( r , " rename_process(%s): %m " , p ) ;
2021-03-30 19:42:36 +02:00
2016-12-06 20:29:07 +01:00
if ( r < 0 )
2017-08-03 22:31:46 +02:00
return ;
2016-12-06 20:29:07 +01:00
2017-10-03 10:41:51 +02:00
# if HAVE_VALGRIND_VALGRIND_H
2016-12-06 20:29:07 +01:00
/* see above, valgrind is weird, we can't verify what we are doing here */
if ( RUNNING_ON_VALGRIND )
2017-08-03 22:31:46 +02:00
return ;
2016-12-06 20:29:07 +01:00
# endif
assert_se ( get_process_comm ( 0 , & comm ) > = 0 ) ;
2021-04-02 11:35:23 +02:00
log_debug ( " comm = <%s> " , comm ) ;
2018-06-01 21:43:43 +02:00
assert_se ( strneq ( comm , p , TASK_COMM_LEN - 1 ) ) ;
2019-05-15 11:55:59 +02:00
/* We expect comm to be at most 16 bytes (TASK_COMM_LEN). The kernel may raise this limit in the
* future . We ' d only check the initial part , at least until we recompile , but this will still pass . */
2016-12-06 20:29:07 +01:00
2019-05-16 12:14:52 +02:00
r = get_process_cmdline ( 0 , SIZE_MAX , 0 , & cmdline ) ;
2018-09-20 16:08:38 +09:00
assert_se ( r > = 0 ) ;
2017-08-03 22:31:46 +02:00
/* we cannot expect cmdline to be renamed properly without privileges */
if ( geteuid ( ) = = 0 ) {
2018-09-20 16:08:38 +09:00
if ( r = = 0 & & detect_container ( ) > 0 )
log_info ( " cmdline = <%s> (not verified, Running in unprivileged container?) " , cmdline ) ;
else {
2021-03-30 19:42:36 +02:00
log_info ( " cmdline = <%s> (expected <%.*s>) " , cmdline , ( int ) strlen ( " test-process-util " ) , p ) ;
bool skip = cmdline [ 0 ] = = ' " ' ; /* A shortcut to check if the string is quoted */
assert_se ( strneq ( cmdline + skip , p , strlen ( " test-process-util " ) ) ) ;
assert_se ( startswith ( cmdline + skip , p ) ) ;
2018-09-20 16:08:38 +09:00
}
2017-08-03 22:31:46 +02:00
} else
log_info ( " cmdline = <%s> (not verified) " , cmdline ) ;
}
static void test_rename_process_one ( const char * p , int ret ) {
siginfo_t si ;
pid_t pid ;
2021-04-02 11:35:23 +02:00
log_info ( " /* %s */ " , __func__ ) ;
2017-08-03 22:31:46 +02:00
pid = fork ( ) ;
assert_se ( pid > = 0 ) ;
if ( pid = = 0 ) {
/* child */
test_rename_process_now ( p , ret ) ;
_exit ( EXIT_SUCCESS ) ;
}
assert_se ( wait_for_terminate ( pid , & si ) > = 0 ) ;
assert_se ( si . si_code = = CLD_EXITED ) ;
assert_se ( si . si_status = = EXIT_SUCCESS ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( rename_process_multi ) {
2017-08-03 22:31:46 +02:00
pid_t pid ;
pid = fork ( ) ;
assert_se ( pid > = 0 ) ;
2016-12-06 20:29:07 +01:00
2017-08-03 22:31:46 +02:00
if ( pid > 0 ) {
siginfo_t si ;
assert_se ( wait_for_terminate ( pid , & si ) > = 0 ) ;
assert_se ( si . si_code = = CLD_EXITED ) ;
assert_se ( si . si_status = = EXIT_SUCCESS ) ;
return ;
}
/* child */
test_rename_process_now ( " one " , 1 ) ;
test_rename_process_now ( " more " , 0 ) ; /* longer than "one", hence truncated */
2017-11-27 21:52:32 +00:00
( void ) setresuid ( 99 , 99 , 99 ) ; /* change uid when running privileged */
2017-08-03 22:31:46 +02:00
test_rename_process_now ( " time! " , 0 ) ;
test_rename_process_now ( " 0 " , 1 ) ; /* shorter than "one", should fit */
test_rename_process_one ( " " , - EINVAL ) ;
test_rename_process_one ( NULL , - EINVAL ) ;
2016-12-06 20:29:07 +01:00
_exit ( EXIT_SUCCESS ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( rename_process ) {
2016-12-06 20:29:07 +01:00
test_rename_process_one ( NULL , - EINVAL ) ;
test_rename_process_one ( " " , - EINVAL ) ;
test_rename_process_one ( " foo " , 1 ) ; /* should always fit */
test_rename_process_one ( " this is a really really long process name, followed by some more words " , 0 ) ; /* unlikely to fit */
test_rename_process_one ( " 1234567 " , 1 ) ; /* should always fit */
}
2021-11-24 12:11:17 +01:00
TEST ( getpid_cached ) {
2017-07-20 15:46:05 +02:00
siginfo_t si ;
pid_t a , b , c , d , e , f , child ;
a = raw_getpid ( ) ;
b = getpid_cached ( ) ;
c = getpid ( ) ;
assert_se ( a = = b & & a = = c ) ;
child = fork ( ) ;
assert_se ( child > = 0 ) ;
if ( child = = 0 ) {
/* In child */
a = raw_getpid ( ) ;
b = getpid_cached ( ) ;
c = getpid ( ) ;
assert_se ( a = = b & & a = = c ) ;
2017-12-22 13:24:40 +01:00
_exit ( EXIT_SUCCESS ) ;
2017-07-20 15:46:05 +02:00
}
d = raw_getpid ( ) ;
e = getpid_cached ( ) ;
f = getpid ( ) ;
assert_se ( a = = d & & a = = e & & a = = f ) ;
assert_se ( wait_for_terminate ( child , & si ) > = 0 ) ;
assert_se ( si . si_status = = 0 ) ;
assert_se ( si . si_code = = CLD_EXITED ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( getpid_measure ) {
2017-07-20 15:46:05 +02:00
usec_t t , q ;
2021-04-02 11:44:48 +02:00
unsigned long long iterations = slow_tests_enabled ( ) ? 1000000 : 1000 ;
log_info ( " /* %s (%llu iterations) */ " , __func__ , iterations ) ;
2021-04-02 11:35:23 +02:00
2017-07-20 15:46:05 +02:00
t = now ( CLOCK_MONOTONIC ) ;
2021-04-02 11:44:48 +02:00
for ( unsigned long long i = 0 ; i < iterations ; i + + )
2017-07-20 15:46:05 +02:00
( void ) getpid ( ) ;
q = now ( CLOCK_MONOTONIC ) - t ;
2021-04-02 11:44:48 +02:00
log_info ( " glibc getpid(): %lf µs each \n " , ( double ) q / iterations ) ;
iterations * = 50 ; /* _cached() is about 50 times faster, so we need more iterations */
2017-07-20 15:46:05 +02:00
t = now ( CLOCK_MONOTONIC ) ;
2021-04-02 11:44:48 +02:00
for ( unsigned long long i = 0 ; i < iterations ; i + + )
2017-07-20 15:46:05 +02:00
( void ) getpid_cached ( ) ;
q = now ( CLOCK_MONOTONIC ) - t ;
2021-04-02 11:44:48 +02:00
log_info ( " getpid_cached(): %lf µs each \n " , ( double ) q / iterations ) ;
2017-07-20 15:46:05 +02:00
}
2021-11-24 12:11:17 +01:00
TEST ( safe_fork ) {
2017-12-22 13:08:14 +01:00
siginfo_t status ;
pid_t pid ;
int r ;
BLOCK_SIGNALS ( SIGCHLD ) ;
r = safe_fork ( " (test-child) " , FORK_RESET_SIGNALS | FORK_CLOSE_ALL_FDS | FORK_DEATHSIG | FORK_NULL_STDIO | FORK_REOPEN_LOG , & pid ) ;
assert_se ( r > = 0 ) ;
if ( r = = 0 ) {
/* child */
usleep ( 100 * USEC_PER_MSEC ) ;
_exit ( 88 ) ;
}
assert_se ( wait_for_terminate ( pid , & status ) > = 0 ) ;
assert_se ( status . si_code = = CLD_EXITED ) ;
assert_se ( status . si_status = = 88 ) ;
}
2021-11-24 12:11:17 +01:00
TEST ( pid_to_ptr ) {
2018-01-11 16:02:47 +01:00
assert_se ( PTR_TO_PID ( NULL ) = = 0 ) ;
assert_se ( PID_TO_PTR ( 0 ) = = NULL ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( 1 ) ) = = 1 ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( 2 ) ) = = 2 ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( - 1 ) ) = = - 1 ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( - 2 ) ) = = - 2 ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( INT16_MAX ) ) = = INT16_MAX ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( INT16_MIN ) ) = = INT16_MIN ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( INT32_MAX ) ) = = INT32_MAX ) ;
assert_se ( PTR_TO_PID ( PID_TO_PTR ( INT32_MIN ) ) = = INT32_MIN ) ;
}
2021-11-24 15:52:13 +01:00
static void test_ioprio_class_from_to_string_one ( const char * val , int expected , int normalized ) {
2018-03-16 11:15:58 +01:00
assert_se ( ioprio_class_from_string ( val ) = = expected ) ;
if ( expected > = 0 ) {
_cleanup_free_ char * s = NULL ;
unsigned ret ;
2021-11-24 15:52:13 +01:00
int combined ;
2018-03-16 11:15:58 +01:00
assert_se ( ioprio_class_to_string_alloc ( expected , & s ) = = 0 ) ;
2021-11-24 15:52:13 +01:00
/* We sometimes get a class number and sometimes a name back */
2018-03-16 11:15:58 +01:00
assert_se ( streq ( s , val ) | |
safe_atou ( val , & ret ) = = 0 ) ;
2021-11-24 15:52:13 +01:00
/* Make sure normalization works, i.e. NONE → BE gets normalized */
combined = ioprio_normalize ( ioprio_prio_value ( expected , 0 ) ) ;
assert_se ( ioprio_prio_class ( combined ) = = normalized ) ;
assert_se ( expected ! = IOPRIO_CLASS_NONE | | ioprio_prio_data ( combined ) = = 4 ) ;
2018-03-16 11:15:58 +01:00
}
}
2016-12-06 20:29:07 +01:00
2021-11-24 12:11:17 +01:00
TEST ( ioprio_class_from_to_string ) {
2021-11-24 15:52:13 +01:00
test_ioprio_class_from_to_string_one ( " none " , IOPRIO_CLASS_NONE , IOPRIO_CLASS_BE ) ;
test_ioprio_class_from_to_string_one ( " realtime " , IOPRIO_CLASS_RT , IOPRIO_CLASS_RT ) ;
test_ioprio_class_from_to_string_one ( " best-effort " , IOPRIO_CLASS_BE , IOPRIO_CLASS_BE ) ;
test_ioprio_class_from_to_string_one ( " idle " , IOPRIO_CLASS_IDLE , IOPRIO_CLASS_IDLE ) ;
test_ioprio_class_from_to_string_one ( " 0 " , IOPRIO_CLASS_NONE , IOPRIO_CLASS_BE ) ;
test_ioprio_class_from_to_string_one ( " 1 " , 1 , 1 ) ;
test_ioprio_class_from_to_string_one ( " 7 " , 7 , 7 ) ;
test_ioprio_class_from_to_string_one ( " 8 " , 8 , 8 ) ;
test_ioprio_class_from_to_string_one ( " 9 " , - EINVAL , - EINVAL ) ;
test_ioprio_class_from_to_string_one ( " -1 " , - EINVAL , - EINVAL ) ;
2018-03-16 11:15:58 +01:00
}
2021-11-24 12:11:17 +01:00
TEST ( setpriority_closest ) {
2020-01-02 17:33:51 +01:00
int r ;
2021-04-02 11:35:23 +02:00
r = safe_fork ( " (test-setprio) " ,
FORK_RESET_SIGNALS | FORK_CLOSE_ALL_FDS | FORK_DEATHSIG | FORK_WAIT | FORK_LOG , NULL ) ;
2020-01-02 17:33:51 +01:00
assert_se ( r > = 0 ) ;
if ( r = = 0 ) {
bool full_test ;
int p , q ;
/* child */
/* rlimit of 30 equals nice level of -10 */
if ( setrlimit ( RLIMIT_NICE , & RLIMIT_MAKE_CONST ( 30 ) ) < 0 ) {
2020-01-08 12:12:16 +01:00
/* If this fails we are probably unprivileged or in a userns of some kind, let's skip
2020-01-02 17:33:51 +01:00
* the full test */
assert_se ( ERRNO_IS_PRIVILEGE ( errno ) ) ;
full_test = false ;
} else {
assert_se ( setresgid ( GID_NOBODY , GID_NOBODY , GID_NOBODY ) > = 0 ) ;
assert_se ( setresuid ( UID_NOBODY , UID_NOBODY , UID_NOBODY ) > = 0 ) ;
full_test = true ;
}
errno = 0 ;
p = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 ) ;
/* It should always be possible to set our nice level to the current one */
assert_se ( setpriority_closest ( p ) > 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & p = = q ) ;
2020-07-07 12:08:22 +02:00
/* It should also be possible to set the nice level to one higher */
2020-01-02 17:33:51 +01:00
if ( p < PRIO_MAX - 1 ) {
assert_se ( setpriority_closest ( + + p ) > 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & p = = q ) ;
}
2020-07-07 12:08:22 +02:00
/* It should also be possible to set the nice level to two higher */
2020-01-02 17:33:51 +01:00
if ( p < PRIO_MAX - 1 ) {
assert_se ( setpriority_closest ( + + p ) > 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & p = = q ) ;
}
if ( full_test ) {
/* These two should work, given the RLIMIT_NICE we set above */
assert_se ( setpriority_closest ( - 10 ) > 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & q = = - 10 ) ;
assert_se ( setpriority_closest ( - 9 ) > 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & q = = - 9 ) ;
/* This should succeed but should be clamped to the limit */
assert_se ( setpriority_closest ( - 11 ) = = 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & q = = - 10 ) ;
assert_se ( setpriority_closest ( - 8 ) > 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & q = = - 8 ) ;
/* This should succeed but should be clamped to the limit */
assert_se ( setpriority_closest ( - 12 ) = = 0 ) ;
errno = 0 ;
q = getpriority ( PRIO_PROCESS , 0 ) ;
assert_se ( errno = = 0 & & q = = - 10 ) ;
}
_exit ( EXIT_SUCCESS ) ;
}
}
2021-11-24 12:11:17 +01:00
TEST ( get_process_ppid ) {
2021-07-07 15:57:51 +02:00
uint64_t limit ;
int r ;
assert_se ( get_process_ppid ( 1 , NULL ) = = - EADDRNOTAVAIL ) ;
/* the process with the PID above the global limit definitely doesn't exist. Verify that */
2021-11-02 18:18:21 +01:00
assert_se ( procfs_get_pid_max ( & limit ) > = 0 ) ;
log_debug ( " kernel.pid_max = % " PRIu64 , limit ) ;
if ( limit < INT_MAX ) {
r = get_process_ppid ( limit + 1 , NULL ) ;
log_debug_errno ( r , " get_process_limit(% " PRIu64 " ) → %d/%m " , limit + 1 , r ) ;
assert ( r = = - ESRCH ) ;
}
2021-07-07 15:57:51 +02:00
for ( pid_t pid = 0 ; ; ) {
_cleanup_free_ char * c1 = NULL , * c2 = NULL ;
pid_t ppid ;
r = get_process_ppid ( pid , & ppid ) ;
if ( r = = - EADDRNOTAVAIL ) {
log_info ( " No further parent PID " ) ;
break ;
}
assert_se ( r > = 0 ) ;
assert_se ( get_process_cmdline ( pid , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & c1 ) > = 0 ) ;
assert_se ( get_process_cmdline ( ppid , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & c2 ) > = 0 ) ;
log_info ( " Parent of " PID_FMT " (%s) is " PID_FMT " (%s). " , pid , c1 , ppid , c2 ) ;
pid = ppid ;
}
}
2021-11-24 12:11:17 +01:00
TEST ( set_oom_score_adjust ) {
2021-09-30 11:19:34 +02:00
int a , b , r ;
assert_se ( get_oom_score_adjust ( & a ) > = 0 ) ;
r = set_oom_score_adjust ( OOM_SCORE_ADJ_MIN ) ;
assert_se ( r > = 0 | | ERRNO_IS_PRIVILEGE ( r ) ) ;
if ( r > = 0 ) {
assert_se ( get_oom_score_adjust ( & b ) > = 0 ) ;
assert_se ( b = = OOM_SCORE_ADJ_MIN ) ;
}
assert_se ( set_oom_score_adjust ( a ) > = 0 ) ;
assert_se ( get_oom_score_adjust ( & b ) > = 0 ) ;
assert_se ( b = = a ) ;
}
2021-11-24 12:11:17 +01:00
DEFINE_CUSTOM_TEST_MAIN ( LOG_INFO , log_show_color ( true ) , /* no outro */ ) ;