chiark / gitweb /
coredump: rework compose_open_fds()
[elogind.git] / src / journal / coredump.c
index a871c570ca7d5f9c84ca1a47602df823e1c65790..50402068a0be12ed5ba77077113d435d5db58fd8 100644 (file)
@@ -142,10 +142,8 @@ static int fix_acl(int fd, uid_t uid) {
          * their own coredumps */
 
         acl = acl_get_fd(fd);
-        if (!acl) {
-                log_error_errno(errno, "Failed to get ACL: %m");
-                return -errno;
-        }
+        if (!acl)
+                return log_error_errno(errno, "Failed to get ACL: %m");
 
         if (acl_create_entry(&acl, &entry) < 0 ||
             acl_set_tag_type(entry, ACL_USER) < 0 ||
@@ -161,10 +159,8 @@ static int fix_acl(int fd, uid_t uid) {
                 return -errno;
         }
 
-        if (acl_set_fd(fd, acl) < 0) {
-                log_error_errno(errno, "Failed to apply ACL: %m");
-                return -errno;
-        }
+        if (acl_set_fd(fd, acl) < 0)
+                return log_error_errno(errno, "Failed to apply ACL: %m");
 #endif
 
         return 0;
@@ -223,15 +219,11 @@ static int fix_permissions(
         fix_acl(fd, uid);
         fix_xattr(fd, info);
 
-        if (fsync(fd) < 0) {
-                log_error_errno(errno, "Failed to sync coredump %s: %m", filename);
-                return -errno;
-        }
+        if (fsync(fd) < 0)
+                return log_error_errno(errno, "Failed to sync coredump %s: %m", filename);
 
-        if (rename(filename, target) < 0) {
-                log_error_errno(errno, "Failed to rename coredump %s -> %s: %m", filename, target);
-                return -errno;
-        }
+        if (rename(filename, target) < 0)
+                return log_error_errno(errno, "Failed to rename coredump %s -> %s: %m", filename, target);
 
         return 0;
 }
@@ -247,10 +239,8 @@ static int maybe_remove_external_coredump(const char *filename, off_t size) {
         if (!filename)
                 return 1;
 
-        if (unlink(filename) < 0 && errno != ENOENT) {
-                log_error_errno(errno, "Failed to unlink %s: %m", filename);
-                return -errno;
-        }
+        if (unlink(filename) < 0 && errno != ENOENT)
+                return log_error_errno(errno, "Failed to unlink %s: %m", filename);
 
         return 1;
 }
@@ -322,10 +312,8 @@ static int save_external_coredump(
         mkdir_p_label("/var/lib/systemd/coredump", 0755);
 
         fd = open(tmp, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0640);
-        if (fd < 0) {
-                log_error_errno(errno, "Failed to create coredump file %s: %m", tmp);
-                return -errno;
-        }
+        if (fd < 0)
+                return log_error_errno(errno, "Failed to create coredump file %s: %m", tmp);
 
         r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max);
         if (r == -EFBIG) {
@@ -429,10 +417,8 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s
         assert(ret);
         assert(ret_size);
 
-        if (lseek(fd, 0, SEEK_SET) == (off_t) -1) {
-                log_warning_errno(errno, "Failed to seek: %m");
-                return -errno;
-        }
+        if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+                return log_warning_errno(errno, "Failed to seek: %m");
 
         field = malloc(9 + size);
         if (!field) {
@@ -473,12 +459,13 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s
  * EOF
  */
 static int compose_open_fds(pid_t pid, char **open_fds) {
+        _cleanup_closedir_ DIR *proc_fd_dir = NULL;
+        _cleanup_close_ int proc_fdinfo_fd = -1;
+        _cleanup_free_ char *buffer = NULL;
         _cleanup_fclose_ FILE *stream = NULL;
-        size_t ignored_size;
         const char *fddelim = "", *path;
         struct dirent *dent = NULL;
-        _cleanup_closedir_ DIR *proc_fd_dir = NULL;
-        _cleanup_close_ int proc_fdinfo_fd = -1;
+        size_t size = 0;
         int r = 0;
 
         assert(pid >= 0);
@@ -489,23 +476,19 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
         if (!proc_fd_dir)
                 return -errno;
 
-        proc_fdinfo_fd = openat(dirfd(proc_fd_dir), "../fdinfo",
-                                O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC|O_PATH);
+        proc_fdinfo_fd = openat(dirfd(proc_fd_dir), "../fdinfo", O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC|O_PATH);
         if (proc_fdinfo_fd < 0)
                 return -errno;
 
-        stream = open_memstream(open_fds, &ignored_size);
+        stream = open_memstream(&buffer, &size);
         if (!stream)
                 return -ENOMEM;
 
-        for (dent = readdir(proc_fd_dir); dent != NULL; dent = readdir(proc_fd_dir)) {
-                _cleanup_free_ char *fdname = NULL;
-                int fd;
+        FOREACH_DIRENT(dent, proc_fd_dir, return -errno) {
                 _cleanup_fclose_ FILE *fdinfo = NULL;
+                _cleanup_free_ char *fdname = NULL;
                 char line[LINE_MAX];
-
-                if (dent->d_name[0] == '.' || strcmp(dent->d_name, "..") == 0)
-                        continue;
+                int fd;
 
                 r = readlinkat_malloc(dirfd(proc_fd_dir), dent->d_name, &fdname);
                 if (r < 0)
@@ -525,11 +508,23 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
                         continue;
                 }
 
-                while(fgets(line, sizeof(line), fdinfo) != NULL)
-                        fprintf(stream, "%s%s",
-                                line, strchr(line, '\n') == NULL ? "\n" : "");
+                FOREACH_LINE(line, fdinfo, break) {
+                        fputs(line, stream);
+                        if (!endswith(line, "\n"))
+                                fputc('\n', stream);
+                }
         }
 
+        errno = 0;
+        fclose(stream);
+        stream = NULL;
+
+        if (errno != 0)
+                return -errno;
+
+        *open_fds = buffer;
+        buffer = NULL;
+
         return 0;
 }