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
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)
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
#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
#cmakedefine HAVE_ACCEPT4 1
+#cmakedefine HAVE_FSTATFS 1
#cmakedefine HAVE_INOTIFY_INIT1 1
#cmakedefine HAVE_GETRANDOM 1
#cmakedefine HAVE_GETRLIMIT 1
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])
#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>
{
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);
_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),
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,
'io.h',
'locale.h',
'linux/close_range.h',
+ 'linux/magic.h',
'locale.h',
'signal.h',
'syslog.h',
'sys/resource.h',
'sys/syscall.h',
'sys/time.h',
+ 'sys/vfs.h',
'unistd.h',
'ws2tcpip.h',
]
)
)
+config.set('HAVE_FSTATFS',
+ cc.has_function(
+ 'fstatfs',
+ prefix : '#include <sys/vfs.h>',
+ args: compile_args_c,
+ )
+)
###############################################################################
# Project options