mirror of
https://github.com/systemd/systemd
synced 2025-10-05 19:54:46 +02:00
Compare commits
3 Commits
6b1ed5e7e6
...
91a96a564f
Author | SHA1 | Date | |
---|---|---|---|
![]() |
91a96a564f | ||
![]() |
7b7a060e83 | ||
![]() |
7325a2b2d1 |
@ -124,14 +124,10 @@ int get_process_comm(pid_t pid, char **ret) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line) {
|
int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line) {
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
|
||||||
_cleanup_free_ char *t = NULL, *ans = NULL;
|
_cleanup_free_ char *t = NULL, *ans = NULL;
|
||||||
const char *p;
|
const char *p;
|
||||||
int r;
|
|
||||||
size_t k;
|
size_t k;
|
||||||
|
int r;
|
||||||
/* This is supposed to be a safety guard against runaway command lines. */
|
|
||||||
size_t max_length = sc_arg_max();
|
|
||||||
|
|
||||||
assert(line);
|
assert(line);
|
||||||
assert(pid >= 0);
|
assert(pid >= 0);
|
||||||
@ -147,36 +143,18 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
|
|||||||
* comm_fallback is false). Returns 0 and sets *line otherwise. */
|
* comm_fallback is false). Returns 0 and sets *line otherwise. */
|
||||||
|
|
||||||
p = procfs_file_alloca(pid, "cmdline");
|
p = procfs_file_alloca(pid, "cmdline");
|
||||||
r = fopen_unlocked(p, "re", &f);
|
r = read_full_virtual_file(p, &t, &k);
|
||||||
if (r == -ENOENT)
|
if (r == -ENOENT)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* We assume that each four-byte character uses one or two columns. If we ever check for combining
|
|
||||||
* characters, this assumption will need to be adjusted. */
|
|
||||||
if ((size_t) 4 * max_columns + 1 < max_columns)
|
|
||||||
max_length = MIN(max_length, (size_t) 4 * max_columns + 1);
|
|
||||||
|
|
||||||
t = new(char, max_length);
|
|
||||||
if (!t)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
k = fread(t, 1, max_length, f);
|
|
||||||
if (k > 0) {
|
if (k > 0) {
|
||||||
/* Arguments are separated by NULs. Let's replace those with spaces. */
|
/* Arguments are separated by NULs. Let's replace those with spaces. */
|
||||||
for (size_t i = 0; i < k - 1; i++)
|
for (size_t i = 0; i < k - 1; i++)
|
||||||
if (t[i] == '\0')
|
if (t[i] == '\0')
|
||||||
t[i] = ' ';
|
t[i] = ' ';
|
||||||
|
|
||||||
t[k] = '\0'; /* Normally, t[k] is already NUL, so this is just a guard in case of short read */
|
|
||||||
} else {
|
} else {
|
||||||
/* We only treat getting nothing as an error. We *could* also get an error after reading some
|
|
||||||
* data, but we ignore that case, as such an error is rather unlikely and we prefer to get
|
|
||||||
* some data rather than none. */
|
|
||||||
if (ferror(f))
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
|
if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
@ -187,7 +165,7 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
mfree(t);
|
free(t);
|
||||||
t = strjoin("[", t2, "]");
|
t = strjoin("[", t2, "]");
|
||||||
if (!t)
|
if (!t)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -405,7 +405,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
|
|||||||
j->unit->id,
|
j->unit->id,
|
||||||
unit_id == array ? "ordering cycle" : "dependency",
|
unit_id == array ? "ordering cycle" : "dependency",
|
||||||
*unit_id, *job_type,
|
*unit_id, *job_type,
|
||||||
unit_ids);
|
"%s", unit_ids);
|
||||||
|
|
||||||
if (delete) {
|
if (delete) {
|
||||||
const char *status;
|
const char *status;
|
||||||
@ -414,7 +414,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
|
|||||||
"MESSAGE=%s: Job %s/%s deleted to break ordering cycle starting with %s/%s",
|
"MESSAGE=%s: Job %s/%s deleted to break ordering cycle starting with %s/%s",
|
||||||
j->unit->id, delete->unit->id, job_type_to_string(delete->type),
|
j->unit->id, delete->unit->id, job_type_to_string(delete->type),
|
||||||
j->unit->id, job_type_to_string(j->type),
|
j->unit->id, job_type_to_string(j->type),
|
||||||
unit_ids);
|
"%s", unit_ids);
|
||||||
|
|
||||||
if (log_get_show_color())
|
if (log_get_show_color())
|
||||||
status = ANSI_HIGHLIGHT_RED " SKIP " ANSI_NORMAL;
|
status = ANSI_HIGHLIGHT_RED " SKIP " ANSI_NORMAL;
|
||||||
@ -432,7 +432,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
|
|||||||
log_struct(LOG_ERR,
|
log_struct(LOG_ERR,
|
||||||
"MESSAGE=%s: Unable to break cycle starting with %s/%s",
|
"MESSAGE=%s: Unable to break cycle starting with %s/%s",
|
||||||
j->unit->id, j->unit->id, job_type_to_string(j->type),
|
j->unit->id, j->unit->id, job_type_to_string(j->type),
|
||||||
unit_ids);
|
"%s", unit_ids);
|
||||||
|
|
||||||
return sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC,
|
return sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC,
|
||||||
"Transaction order is cyclic. See system logs for details.");
|
"Transaction order is cyclic. See system logs for details.");
|
||||||
|
@ -236,6 +236,11 @@ static void test_get_process_cmdline_harder(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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");
|
||||||
|
|
||||||
assert_se(unlink(path) >= 0);
|
assert_se(unlink(path) >= 0);
|
||||||
|
|
||||||
assert_se(prctl(PR_SET_NAME, "testa") >= 0);
|
assert_se(prctl(PR_SET_NAME, "testa") >= 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user