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