X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fglocalfileinputstream.c;h=2b7944462869ca077f5e83149ad2a1f27f1d8999;hb=2a2b11b1bb6c702d6b2ef1c37524a57688a94a4e;hp=294ad07989f7c22ca191d228a38b009b42ab5734;hpb=37ac644bd18168330f43f4d52be7e3cbb3415415;p=platform%2Fupstream%2Fglib.git diff --git a/gio/glocalfileinputstream.c b/gio/glocalfileinputstream.c index 294ad07..2b79444 100644 --- a/gio/glocalfileinputstream.c +++ b/gio/glocalfileinputstream.c @@ -13,43 +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 -#ifdef HAVE_UNISTD_H -#include -#endif #include #include #include +#include "gcancellable.h" #include "gioerror.h" #include "glocalfileinputstream.h" #include "glocalfileinfo.h" #include "glibintl.h" +#ifdef G_OS_UNIX +#include +#include "glib-unix.h" +#include "gfiledescriptorbased.h" +#endif + #ifdef G_OS_WIN32 #include #endif -#include "gioalias.h" - -#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); - 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, @@ -70,31 +83,25 @@ 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_fn = g_local_file_input_stream_read; stream_class->skip = g_local_file_input_stream_skip; @@ -105,20 +112,21 @@ g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass) 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) { @@ -173,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); @@ -193,8 +201,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; @@ -205,7 +213,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 @@ -214,29 +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) - { - int errsv = errno; - - g_set_error (error, G_IO_ERROR, - g_io_error_from_errno (errsv), - _("Error closing file: %s"), - g_strerror (errsv)); - } - 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; } @@ -319,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) { @@ -334,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