Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / glib / giounix.c
blob10852751657ab33c822936b76852dd54ce68a066
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 Library 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 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library 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-1999. 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 {
47 GIOChannel channel;
48 gint fd;
51 struct _GIOUnixWatch {
52 GPollFD pollfd;
53 GIOChannel *channel;
54 GIOCondition condition;
55 GIOFunc callback;
59 static GIOError g_io_unix_read (GIOChannel *channel,
60 gchar *buf,
61 guint count,
62 guint *bytes_written);
64 static GIOError g_io_unix_write(GIOChannel *channel,
65 gchar *buf,
66 guint count,
67 guint *bytes_written);
68 static GIOError g_io_unix_seek (GIOChannel *channel,
69 gint offset,
70 GSeekType type);
71 static void g_io_unix_close (GIOChannel *channel);
72 static void g_io_unix_free (GIOChannel *channel);
73 static guint g_io_unix_add_watch (GIOChannel *channel,
74 gint priority,
75 GIOCondition condition,
76 GIOFunc func,
77 gpointer user_data,
78 GDestroyNotify notify);
79 static gboolean g_io_unix_prepare (gpointer source_data,
80 GTimeVal *current_time,
81 gint *timeout,
82 gpointer user_data);
83 static gboolean g_io_unix_check (gpointer source_data,
84 GTimeVal *current_time,
85 gpointer user_data);
86 static gboolean g_io_unix_dispatch (gpointer source_data,
87 GTimeVal *current_time,
88 gpointer user_data);
89 static void g_io_unix_destroy (gpointer source_data);
91 GSourceFuncs unix_watch_funcs = {
92 g_io_unix_prepare,
93 g_io_unix_check,
94 g_io_unix_dispatch,
95 g_io_unix_destroy
98 GIOFuncs unix_channel_funcs = {
99 g_io_unix_read,
100 g_io_unix_write,
101 g_io_unix_seek,
102 g_io_unix_close,
103 g_io_unix_add_watch,
104 g_io_unix_free,
107 static gboolean
108 g_io_unix_prepare (gpointer source_data,
109 GTimeVal *current_time,
110 gint *timeout,
111 gpointer user_data)
113 *timeout = -1;
114 return FALSE;
117 static gboolean
118 g_io_unix_check (gpointer source_data,
119 GTimeVal *current_time,
120 gpointer user_data)
122 GIOUnixWatch *data = source_data;
124 return (data->pollfd.revents & data->condition);
127 static gboolean
128 g_io_unix_dispatch (gpointer source_data,
129 GTimeVal *current_time,
130 gpointer user_data)
133 GIOUnixWatch *data = source_data;
135 return (*data->callback)(data->channel,
136 data->pollfd.revents & data->condition,
137 user_data);
140 static void
141 g_io_unix_destroy (gpointer source_data)
143 GIOUnixWatch *data = source_data;
145 g_main_remove_poll (&data->pollfd);
146 g_io_channel_unref (data->channel);
147 g_free (data);
150 static GIOError
151 g_io_unix_read (GIOChannel *channel,
152 gchar *buf,
153 guint count,
154 guint *bytes_read)
156 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
157 gint result;
159 result = read (unix_channel->fd, buf, count);
161 if (result < 0)
163 *bytes_read = 0;
164 switch (errno)
166 case EINVAL:
167 return G_IO_ERROR_INVAL;
168 case EAGAIN:
169 return G_IO_ERROR_AGAIN;
170 default:
171 return G_IO_ERROR_UNKNOWN;
174 else
176 *bytes_read = result;
177 return G_IO_ERROR_NONE;
181 static GIOError
182 g_io_unix_write(GIOChannel *channel,
183 gchar *buf,
184 guint count,
185 guint *bytes_written)
187 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
188 gint result;
190 result = write (unix_channel->fd, buf, count);
192 if (result < 0)
194 *bytes_written = 0;
195 switch (errno)
197 case EINVAL:
198 return G_IO_ERROR_INVAL;
199 case EAGAIN:
200 return G_IO_ERROR_AGAIN;
201 default:
202 return G_IO_ERROR_UNKNOWN;
205 else
207 *bytes_written = result;
208 return G_IO_ERROR_NONE;
212 static GIOError
213 g_io_unix_seek (GIOChannel *channel,
214 gint offset,
215 GSeekType type)
217 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
218 int whence;
219 off_t result;
221 switch (type)
223 case G_SEEK_SET:
224 whence = SEEK_SET;
225 break;
226 case G_SEEK_CUR:
227 whence = SEEK_CUR;
228 break;
229 case G_SEEK_END:
230 whence = SEEK_END;
231 break;
232 default:
233 g_warning ("g_io_unix_seek: unknown seek type");
234 return G_IO_ERROR_UNKNOWN;
237 result = lseek (unix_channel->fd, offset, whence);
239 if (result < 0)
241 switch (errno)
243 case EINVAL:
244 return G_IO_ERROR_INVAL;
245 default:
246 return G_IO_ERROR_UNKNOWN;
249 else
250 return G_IO_ERROR_NONE;
254 static void
255 g_io_unix_close (GIOChannel *channel)
257 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
259 close (unix_channel->fd);
262 static void
263 g_io_unix_free (GIOChannel *channel)
265 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
267 g_free (unix_channel);
270 static guint
271 g_io_unix_add_watch (GIOChannel *channel,
272 gint priority,
273 GIOCondition condition,
274 GIOFunc func,
275 gpointer user_data,
276 GDestroyNotify notify)
278 GIOUnixWatch *watch = g_new (GIOUnixWatch, 1);
279 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
281 watch->channel = channel;
282 g_io_channel_ref (channel);
284 watch->callback = func;
285 watch->condition = condition;
287 watch->pollfd.fd = unix_channel->fd;
288 watch->pollfd.events = condition;
290 g_main_add_poll (&watch->pollfd, priority);
292 return g_source_add (priority, TRUE, &unix_watch_funcs, watch, user_data, notify);
295 GIOChannel *
296 g_io_channel_unix_new (gint fd)
298 GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
299 GIOChannel *channel = (GIOChannel *)unix_channel;
301 g_io_channel_init (channel);
302 channel->funcs = &unix_channel_funcs;
304 unix_channel->fd = fd;
305 return channel;
308 gint
309 g_io_channel_unix_get_fd (GIOChannel *channel)
311 GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
312 return unix_channel->fd;