diff --git a/gio/glocalfileinputstream.c b/gio/glocalfileinputstream.c index 5d4acf66f..2c32353e1 100644 --- a/gio/glocalfileinputstream.c +++ b/gio/glocalfileinputstream.c @@ -185,7 +185,7 @@ g_local_file_input_stream_skip (GInputStream *stream, GCancellable *cancellable, GError **error) { - off_t res, start; + off_t start, end; GLocalFileInputStream *file; file = G_LOCAL_FILE_INPUT_STREAM (stream); @@ -205,8 +205,8 @@ g_local_file_input_stream_skip (GInputStream *stream, return -1; } - res = lseek (file->priv->fd, count, SEEK_CUR); - if (res == -1) + end = lseek (file->priv->fd, 0, SEEK_END); + if (end == -1) { int errsv = errno; @@ -217,7 +217,22 @@ g_local_file_input_stream_skip (GInputStream *stream, return -1; } - return res - start; + if (end - start > count) + { + end = lseek (file->priv->fd, count - (end - start), SEEK_CUR); + if (end == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error seeking in file: %s"), + g_strerror (errsv)); + return -1; + } + } + + return end - start; } static gboolean diff --git a/gio/tests/readwrite.c b/gio/tests/readwrite.c index 0484d186a..5ac2f6ff2 100644 --- a/gio/tests/readwrite.c +++ b/gio/tests/readwrite.c @@ -62,6 +62,18 @@ verify_iostream (GFileIOStream *file_iostream) verify_pos (iostream, strlen (original_data)); + res = g_seekable_seek (G_SEEKABLE (iostream), + 10, G_SEEK_SET, + NULL, NULL); + + res = g_input_stream_skip (in, 5, NULL, NULL); + g_assert (res == 5); + verify_pos (iostream, 15); + + res = g_input_stream_skip (in, 10000, NULL, NULL); + g_assert (res == strlen (original_data) - 15); + verify_pos (iostream, strlen (original_data)); + res = g_seekable_seek (G_SEEKABLE (iostream), 10, G_SEEK_SET, NULL, NULL);