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