X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fglocalfileinputstream.c;h=2b7944462869ca077f5e83149ad2a1f27f1d8999;hb=25990eb2b6da94e1d03631eab8a952ef84cb9986;hp=0cecaa8001ba70a5e5f1587eda582134d2550501;hpb=d9594f5709313d6e7a8a4f3e5f3b23fc72017417;p=platform%2Fupstream%2Fglib.git
diff --git a/gio/glocalfileinputstream.c b/gio/glocalfileinputstream.c
index 0cecaa8..2b79444 100644
--- a/gio/glocalfileinputstream.c
+++ b/gio/glocalfileinputstream.c
@@ -13,37 +13,56 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see .
*
* Author: Alexander Larsson
*/
-#include
+#include "config.h"
#include
#include
#include
-#include
#include
#include
#include
+#include "gcancellable.h"
#include "gioerror.h"
#include "glocalfileinputstream.h"
#include "glocalfileinfo.h"
#include "glibintl.h"
-#include "gioalias.h"
+#ifdef G_OS_UNIX
+#include
+#include "glib-unix.h"
+#include "gfiledescriptorbased.h"
+#endif
-#define g_local_file_input_stream_get_type _g_local_file_input_stream_get_type
-G_DEFINE_TYPE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM);
+#ifdef G_OS_WIN32
+#include
+#endif
struct _GLocalFileInputStreamPrivate {
int fd;
+ guint do_close : 1;
};
+#ifdef G_OS_UNIX
+static void g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface);
+#endif
+
+#define g_local_file_input_stream_get_type _g_local_file_input_stream_get_type
+#ifdef G_OS_UNIX
+G_DEFINE_TYPE_WITH_CODE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM,
+ G_ADD_PRIVATE (GLocalFileInputStream)
+ G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED,
+ g_file_descriptor_based_iface_init))
+#else
+G_DEFINE_TYPE_WITH_CODE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM,
+ G_ADD_PRIVATE (GLocalFileInputStream))
+#endif
+
static gssize g_local_file_input_stream_read (GInputStream *stream,
void *buffer,
gsize count,
@@ -64,55 +83,50 @@ static gboolean g_local_file_input_stream_seek (GFileInputStream *strea
GCancellable *cancellable,
GError **error);
static GFileInfo *g_local_file_input_stream_query_info (GFileInputStream *stream,
- char *attributes,
+ const char *attributes,
GCancellable *cancellable,
GError **error);
+#ifdef G_OS_UNIX
+static int g_local_file_input_stream_get_fd (GFileDescriptorBased *stream);
+#endif
-static void
-g_local_file_input_stream_finalize (GObject *object)
+void
+_g_local_file_input_stream_set_do_close (GLocalFileInputStream *in,
+ gboolean do_close)
{
- GLocalFileInputStream *file;
-
- file = G_LOCAL_FILE_INPUT_STREAM (object);
-
- if (G_OBJECT_CLASS (g_local_file_input_stream_parent_class)->finalize)
- (*G_OBJECT_CLASS (g_local_file_input_stream_parent_class)->finalize) (object);
+ in->priv->do_close = do_close;
}
static void
g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (GLocalFileInputStreamPrivate));
-
- gobject_class->finalize = g_local_file_input_stream_finalize;
- stream_class->read = g_local_file_input_stream_read;
+ stream_class->read_fn = g_local_file_input_stream_read;
stream_class->skip = g_local_file_input_stream_skip;
- stream_class->close = g_local_file_input_stream_close;
+ stream_class->close_fn = g_local_file_input_stream_close;
file_stream_class->tell = g_local_file_input_stream_tell;
file_stream_class->can_seek = g_local_file_input_stream_can_seek;
file_stream_class->seek = g_local_file_input_stream_seek;
file_stream_class->query_info = g_local_file_input_stream_query_info;
}
+#ifdef G_OS_UNIX
+static void
+g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface)
+{
+ iface->get_fd = g_local_file_input_stream_get_fd;
+}
+#endif
+
static void
g_local_file_input_stream_init (GLocalFileInputStream *info)
{
- info->priv = G_TYPE_INSTANCE_GET_PRIVATE (info,
- G_TYPE_LOCAL_FILE_INPUT_STREAM,
- GLocalFileInputStreamPrivate);
+ info->priv = g_local_file_input_stream_get_instance_private (info);
+ info->priv->do_close = TRUE;
}
-/**
- * g_local_file_input_stream_new:
- * @fd: File Descriptor.
- *
- * Returns: #GFileInputStream for the given file descriptor.
- **/
GFileInputStream *
_g_local_file_input_stream_new (int fd)
{
@@ -125,11 +139,11 @@ _g_local_file_input_stream_new (int fd)
}
static gssize
-g_local_file_input_stream_read (GInputStream *stream,
- void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error)
+g_local_file_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFileInputStream *file;
gssize res;
@@ -144,13 +158,15 @@ g_local_file_input_stream_read (GInputStream *stream,
res = read (file->priv->fd, buffer, count);
if (res == -1)
{
- if (errno == EINTR)
+ int errsv = errno;
+
+ if (errsv == EINTR)
continue;
g_set_error (error, G_IO_ERROR,
- g_io_error_from_errno (errno),
+ g_io_error_from_errno (errsv),
_("Error reading from file: %s"),
- g_strerror (errno));
+ g_strerror (errsv));
}
break;
@@ -160,12 +176,12 @@ g_local_file_input_stream_read (GInputStream *stream,
}
static gssize
-g_local_file_input_stream_skip (GInputStream *stream,
- gsize count,
- GCancellable *cancellable,
- GError **error)
+g_local_file_input_stream_skip (GInputStream *stream,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
{
- off_t res, start;
+ off_t start, end;
GLocalFileInputStream *file;
file = G_LOCAL_FILE_INPUT_STREAM (stream);
@@ -176,53 +192,72 @@ g_local_file_input_stream_skip (GInputStream *stream,
start = lseek (file->priv->fd, 0, SEEK_CUR);
if (start == -1)
{
+ int errsv = errno;
+
g_set_error (error, G_IO_ERROR,
- g_io_error_from_errno (errno),
+ g_io_error_from_errno (errsv),
_("Error seeking in file: %s"),
- g_strerror (errno));
+ g_strerror (errsv));
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;
+
g_set_error (error, G_IO_ERROR,
- g_io_error_from_errno (errno),
+ g_io_error_from_errno (errsv),
_("Error seeking in file: %s"),
- g_strerror (errno));
+ g_strerror (errsv));
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
-g_local_file_input_stream_close (GInputStream *stream,
- GCancellable *cancellable,
- GError **error)
+g_local_file_input_stream_close (GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFileInputStream *file;
- int res;
file = G_LOCAL_FILE_INPUT_STREAM (stream);
+ if (!file->priv->do_close)
+ return TRUE;
+
if (file->priv->fd == -1)
return TRUE;
- while (1)
+ if (!g_close (file->priv->fd, NULL))
{
- res = close (file->priv->fd);
- if (res == -1)
- {
- g_set_error (error, G_IO_ERROR,
- g_io_error_from_errno (errno),
- _("Error closing file: %s"),
- g_strerror (errno));
- }
- break;
+ int errsv = errno;
+
+ g_set_error (error, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ _("Error closing file: %s"),
+ g_strerror (errsv));
+ return FALSE;
}
- return res != -1;
+ return TRUE;
}
@@ -252,8 +287,7 @@ g_local_file_input_stream_can_seek (GFileInputStream *stream)
pos = lseek (file->priv->fd, 0, SEEK_CUR);
- if (pos == (off_t)-1 &&
- errno == ESPIPE)
+ if (pos == (off_t)-1 && errno == ESPIPE)
return FALSE;
return TRUE;
@@ -277,11 +311,11 @@ seek_type_to_lseek (GSeekType type)
}
static gboolean
-g_local_file_input_stream_seek (GFileInputStream *stream,
- goffset offset,
- GSeekType type,
- GCancellable *cancellable,
- GError **error)
+g_local_file_input_stream_seek (GFileInputStream *stream,
+ goffset offset,
+ GSeekType type,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFileInputStream *file;
off_t pos;
@@ -292,10 +326,12 @@ g_local_file_input_stream_seek (GFileInputStream *stream,
if (pos == (off_t)-1)
{
+ int errsv = errno;
+
g_set_error (error, G_IO_ERROR,
- g_io_error_from_errno (errno),
+ g_io_error_from_errno (errsv),
_("Error seeking in file: %s"),
- g_strerror (errno));
+ g_strerror (errsv));
return FALSE;
}
@@ -303,10 +339,10 @@ g_local_file_input_stream_seek (GFileInputStream *stream,
}
static GFileInfo *
-g_local_file_input_stream_query_info (GFileInputStream *stream,
- char *attributes,
- GCancellable *cancellable,
- GError **error)
+g_local_file_input_stream_query_info (GFileInputStream *stream,
+ const char *attributes,
+ GCancellable *cancellable,
+ GError **error)
{
GLocalFileInputStream *file;
@@ -319,3 +355,12 @@ g_local_file_input_stream_query_info (GFileInputStream *stream,
attributes,
error);
}
+
+#ifdef G_OS_UNIX
+static int
+g_local_file_input_stream_get_fd (GFileDescriptorBased *fd_based)
+{
+ GLocalFileInputStream *stream = G_LOCAL_FILE_INPUT_STREAM (fd_based);
+ return stream->priv->fd;
+}
+#endif