cleanup
[platform/upstream/glib.git] / glib / giounix.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * giounix.c: IO Channels using unix file descriptors
5  * Copyright 1998 Owen Taylor
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GLib Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GLib at ftp://ftp.gtk.org/pub/gtk/.
26  */
27
28 /*
29  * MT safe
30  */
31
32 #include "config.h"
33
34 #define _POSIX_SOURCE           /* for SSIZE_MAX */
35
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <stdio.h>
39 #include <unistd.h>
40 #include <errno.h>
41 #include <string.h>
42 #include <fcntl.h>
43 #include <glib/gstdio.h>
44
45 #include "giochannel.h"
46
47 #include "gerror.h"
48 #include "gfileutils.h"
49 #include "gstrfuncs.h"
50 #include "gtestutils.h"
51
52 /*
53  * Unix IO Channels
54  */
55
56 typedef struct _GIOUnixChannel GIOUnixChannel;
57 typedef struct _GIOUnixWatch GIOUnixWatch;
58
59 struct _GIOUnixChannel
60 {
61   GIOChannel channel;
62   gint fd;
63 };
64
65 struct _GIOUnixWatch
66 {
67   GSource       source;
68   GPollFD       pollfd;
69   GIOChannel   *channel;
70   GIOCondition  condition;
71 };
72
73
74 static GIOStatus        g_io_unix_read          (GIOChannel   *channel,
75                                                  gchar        *buf,
76                                                  gsize         count,
77                                                  gsize        *bytes_read,
78                                                  GError      **err);
79 static GIOStatus        g_io_unix_write         (GIOChannel   *channel,
80                                                  const gchar  *buf,
81                                                  gsize         count,
82                                                  gsize        *bytes_written,
83                                                  GError      **err);
84 static GIOStatus        g_io_unix_seek          (GIOChannel   *channel,
85                                                  gint64        offset,
86                                                  GSeekType     type,
87                                                  GError      **err);
88 static GIOStatus        g_io_unix_close         (GIOChannel   *channel,
89                                                  GError      **err);
90 static void             g_io_unix_free          (GIOChannel   *channel);
91 static GSource*         g_io_unix_create_watch  (GIOChannel   *channel,
92                                                  GIOCondition  condition);
93 static GIOStatus        g_io_unix_set_flags     (GIOChannel   *channel,
94                                                  GIOFlags      flags,
95                                                  GError      **err);
96 static GIOFlags         g_io_unix_get_flags     (GIOChannel   *channel);
97
98 static gboolean g_io_unix_prepare  (GSource     *source,
99                                     gint        *timeout);
100 static gboolean g_io_unix_check    (GSource     *source);
101 static gboolean g_io_unix_dispatch (GSource     *source,
102                                     GSourceFunc  callback,
103                                     gpointer     user_data);
104 static void     g_io_unix_finalize (GSource     *source);
105
106 GSourceFuncs g_io_watch_funcs = {
107   g_io_unix_prepare,
108   g_io_unix_check,
109   g_io_unix_dispatch,
110   g_io_unix_finalize
111 };
112
113 static GIOFuncs unix_channel_funcs = {
114   g_io_unix_read,
115   g_io_unix_write,
116   g_io_unix_seek,
117   g_io_unix_close,
118   g_io_unix_create_watch,
119   g_io_unix_free,
120   g_io_unix_set_flags,
121   g_io_unix_get_flags,
122 };
123
124 static gboolean 
125 g_io_unix_prepare (GSource  *source,
126                    gint     *timeout)
127 {
128   GIOUnixWatch *watch = (GIOUnixWatch *)source;
129   GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
130
131   *timeout = -1;
132
133   /* Only return TRUE here if _all_ bits in watch->condition will be set
134    */
135   return ((watch->condition & buffer_condition) == watch->condition);
136 }
137
138 static gboolean 
139 g_io_unix_check (GSource  *source)
140 {
141   GIOUnixWatch *watch = (GIOUnixWatch *)source;
142   GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
143   GIOCondition poll_condition = watch->pollfd.revents;
144
145   return ((poll_condition | buffer_condition) & watch->condition);
146 }
147
148 static gboolean
149 g_io_unix_dispatch (GSource     *source,
150                     GSourceFunc  callback,
151                     gpointer     user_data)
152
153 {
154   GIOFunc func = (GIOFunc)callback;
155   GIOUnixWatch *watch = (GIOUnixWatch *)source;
156   GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
157
158   if (!func)
159     {
160       g_warning ("IO watch dispatched without callback\n"
161                  "You must call g_source_connect().");
162       return FALSE;
163     }
164   
165   return (*func) (watch->channel,
166                   (watch->pollfd.revents | buffer_condition) & watch->condition,
167                   user_data);
168 }
169
170 static void 
171 g_io_unix_finalize (GSource *source)
172 {
173   GIOUnixWatch *watch = (GIOUnixWatch *)source;
174
175   g_io_channel_unref (watch->channel);
176 }
177
178 static GIOStatus
179 g_io_unix_read (GIOChannel *channel, 
180                 gchar      *buf, 
181                 gsize       count,
182                 gsize      *bytes_read,
183                 GError    **err)
184 {
185   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
186   gssize result;
187
188   if (count > SSIZE_MAX) /* At least according to the Debian manpage for read */
189     count = SSIZE_MAX;
190
191  retry:
192   result = read (unix_channel->fd, buf, count);
193
194   if (result < 0)
195     {
196       int errsv = errno;
197       *bytes_read = 0;
198
199       switch (errsv)
200         {
201 #ifdef EINTR
202           case EINTR:
203             goto retry;
204 #endif
205 #ifdef EAGAIN
206           case EAGAIN:
207             return G_IO_STATUS_AGAIN;
208 #endif
209           default:
210             g_set_error_literal (err, G_IO_CHANNEL_ERROR,
211                                  g_io_channel_error_from_errno (errsv),
212                                  g_strerror (errsv));
213             return G_IO_STATUS_ERROR;
214         }
215     }
216
217   *bytes_read = result;
218
219   return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
220 }
221
222 static GIOStatus
223 g_io_unix_write (GIOChannel  *channel, 
224                  const gchar *buf, 
225                  gsize       count,
226                  gsize      *bytes_written,
227                  GError    **err)
228 {
229   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
230   gssize result;
231
232  retry:
233   result = write (unix_channel->fd, buf, count);
234
235   if (result < 0)
236     {
237       int errsv = errno;
238       *bytes_written = 0;
239
240       switch (errsv)
241         {
242 #ifdef EINTR
243           case EINTR:
244             goto retry;
245 #endif
246 #ifdef EAGAIN
247           case EAGAIN:
248             return G_IO_STATUS_AGAIN;
249 #endif
250           default:
251             g_set_error_literal (err, G_IO_CHANNEL_ERROR,
252                                  g_io_channel_error_from_errno (errsv),
253                                  g_strerror (errsv));
254             return G_IO_STATUS_ERROR;
255         }
256     }
257
258   *bytes_written = result;
259
260   return G_IO_STATUS_NORMAL;
261 }
262
263 static GIOStatus
264 g_io_unix_seek (GIOChannel *channel,
265                 gint64      offset, 
266                 GSeekType   type,
267                 GError    **err)
268 {
269   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
270   int whence;
271   off_t tmp_offset;
272   off_t result;
273
274   switch (type)
275     {
276     case G_SEEK_SET:
277       whence = SEEK_SET;
278       break;
279     case G_SEEK_CUR:
280       whence = SEEK_CUR;
281       break;
282     case G_SEEK_END:
283       whence = SEEK_END;
284       break;
285     default:
286       whence = -1; /* Shut the compiler up */
287       g_assert_not_reached ();
288     }
289
290   tmp_offset = offset;
291   if (tmp_offset != offset)
292     {
293       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
294                            g_io_channel_error_from_errno (EINVAL),
295                            g_strerror (EINVAL));
296       return G_IO_STATUS_ERROR;
297     }
298   
299   result = lseek (unix_channel->fd, tmp_offset, whence);
300
301   if (result < 0)
302     {
303       int errsv = errno;
304       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
305                            g_io_channel_error_from_errno (errsv),
306                            g_strerror (errsv));
307       return G_IO_STATUS_ERROR;
308     }
309
310   return G_IO_STATUS_NORMAL;
311 }
312
313
314 static GIOStatus
315 g_io_unix_close (GIOChannel *channel,
316                  GError    **err)
317 {
318   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
319
320   if (close (unix_channel->fd) < 0)
321     {
322       int errsv = errno;
323       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
324                            g_io_channel_error_from_errno (errsv),
325                            g_strerror (errsv));
326       return G_IO_STATUS_ERROR;
327     }
328
329   return G_IO_STATUS_NORMAL;
330 }
331
332 static void 
333 g_io_unix_free (GIOChannel *channel)
334 {
335   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
336
337   g_free (unix_channel);
338 }
339
340 static GSource *
341 g_io_unix_create_watch (GIOChannel   *channel,
342                         GIOCondition  condition)
343 {
344   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
345   GSource *source;
346   GIOUnixWatch *watch;
347
348
349   source = g_source_new (&g_io_watch_funcs, sizeof (GIOUnixWatch));
350   g_source_set_name (source, "GIOChannel (Unix)");
351   watch = (GIOUnixWatch *)source;
352   
353   watch->channel = channel;
354   g_io_channel_ref (channel);
355   
356   watch->condition = condition;
357
358   watch->pollfd.fd = unix_channel->fd;
359   watch->pollfd.events = condition;
360
361   g_source_add_poll (source, &watch->pollfd);
362
363   return source;
364 }
365
366 static GIOStatus
367 g_io_unix_set_flags (GIOChannel *channel,
368                      GIOFlags    flags,
369                      GError    **err)
370 {
371   glong fcntl_flags;
372   GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel;
373
374   fcntl_flags = 0;
375
376   if (flags & G_IO_FLAG_APPEND)
377     fcntl_flags |= O_APPEND;
378   if (flags & G_IO_FLAG_NONBLOCK)
379 #ifdef O_NONBLOCK
380     fcntl_flags |= O_NONBLOCK;
381 #else
382     fcntl_flags |= O_NDELAY;
383 #endif
384
385   if (fcntl (unix_channel->fd, F_SETFL, fcntl_flags) == -1)
386     {
387       int errsv = errno;
388       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
389                            g_io_channel_error_from_errno (errsv),
390                            g_strerror (errsv));
391       return G_IO_STATUS_ERROR;
392     }
393
394   return G_IO_STATUS_NORMAL;
395 }
396
397 static GIOFlags
398 g_io_unix_get_flags (GIOChannel *channel)
399 {
400   GIOFlags flags = 0;
401   glong fcntl_flags;
402   GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel;
403
404   fcntl_flags = fcntl (unix_channel->fd, F_GETFL);
405
406   if (fcntl_flags == -1)
407     {
408       int err = errno;
409       g_warning (G_STRLOC "Error while getting flags for FD: %s (%d)\n",
410                  g_strerror (err), err);
411       return 0;
412     }
413
414   if (fcntl_flags & O_APPEND)
415     flags |= G_IO_FLAG_APPEND;
416 #ifdef O_NONBLOCK
417   if (fcntl_flags & O_NONBLOCK)
418 #else
419   if (fcntl_flags & O_NDELAY)
420 #endif
421     flags |= G_IO_FLAG_NONBLOCK;
422
423   switch (fcntl_flags & (O_RDONLY | O_WRONLY | O_RDWR))
424     {
425       case O_RDONLY:
426         channel->is_readable = TRUE;
427         channel->is_writeable = FALSE;
428         break;
429       case O_WRONLY:
430         channel->is_readable = FALSE;
431         channel->is_writeable = TRUE;
432         break;
433       case O_RDWR:
434         channel->is_readable = TRUE;
435         channel->is_writeable = TRUE;
436         break;
437       default:
438         g_assert_not_reached ();
439     }
440
441   return flags;
442 }
443
444 GIOChannel *
445 g_io_channel_new_file (const gchar *filename,
446                        const gchar *mode,
447                        GError     **error)
448 {
449   int fid, flags;
450   mode_t create_mode;
451   GIOChannel *channel;
452   enum { /* Cheesy hack */
453     MODE_R = 1 << 0,
454     MODE_W = 1 << 1,
455     MODE_A = 1 << 2,
456     MODE_PLUS = 1 << 3,
457     MODE_R_PLUS = MODE_R | MODE_PLUS,
458     MODE_W_PLUS = MODE_W | MODE_PLUS,
459     MODE_A_PLUS = MODE_A | MODE_PLUS
460   } mode_num;
461   struct stat buffer;
462
463   g_return_val_if_fail (filename != NULL, NULL);
464   g_return_val_if_fail (mode != NULL, NULL);
465   g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
466
467   switch (mode[0])
468     {
469       case 'r':
470         mode_num = MODE_R;
471         break;
472       case 'w':
473         mode_num = MODE_W;
474         break;
475       case 'a':
476         mode_num = MODE_A;
477         break;
478       default:
479         g_warning ("Invalid GIOFileMode %s.\n", mode);
480         return NULL;
481     }
482
483   switch (mode[1])
484     {
485       case '\0':
486         break;
487       case '+':
488         if (mode[2] == '\0')
489           {
490             mode_num |= MODE_PLUS;
491             break;
492           }
493         /* Fall through */
494       default:
495         g_warning ("Invalid GIOFileMode %s.\n", mode);
496         return NULL;
497     }
498
499   switch (mode_num)
500     {
501       case MODE_R:
502         flags = O_RDONLY;
503         break;
504       case MODE_W:
505         flags = O_WRONLY | O_TRUNC | O_CREAT;
506         break;
507       case MODE_A:
508         flags = O_WRONLY | O_APPEND | O_CREAT;
509         break;
510       case MODE_R_PLUS:
511         flags = O_RDWR;
512         break;
513       case MODE_W_PLUS:
514         flags = O_RDWR | O_TRUNC | O_CREAT;
515         break;
516       case MODE_A_PLUS:
517         flags = O_RDWR | O_APPEND | O_CREAT;
518         break;
519       case MODE_PLUS:
520       default:
521         g_assert_not_reached ();
522         flags = 0;
523     }
524
525   create_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
526
527   fid = g_open (filename, flags, create_mode);
528   if (fid == -1)
529     {
530       int err = errno;
531       g_set_error_literal (error, G_FILE_ERROR,
532                            g_file_error_from_errno (err),
533                            g_strerror (err));
534       return (GIOChannel *)NULL;
535     }
536
537   if (fstat (fid, &buffer) == -1) /* In case someone opens a FIFO */
538     {
539       int err = errno;
540       close (fid);
541       g_set_error_literal (error, G_FILE_ERROR,
542                            g_file_error_from_errno (err),
543                            g_strerror (err));
544       return (GIOChannel *)NULL;
545     }
546
547   channel = (GIOChannel *) g_new (GIOUnixChannel, 1);
548
549   channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
550                          || S_ISBLK (buffer.st_mode);
551
552   switch (mode_num)
553     {
554       case MODE_R:
555         channel->is_readable = TRUE;
556         channel->is_writeable = FALSE;
557         break;
558       case MODE_W:
559       case MODE_A:
560         channel->is_readable = FALSE;
561         channel->is_writeable = TRUE;
562         break;
563       case MODE_R_PLUS:
564       case MODE_W_PLUS:
565       case MODE_A_PLUS:
566         channel->is_readable = TRUE;
567         channel->is_writeable = TRUE;
568         break;
569       case MODE_PLUS:
570       default:
571         g_assert_not_reached ();
572     }
573
574   g_io_channel_init (channel);
575   channel->close_on_unref = TRUE; /* must be after g_io_channel_init () */
576   channel->funcs = &unix_channel_funcs;
577
578   ((GIOUnixChannel *) channel)->fd = fid;
579   return channel;
580 }
581
582 /**
583  * g_io_channel_unix_new:
584  * @fd: a file descriptor.
585  *
586  * Creates a new #GIOChannel given a file descriptor. On UNIX systems
587  * this works for plain files, pipes, and sockets.
588  *
589  * The returned #GIOChannel has a reference count of 1.
590  *
591  * The default encoding for #GIOChannel is UTF-8. If your application
592  * is reading output from a command using via pipe, you may need to set
593  * the encoding to the encoding of the current locale (see
594  * g_get_charset()) with the g_io_channel_set_encoding() function.
595  *
596  * If you want to read raw binary data without interpretation, then
597  * call the g_io_channel_set_encoding() function with %NULL for the
598  * encoding argument.
599  *
600  * This function is available in GLib on Windows, too, but you should
601  * avoid using it on Windows. The domain of file descriptors and
602  * sockets overlap. There is no way for GLib to know which one you mean
603  * in case the argument you pass to this function happens to be both a
604  * valid file descriptor and socket. If that happens a warning is
605  * issued, and GLib assumes that it is the file descriptor you mean.
606  *
607  * Returns: a new #GIOChannel.
608  **/
609 GIOChannel *
610 g_io_channel_unix_new (gint fd)
611 {
612   struct stat buffer;
613   GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
614   GIOChannel *channel = (GIOChannel *)unix_channel;
615
616   g_io_channel_init (channel);
617   channel->funcs = &unix_channel_funcs;
618
619   unix_channel->fd = fd;
620
621   /* I'm not sure if fstat on a non-file (e.g., socket) works
622    * it should be safe to say if it fails, the fd isn't seekable.
623    */
624   /* Newer UNIX versions support S_ISSOCK(), fstat() will probably
625    * succeed in most cases.
626    */
627   if (fstat (unix_channel->fd, &buffer) == 0)
628     channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
629                            || S_ISBLK (buffer.st_mode);
630   else /* Assume not seekable */
631     channel->is_seekable = FALSE;
632
633   g_io_unix_get_flags (channel); /* Sets is_readable, is_writeable */
634
635   return channel;
636 }
637
638 /**
639  * g_io_channel_unix_get_fd:
640  * @channel: a #GIOChannel, created with g_io_channel_unix_new().
641  *
642  * Returns the file descriptor of the #GIOChannel.
643  *
644  * On Windows this function returns the file descriptor or socket of
645  * the #GIOChannel.
646  *
647  * Returns: the file descriptor of the #GIOChannel.
648  **/
649 gint
650 g_io_channel_unix_get_fd (GIOChannel *channel)
651 {
652   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
653   return unix_channel->fd;
654 }