process-util.c revision 6bc73acb01e2782f0ef3ec70dde3dc3f5b5da081
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "alloc-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "log.h"
#include "process-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "user-util.h"
#include "util.h"
const char *p;
char state;
int r;
r = read_one_line_file(p, &line);
if (r == -ENOENT)
return -ESRCH;
if (r < 0)
return r;
if (!p)
return -EIO;
p++;
return -EIO;
return (unsigned char) state;
}
const char *p;
int r;
r = read_one_line_file(p, name);
if (r == -ENOENT)
return -ESRCH;
return r;
}
char *r = NULL, *k;
const char *p;
int c;
f = fopen(p, "re");
if (!f) {
return -ESRCH;
return -errno;
}
if (max_length == 0) {
free(r);
return -ENOMEM;
}
}
if (len > 0)
r[len-1] = 0;
} else {
bool space = false;
r = new(char, max_length);
if (!r)
return -ENOMEM;
k = r;
left = max_length;
if (isprint(c)) {
if (space) {
if (left <= 4)
break;
*(k++) = ' ';
left--;
space = false;
}
if (left <= 4)
break;
*(k++) = (char) c;
left--;
} else
space = true;
}
if (left <= 4) {
memcpy(k, "...", n);
k[n] = 0;
} else
*k = 0;
}
/* Kernel threads have no argv[] */
if (isempty(r)) {
_cleanup_free_ char *t = NULL;
int h;
free(r);
if (!comm_fallback)
return -ENOENT;
h = get_process_comm(pid, &t);
if (h < 0)
return h;
if (!r)
return -ENOMEM;
}
*line = r;
return 0;
}
/* This is a like a poor man's setproctitle(). It changes the
* comm field, argv[0], and also the glibc's internally used
* name of the process. For the first one a limit of 16 chars
* applies, to the second one usually one of 10 (i.e. length
* "systemd"). If you pass a longer string it will be
* truncated */
if (saved_argc > 0) {
int i;
if (saved_argv[0])
for (i = 1; i < saved_argc; i++) {
if (!saved_argv[i])
break;
}
}
}
const char *p;
char c;
bool eof;
FILE *f;
return 0;
f = fopen(p, "re");
if (!f) {
return -ESRCH;
return -errno;
}
fclose(f);
/* Kernel threads have an empty cmdline */
if (count <= 0)
return 0;
}
const char *p;
int r;
if (r == -ENOENT)
return -ESRCH;
return r;
}
int r;
if (r == -ENOENT)
return -ESRCH;
if (r < 0)
return r;
return 0;
}
const char *p;
char *d;
int r;
r = get_process_link_contents(p, name);
if (r < 0)
return r;
if (d)
*d = '\0';
return 0;
}
const char *p;
if (pid == 0)
return getuid();
f = fopen(p, "re");
if (!f) {
return -ESRCH;
return -errno;
}
char *l;
if (startswith(l, field)) {
l += strspn(l, WHITESPACE);
l[strcspn(l, WHITESPACE)] = 0;
}
}
return -EIO;
}
}
}
const char *p;
return get_process_link_contents(p, cwd);
}
const char *p;
return get_process_link_contents(p, root);
}
int c;
const char *p;
f = fopen(p, "re");
if (!f) {
return -ESRCH;
return -errno;
}
return -ENOMEM;
if (c == '\0')
else
}
if (!outcome) {
if (!outcome)
return -ENOMEM;
} else
return 0;
}
int r;
long unsigned ppid;
const char *p;
if (pid == 0) {
return 0;
}
r = read_one_line_file(p, &line);
if (r == -ENOENT)
return -ESRCH;
if (r < 0)
return r;
/* Let's skip the pid and comm fields. The latter is enclosed
* in () but does not escape any () in its value, so let's
* skip over it manually */
if (!p)
return -EIO;
p++;
if (sscanf(p, " "
"%*c " /* state */
"%lu ", /* ppid */
&ppid) != 1)
return -EIO;
return -ERANGE;
return 0;
}
if (!status)
for (;;) {
continue;
return -errno;
}
return 0;
}
}
/*
* Return values:
* < 0 : wait_for_terminate() failed to get the state of the
* process, the process was terminated by a signal, or
* failed for an unknown reason.
* >=0 : The process terminated normally, and its exit code is
* returned.
*
* That is, success is indicated by a return value of zero, and an
* error is indicated by a non-zero value.
*
* A warning is emitted if the process terminates abnormally,
* and also if it returns non-zero unless check_exit_code is true.
*/
int r;
if (r < 0)
else
return -EPROTO;
}
return -EPROTO;
}
if (!pid)
return;
if (*pid <= 1)
return;
}
int r;
if (r >= 0)
return r;
}
int r;
bool done = false;
size_t l;
const char *path;
if (!f) {
return -ESRCH;
return -errno;
}
r = 0;
do {
unsigned i;
for (i = 0; i < sizeof(line)-1; i++) {
int c;
c = getc(f);
if (_unlikely_(c == EOF)) {
done = true;
break;
} else if (c == 0)
break;
line[i] = c;
}
line[i] = 0;
if (!value)
return -ENOMEM;
r = 1;
break;
}
} while (!done);
return r;
}
/* Checks whether a PID is still valid at all, including a zombie */
if (pid <= 0)
return false;
return true;
}
int r;
/* Checks whether a PID is still valid and not a zombie */
if (pid <= 0)
return false;
r = get_process_state(pid);
if (r == -ESRCH || r == 'Z')
return false;
return true;
}
bool is_main_thread(void) {
static thread_local int cached = 0;
if (_unlikely_(cached == 0))
return cached > 0;
}