X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fglocalfileinputstream.c;h=2b7944462869ca077f5e83149ad2a1f27f1d8999;hb=958da1e9dc82fbb91862501226b8928faf2f9558;hp=a1aa00b43e04fa0dc46893d7d5e304bcd9e6838f;hpb=a2ca589703273fca80cb126430a8b058aba3eb52;p=platform%2Fupstream%2Fglib.git diff --git a/gio/glocalfileinputstream.c b/gio/glocalfileinputstream.c index a1aa00b..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) { @@ -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; @@ -165,7 +181,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); @@ -176,24 +192,43 @@ 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 @@ -202,25 +237,27 @@ g_local_file_input_stream_close (GInputStream *stream, 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; } @@ -250,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; @@ -290,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; } @@ -302,7 +340,7 @@ g_local_file_input_stream_seek (GFileInputStream *stream, static GFileInfo * g_local_file_input_stream_query_info (GFileInputStream *stream, - char *attributes, + const char *attributes, GCancellable *cancellable, GError **error) { @@ -317,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