Include <string.h> for memcpy.
[glib.git] / giounix.c
blobca98e0c860f4b27aca3eef05706068036d88d055
1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * giounix.c: IO Channels using unix file descriptors
5 * Copyright 1998 Owen Taylor
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.
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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
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/.
30 /*
31 * MT safe
34 #include "glib.h"
35 #include <sys/types.h>
36 #include <unistd.h>
37 #include <errno.h>
40 * Unix IO Channels
43 typedef struct _GIOUnixChannel GIOUnixChannel;
44 typedef struct _GIOUnixWatch GIOUnixWatch;
46 struct _GIOUnixChannel
48 GIOChannel channel;
49 gint fd;
52 struct _GIOUnixWatch
54 GSource source;
55 GPollFD pollfd;
56 GIOChannel *channel;
57 GIOCondition condition;
58 GIOFunc callback;
62 static GIOError g_io_unix_read (GIOChannel *channel,
63 gchar *buf,
64 guint count,
65 guint *bytes_written);
66 static GIOError g_io_unix_write (GIOChannel *channel,
67 gchar *buf,
68 guint count,
69 guint *bytes_written);
70 static GIOError g_io_unix_seek (GIOChannel *channel,
71 gint offset,
72 GSeekType type);
73 static void g_io_unix_close (GIOChannel *channel);
74 static void g_io_unix_free (GIOChannel *channel);
75 static GSource *g_io_unix_create_watch (GIOChannel *channel,
76 GIOCondition condition);
78 static gboolean g_io_unix_prepare (GSource *source,
79 gint *timeout);
80 static gboolean g_io_unix_check (GSource *source);
81 static gboolean g_io_unix_dispatch (GSource *source,
82 GSourceFunc callback,
83 gpointer user_data);
84 static void g_io_unix_destroy (GSource *source);
86 GSourceFuncs unix_watch_funcs = {
87 g_io_unix_prepare,
88 g_io_unix_check,
89 g_io_unix_dispatch,
90 g_io_unix_destroy
93 GIOFuncs unix_channel_funcs = {
94 g_io_unix_read,
95 g_io_unix_write,
96 g_io_unix_seek,
97 g_io_unix_close,
98 g_io_unix_create_watch,
99 g_io_unix_free,
102 static gboolean
103 g_io_unix_prepare (GSource *source,
104 gint *timeout)
106 *timeout = -1;
107 return FALSE;
110 static gboolean
111 g_io_unix_check (GSource *source)
113 GIOUnixWatch *watch = (GIOUnixWatch *)source;
115 return (watch->pollfd.revents & watch->condition);
118 static gboolean
119 g_io_unix_dispatch (GSource *source,
120 GSourceFunc callback,
121 gpointer user_data)
124 GIOFunc func = (GIOFunc)callback;
125 GIOUnixWatch *watch = (GIOUnixWatch *)source;
127 if (!func)
129 g_warning ("IO watch dispatched without callback\n"
130 "You must call g_source_connect().");
131 return FALSE;
134 return (*func) (watch->channel,
135 watch->pollfd.revents & watch->condition,
136 user_data);
139 static void
140 g_io_unix_destroy (GSource *source)
142 GIOUnixWatch *watch = (GIOUnixWatch *)source;
144 g_io_channel_unref (watch->channel);
147 static GIOError
148 g_io_unix_read (GIOChannel *channel,
149 gchar *buf,
150 guint count,
151 guint *bytes_read)
153 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
154 gint result;
156 result = read (unix_channel->fd, buf, count);
158 if (result < 0)
160 *bytes_read = 0;
161 switch (errno)
163 case EINVAL:
164 return G_IO_ERROR_INVAL;
165 case EAGAIN:
166 case EINTR:
167 return G_IO_ERROR_AGAIN;
168 default:
169 return G_IO_ERROR_UNKNOWN;
172 else
174 *bytes_read = result;
175 return G_IO_ERROR_NONE;
179 static GIOError
180 g_io_unix_write(GIOChannel *channel,
181 gchar *buf,
182 guint count,
183 guint *bytes_written)
185 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
186 gint result;
188 result = write (unix_channel->fd, buf, count);
190 if (result < 0)
192 *bytes_written = 0;
193 switch (errno)
195 case EINVAL:
196 return G_IO_ERROR_INVAL;
197 case EAGAIN:
198 case EINTR:
199 return G_IO_ERROR_AGAIN;
200 default:
201 return G_IO_ERROR_UNKNOWN;
204 else
206 *bytes_written = result;
207 return G_IO_ERROR_NONE;
211 static GIOError
212 g_io_unix_seek (GIOChannel *channel,
213 gint offset,
214 GSeekType type)
216 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
217 int whence;
218 off_t result;
220 switch (type)
222 case G_SEEK_SET:
223 whence = SEEK_SET;
224 break;
225 case G_SEEK_CUR:
226 whence = SEEK_CUR;
227 break;
228 case G_SEEK_END:
229 whence = SEEK_END;
230 break;
231 default:
232 g_warning ("g_io_unix_seek: unknown seek type");
233 return G_IO_ERROR_UNKNOWN;
236 result = lseek (unix_channel->fd, offset, whence);
238 if (result < 0)
240 switch (errno)
242 case EINVAL:
243 return G_IO_ERROR_INVAL;
244 default:
245 return G_IO_ERROR_UNKNOWN;
248 else
249 return G_IO_ERROR_NONE;
253 static void
254 g_io_unix_close (GIOChannel *channel)
256 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
258 close (unix_channel->fd);
261 static void
262 g_io_unix_free (GIOChannel *channel)
264 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
266 g_free (unix_channel);
269 static GSource *
270 g_io_unix_create_watch (GIOChannel *channel,
271 GIOCondition condition)
273 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
274 GSource *source;
275 GIOUnixWatch *watch;
278 source = g_source_new (&unix_watch_funcs, sizeof (GIOUnixWatch));
279 watch = (GIOUnixWatch *)source;
281 watch->channel = channel;
282 g_io_channel_ref (channel);
284 watch->condition = condition;
286 watch->pollfd.fd = unix_channel->fd;
287 watch->pollfd.events = condition;
289 g_source_add_poll (source, &watch->pollfd);
291 return source;
294 GIOChannel *
295 g_io_channel_unix_new (gint fd)
297 GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
298 GIOChannel *channel = (GIOChannel *)unix_channel;
300 g_io_channel_init (channel);
301 channel->funcs = &unix_channel_funcs;
303 unix_channel->fd = fd;
304 return channel;
307 gint
308 g_io_channel_unix_get_fd (GIOChannel *channel)
310 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
311 return unix_channel->fd;