chiark / gitweb /
shared: procfs_file_alloca: handle pid==0
[elogind.git] / src / shared / util.h
index 338d79c7ac5822be36c0c1b312df422b1aeef1c6..86456542679491cb0228fdf2f7898c099b3ae4f2 100644 (file)
 #include <unistd.h>
 #include <locale.h>
 #include <mntent.h>
+#include <sys/socket.h>
+
+#if SIZEOF_PID_T == 4
+#  define PID_FMT "%" PRIu32
+#elif SIZEOF_PID_T == 2
+#  define PID_FMT "%" PRIu16
+#else
+#  error Unknown pid_t size
+#endif
+
+#if SIZEOF_UID_T == 4
+#  define UID_FMT "%" PRIu32
+#elif SIZEOF_UID_T == 2
+#  define UID_FMT "%" PRIu16
+#else
+#  error Unknown uid_t size
+#endif
 
 #include "macro.h"
 #include "time-util.h"
 
 /* What is interpreted as whitespace? */
 #define WHITESPACE " \t\n\r"
-#define NEWLINE "\n\r"
-#define QUOTES "\"\'"
-#define COMMENTS "#;"
+#define NEWLINE    "\n\r"
+#define QUOTES     "\"\'"
+#define COMMENTS   "#;"
+#define GLOB_CHARS "*?["
 
 #define FORMAT_BYTES_MAX 8
 
@@ -626,6 +644,13 @@ bool path_is_safe(const char *p) _pure_;
 bool string_is_safe(const char *p) _pure_;
 bool string_has_cc(const char *p) _pure_;
 
+/**
+ * Check if a string contains any glob patterns.
+ */
+_pure_ static inline bool string_is_glob(const char *p) {
+        return !!strpbrk(p, GLOB_CHARS);
+}
+
 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
                  int (*compar) (const void *, const void *, void *),
                  void *arg);
@@ -711,7 +736,7 @@ static inline void _reset_umask_(struct _umask_struct_ *s) {
              _saved_umask_.quit = true)
 
 static inline unsigned u64log2(uint64_t n) {
-        return (n > 1) ? __builtin_clzll(n) ^ 63U : 0;
+        return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
 }
 
 static inline bool logind_running(void) {
@@ -752,9 +777,13 @@ int unlink_noerrno(const char *path);
 #define procfs_file_alloca(pid, field)                                  \
         ({                                                              \
                 pid_t _pid_ = (pid);                                    \
-                char *_r_;                                              \
-                _r_ = alloca(sizeof("/proc/") -1 + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
-                sprintf(_r_, "/proc/%lu/" field, (unsigned long) _pid_); \
+                const char *_r_;                                        \
+                if (_pid_ == 0) {                                       \
+                        _r_ = ("/proc/self/" field);                    \
+                } else {                                                \
+                        _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
+                        sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_);                       \
+                }                                                       \
                 _r_;                                                    \
         })
 
@@ -811,3 +840,6 @@ int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd);
 int namespace_enter(int pidns_fd, int mntns_fd, int root_fd);
 
 bool pid_valid(pid_t pid);
+
+int getpeercred(int fd, struct ucred *ucred);
+int getpeersec(int fd, char **ret);