2017-11-18 17:09:20 +01:00
/* SPDX-License-Identifier: LGPL-2.1+ */
2015-04-10 19:10:00 +02:00
2019-10-31 11:07:23 +09:00
# include <fcntl.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"
2020-01-02 17:33:51 +01:00
# include "errno-util.h"
2016-06-14 23:52:29 +02:00
# include "fd-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"
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
2016-06-12 19:42:51 -04:00
static void test_get_process_comm ( 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 ;
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
2016-06-12 19:42:51 -04:00
assert_se ( get_process_ppid ( pid , & e ) > = 0 ) ;
log_info ( " PID " PID_FMT " PPID: " PID_FMT , pid , e ) ;
assert_se ( pid = = 1 ? e = = 0 : 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
}
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 ;
log_info ( " input: <%s> — output: <%s> " , input , output ) ;
assert_se ( prctl ( PR_SET_NAME , input ) > = 0 ) ;
assert_se ( get_process_comm ( 0 , & n ) > = 0 ) ;
log_info ( " got: <%s> " , n ) ;
assert_se ( streq_ptr ( n , output ) ) ;
}
static void test_get_process_comm_escape ( void ) {
_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 ) ;
}
2015-04-10 19:10:00 +02:00
static void test_pid_is_unwaited ( void ) {
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 ) ) ;
}
static void test_pid_is_alive ( void ) {
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 ) ) ;
}
2016-02-22 18:36:54 +01:00
static void test_personality ( void ) {
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
}
2016-06-14 23:52:29 +02:00
static void test_get_process_cmdline_harder ( void ) {
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 ;
}
2016-06-14 23:52:29 +02:00
assert_se ( unlink ( path ) > = 0 ) ;
assert_se ( prctl ( PR_SET_NAME , " testa " ) > = 0 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , SIZE_MAX , 0 , & line ) = = - ENOENT ) ;
2016-06-14 23:52:29 +02:00
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [testa] " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 0 , 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
log_info ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 7 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [testa] " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 8 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [testa] " ) ) ;
line = mfree ( 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 ( write ( fd , " foo \0 bar " , 8 ) = = 8 ) ;
2016-06-14 23:52:29 +02:00
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , SIZE_MAX , 0 , & 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
log_info ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , SIZE_MAX , 0 , & 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
log_info ( " '%s' " , line ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 , " … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 , " f… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 , " fo… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 , " foo… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 , " foo … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 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 , " foo b… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 7 , 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 , " foo ba… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 8 , 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 , " foo bar… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 9 , 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 , " foo bar … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 10 , 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 , " foo bar q… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 11 , 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 , " foo bar qu… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 12 , 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 , " foo bar quux " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 13 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 14 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " foo bar quux " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 1000 , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
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 ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , SIZE_MAX , 0 , & line ) = = - ENOENT ) ;
2016-06-14 23:52:29 +02:00
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , SIZE_MAX , PROCESS_CMDLINE_COMM_FALLBACK , & line ) > = 0 ) ;
2016-06-14 23:52:29 +02:00
assert_se ( streq ( line , " [aaaa bbbb cccc] " ) ) ;
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 10 , 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 , " [aaaa bbb… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 11 , 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 , " [aaaa bbbb… " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
2019-05-16 12:14:52 +02:00
assert_se ( get_process_cmdline ( getpid_cached ( ) , 12 , 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 , " [aaaa bbbb … " ) ) ;
2016-06-14 23:52:29 +02:00
line = mfree ( line ) ;
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 ;
r = rename_process ( p ) ;
assert_se ( r = = ret | |
( ret = = 0 & & r > = 0 ) | |
( ret > 0 & & r > 0 ) ) ;
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 ) ;
log_info ( " 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 {
log_info ( " cmdline = <%s> " , cmdline ) ;
assert_se ( strneq ( p , cmdline , STRLEN ( " test-process-util " ) ) ) ;
assert_se ( startswith ( p , cmdline ) ) ;
}
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 ;
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 ) ;
}
static void test_rename_process_multi ( void ) {
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 ) ;
}
static void test_rename_process ( void ) {
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 */
2017-08-03 22:31:46 +02:00
test_rename_process_multi ( ) ; /* multiple invocations and dropped privileges */
2016-12-06 20:29:07 +01:00
}
2017-07-20 15:46:05 +02:00
static void test_getpid_cached ( void ) {
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 ) ;
}
# define MEASURE_ITERATIONS (10000000LLU)
static void test_getpid_measure ( void ) {
unsigned long long i ;
usec_t t , q ;
t = now ( CLOCK_MONOTONIC ) ;
for ( i = 0 ; i < MEASURE_ITERATIONS ; i + + )
( void ) getpid ( ) ;
q = now ( CLOCK_MONOTONIC ) - t ;
2019-07-11 08:47:41 +02:00
log_info ( " glibc getpid(): %lf µs each \n " , ( double ) q / MEASURE_ITERATIONS ) ;
2017-07-20 15:46:05 +02:00
t = now ( CLOCK_MONOTONIC ) ;
for ( i = 0 ; i < MEASURE_ITERATIONS ; i + + )
( void ) getpid_cached ( ) ;
q = now ( CLOCK_MONOTONIC ) - t ;
2019-07-11 08:47:41 +02:00
log_info ( " getpid_cached(): %lf µs each \n " , ( double ) q / MEASURE_ITERATIONS ) ;
2017-07-20 15:46:05 +02:00
}
2017-12-22 13:08:14 +01:00
static void test_safe_fork ( void ) {
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 ) ;
}
2018-01-11 16:02:47 +01:00
static void test_pid_to_ptr ( void ) {
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 ) ;
}
2018-03-16 11:15:58 +01:00
static void test_ioprio_class_from_to_string_one ( const char * val , int expected ) {
assert_se ( ioprio_class_from_string ( val ) = = expected ) ;
if ( expected > = 0 ) {
_cleanup_free_ char * s = NULL ;
unsigned ret ;
assert_se ( ioprio_class_to_string_alloc ( expected , & s ) = = 0 ) ;
/* We sometimes get a class number and sometimes a number back */
assert_se ( streq ( s , val ) | |
safe_atou ( val , & ret ) = = 0 ) ;
}
}
2016-12-06 20:29:07 +01:00
2018-03-16 11:15:58 +01:00
static void test_ioprio_class_from_to_string ( void ) {
test_ioprio_class_from_to_string_one ( " none " , IOPRIO_CLASS_NONE ) ;
test_ioprio_class_from_to_string_one ( " realtime " , IOPRIO_CLASS_RT ) ;
test_ioprio_class_from_to_string_one ( " best-effort " , IOPRIO_CLASS_BE ) ;
test_ioprio_class_from_to_string_one ( " idle " , IOPRIO_CLASS_IDLE ) ;
test_ioprio_class_from_to_string_one ( " 0 " , 0 ) ;
test_ioprio_class_from_to_string_one ( " 1 " , 1 ) ;
test_ioprio_class_from_to_string_one ( " 7 " , 7 ) ;
test_ioprio_class_from_to_string_one ( " 8 " , 8 ) ;
test_ioprio_class_from_to_string_one ( " 9 " , - 1 ) ;
test_ioprio_class_from_to_string_one ( " -1 " , - 1 ) ;
}
2020-01-02 17:33:51 +01:00
static void test_setpriority_closest ( void ) {
int r ;
r = safe_fork ( " (test-setprio) " , FORK_RESET_SIGNALS | FORK_CLOSE_ALL_FDS | FORK_DEATHSIG | FORK_WAIT | FORK_LOG , NULL ) ;
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 ) ;
}
}
2018-03-16 11:15:58 +01:00
int main ( int argc , char * argv [ ] ) {
2018-09-13 14:31:13 +02:00
test_setup_logging ( LOG_DEBUG ) ;
2015-04-10 19:10:00 +02:00
2019-03-15 10:46:54 +01:00
save_argc_argv ( argc , argv ) ;
2016-12-06 20:29:07 +01:00
2016-06-12 19:51:11 -04:00
if ( argc > 1 ) {
pid_t pid = 0 ;
( void ) parse_pid ( argv [ 1 ] , & pid ) ;
test_get_process_comm ( pid ) ;
} else {
2016-07-27 14:22:26 -07:00
TEST_REQ_RUNNING_SYSTEMD ( test_get_process_comm ( 1 ) ) ;
2016-06-12 19:51:11 -04:00
test_get_process_comm ( getpid ( ) ) ;
}
2018-05-16 21:50:35 -04:00
test_get_process_comm_escape ( ) ;
2015-04-10 19:10:00 +02:00
test_pid_is_unwaited ( ) ;
test_pid_is_alive ( ) ;
2016-02-22 18:36:54 +01:00
test_personality ( ) ;
2016-06-14 23:52:29 +02:00
test_get_process_cmdline_harder ( ) ;
2016-12-06 20:29:07 +01:00
test_rename_process ( ) ;
2017-07-20 15:46:05 +02:00
test_getpid_cached ( ) ;
test_getpid_measure ( ) ;
2017-12-22 13:08:14 +01:00
test_safe_fork ( ) ;
2018-01-11 16:02:47 +01:00
test_pid_to_ptr ( ) ;
2018-03-16 11:15:58 +01:00
test_ioprio_class_from_to_string ( ) ;
2020-01-02 17:33:51 +01:00
test_setpriority_closest ( ) ;
2015-04-10 19:10:00 +02:00
return 0 ;
}