mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-22 18:22:11 +01:00
gio: Implement GSeekable on GUnixInputStream
It seems like an artificial limitation, and prevents us seeking DBus-passed file-descriptors. Fixes https://gitlab.gnome.org/GNOME/glib/-/issues/3200
This commit is contained in:
parent
30d6e911c4
commit
c614f5170b
@ -66,6 +66,7 @@ struct _GUnixInputStreamPrivate {
|
|||||||
|
|
||||||
static void g_unix_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface);
|
static void g_unix_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface);
|
||||||
static void g_unix_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface);
|
static void g_unix_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface);
|
||||||
|
static void g_unix_input_stream_seekable_iface_init (GSeekableIface *iface);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GUnixInputStream, g_unix_input_stream, G_TYPE_INPUT_STREAM,
|
G_DEFINE_TYPE_WITH_CODE (GUnixInputStream, g_unix_input_stream, G_TYPE_INPUT_STREAM,
|
||||||
G_ADD_PRIVATE (GUnixInputStream)
|
G_ADD_PRIVATE (GUnixInputStream)
|
||||||
@ -73,6 +74,8 @@ G_DEFINE_TYPE_WITH_CODE (GUnixInputStream, g_unix_input_stream, G_TYPE_INPUT_STR
|
|||||||
g_unix_input_stream_pollable_iface_init)
|
g_unix_input_stream_pollable_iface_init)
|
||||||
G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED,
|
G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED,
|
||||||
g_unix_input_stream_file_descriptor_based_iface_init)
|
g_unix_input_stream_file_descriptor_based_iface_init)
|
||||||
|
G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
|
||||||
|
g_unix_input_stream_seekable_iface_init)
|
||||||
)
|
)
|
||||||
|
|
||||||
static void g_unix_input_stream_set_property (GObject *object,
|
static void g_unix_input_stream_set_property (GObject *object,
|
||||||
@ -106,6 +109,19 @@ static gboolean g_unix_input_stream_pollable_is_readable (GPollableInputStream
|
|||||||
static GSource *g_unix_input_stream_pollable_create_source (GPollableInputStream *stream,
|
static GSource *g_unix_input_stream_pollable_create_source (GPollableInputStream *stream,
|
||||||
GCancellable *cancellable);
|
GCancellable *cancellable);
|
||||||
|
|
||||||
|
static goffset g_unix_input_stream_tell (GSeekable *seekable);
|
||||||
|
static gboolean g_unix_input_stream_can_seek (GSeekable *seekable);
|
||||||
|
static gboolean g_unix_input_stream_seek (GSeekable *seekable,
|
||||||
|
goffset offset,
|
||||||
|
GSeekType type,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
static gboolean g_unix_input_stream_can_truncate (GSeekable *seekable);
|
||||||
|
static gboolean g_unix_input_stream_truncate (GSeekable *seekable,
|
||||||
|
goffset offset,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_unix_input_stream_class_init (GUnixInputStreamClass *klass)
|
g_unix_input_stream_class_init (GUnixInputStreamClass *klass)
|
||||||
{
|
{
|
||||||
@ -165,6 +181,16 @@ g_unix_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface
|
|||||||
iface->get_fd = (int (*) (GFileDescriptorBased *))g_unix_input_stream_get_fd;
|
iface->get_fd = (int (*) (GFileDescriptorBased *))g_unix_input_stream_get_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_unix_input_stream_seekable_iface_init (GSeekableIface *iface)
|
||||||
|
{
|
||||||
|
iface->tell = g_unix_input_stream_tell;
|
||||||
|
iface->can_seek = g_unix_input_stream_can_seek;
|
||||||
|
iface->seek = g_unix_input_stream_seek;
|
||||||
|
iface->can_truncate = g_unix_input_stream_can_truncate;
|
||||||
|
iface->truncate_fn = g_unix_input_stream_truncate;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_unix_input_stream_set_property (GObject *object,
|
g_unix_input_stream_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -480,3 +506,80 @@ g_unix_input_stream_pollable_create_source (GPollableInputStream *stream,
|
|||||||
|
|
||||||
return pollable_source;
|
return pollable_source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static goffset
|
||||||
|
g_unix_input_stream_tell (GSeekable *seekable)
|
||||||
|
{
|
||||||
|
GUnixInputStream *unix_stream = G_UNIX_INPUT_STREAM (seekable);
|
||||||
|
goffset rc = lseek (unix_stream->priv->fd, 0, SEEK_CUR);
|
||||||
|
if (rc < 0)
|
||||||
|
g_critical ("cannot tell GUnixInputStream: %s", g_strerror (errno));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
g_unix_input_stream_can_seek (GSeekable *seekable)
|
||||||
|
{
|
||||||
|
GUnixInputStream *unix_stream = G_UNIX_INPUT_STREAM (seekable);
|
||||||
|
return lseek (unix_stream->priv->fd, 0, SEEK_CUR) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_seek_type_to_lseek (GSeekType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case G_SEEK_CUR:
|
||||||
|
return SEEK_CUR;
|
||||||
|
case G_SEEK_SET:
|
||||||
|
return SEEK_SET;
|
||||||
|
case G_SEEK_END:
|
||||||
|
return SEEK_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
g_unix_input_stream_seek (GSeekable *seekable,
|
||||||
|
goffset offset,
|
||||||
|
GSeekType type,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GUnixInputStream *unix_stream = G_UNIX_INPUT_STREAM (seekable);
|
||||||
|
goffset rc;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_UNIX_INPUT_STREAM (unix_stream), FALSE);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||||
|
|
||||||
|
rc = lseek (unix_stream->priv->fd, offset, _seek_type_to_lseek (type));
|
||||||
|
if (rc < 0)
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
g_io_error_from_errno (errno),
|
||||||
|
"Error seeking file descriptor: %s",
|
||||||
|
g_strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
g_unix_input_stream_can_truncate (GSeekable *seekable)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
g_unix_input_stream_truncate (GSeekable *seekable,
|
||||||
|
goffset offset,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
"Cannot truncate GUnixInputStream");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user