Removed unnecessary file
[platform/upstream/glib.git] / gio / glocalfileinputstream.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include <config.h>
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <errno.h>
30
31 #include <glib.h>
32 #include <glib/gstdio.h>
33 #include "gioerror.h"
34 #include "glocalfileinputstream.h"
35 #include "glocalfileinfo.h"
36 #include "glibintl.h"
37
38 #include "gioalias.h"
39
40 #define g_local_file_input_stream_get_type _g_local_file_input_stream_get_type
41 G_DEFINE_TYPE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM);
42
43 struct _GLocalFileInputStreamPrivate {
44   int fd;
45 };
46
47 static gssize     g_local_file_input_stream_read       (GInputStream      *stream,
48                                                         void              *buffer,
49                                                         gsize              count,
50                                                         GCancellable      *cancellable,
51                                                         GError           **error);
52 static gssize     g_local_file_input_stream_skip       (GInputStream      *stream,
53                                                         gsize              count,
54                                                         GCancellable      *cancellable,
55                                                         GError           **error);
56 static gboolean   g_local_file_input_stream_close      (GInputStream      *stream,
57                                                         GCancellable      *cancellable,
58                                                         GError           **error);
59 static goffset    g_local_file_input_stream_tell       (GFileInputStream  *stream);
60 static gboolean   g_local_file_input_stream_can_seek   (GFileInputStream  *stream);
61 static gboolean   g_local_file_input_stream_seek       (GFileInputStream  *stream,
62                                                         goffset            offset,
63                                                         GSeekType          type,
64                                                         GCancellable      *cancellable,
65                                                         GError           **error);
66 static GFileInfo *g_local_file_input_stream_query_info (GFileInputStream  *stream,
67                                                         char              *attributes,
68                                                         GCancellable      *cancellable,
69                                                         GError           **error);
70
71 static void
72 g_local_file_input_stream_finalize (GObject *object)
73 {
74   GLocalFileInputStream *file;
75   
76   file = G_LOCAL_FILE_INPUT_STREAM (object);
77   
78   if (G_OBJECT_CLASS (g_local_file_input_stream_parent_class)->finalize)
79     (*G_OBJECT_CLASS (g_local_file_input_stream_parent_class)->finalize) (object);
80 }
81
82 static void
83 g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass)
84 {
85   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
86   GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
87   GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass);
88   
89   g_type_class_add_private (klass, sizeof (GLocalFileInputStreamPrivate));
90   
91   gobject_class->finalize = g_local_file_input_stream_finalize;
92
93   stream_class->read = g_local_file_input_stream_read;
94   stream_class->skip = g_local_file_input_stream_skip;
95   stream_class->close = g_local_file_input_stream_close;
96   file_stream_class->tell = g_local_file_input_stream_tell;
97   file_stream_class->can_seek = g_local_file_input_stream_can_seek;
98   file_stream_class->seek = g_local_file_input_stream_seek;
99   file_stream_class->query_info = g_local_file_input_stream_query_info;
100 }
101
102 static void
103 g_local_file_input_stream_init (GLocalFileInputStream *info)
104 {
105   info->priv = G_TYPE_INSTANCE_GET_PRIVATE (info,
106                                             G_TYPE_LOCAL_FILE_INPUT_STREAM,
107                                             GLocalFileInputStreamPrivate);
108 }
109
110 /**
111  * g_local_file_input_stream_new:
112  * @fd: File Descriptor.
113  * 
114  * Returns: #GFileInputStream for the given file descriptor.
115  **/
116 GFileInputStream *
117 _g_local_file_input_stream_new (int fd)
118 {
119   GLocalFileInputStream *stream;
120
121   stream = g_object_new (G_TYPE_LOCAL_FILE_INPUT_STREAM, NULL);
122   stream->priv->fd = fd;
123   
124   return G_FILE_INPUT_STREAM (stream);
125 }
126
127 static gssize
128 g_local_file_input_stream_read (GInputStream *stream,
129                                 void         *buffer,
130                                 gsize         count,
131                                 GCancellable *cancellable,
132                                 GError      **error)
133 {
134   GLocalFileInputStream *file;
135   gssize res;
136
137   file = G_LOCAL_FILE_INPUT_STREAM (stream);
138
139   res = -1;
140   while (1)
141     {
142       if (g_cancellable_set_error_if_cancelled (cancellable, error))
143         break;
144       res = read (file->priv->fd, buffer, count);
145       if (res == -1)
146         {
147           if (errno == EINTR)
148             continue;
149           
150           g_set_error (error, G_IO_ERROR,
151                        g_io_error_from_errno (errno),
152                        _("Error reading from file: %s"),
153                        g_strerror (errno));
154         }
155       
156       break;
157     }
158   
159   return res;
160 }
161
162 static gssize
163 g_local_file_input_stream_skip (GInputStream *stream,
164                                 gsize         count,
165                                 GCancellable *cancellable,
166                                 GError      **error)
167 {
168   off_t res, start;
169   GLocalFileInputStream *file;
170
171   file = G_LOCAL_FILE_INPUT_STREAM (stream);
172   
173   if (g_cancellable_set_error_if_cancelled (cancellable, error))
174     return -1;
175   
176   start = lseek (file->priv->fd, 0, SEEK_CUR);
177   if (start == -1)
178     {
179       g_set_error (error, G_IO_ERROR,
180                    g_io_error_from_errno (errno),
181                    _("Error seeking in file: %s"),
182                    g_strerror (errno));
183       return -1;
184     }
185   
186   res = lseek (file->priv->fd, count, SEEK_CUR);
187   if (res == -1)
188     {
189       g_set_error (error, G_IO_ERROR,
190                    g_io_error_from_errno (errno),
191                    _("Error seeking in file: %s"),
192                    g_strerror (errno));
193       return -1;
194     }
195
196   return res - start;
197 }
198
199 static gboolean
200 g_local_file_input_stream_close (GInputStream *stream,
201                                  GCancellable *cancellable,
202                                  GError      **error)
203 {
204   GLocalFileInputStream *file;
205   int res;
206
207   file = G_LOCAL_FILE_INPUT_STREAM (stream);
208
209   if (file->priv->fd == -1)
210     return TRUE;
211
212   while (1)
213     {
214       res = close (file->priv->fd);
215       if (res == -1)
216         {
217           g_set_error (error, G_IO_ERROR,
218                        g_io_error_from_errno (errno),
219                        _("Error closing file: %s"),
220                        g_strerror (errno));
221         }
222       break;
223     }
224
225   return res != -1;
226 }
227
228
229 static goffset
230 g_local_file_input_stream_tell (GFileInputStream *stream)
231 {
232   GLocalFileInputStream *file;
233   off_t pos;
234
235   file = G_LOCAL_FILE_INPUT_STREAM (stream);
236   
237   pos = lseek (file->priv->fd, 0, SEEK_CUR);
238
239   if (pos == (off_t)-1)
240     return 0;
241   
242   return pos;
243 }
244
245 static gboolean
246 g_local_file_input_stream_can_seek (GFileInputStream *stream)
247 {
248   GLocalFileInputStream *file;
249   off_t pos;
250
251   file = G_LOCAL_FILE_INPUT_STREAM (stream);
252   
253   pos = lseek (file->priv->fd, 0, SEEK_CUR);
254
255   if (pos == (off_t)-1 &&
256       errno == ESPIPE)
257     return FALSE;
258   
259   return TRUE;
260 }
261
262 static int
263 seek_type_to_lseek (GSeekType type)
264 {
265   switch (type)
266     {
267     default:
268     case G_SEEK_CUR:
269       return SEEK_CUR;
270       
271     case G_SEEK_SET:
272       return SEEK_SET;
273       
274     case G_SEEK_END:
275       return SEEK_END;
276     }
277 }
278
279 static gboolean
280 g_local_file_input_stream_seek (GFileInputStream     *stream,
281                                 goffset               offset,
282                                 GSeekType             type,
283                                 GCancellable         *cancellable,
284                                 GError              **error)
285 {
286   GLocalFileInputStream *file;
287   off_t pos;
288
289   file = G_LOCAL_FILE_INPUT_STREAM (stream);
290
291   pos = lseek (file->priv->fd, offset, seek_type_to_lseek (type));
292
293   if (pos == (off_t)-1)
294     {
295       g_set_error (error, G_IO_ERROR,
296                    g_io_error_from_errno (errno),
297                    _("Error seeking in file: %s"),
298                    g_strerror (errno));
299       return FALSE;
300     }
301   
302   return TRUE;
303 }
304
305 static GFileInfo *
306 g_local_file_input_stream_query_info (GFileInputStream     *stream,
307                                       char                 *attributes,
308                                       GCancellable         *cancellable,
309                                       GError              **error)
310 {
311   GLocalFileInputStream *file;
312
313   file = G_LOCAL_FILE_INPUT_STREAM (stream);
314
315   if (g_cancellable_set_error_if_cancelled (cancellable, error))
316     return NULL;
317   
318   return _g_local_file_info_get_from_fd (file->priv->fd,
319                                          attributes,
320                                          error);
321 }