Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / sandbox / client-CaptiveIOChannel.c
1 /* $Id$
2  * CORBA/ORBit client side of image GIOChannel object of sandbox_child()
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "client-CaptiveIOChannel.h"    /* self */
23 #include <glib/gmessages.h>
24 #include "split.h"
25 #include <string.h>
26 #include "captive/macros.h"
27 #include "../client/lib.h"      /* for captive_giochannel_setup() */
28
29
30 struct captive_io_channel {
31         GIOChannel iochannel;
32         Captive_CaptiveIOChannel corba_captive_io_channel;
33         };
34
35
36 G_LOCK_DEFINE_STATIC(captive_io_channel_funcs);
37 static GIOFuncs captive_io_channel_funcs;
38
39
40 static gboolean validate_captive_io_channel(struct captive_io_channel *captive_io_channel)
41 {
42         g_return_val_if_fail(captive_io_channel!=NULL,FALSE);
43         g_return_val_if_fail(captive_io_channel->corba_captive_io_channel!=NULL,FALSE);
44
45         return TRUE;
46 }
47
48
49 static GIOStatus captive_io_channel_io_read
50                 (GIOChannel *channel,gchar *buffer_captive,gsize count,gsize *bytes_read_return,GError **err)
51 {
52 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
53 Captive_Bytes *buffer_corba;
54
55         g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR);
56         g_return_val_if_fail(buffer_captive!=NULL,G_IO_STATUS_ERROR);
57         g_return_val_if_fail(bytes_read_return!=NULL,G_IO_STATUS_ERROR);
58
59         *bytes_read_return=0;
60
61         Captive_CaptiveIOChannel_read(captive_io_channel->corba_captive_io_channel,&buffer_corba,count,&captive_corba_ev);
62         if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
63                 return G_IO_STATUS_ERROR;
64
65         g_return_val_if_fail(buffer_corba->_length<=count,G_IO_STATUS_ERROR);
66         memcpy(buffer_captive,buffer_corba->_buffer,buffer_corba->_length);
67         *bytes_read_return=buffer_corba->_length;
68
69         Captive_Bytes__freekids(buffer_corba,NULL/* 'd'; meaning? */);
70         CORBA_free(buffer_corba);
71
72         return (*bytes_read_return == 0 ? G_IO_STATUS_EOF : G_IO_STATUS_NORMAL);
73 }
74
75
76 static GIOStatus captive_io_channel_io_write
77                 (GIOChannel *channel,const gchar *buffer_captive,gsize count,gsize *bytes_written_return,GError **err)
78 {
79 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
80 Captive_Bytes buffer_corba_local;
81 Captive_GSize bytes_written_corba;
82
83         g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR);
84         g_return_val_if_fail(buffer_captive!=NULL,G_IO_STATUS_ERROR);
85         g_return_val_if_fail(bytes_written_return!=NULL,G_IO_STATUS_ERROR);
86
87         *bytes_written_return=0;
88
89         buffer_corba_local._maximum=count;
90         buffer_corba_local._length=count;
91         buffer_corba_local._buffer=(/* de-const */gpointer)buffer_captive;
92         buffer_corba_local._release=FALSE;
93
94         Captive_CaptiveIOChannel_write(captive_io_channel->corba_captive_io_channel,
95                         &buffer_corba_local,&bytes_written_corba,&captive_corba_ev);
96         if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
97                 return G_IO_STATUS_ERROR;
98
99         *bytes_written_return=bytes_written_corba;
100
101         return G_IO_STATUS_NORMAL;
102 }
103
104
105 static GIOStatus captive_io_channel_io_seek(GIOChannel *channel,gint64 offset,GSeekType type,GError **err)
106 {
107 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
108
109         g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR);
110
111         Captive_CaptiveIOChannel_seek(captive_io_channel->corba_captive_io_channel,offset,type,&captive_corba_ev);
112         if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
113                 return G_IO_STATUS_ERROR;
114
115         return G_IO_STATUS_NORMAL;
116 }
117
118
119 static GIOStatus captive_io_channel_io_close(GIOChannel *channel,GError **err)
120 {
121 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
122
123         g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR);
124
125         /* We are not authorized to destroy 'captive_io_channel->corba_captive_io_channel'. */
126         /* flush()? */
127         captive_io_channel->corba_captive_io_channel=NULL;
128
129         return G_IO_STATUS_NORMAL;
130 }
131
132
133 static GSource* captive_io_channel_io_create_watch(GIOChannel *channel,GIOCondition condition)
134 {
135 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
136
137         g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),NULL);
138
139         g_return_val_if_reached(NULL);  /* FIXME: NOT IMPLEMENTED YET */
140 }
141
142
143 static void captive_io_channel_io_free(GIOChannel *channel)
144 {
145 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
146
147         /* After captive_io_channel_io_close() 'captive_io_channel'
148          * may be no longer valid for validate_captive_io_channel(captive_io_channel).
149          */
150         g_return_if_fail(captive_io_channel!=NULL);
151
152         g_assert(captive_io_channel->corba_captive_io_channel==NULL);
153
154         g_free(captive_io_channel);
155 }
156
157
158 static GIOStatus captive_io_channel_io_set_flags(GIOChannel *channel,GIOFlags flags,GError **err)
159 {
160 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
161
162         g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),G_IO_STATUS_ERROR);
163
164         /* no G_IO_FLAG_APPEND and no G_IO_FLAG_NONBLOCK */
165         g_return_val_if_fail((flags&G_IO_FLAG_SET_MASK)==0,G_IO_STATUS_ERROR);
166
167         return G_IO_STATUS_NORMAL;
168 }
169
170
171 static GIOFlags captive_io_channel_io_get_flags(GIOChannel *channel)
172 {
173 struct captive_io_channel *captive_io_channel=(struct captive_io_channel *)channel;
174
175         g_return_val_if_fail(validate_captive_io_channel(captive_io_channel),0);
176
177         return 0;       /* | !G_IO_FLAG_APPEND | !G_IO_FLAG_NONBLOCK */
178 }
179
180
181 struct captive_io_channel *captive_io_channel_new(Captive_CaptiveIOChannel corba_captive_io_channel,gboolean writeable)
182 {
183 struct captive_io_channel *captive_io_channel;
184
185         g_return_val_if_fail(corba_captive_io_channel!=NULL,NULL);
186
187         G_LOCK(captive_io_channel_funcs);
188         captive_io_channel_funcs.io_read        =captive_io_channel_io_read;
189         captive_io_channel_funcs.io_write       =captive_io_channel_io_write;
190         captive_io_channel_funcs.io_seek        =captive_io_channel_io_seek;
191         captive_io_channel_funcs.io_close       =captive_io_channel_io_close;
192         captive_io_channel_funcs.io_create_watch=captive_io_channel_io_create_watch;
193         captive_io_channel_funcs.io_free        =captive_io_channel_io_free;
194         captive_io_channel_funcs.io_set_flags   =captive_io_channel_io_set_flags;
195         captive_io_channel_funcs.io_get_flags   =captive_io_channel_io_get_flags;
196         G_UNLOCK(captive_io_channel_funcs);
197
198         captive_new(captive_io_channel);
199         g_assert(G_STRUCT_OFFSET(struct captive_io_channel,iochannel)==0);      /* safely re-type-able */
200         g_io_channel_init(&captive_io_channel->iochannel);
201         captive_io_channel->iochannel.funcs=&captive_io_channel_funcs;
202         captive_io_channel->iochannel.is_seekable=TRUE;
203         captive_io_channel->iochannel.is_readable=TRUE;
204         captive_io_channel->iochannel.is_writeable=writeable;
205         captive_io_channel->iochannel.close_on_unref=TRUE;      /* run g_io_channel_shutdown() flush on last unref */
206         captive_io_channel->corba_captive_io_channel=corba_captive_io_channel;
207
208         captive_giochannel_setup(&captive_io_channel->iochannel);
209
210         return captive_io_channel;
211 }
212
213
214 gboolean captive_io_channel_get_size(GIOChannel *giochannel,guint64 *size_return)
215 {
216 struct captive_io_channel *captive_io_channel;
217
218         g_return_val_if_fail(giochannel!=NULL,FALSE);
219         g_return_val_if_fail(size_return!=NULL,FALSE);
220
221         if (giochannel->funcs!=&captive_io_channel_funcs)
222                 return FALSE;
223         captive_io_channel=(struct captive_io_channel *)giochannel;
224
225         *size_return=Captive_CaptiveIOChannel_size(captive_io_channel->corba_captive_io_channel,&captive_corba_ev);
226         if (GNOME_VFS_OK!=captive_sandbox_parent_return_from_CORBA_Environment(&captive_corba_ev,NULL))
227                 return FALSE;
228
229         return TRUE;
230 }