summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2023-03-20 01:40:20 +0000
committerSimon McVittie <smcv@collabora.com>2023-05-15 19:06:54 +0000
commit4364b9ebb3acef566a2c1955423426584147226e (patch)
treeafbef4a885ef77ca7c0adcaf0e8b87912fc8f10e
parent1a74c43c0e545f41b6266713362c42748ee579e8 (diff)
downloaddbus-4364b9ebb3acef566a2c1955423426584147226e.tar.gz
Support /proc in _dbus_file_get_content
procfs has special semantics: most files are 0 size, only one read can be done on a file, and they are not larger than 4MB. Enhance _dbus_file_get_content() so that we can read files from /proc with it. Signed-off-by: Luca Boccassi <bluca@debian.org>
-rw-r--r--cmake/ConfigureChecks.cmake3
-rw-r--r--cmake/config.h.cmake3
-rw-r--r--configure.ac3
-rw-r--r--dbus/dbus-file-unix.c50
-rw-r--r--meson.build9
5 files changed, 64 insertions, 4 deletions
diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake
index 172db213..dfa21a55 100644
--- a/cmake/ConfigureChecks.cmake
+++ b/cmake/ConfigureChecks.cmake
@@ -15,6 +15,7 @@ check_include_file(errno.h HAVE_ERRNO_H) # dbus-sysdeps.c
check_include_file(inttypes.h HAVE_INTTYPES_H) # dbus-pipe.h
check_include_file(io.h HAVE_IO_H) # internal
check_include_file(linux/close_range.h HAVE_LINUX_CLOSE_RANGE_H)
+check_include_file(linux/magic.h HAVE_LINUX_MAGIC_H)
check_include_file(locale.h HAVE_LOCALE_H)
check_include_file(signal.h HAVE_SIGNAL_H)
check_include_file(stdio.h HAVE_STDIO_H) # dbus-sysdeps.h
@@ -26,6 +27,7 @@ check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H)
check_include_file(sys/syscall.h HAVE_SYS_SYSCALL_H)
check_include_file(sys/prctl.h HAVE_SYS_PRCTL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)# dbus-sysdeps-win.c
+check_include_file(sys/vfs.h HAVE_SYS_VFS_H)
check_include_file(ws2tcpip.h HAVE_WS2TCPIP_H)# dbus-sysdeps-win.c
check_include_file(unistd.h HAVE_UNISTD_H) # dbus-sysdeps-util-win.c
check_include_file(sys/inotify.h DBUS_BUS_ENABLE_INOTIFY)
@@ -64,6 +66,7 @@ check_symbol_exists(environ "unistd.h" HAVE_DECL_ENVIRON)
check_symbol_exists(LOG_PERROR "syslog.h" HAVE_DECL_LOG_PERROR)
check_symbol_exists(setresuid "unistd.h" HAVE_SETRESUID)
check_symbol_exists(getresuid "unistd.h" HAVE_GETRESUID)
+check_symbol_exists(fstatfs "sys/vfs.h" HAVE_FSTATFS)
check_struct_member(cmsgcred cmcred_pid "sys/types.h;sys/socket.h" HAVE_CMSGCRED) # dbus-sysdeps.c
diff --git a/cmake/config.h.cmake b/cmake/config.h.cmake
index 395a583d..43771b99 100644
--- a/cmake/config.h.cmake
+++ b/cmake/config.h.cmake
@@ -120,10 +120,12 @@
#cmakedefine HAVE_SYSLOG_H 1
#cmakedefine HAVE_SYS_EVENTS_H 1
#cmakedefine HAVE_SYS_INOTIFY_H 1
+#cmakedefine HAVE_LINUX_MAGIC_H 1
#cmakedefine HAVE_SYS_PRCTL_H 1
#cmakedefine HAVE_SYS_RANDOM_H 1
#cmakedefine HAVE_SYS_RESOURCE_H 1
#cmakedefine HAVE_SYS_SYSCALL_H 1
+#cmakedefine HAVE_SYS_VFS_H 1
/* Define to 1 if you have sys/time.h */
#cmakedefine HAVE_SYS_TIME_H 1
@@ -185,6 +187,7 @@
#cmakedefine HAVE_ACCEPT4 1
+#cmakedefine HAVE_FSTATFS 1
#cmakedefine HAVE_INOTIFY_INIT1 1
#cmakedefine HAVE_GETRANDOM 1
#cmakedefine HAVE_GETRLIMIT 1
diff --git a/configure.ac b/configure.ac
index 92124838..2620f372 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1023,6 +1023,9 @@ if test x$with_valgrind != xno; then
AC_DEFINE([WITH_VALGRIND], [1], [Define to add Valgrind instrumentation])
fi
+AC_CHECK_HEADERS(sys/vfs.h, [AC_CHECK_FUNCS(fstatfs)])
+AC_CHECK_HEADERS([linux/magic.h])
+
#### Set up final flags
LIBDBUS_LIBS="$THREAD_LIBS $NETWORK_libs $SYSTEMD_LIBS"
AC_SUBST([LIBDBUS_LIBS])
diff --git a/dbus/dbus-file-unix.c b/dbus/dbus-file-unix.c
index 6da44504..d5fa029e 100644
--- a/dbus/dbus-file-unix.c
+++ b/dbus/dbus-file-unix.c
@@ -33,7 +33,13 @@
#include "dbus-sysdeps.h"
#include "dbus-sysdeps-unix.h"
+#ifdef HAVE_LINUX_MAGIC_H
+#include <linux/magic.h>
+#endif
#include <sys/stat.h>
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
@@ -60,9 +66,14 @@ _dbus_file_get_contents (DBusString *str,
{
int fd;
struct stat sb;
+#ifdef HAVE_FSTATFS
+ struct statfs sfs;
+#endif
int orig_len;
int total;
+ int file_size;
const char *filename_c;
+ dbus_bool_t is_procfs = FALSE;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -104,17 +115,47 @@ _dbus_file_get_contents (DBusString *str,
_dbus_close (fd, NULL);
return FALSE;
}
+
+ /* procfs has different semantics - most files are 0 size,
+ * we can do only one read, and at most we can read 4M.
+ */
+#ifdef HAVE_FSTATFS
+ if (sb.st_size == 0)
+ {
+ if (fstatfs(fd, &sfs) < 0)
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to stat \"%s\": %s",
+ filename_c,
+ _dbus_strerror (errno));
+
+ _dbus_verbose ("fstatvfs() failed: %s",
+ _dbus_strerror (errno));
+
+ _dbus_close (fd, NULL);
+
+ return FALSE;
+ }
+ if (sfs.f_type == PROC_SUPER_MAGIC)
+ is_procfs = TRUE;
+ }
+#endif
+
+ if (is_procfs)
+ file_size = _DBUS_ONE_MEGABYTE;
+ else
+ file_size = sb.st_size;
total = 0;
orig_len = _dbus_string_get_length (str);
- if (sb.st_size > 0 && S_ISREG (sb.st_mode))
+ if (file_size > 0 && S_ISREG (sb.st_mode))
{
int bytes_read;
- while (total < (int) sb.st_size)
+ do
{
bytes_read = _dbus_read (fd, str,
- sb.st_size - total);
+ file_size - total);
if (bytes_read <= 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
@@ -132,11 +173,12 @@ _dbus_file_get_contents (DBusString *str,
else
total += bytes_read;
}
+ while (total < file_size && !is_procfs);
_dbus_close (fd, NULL);
return TRUE;
}
- else if (sb.st_size != 0)
+ else if (file_size != 0)
{
_dbus_verbose ("Can only open regular files at the moment.\n");
dbus_set_error (error, DBUS_ERROR_FAILED,
diff --git a/meson.build b/meson.build
index df302a7d..e2cbc368 100644
--- a/meson.build
+++ b/meson.build
@@ -670,6 +670,7 @@ check_headers = [
'io.h',
'locale.h',
'linux/close_range.h',
+ 'linux/magic.h',
'locale.h',
'signal.h',
'syslog.h',
@@ -678,6 +679,7 @@ check_headers = [
'sys/resource.h',
'sys/syscall.h',
'sys/time.h',
+ 'sys/vfs.h',
'unistd.h',
'ws2tcpip.h',
]
@@ -753,6 +755,13 @@ config.set('HAVE_UNPCBID',
)
)
+config.set('HAVE_FSTATFS',
+ cc.has_function(
+ 'fstatfs',
+ prefix : '#include <sys/vfs.h>',
+ args: compile_args_c,
+ )
+)
###############################################################################
# Project options