1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * bonobo-stream-fs.c: Sample file-system based Stream implementation
5 * This is just a sample file-system based Stream implementation.
6 * it is only used for debugging purposes
9 * Miguel de Icaza (miguel@gnu.org)
10 * Michael Meeks (michael@ximian.com)
12 * Copyright 2001, Ximian, Inc
15 #include "bonobo-stream-fs.h"
21 #include <libgnomevfs/gnome-vfs-mime.h>
23 struct _BonoboStreamFSPrivate {
27 static BonoboObjectClass *bonobo_stream_fs_parent_class;
30 bonobo_mode_to_fs (Bonobo_Storage_OpenMode mode)
34 if (mode & Bonobo_Storage_READ)
36 if (mode & Bonobo_Storage_WRITE)
38 if (mode & Bonobo_Storage_CREATE)
39 fs_mode |= O_CREAT | O_RDWR;
40 if (mode & Bonobo_Storage_FAILIFEXIST)
46 static Bonobo_StorageInfo*
47 fs_get_info (PortableServer_Servant stream,
48 const Bonobo_StorageInfoFields mask,
49 CORBA_Environment *ev)
51 BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (
52 bonobo_object (stream));
53 Bonobo_StorageInfo *si;
56 if (mask & ~(Bonobo_FIELD_CONTENT_TYPE | Bonobo_FIELD_SIZE |
58 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
59 ex_Bonobo_Storage_NotSupported, NULL);
60 return CORBA_OBJECT_NIL;
63 if (fstat (stream_fs->fd, &st) == -1)
66 si = Bonobo_StorageInfo__alloc ();
68 si->size = st.st_size;
69 si->type = Bonobo_STORAGE_TYPE_REGULAR;
70 si->name = CORBA_string_dup ("");
71 si->content_type = CORBA_string_dup (stream_fs->priv->mime_type);
78 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
79 ex_Bonobo_Stream_NoPermission, NULL);
81 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
82 ex_Bonobo_Stream_IOError, NULL);
85 return CORBA_OBJECT_NIL;
89 fs_set_info (PortableServer_Servant stream,
90 const Bonobo_StorageInfo *info,
91 const Bonobo_StorageInfoFields mask,
92 CORBA_Environment *ev)
94 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
95 ex_Bonobo_Stream_NotSupported, NULL);
99 fs_write (PortableServer_Servant stream,
100 const Bonobo_Stream_iobuf *buffer,
101 CORBA_Environment *ev)
103 BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (
104 bonobo_object (stream));
107 while ((write (stream_fs->fd, buffer->_buffer, buffer->_length) == -1)
108 && (errno == EINTR));
110 if (errno == EINTR) return;
112 if ((errno == EBADF) || (errno == EINVAL))
113 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
114 ex_Bonobo_Stream_NoPermission, NULL);
116 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
117 ex_Bonobo_Stream_IOError, NULL);
121 fs_read (PortableServer_Servant stream,
123 Bonobo_Stream_iobuf **buffer,
124 CORBA_Environment *ev)
126 BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (
127 bonobo_object (stream));
132 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
133 ex_Bonobo_Stream_IOError, NULL);
137 *buffer = Bonobo_Stream_iobuf__alloc ();
138 CORBA_sequence_set_release (*buffer, TRUE);
139 data = CORBA_sequence_CORBA_octet_allocbuf (count);
140 (*buffer)->_buffer = data;
141 (*buffer)->_length = 0;
144 bytes_read = read (stream_fs->fd, data, count);
145 } while ((bytes_read == -1) && (errno == EINTR));
148 if (bytes_read == -1) {
149 CORBA_free (*buffer);
153 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
154 ex_Bonobo_Stream_NoPermission,
157 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
158 ex_Bonobo_Stream_IOError, NULL);
160 (*buffer)->_length = bytes_read;
164 fs_seek (PortableServer_Servant stream,
166 Bonobo_Stream_SeekType whence,
167 CORBA_Environment *ev)
169 BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (
170 bonobo_object (stream));
174 if (whence == Bonobo_Stream_SeekCur)
175 fs_whence = SEEK_CUR;
176 else if (whence == Bonobo_Stream_SeekEnd)
177 fs_whence = SEEK_END;
179 fs_whence = SEEK_SET;
181 if ((pos = lseek (stream_fs->fd, offset, fs_whence)) == -1) {
184 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
185 ex_Bonobo_Stream_NotSupported,
188 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
189 ex_Bonobo_Stream_IOError, NULL);
197 fs_truncate (PortableServer_Servant stream,
198 const CORBA_long new_size,
199 CORBA_Environment *ev)
201 BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (
202 bonobo_object (stream));
204 if (ftruncate (stream_fs->fd, new_size) == 0)
208 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
209 ex_Bonobo_Stream_NoPermission, NULL);
211 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
212 ex_Bonobo_Stream_IOError, NULL);
216 fs_commit (PortableServer_Servant stream,
217 CORBA_Environment *ev)
219 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
220 ex_Bonobo_Stream_NotSupported, NULL);
224 fs_revert (PortableServer_Servant stream,
225 CORBA_Environment *ev)
227 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
228 ex_Bonobo_Stream_NotSupported, NULL);
232 fs_destroy (BonoboObject *object)
234 BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (object);
236 if (stream_fs->fd >= 0 &&
237 close (stream_fs->fd))
238 g_warning ("Close failed");
242 g_free (stream_fs->path);
243 stream_fs->path = NULL;
245 if (stream_fs->priv->mime_type)
246 g_free (stream_fs->priv->mime_type);
247 stream_fs->priv->mime_type = NULL;
249 bonobo_stream_fs_parent_class->destroy (object);
253 fs_finalize (GObject *object)
255 BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (object);
258 g_free (stream_fs->priv);
259 stream_fs->priv = NULL;
261 bonobo_stream_fs_parent_class->parent_class.finalize (object);
265 bonobo_stream_fs_class_init (BonoboStreamFSClass *klass)
267 GObjectClass *oclass = (GObjectClass *) klass;
268 POA_Bonobo_Stream__epv *epv = &klass->epv;
270 bonobo_stream_fs_parent_class =
271 g_type_class_peek_parent (klass);
273 epv->getInfo = fs_get_info;
274 epv->setInfo = fs_set_info;
275 epv->write = fs_write;
278 epv->truncate = fs_truncate;
279 epv->commit = fs_commit;
280 epv->revert = fs_revert;
282 oclass->finalize = fs_finalize;
283 ((BonoboObjectClass *)oclass)->destroy = fs_destroy;
287 bonobo_stream_fs_init (BonoboStreamFS *stream_fs)
289 stream_fs->priv = g_new0 (BonoboStreamFSPrivate,1);
290 stream_fs->priv->mime_type = NULL;
294 * bonobo_stream_fs_get_type:
296 * Returns the GType for the BonoboStreamFS class.
299 bonobo_stream_fs_get_type (void)
301 static GType type = 0;
305 sizeof (BonoboStreamFSClass),
306 (GBaseInitFunc) NULL,
307 (GBaseFinalizeFunc) NULL,
308 (GClassInitFunc) bonobo_stream_fs_class_init,
309 NULL, /* class_finalize */
310 NULL, /* class_data */
311 sizeof (BonoboStreamFS),
313 (GInstanceInitFunc) bonobo_stream_fs_init
316 type = bonobo_type_unique (
318 POA_Bonobo_Stream__init, NULL,
319 G_STRUCT_OFFSET (BonoboStreamFSClass, epv),
320 &info, "BonoboStreamFS");
326 static BonoboStreamFS *
327 bonobo_stream_create (int fd, const char *path)
329 BonoboStreamFS *stream_fs;
331 if (!(stream_fs = g_object_new (bonobo_stream_fs_get_type (), NULL)))
335 stream_fs->priv->mime_type = g_strdup
336 (gnome_vfs_get_file_mime_type (path, NULL, FALSE));
343 * bonobo_stream_fs_open:
344 * @path: The path to the file to be opened.
345 * @flags: The flags with which the file should be opened.
347 * Creates a new BonoboStream object for the filename specified by
351 bonobo_stream_fs_open (const char *path, gint flags, gint mode,
352 CORBA_Environment *ev)
354 BonoboStreamFS *stream;
360 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
361 ex_Bonobo_Storage_IOError, NULL);
365 if (((v = stat (path, &st)) == -1) &&
366 !(flags & Bonobo_Storage_CREATE)) {
368 if ((errno == ENOENT) || (errno == ENOTDIR))
369 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
370 ex_Bonobo_Storage_NotFound,
372 else if (errno == EACCES)
373 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
374 ex_Bonobo_Storage_NoPermission,
377 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
378 ex_Bonobo_Storage_IOError, NULL);
382 if ((v != -1) && S_ISDIR(st.st_mode)) {
383 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
384 ex_Bonobo_Storage_NotStream,
390 fs_flags = bonobo_mode_to_fs (flags);
392 if ((fd = open (path, fs_flags, mode)) == -1) {
394 if ((errno == ENOENT) || (errno == ENOTDIR))
395 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
396 ex_Bonobo_Storage_NotFound,
398 else if (errno == EACCES)
399 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
400 ex_Bonobo_Storage_NoPermission,
402 else if (errno == EEXIST)
403 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
404 ex_Bonobo_Storage_NameExists,
407 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
408 ex_Bonobo_Storage_IOError, NULL);
412 if (!(stream = bonobo_stream_create (fd, path)))
413 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
414 ex_Bonobo_Storage_IOError, NULL);