summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/formats-util.h16
-rw-r--r--src/basic/process-util.c90
-rw-r--r--src/basic/socket-util.c24
3 files changed, 106 insertions, 24 deletions
diff --git a/src/basic/formats-util.h b/src/basic/formats-util.h
index 9b4e8e98fa..39a185f59b 100644
--- a/src/basic/formats-util.h
+++ b/src/basic/formats-util.h
@@ -61,3 +61,19 @@
#else
# error Unknown rlim_t size
#endif
+
+#if SIZEOF_DEV_T == 8
+# define DEV_FMT "%" PRIu64
+#elif SIZEOF_DEV_T == 4
+# define DEV_FMT "%" PRIu32
+#else
+# error Unknown dev_t size
+#endif
+
+#if SIZEOF_INO_T == 8
+# define INO_FMT "%" PRIu64
+#elif SIZEOF_INO_T == 4
+# define INO_FMT "%" PRIu32
+#else
+# error Unknown ino_t size
+#endif
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 08fa98bb9e..b5b068ad38 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -110,6 +110,15 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
assert(line);
assert(pid >= 0);
+ /* Retrieves a process' command line. Replaces unprintable characters while doing so by whitespace (coalescing
+ * multiple sequential ones into one). If max_length is != 0 will return a string of the specified size at most
+ * (the trailing NUL byte does count towards the length here!), abbreviated with a "..." ellipsis. If
+ * comm_fallback is true and the process has no command line set (the case for kernel threads), or has a
+ * command line that resolves to the empty string will return the "comm" name of the process instead.
+ *
+ * Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
+ * comm_fallback is false). */
+
p = procfs_file_alloca(pid, "cmdline");
f = fopen(p, "re");
@@ -119,12 +128,22 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
return -errno;
}
- if (max_length == 0) {
+ if (max_length == 1) {
+
+ /* If there's only room for one byte, return the empty string */
+ r = new0(char, 1);
+ if (!r)
+ return -ENOMEM;
+
+ *line = r;
+ return 0;
+
+ } else if (max_length == 0) {
size_t len = 0, allocated = 0;
while ((c = getc(f)) != EOF) {
- if (!GREEDY_REALLOC(r, allocated, len+2)) {
+ if (!GREEDY_REALLOC(r, allocated, len+3)) {
free(r);
return -ENOMEM;
}
@@ -136,7 +155,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
}
r[len++] = c;
- } else
+ } else if (len > 0)
space = true;
}
@@ -144,6 +163,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
r[len] = 0;
} else {
+ bool dotdotdot = false;
size_t left;
r = new(char, max_length);
@@ -155,28 +175,46 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
while ((c = getc(f)) != EOF) {
if (isprint(c)) {
+
if (space) {
- if (left <= 4)
+ if (left <= 2) {
+ dotdotdot = true;
break;
+ }
*(k++) = ' ';
left--;
space = false;
}
- if (left <= 4)
+ if (left <= 1) {
+ dotdotdot = true;
break;
+ }
*(k++) = (char) c;
left--;
- } else
+ } else if (k > r)
space = true;
}
- if (left <= 4) {
- size_t n = MIN(left-1, 3U);
- memcpy(k, "...", n);
- k[n] = 0;
+ if (dotdotdot) {
+ if (max_length <= 4) {
+ k = r;
+ left = max_length;
+ } else {
+ k = r + max_length - 4;
+ left = 4;
+
+ /* Eat up final spaces */
+ while (k > r && isspace(k[-1])) {
+ k--;
+ left++;
+ }
+ }
+
+ strncpy(k, "...", left-1);
+ k[left] = 0;
} else
*k = 0;
}
@@ -195,7 +233,37 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
if (h < 0)
return h;
- r = strjoin("[", t, "]", NULL);
+ if (max_length == 0)
+ r = strjoin("[", t, "]", NULL);
+ else {
+ size_t l;
+
+ l = strlen(t);
+
+ if (l + 3 <= max_length)
+ r = strjoin("[", t, "]", NULL);
+ else if (max_length <= 6) {
+
+ r = new(char, max_length);
+ if (!r)
+ return -ENOMEM;
+
+ memcpy(r, "[...]", max_length-1);
+ r[max_length-1] = 0;
+ } else {
+ char *e;
+
+ t[max_length - 6] = 0;
+
+ /* Chop off final spaces */
+ e = strchr(t, 0);
+ while (e > t && isspace(e[-1]))
+ e--;
+ *e = 0;
+
+ r = strjoin("[", t, "...]", NULL);
+ }
+ }
if (!r)
return -ENOMEM;
}
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index c8769a54f4..385c3e4df3 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -85,7 +85,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
return -EINVAL;
a->sockaddr.in6.sin6_family = AF_INET6;
- a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+ a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
a->size = sizeof(struct sockaddr_in6);
} else if (*s == '/') {
@@ -133,7 +133,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
if (r > 0) {
/* Gotcha, it's a traditional IPv4 address */
a->sockaddr.in.sin_family = AF_INET;
- a->sockaddr.in.sin_port = htons((uint16_t) u);
+ a->sockaddr.in.sin_port = htobe16((uint16_t)u);
a->size = sizeof(struct sockaddr_in);
} else {
unsigned idx;
@@ -147,7 +147,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
return -EINVAL;
a->sockaddr.in6.sin6_family = AF_INET6;
- a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+ a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
a->sockaddr.in6.sin6_scope_id = idx;
a->sockaddr.in6.sin6_addr = in6addr_any;
a->size = sizeof(struct sockaddr_in6);
@@ -164,12 +164,12 @@ int socket_address_parse(SocketAddress *a, const char *s) {
if (socket_ipv6_is_supported()) {
a->sockaddr.in6.sin6_family = AF_INET6;
- a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+ a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
a->sockaddr.in6.sin6_addr = in6addr_any;
a->size = sizeof(struct sockaddr_in6);
} else {
a->sockaddr.in.sin_family = AF_INET;
- a->sockaddr.in.sin_port = htons((uint16_t) u);
+ a->sockaddr.in.sin_port = htobe16((uint16_t)u);
a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
a->size = sizeof(struct sockaddr_in);
}
@@ -488,9 +488,7 @@ int sockaddr_port(const struct sockaddr *_sa) {
if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
return -EAFNOSUPPORT;
- return ntohs(sa->sa.sa_family == AF_INET6 ?
- sa->in6.sin6_port :
- sa->in.sin_port);
+ return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port);
}
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
@@ -506,13 +504,13 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
case AF_INET: {
uint32_t a;
- a = ntohl(sa->in.sin_addr.s_addr);
+ a = be32toh(sa->in.sin_addr.s_addr);
if (include_port)
r = asprintf(&p,
"%u.%u.%u.%u:%u",
a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
- ntohs(sa->in.sin_port));
+ be16toh(sa->in.sin_port));
else
r = asprintf(&p,
"%u.%u.%u.%u",
@@ -534,7 +532,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
r = asprintf(&p,
"%u.%u.%u.%u:%u",
a[0], a[1], a[2], a[3],
- ntohs(sa->in6.sin6_port));
+ be16toh(sa->in6.sin6_port));
else
r = asprintf(&p,
"%u.%u.%u.%u",
@@ -550,7 +548,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
r = asprintf(&p,
"[%s]:%u",
a,
- ntohs(sa->in6.sin6_port));
+ be16toh(sa->in6.sin6_port));
if (r < 0)
return -ENOMEM;
} else {
@@ -988,7 +986,7 @@ ssize_t next_datagram_size_fd(int fd) {
l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC);
if (l < 0) {
- if (errno == EOPNOTSUPP)
+ if (errno == EOPNOTSUPP || errno == EFAULT)
goto fallback;
return -errno;