bonobo-process
- From: ISO-8859-1 <alex ximian com>
- To: Dietmar Maurer <dietmar ximian com>
- Cc: gnome-components-list gnome org
- Subject: bonobo-process
- Date: 06 Jun 2001 14:38:51 -0400
Hi,
On 05 Jun 2001 08:17:04 +0200, Dietmar Maurer wrote:
> > Anyways, there are a couple of open issues (security, and how the
> > moniker should work), so I thought it would make a good addition to
> > bonobo-extras.
>
> Well, everything sounds useful :-) Where can I find the sources?
Okay, here is a big patch against bonobo to supply bonobo-process,
bonobo-stream-fd, and bonobo-moniker-exec.
If this is okay I can get the bonobo-extra build stuff up and running if
you want.
Also, there is a smaller patch to bonobo-stream-client.c to handle
partial reads correctly, though I'm not sure if I'm breaking semantics
here.
The big question with the exec moniker is how to handle changing to
another user to execute a command, both for security, and handling
generic PAM authentication.
-Alex
--
make: *** No rule to make target `sense'. Stop.
Index: bonobo.h
===================================================================
RCS file: /cvs/gnome/bonobo/bonobo.h,v
retrieving revision 1.51
diff -u -r1.51 bonobo.h
--- bonobo.h 2001/04/23 20:47:11 1.51
+++ bonobo.h 2001/06/06 18:13:02
@@ -74,6 +74,8 @@
#include <bonobo/bonobo-print.h>
#include <bonobo/bonobo-print-client.h>
+#include <bonobo/bonobo-process.h>
+
#ifdef __cplusplus
}
#endif
Index: bonobo/Makefile.am
===================================================================
RCS file: /cvs/gnome/bonobo/bonobo/Makefile.am,v
retrieving revision 1.171
diff -u -r1.171 Makefile.am
--- bonobo/Makefile.am 2001/04/16 23:25:54 1.171
+++ bonobo/Makefile.am 2001/06/06 18:13:02
@@ -39,6 +39,7 @@
$(top_srcdir)/idl/Bonobo_Moniker.idl \
$(top_srcdir)/idl/Bonobo_Persist.idl \
$(top_srcdir)/idl/Bonobo_Print.idl \
+ $(top_srcdir)/idl/Bonobo_Process.idl \
$(top_srcdir)/idl/Bonobo_Progressive.idl \
$(top_srcdir)/idl/Bonobo_Property.idl \
$(top_srcdir)/idl/Bonobo_Storage.idl \
@@ -80,12 +81,14 @@
bonobo-persist-file.c \
bonobo-persist-stream.c \
bonobo-persist.c \
+ bonobo-process.c \
bonobo-progressive.c \
bonobo-shlib-factory.c \
bonobo-storage-plugin.c \
bonobo-storage.c \
bonobo-stream.c \
bonobo-stream-client.c \
+ bonobo-stream-fd.c \
bonobo-stream-memory.c \
bonobo-transient.c \
bonobo-property.c \
@@ -130,6 +133,7 @@
bonobo-persist-stream.h \
bonobo-persist.h \
bonobo-plug.h \
+ bonobo-process.h \
bonobo-progressive.h \
bonobo-property-bag.h \
bonobo-property-bag-client.h \
@@ -143,6 +147,7 @@
bonobo-storage-plugin.h \
bonobo-storage.h \
bonobo-stream-client.h \
+ bonobo-stream-fd.h \
bonobo-stream-memory.h \
bonobo-stream.h \
bonobo-transient.h \
Index: bonobo/bonobo-process.c
===================================================================
RCS file: bonobo-process.c
diff -N bonobo-process.c
--- /dev/null Tue May 5 16:32:27 1998
+++ bonobo-process.c Wed Jun 6 14:13:02 2001
@@ -0,0 +1,316 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * bonobo-process.c: Generic process interface for callbacks.
+ *
+ * Authors:
+ * Alex Graveley (alex ximian com)
+ *
+ * Copyright (C) 2001, Ximian, Inc.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <gtk/gtksignal.h>
+
+#include <bonobo/bonobo-event-source.h>
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-process.h>
+
+#define PARENT_TYPE BONOBO_X_OBJECT_TYPE
+
+static GtkObjectClass *bonobo_process_parent_class;
+
+struct _BonoboProcessPrivate {
+ pid_t pid;
+ int return_val;
+ guint waitpid_tag;
+
+ Bonobo_Stream in_stream;
+ Bonobo_Stream out_stream;
+ Bonobo_Stream err_stream;
+};
+
+enum SIGNALS {
+ SIGNAL_SENT,
+ PROCESS_EXIT,
+ LAST_SIGNAL
+};
+static guint signals [LAST_SIGNAL] = { 0 };
+
+static gboolean bonobo_process_idle_waitpid (gpointer user_data);
+
+static void
+impl_Bonobo_Process_signal (PortableServer_Servant servant,
+ CORBA_long signum,
+ CORBA_Environment *ev)
+{
+ BonoboProcess *process;
+ BonoboEventSource *source;
+
+ process = BONOBO_PROCESS (bonobo_object_from_servant (servant));
+
+ bonobo_return_if_fail (signum < 0, ev);
+
+ if (kill (process->priv->pid, signum) != 0) {
+ switch (errno) {
+ case EINVAL:
+ return;
+ case EPERM:
+ bonobo_exception_set (ev,
+ ex_Bonobo_Process_NoPermission);
+ return;
+ case ESRCH:
+ g_source_remove (process->priv->waitpid_tag);
+ bonobo_process_idle_waitpid (process);
+ return;
+ }
+ }
+
+ gtk_signal_emit (GTK_OBJECT (process),
+ signals [SIGNAL_SENT],
+ signum,
+ ev);
+
+ source = BONOBO_EVENT_SOURCE (
+ bonobo_object_query_local_interface (
+ BONOBO_OBJECT (process),
+ "IDL:Bonobo/EventSource:1.0"));
+
+ if (source) {
+ BonoboArg arg;
+ arg._type = TC_CORBA_long;
+ arg._value = &signum;
+ bonobo_event_source_notify_listeners (source,
+ "signal_sent",
+ &arg,
+ ev);
+ bonobo_object_unref (BONOBO_OBJECT (source));
+ }
+}
+
+static CORBA_boolean
+impl_Bonobo_Process_isRunning (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ BonoboProcess *process;
+ process = BONOBO_PROCESS (bonobo_object_from_servant (servant));
+
+ if (process->priv->waitpid_tag == 0)
+ return TRUE;
+ else if (kill (process->priv->pid, 0) != 0 && errno == ESRCH)
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bonobo_Stream
+impl_Bonobo_Process_getInputStream (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ BonoboProcess *process;
+ process = BONOBO_PROCESS (bonobo_object_from_servant (servant));
+
+ if (!process->priv->in_stream)
+ bonobo_exception_set (ev, ex_Bonobo_Process_NoPermission);
+
+ return bonobo_object_dup_ref (process->priv->in_stream, ev);
+}
+
+static Bonobo_Stream
+impl_Bonobo_Process_getOutputStream (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ BonoboProcess *process;
+ process = BONOBO_PROCESS (bonobo_object_from_servant (servant));
+
+ if (!process->priv->out_stream)
+ bonobo_exception_set (ev, ex_Bonobo_Process_NoPermission);
+
+ return bonobo_object_dup_ref (process->priv->out_stream, ev);
+}
+
+static Bonobo_Stream
+impl_Bonobo_Process_getErrorStream (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ BonoboProcess *process;
+ process = BONOBO_PROCESS (bonobo_object_from_servant (servant));
+
+ if (!process->priv->err_stream)
+ bonobo_exception_set (ev, ex_Bonobo_Process_NoPermission);
+
+ return bonobo_object_dup_ref (process->priv->err_stream, ev);
+}
+
+static void
+bonobo_process_finalize (GtkObject *object)
+{
+ BonoboProcess *process;
+ BonoboProcessPrivate *pr;
+ CORBA_Environment ev;
+
+ process = BONOBO_PROCESS (object);
+ pr = process->priv;
+
+ if (pr->waitpid_tag) g_source_remove (pr->waitpid_tag);
+
+ CORBA_exception_init (&ev);
+
+ if (pr->in_stream) bonobo_object_release_unref (pr->in_stream, &ev);
+ if (pr->out_stream) bonobo_object_release_unref (pr->out_stream, &ev);
+ if (pr->err_stream) bonobo_object_release_unref (pr->err_stream, &ev);
+
+ CORBA_exception_free (&ev);
+
+ g_free (pr);
+
+ bonobo_process_parent_class->finalize (object);
+}
+
+static void
+bonobo_process_class_init (BonoboProcessClass *klass)
+{
+ GtkObjectClass *oclass = (GtkObjectClass *)klass;
+ POA_Bonobo_Process__epv *epv = &klass->epv;
+
+ bonobo_process_parent_class = gtk_type_class (PARENT_TYPE);
+
+ oclass->finalize = bonobo_process_finalize;
+
+ signals [SIGNAL_SENT] = gtk_signal_new (
+ "signal_sent", GTK_RUN_LAST, oclass->type,
+ GTK_SIGNAL_OFFSET (BonoboProcessClass, signal_sent),
+ gtk_marshal_NONE__INT_POINTER, GTK_TYPE_NONE, 2,
+ GTK_TYPE_INT, GTK_TYPE_POINTER);
+
+ signals [PROCESS_EXIT] = gtk_signal_new (
+ "process_exit", GTK_RUN_LAST, oclass->type,
+ GTK_SIGNAL_OFFSET (BonoboProcessClass, process_exit),
+ gtk_marshal_NONE__INT_POINTER, GTK_TYPE_NONE, 2,
+ GTK_TYPE_INT, GTK_TYPE_POINTER);
+
+ gtk_object_class_add_signals (oclass, signals, LAST_SIGNAL);
+
+ epv->signal = impl_Bonobo_Process_signal;
+ epv->isRunning = impl_Bonobo_Process_isRunning;
+ epv->getInputStream = impl_Bonobo_Process_getInputStream;
+ epv->getOutputStream = impl_Bonobo_Process_getOutputStream;
+ epv->getErrorStream = impl_Bonobo_Process_getErrorStream;
+}
+
+static void
+bonobo_process_init (GtkObject *object)
+{
+ BonoboProcess *process;
+
+ process = BONOBO_PROCESS(object);
+ process->priv = g_new (BonoboProcessPrivate, 1);
+ process->priv->pid = 0;
+ process->priv->return_val = 0;
+ process->priv->waitpid_tag = 0;
+}
+
+BONOBO_X_TYPE_FUNC_FULL (BonoboProcess,
+ Bonobo_Process,
+ PARENT_TYPE,
+ bonobo_process);
+
+static gboolean
+bonobo_process_idle_waitpid (gpointer user_data)
+{
+ BonoboProcess *process = user_data;
+ BonoboEventSource *source;
+ BonoboArg arg;
+ CORBA_Environment ev;
+
+ switch (waitpid (process->priv->pid,
+ &process->priv->return_val,
+ WNOHANG)) {
+ case 0:
+ return TRUE;
+ case -1:
+ process->priv->waitpid_tag = 0;
+ return FALSE;
+ default:
+ CORBA_exception_init (&ev);
+
+ gtk_signal_emit (GTK_OBJECT (process),
+ signals [PROCESS_EXIT],
+ process->priv->return_val,
+ ev);
+
+ source = BONOBO_EVENT_SOURCE (
+ bonobo_object_query_local_interface (
+ BONOBO_OBJECT (process),
+ "IDL:Bonobo/EventSource:1.0"));
+
+ if (source) {
+ arg._type = TC_CORBA_long;
+ arg._value = &process->priv->return_val;
+ bonobo_event_source_notify_listeners (source,
+ "process_exit",
+ &arg,
+ &ev);
+ bonobo_object_unref (BONOBO_OBJECT (source));
+ }
+
+ CORBA_exception_free (&ev);
+
+ return FALSE;
+ }
+}
+
+BonoboProcess *
+bonobo_process_attach (pid_t pid)
+{
+ BonoboProcess *process;
+ BonoboEventSource *source;
+
+ if (kill (pid, 0) != 0 && errno == ESRCH) return NULL;
+
+ process = gtk_type_new (BONOBO_PROCESS_TYPE);
+
+ process->priv->pid = pid;
+ process->priv->waitpid_tag = g_idle_add (bonobo_process_idle_waitpid,
+ process);
+
+ source = bonobo_event_source_new ();
+
+ bonobo_object_add_interface (BONOBO_OBJECT (process),
+ BONOBO_OBJECT (source));
+
+ return process;
+}
+
+BonoboProcess *
+bonobo_process_attach_full (pid_t pid,
+ Bonobo_Stream in_stream,
+ Bonobo_Stream out_stream,
+ Bonobo_Stream err_stream)
+{
+ BonoboProcess *process;
+
+ process = bonobo_process_attach (pid);
+
+ if (process) {
+ CORBA_Environment ev;
+ CORBA_exception_init (&ev);
+
+ if (in_stream)
+ process->priv->in_stream =
+ bonobo_object_dup_ref (in_stream, &ev);
+ if (out_stream)
+ process->priv->out_stream =
+ bonobo_object_dup_ref (out_stream, &ev);
+ if (err_stream)
+ process->priv->err_stream =
+ bonobo_object_dup_ref (err_stream, &ev);
+
+ CORBA_exception_free (&ev);
+ }
+
+ return process;
+}
Index: bonobo/bonobo-process.h
===================================================================
RCS file: bonobo-process.h
diff -N bonobo-process.h
--- /dev/null Tue May 5 16:32:27 1998
+++ bonobo-process.h Wed Jun 6 14:13:02 2001
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * bonobo-process.h: Generic process interface for callbacks.
+ *
+ * Authors:
+ * Alex Graveley (alex helixcode com)
+ *
+ * Copyright (C) 2000, Helix Code, Inc.
+ */
+
+#ifndef _BONOBO_PROCESS_H_
+#define _BONOBO_PROCESS_H_
+
+#include <sys/types.h>
+#include <bonobo/bonobo-arg.h>
+#include <bonobo/bonobo-xobject.h>
+
+BEGIN_GNOME_DECLS
+
+#define BONOBO_PROCESS_TYPE (bonobo_process_get_type ())
+#define BONOBO_PROCESS(o) (GTK_CHECK_CAST ((o), BONOBO_PROCESS_TYPE, BonoboProcess))
+#define BONOBO_PROCESS_CLASS(k) (GTK_CHECK_CLASS_CAST((k), BONOBO_PROCESS_TYPE, BonoboProcessClass))
+#define BONOBO_IS_PROCESS(o) (GTK_CHECK_TYPE ((o), BONOBO_PROCESS_TYPE))
+#define BONOBO_IS_PROCESS_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), BONOBO_PROCESS_TYPE))
+
+typedef struct _BonoboProcessPrivate BonoboProcessPrivate;
+
+typedef struct {
+ BonoboXObject parent;
+
+ BonoboProcessPrivate *priv;
+} BonoboProcess;
+
+typedef struct {
+ BonoboXObjectClass parent_class;
+
+ POA_Bonobo_Process__epv epv;
+
+ /* Signals */
+ void (* signal_sent) (BonoboProcess *process,
+ CORBA_long signal,
+ CORBA_Environment *ev);
+
+ void (* process_exit) (BonoboProcess *process,
+ CORBA_long retval,
+ CORBA_Environment *ev);
+} BonoboProcessClass;
+
+GtkType bonobo_process_get_type (void);
+
+BonoboProcess *bonobo_process_attach (pid_t pid);
+
+BonoboProcess *bonobo_process_attach_full (pid_t pid,
+ Bonobo_Stream in_stream,
+ Bonobo_Stream out_stream,
+ Bonobo_Stream err_stream);
+
+END_GNOME_DECLS
+
+#endif /* _BONOBO_PROCESS_H_ */
+
Index: bonobo/bonobo-stream-fd.c
===================================================================
RCS file: bonobo-stream-fd.c
diff -N bonobo-stream-fd.c
--- /dev/null Tue May 5 16:32:27 1998
+++ bonobo-stream-fd.c Wed Jun 6 14:13:02 2001
@@ -0,0 +1,403 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/**
+ * bonobo-stream-fd.c: Unix file descriptor based stream
+ *
+ * Author:
+ * Alex Graveley (alex ximian com)
+ *
+ * Copyright 2001, Ximian, Inc.
+ */
+
+#include <config.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <libgnome/gnome-defs.h>
+#include <libgnome/gnome-util.h>
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-stream-fd.h>
+
+static BonoboStreamClass *bonobo_stream_fd_parent_class;
+
+static Bonobo_StorageInfo*
+fd_get_info (BonoboStream *stream,
+ const Bonobo_StorageInfoFields mask,
+ CORBA_Environment *ev)
+{
+ Bonobo_StorageInfo *si;
+
+ si = Bonobo_StorageInfo__alloc ();
+
+ si->size = -1;
+ si->type = Bonobo_STORAGE_TYPE_REGULAR;
+ si->name = CORBA_string_dup ("");
+ si->content_type = CORBA_string_dup ("application/octet-stream");
+
+ return si;
+}
+
+static void
+fd_set_info (BonoboStream *stream,
+ const Bonobo_StorageInfo *info,
+ const Bonobo_StorageInfoFields mask,
+ CORBA_Environment *ev)
+{
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NotSupported);
+}
+
+static void
+fd_truncate (BonoboStream *stream,
+ const CORBA_long new_size,
+ CORBA_Environment *ev)
+{
+ BonoboStreamFd *sfd = BONOBO_STREAM_FD (stream);
+
+ if (!(sfd->mode & BONOBO_STREAM_FD_TRUNCATE)) {
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NotSupported);
+ return;
+ }
+
+ if (ftruncate (sfd->fd, new_size) < 0)
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NoPermission);
+}
+
+static void
+fd_write (BonoboStream *stream,
+ const Bonobo_Stream_iobuf *buffer,
+ CORBA_Environment *ev)
+{
+ BonoboStreamFd *sfd = BONOBO_STREAM_FD (stream);
+ gint result = 0, total = 0;
+
+ if (!(sfd->mode & BONOBO_STREAM_FD_WRITE)) {
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NotSupported);
+ return;
+ }
+
+ while (total < buffer->_length) {
+ result = write (sfd->fd, buffer->_buffer, buffer->_length);
+
+ if (result < 0) {
+ switch (errno) {
+ case EBADF:
+ case EINVAL:
+ case EISDIR:
+ bonobo_exception_set (
+ ev,
+ ex_Bonobo_Stream_NoPermission);
+ default:
+ bonobo_exception_set (
+ ev,
+ ex_Bonobo_Stream_IOError);
+ }
+ return;
+ }
+
+ total -= result;
+ }
+}
+
+static void
+fd_read (BonoboStream *stream,
+ CORBA_long count,
+ Bonobo_Stream_iobuf **buffer,
+ CORBA_Environment *ev)
+{
+ BonoboStreamFd *sfd = BONOBO_STREAM_FD (stream);
+ gint result = 0;
+
+ if (!(sfd->mode & BONOBO_STREAM_FD_READ)) {
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NotSupported);
+ return;
+ }
+
+ *buffer = Bonobo_Stream_iobuf__alloc ();
+ CORBA_sequence_set_release (*buffer, TRUE);
+ (*buffer)->_buffer = CORBA_sequence_CORBA_octet_allocbuf (count);
+ (*buffer)->_length = count;
+
+ while (count) {
+ result = read (sfd->fd, (*buffer)->_buffer, count);
+
+ if (result < 0) {
+ switch (errno) {
+ case EBADF:
+ case EINVAL:
+ case EISDIR:
+ bonobo_exception_set (
+ ev,
+ ex_Bonobo_Stream_NoPermission);
+ default:
+ bonobo_exception_set (
+ ev,
+ ex_Bonobo_Stream_IOError);
+ }
+ return;
+ } else if (result == 0) {
+ (*buffer)->_length -= count;
+ break;
+ }
+
+ count -= result;
+ }
+}
+
+static CORBA_long
+fd_seek (BonoboStream *stream,
+ CORBA_long offset,
+ Bonobo_Stream_SeekType whence,
+ CORBA_Environment *ev)
+{
+ BonoboStreamFd *sfd = BONOBO_STREAM_FD (stream);
+ int pos = 0;
+
+ if (!(sfd->mode & BONOBO_STREAM_FD_SEEK)) {
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NotSupported);
+ return pos;
+ }
+
+ switch (whence){
+ case Bonobo_Stream_SEEK_SET:
+ whence = SEEK_SET;
+ break;
+
+ case Bonobo_Stream_SEEK_CUR:
+ whence = SEEK_CUR;
+ break;
+
+ case Bonobo_Stream_SEEK_END:
+ whence = SEEK_END;
+ break;
+ default:
+ g_warning ("Signal exception");
+ }
+
+ pos = lseek (sfd->fd, (off_t) offset, whence);
+
+ if (pos < 0) {
+ bonobo_exception_set (ev, ex_Bonobo_Stream_IOError);
+ return 0;
+ }
+
+ return pos;
+}
+
+#define COPY_TO_BLOCK_SIZE 8192
+
+static void
+fd_copy_to (BonoboStream *stream,
+ const CORBA_char *dest,
+ const CORBA_long bytes,
+ CORBA_long *read,
+ CORBA_long *written,
+ CORBA_Environment *ev)
+{
+ int dest_fd;
+
+ if (*dest == '\0' || (bytes < -1 || bytes == 0)) {
+ bonobo_exception_set (ev, ex_Bonobo_Stream_IOError);
+ return;
+ }
+
+ dest_fd = open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND);
+
+ if (dest_fd < 0) {
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NoPermission);
+ return;
+ }
+
+ while (1) {
+ Bonobo_Stream_iobuf *buf;
+ int result;
+
+ fd_read (stream, COPY_TO_BLOCK_SIZE, &buf, ev);
+
+ if (buf->_length == 0 || BONOBO_EX (ev)) break;
+
+ *read += buf->_length;
+
+ result = write (dest_fd, buf->_buffer, buf->_length);
+
+ if (result < 0) {
+ switch (errno) {
+ case EBADF:
+ case EINVAL:
+ case EISDIR:
+ bonobo_exception_set (
+ ev,
+ ex_Bonobo_Stream_NoPermission);
+ default:
+ bonobo_exception_set (
+ ev,
+ ex_Bonobo_Stream_IOError);
+ }
+ break;
+ }
+
+ *written += result;
+ };
+}
+
+static void
+fd_commit (BonoboStream *stream, CORBA_Environment *ev)
+{
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NotSupported);
+}
+
+static void
+fd_revert (BonoboStream *stream, CORBA_Environment *ev)
+{
+ bonobo_exception_set (ev, ex_Bonobo_Stream_NotSupported);
+}
+
+static void
+fd_destroy (GtkObject *object)
+{
+ BonoboStreamFd *sfd = BONOBO_STREAM_FD (object);
+
+ if (sfd->own_fd) close (sfd->fd);
+
+ GTK_OBJECT_CLASS (bonobo_stream_fd_parent_class)->destroy (object);
+}
+
+static int
+fd_get_unix_fd (BonoboStreamFd *stream_fd)
+{
+ g_return_val_if_fail (BONOBO_IS_STREAM_FD (stream_fd), -1);
+
+ return stream_fd->fd;
+}
+
+static void
+bonobo_stream_fd_class_init (BonoboStreamFdClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *) klass;
+ BonoboStreamClass *sclass = BONOBO_STREAM_CLASS (klass);
+
+ bonobo_stream_fd_parent_class = gtk_type_class (bonobo_stream_get_type ());
+
+ object_class->destroy = fd_destroy;
+
+ sclass->get_info = fd_get_info;
+ sclass->set_info = fd_set_info;
+ sclass->write = fd_write;
+ sclass->read = fd_read;
+ sclass->seek = fd_seek;
+ sclass->truncate = fd_truncate;
+ sclass->copy_to = fd_copy_to;
+ sclass->commit = fd_commit;
+ sclass->revert = fd_revert;
+
+ klass->get_unix_fd = fd_get_unix_fd;
+}
+
+/**
+ * bonobo_stream_fd_get_type:
+ *
+ * Returns: the GtkType of the BonoboStreamFd class.
+ */
+GtkType
+bonobo_stream_fd_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type){
+ GtkTypeInfo info = {
+ "BonoboStreamFd",
+ sizeof (BonoboStreamFd),
+ sizeof (BonoboStreamFdClass),
+ (GtkClassInitFunc) bonobo_stream_fd_class_init,
+ (GtkObjectInitFunc) NULL,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (bonobo_stream_get_type (), &info);
+ }
+
+ return type;
+}
+
+BonoboStreamFd *
+bonobo_stream_fd_construct (BonoboStreamFd *stream_fd,
+ Bonobo_Stream corba_stream,
+ int fd,
+ int mode,
+ gboolean take_ownership)
+{
+ g_return_val_if_fail (corba_stream != CORBA_OBJECT_NIL, NULL);
+ g_return_val_if_fail (BONOBO_IS_STREAM_FD (stream_fd), NULL);
+
+ stream_fd->fd = fd;
+ stream_fd->mode = mode;
+ stream_fd->own_fd = take_ownership;
+
+ return BONOBO_STREAM_FD (
+ bonobo_object_construct (BONOBO_OBJECT (stream_fd),
+ corba_stream));
+}
+
+/**
+ * bonobo_stream_fd_create:
+ * @buffer: The data for which a BonoboStreamFd object is to be created.
+ * @size: The size in bytes of @buffer.
+ * @read_only: Specifies whether or not the returned BonoboStreamFd
+ * object should allow write() operations.
+ * @resizable: Whether or not the buffer should be resized as needed.
+ *
+ * Creates a new BonoboStreamFd object.
+ *
+ * If @buffer is non-%NULL, @size bytes are copied from it into a new
+ * buffer. If @buffer is %NULL, a new buffer of size @size is created
+ * and filled with zero bytes.
+ *
+ * When data is read out of or (if @read_only is FALSE) written into
+ * the returned BonoboStream object, the read() and write() operations
+ * operate on the new buffer. If @resizable is TRUE, writing or seeking
+ * past the end of the buffer will cause the buffer to be expanded (with
+ * the new space zero-filled for a seek).
+ *
+ * Returns: the constructed BonoboStream object
+ **/
+BonoboStream *
+bonobo_stream_fd_create (int fd, int mode, gboolean take_ownership)
+{
+ BonoboStreamFd *stream_fd;
+ Bonobo_Stream corba_stream;
+
+ stream_fd = gtk_type_new (bonobo_stream_fd_get_type ());
+ if (stream_fd == NULL)
+ return NULL;
+
+ corba_stream = bonobo_stream_corba_object_create (
+ BONOBO_OBJECT (stream_fd));
+
+ if (corba_stream == CORBA_OBJECT_NIL) {
+ bonobo_object_unref (BONOBO_OBJECT (stream_fd));
+ return NULL;
+ }
+
+ return BONOBO_STREAM (bonobo_stream_fd_construct (stream_fd,
+ corba_stream,
+ fd,
+ mode,
+ take_ownership));
+}
+
+/**
+ * bonobo_stream_fd_get_unix_fd:
+ * @stream_fd: a BonoboStreamFd
+ *
+ * Returns the UNIX file descriptor associated with a BonoboStreamFd
+ *
+ * Return value: the fd.
+ **/
+int
+bonobo_stream_fd_get_unix_fd (BonoboStreamFd *stream_fd)
+{
+ return BONOBO_STREAM_FD_CLASS(
+ GTK_OBJECT(stream_fd)->klass)->get_unix_fd (stream_fd);
+}
Index: bonobo/bonobo-stream-fd.h
===================================================================
RCS file: bonobo-stream-fd.h
diff -N bonobo-stream-fd.h
--- /dev/null Tue May 5 16:32:27 1998
+++ bonobo-stream-fd.h Wed Jun 6 14:13:02 2001
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/**
+ * bonobo-stream-fd.h: Unix file descriptor based stream
+ *
+ * Author:
+ * Alex Graveley (alex ximian com)
+ *
+ * Copyright 2001, Ximian, Inc.
+ */
+
+#ifndef _BONOBO_STREAM_FD_H_
+#define _BONOBO_STREAM_FD_H_
+
+#include <bonobo/bonobo-stream.h>
+
+BEGIN_GNOME_DECLS
+
+#define BONOBO_STREAM_FD_TYPE (bonobo_stream_fd_get_type ())
+#define BONOBO_STREAM_FD(o) (GTK_CHECK_CAST ((o), BONOBO_STREAM_FD_TYPE, BonoboStreamFd))
+#define BONOBO_STREAM_FD_CLASS(k) (GTK_CHECK_CLASS_CAST((k), BONOBO_STREAM_FD_TYPE, BonoboStreamFdClass))
+#define BONOBO_IS_STREAM_FD(o) (GTK_CHECK_TYPE ((o), BONOBO_STREAM_FD_TYPE))
+#define BONOBO_IS_STREAM_FD_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), BONOBO_STREAM_FD_TYPE))
+
+typedef enum {
+ BONOBO_STREAM_FD_READ = (1 << 0),
+ BONOBO_STREAM_FD_WRITE = (1 << 1),
+ BONOBO_STREAM_FD_SEEK = (1 << 2),
+ BONOBO_STREAM_FD_TRUNCATE = (1 << 3),
+
+ BONOBO_STREAM_FD_SOCKET = (BONOBO_STREAM_FD_READ |
+ BONOBO_STREAM_FD_WRITE),
+
+ BONOBO_STREAM_FD_FILE = (BONOBO_STREAM_FD_READ |
+ BONOBO_STREAM_FD_WRITE |
+ BONOBO_STREAM_FD_SEEK |
+ BONOBO_STREAM_FD_TRUNCATE)
+} BonoboStreamFdMode;
+
+typedef struct _BonoboStreamFdPrivate BonoboStreamFdPrivate;
+
+typedef struct {
+ BonoboStream stream;
+
+ int fd;
+ int mode;
+ gboolean own_fd;
+
+ BonoboStreamFdPrivate *priv;
+} BonoboStreamFd;
+
+typedef struct {
+ BonoboStreamClass parent_class;
+ int (*get_unix_fd) (BonoboStreamFd *stream_fd);
+} BonoboStreamFdClass;
+
+GtkType bonobo_stream_fd_get_type (void);
+BonoboStreamFd *bonobo_stream_fd_construct (BonoboStreamFd *stream_fd,
+ Bonobo_Stream corba_stream,
+ int fd,
+ int mode,
+ gboolean take_ownership);
+
+BonoboStream *bonobo_stream_fd_create (int fd,
+ int mode,
+ gboolean take_ownership);
+
+int bonobo_stream_fd_get_unix_fd (BonoboStreamFd *stream_fd);
+
+END_GNOME_DECLS
+
+#endif /* _BONOBO_STREAM_FD_H_ */
Index: idl/Bonobo.idl
===================================================================
RCS file: /cvs/gnome/bonobo/idl/Bonobo.idl,v
retrieving revision 1.44
diff -u -r1.44 Bonobo.idl
--- idl/Bonobo.idl 2001/01/25 20:01:15 1.44
+++ idl/Bonobo.idl 2001/06/06 18:13:02
@@ -45,6 +45,7 @@
/* Misc. stuff. */
#include <Bonobo_Desktop.idl>
+#include <Bonobo_Process.idl>
#if !defined(__BONOBO_COMPILATION) && defined(__ORBIT_IDL__)
#pragma inhibit pop
Index: idl/Bonobo_Process.idl
===================================================================
RCS file: Bonobo_Process.idl
diff -N Bonobo_Process.idl
--- /dev/null Tue May 5 16:32:27 1998
+++ Bonobo_Process.idl Wed Jun 6 14:13:02 2001
@@ -0,0 +1,40 @@
+/*
+ * bonobo-process.idl: UNIX Process manipulation.
+ *
+ * Copyright (C) 1999, 2000 Helix Code, Inc.
+ *
+ * Author:
+ * Alex Graveley (alex ximian com)
+ *
+ * Terms:
+ *
+ * Process: This interface provides access to a currently running
+ * process, and allows signalling the process, and accessing
+ * the STDIN, STDOUT, and STDERR using Streams.
+ *
+ */
+
+#ifndef BONOBO_PROCESS_IDL
+#define BONOBO_PROCESS_IDL
+
+#include "Bonobo_Unknown.idl"
+
+module Bonobo {
+
+ interface Process : Unknown {
+ exception NoPermission {};
+
+ void signal (in long signum) raises (NoPermission);
+
+ boolean isRunning ();
+
+ Stream getInputStream () raises (NoPermission);
+
+ Stream getOutputStream () raises (NoPermission);
+
+ Stream getErrorStream () raises (NoPermission);
+ };
+
+};
+
+#endif /* BONOBO_PROCESS_IDL */
Index: monikers/Bonobo_Moniker_exec.oaf.in
===================================================================
RCS file: Bonobo_Moniker_exec.oaf.in
diff -N Bonobo_Moniker_exec.oaf.in
--- /dev/null Tue May 5 16:32:27 1998
+++ Bonobo_Moniker_exec.oaf.in Wed Jun 6 14:13:02 2001
@@ -0,0 +1,30 @@
+<oaf_info>
+
+<oaf_server iid="OAFIID:Bonobo_Moniker_exec_Factory"
+ type="exe"
+ location="bonobo-moniker-exec">
+ <oaf_attribute name="repo_ids" type="stringv">
+ <item value="IDL:GNOME/GenericFactory:1.0"/>
+ </oaf_attribute>
+
+ <oaf_attribute name="name"
+ type="string"
+ _value="Process Execution Moniker factory"/>
+</oaf_server>
+
+<oaf_server iid="OAFIID:Bonobo_Moniker_exec"
+ type="factory"
+ location="OAFIID:Bonobo_Moniker_exec_Factory">
+ <oaf_attribute name="repo_ids" type="stringv">
+ <item value="IDL:Bonobo/Moniker:1.0"/>
+ <item value="IDL:Bonobo/Unknown:1.0"/>
+ </oaf_attribute>
+ <oaf_attribute name="name"
+ type="string"
+ _value="Process Execution Moniker"/>
+ <oaf_attribute name="bonobo:moniker" type="stringv">
+ <item value="exec:"/>
+ </oaf_attribute>
+</oaf_server>
+
+</oaf_info>
Index: monikers/Bonobo_Moniker_std.oaf.in.in
===================================================================
RCS file: /cvs/gnome/bonobo/monikers/Bonobo_Moniker_std.oaf.in.in,v
retrieving revision 1.3
diff -u -r1.3 Bonobo_Moniker_std.oaf.in.in
--- monikers/Bonobo_Moniker_std.oaf.in.in 2001/01/25 09:26:21 1.3
+++ monikers/Bonobo_Moniker_std.oaf.in.in 2001/06/06 18:13:02
@@ -100,6 +100,7 @@
<item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute>
<oaf_attribute name="bonobo:moniker_extender" type="stringv">
+ <item value="exec:"/>
<item value="file:"/>
<item value="http:"/>
<item value="gunzip:"/>
Index: monikers/Makefile.am
===================================================================
RCS file: /cvs/gnome/bonobo/monikers/Makefile.am,v
retrieving revision 1.37
diff -u -r1.37 Makefile.am
--- monikers/Makefile.am 2001/05/05 22:57:34 1.37
+++ monikers/Makefile.am 2001/06/06 18:13:02
@@ -8,6 +8,7 @@
$(BONOBO_TEST_CFLAGS)
OAF_FILES = \
+ Bonobo_Moniker_exec.oaf.in \
Bonobo_Moniker_gzip.oaf.in \
Bonobo_Moniker_http.oaf.in
@@ -26,6 +27,7 @@
moniker_LTLIBRARIES = libmoniker_std.la
bin_PROGRAMS = \
+ bonobo-moniker-exec \
bonobo-moniker-gunzip \
bonobo-moniker-http \
moniker-test
@@ -57,6 +59,12 @@
bonobo-moniker-std.c
libmoniker_std_la_LDFLAGS = -module
+
+bonobo_moniker_exec_SOURCES = \
+ bonobo-moniker-exec.c
+
+bonobo_moniker_exec_LDADD = \
+ $(moniker_ldadd)
bonobo_moniker_gunzip_SOURCES = \
bonobo-moniker-gunzip.c \
Index: monikers/bonobo-moniker-exec.c
===================================================================
RCS file: bonobo-moniker-exec.c
diff -N bonobo-moniker-exec.c
--- /dev/null Tue May 5 16:32:27 1998
+++ bonobo-moniker-exec.c Wed Jun 6 14:13:02 2001
@@ -0,0 +1,321 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * bonobo-moniker-file.c: Process execution Moniker implementation
+ *
+ * Author:
+ * Alex Graveley (alex ximian com)
+ *
+ * Copyright 2001, Ximian, Inc.
+ */
+
+#include <config.h>
+
+#include <bonobo/bonobo.h>
+#include <bonobo/bonobo-stream-fd.h>
+#include <bonobo/bonobo-moniker-extender.h>
+
+typedef struct {
+ gchar *path;
+ gchar *host;
+ gchar *user;
+ gchar *passwd;
+ gchar *rsh;
+} BonoboExecProcessInit;
+
+static BonoboExecProcessInit *
+bonobo_moniker_exec_parse_path (const gchar *path)
+{
+ BonoboExecProcessInit *pi;
+ gchar **split, **split2;
+ gint x = 0;
+
+ split = g_strsplit (path, ";", 0);
+
+ if (!split || !split [0] || !split [0][0]) return NULL;
+
+ pi = g_new0 (BonoboExecProcessInit, 1);
+
+ while (split [x]) {
+ split2 = g_strsplit (split [x], "=", 0);
+
+ if (split2 [1]) {
+ g_strstrip (split2 [0]);
+ g_strstrip (split2 [1]);
+
+ if (!strcmp ("host", split2 [0]))
+ pi->host = g_strdup (split2 [1]);
+ else if (!strcmp ("user", split2 [0]))
+ pi->user = g_strdup (split2 [1]);
+ else if (!strcmp ("passwd", split2 [0]))
+ pi->passwd = g_strdup (split2 [1]);
+ else if (!strcmp ("rsh", split2 [0]))
+ pi->rsh = g_strdup (split2 [1]);
+ else g_warning ("Unknown option \"%s=%s\" "
+ "passed to Bonobo exec moniker",
+ split2 [0],
+ split2 [1]);
+ } else {
+ if (!pi->path) pi->path = g_strdup (split2 [0]);
+ else g_warning ("Two exec paths passed to "
+ "Bonobo exec moniker");
+ }
+
+ g_strfreev (split2);
+ x++;
+ }
+
+ g_strfreev (split);
+
+ return pi;
+}
+
+typedef struct {
+ Bonobo_Stream in_stream;
+ Bonobo_Stream out_stream;
+ Bonobo_Process process;
+} BonoboExecReader;
+
+static gboolean
+bonobo_moniker_exec_stdin_reader (BonoboExecReader *reader)
+{
+ CORBA_Environment ev;
+ gchar *buf;
+ gint bytes_read;
+
+ CORBA_exception_init (&ev);
+
+ buf = bonobo_stream_client_read (reader->in_stream,
+ 4096,
+ &bytes_read,
+ &ev);
+
+ if (BONOBO_EX (&ev)) goto FINISHED_READ;
+ if (!bytes_read) return TRUE;
+
+ bonobo_stream_client_write (reader->out_stream,
+ buf,
+ bytes_read,
+ &ev);
+
+
+ CORBA_exception_free (&ev);
+
+ return TRUE;
+
+ FINISHED_READ:
+ bonobo_object_release_unref (reader->in_stream, &ev);
+ bonobo_object_release_unref (reader->out_stream, &ev);
+ bonobo_object_release_unref (reader->process, &ev);
+ g_free (reader);
+
+ CORBA_exception_free (&ev);
+
+ return FALSE;
+}
+
+static Bonobo_Unknown
+bonobo_moniker_exec_resolve (BonoboMoniker *moniker,
+ const Bonobo_ResolveOptions *options,
+ const CORBA_char *requested_interface,
+ CORBA_Environment *ev)
+{
+ Bonobo_Unknown retval = NULL;
+ Bonobo_Moniker parent;
+ Bonobo_Stream in_stream = NULL;
+ BonoboProcess *process;
+ BonoboStream *io_streams [3] = { NULL, NULL, NULL };
+ const char *path;
+ BonoboExecProcessInit *pi;
+ BonoboExecReader *read_state;
+ gint pair [3][2] = { {0,0}, {0,0}, {0,0} };
+ gint pid;
+
+ if (strcmp (requested_interface, "IDL:Bonobo/Process:1.0") ||
+ strcmp (requested_interface, "IDL:Bonobo/Stream:1.0"))
+ return bonobo_moniker_use_extender (
+ "OAFIID:Bonobo_MonikerExtender_exec",
+ moniker,
+ options,
+ requested_interface,
+ ev);
+
+ parent = bonobo_moniker_get_parent (moniker, ev);
+ if (BONOBO_EX (ev)) return NULL;
+
+ if (parent) {
+ in_stream = Bonobo_Moniker_resolve (parent,
+ options,
+ "IDL:Bonobo/Stream:1.0",
+ ev);
+
+ if (BONOBO_EX (ev) || !in_stream) {
+ bonobo_object_release_unref (parent, ev);
+ return NULL;
+ }
+ }
+
+ path = bonobo_moniker_get_name (moniker);
+ pi = bonobo_moniker_exec_parse_path (path);
+
+ if (!pi) return NULL;
+ if (!pi->path) goto ERROR;
+
+ if (pipe (pair [0]) < 0) goto ERROR;
+ if (pipe (pair [1]) < 0) goto PIPE_ERROR;
+ if (pipe (pair [2]) < 0) goto PIPE_ERROR;
+
+ pid = fork ();
+
+ switch (pid) {
+ case -1:
+ goto PIPE_ERROR;
+ case 0:
+ dup2 (pair [0][0], STDIN_FILENO);
+ dup2 (pair [1][1], STDOUT_FILENO);
+ dup2 (pair [2][1], STDERR_FILENO);
+
+ /* FIXME: handle sending of password correctly.
+ fork twice and sniff stdout for something
+ resembling a password prompt. */
+ if (pi->user && pi->passwd) {
+ write (pair [0][1],
+ pi->passwd,
+ strlen (pi->passwd));
+ write (pair [0][1], "\n", 1);
+ }
+
+ close (pair [0][0]);
+ close (pair [0][1]);
+ close (pair [1][0]);
+ close (pair [1][1]);
+ close (pair [2][0]);
+ close (pair [2][1]);
+
+ if (pi->host) {
+ if (pi->user)
+ execlp (pi->rsh ? pi->rsh : "rsh",
+ pi->rsh ? pi->rsh : "rsh",
+ "-l",
+ pi->user,
+ pi->host,
+ pi->path,
+ NULL);
+ else
+ execlp (pi->rsh ? pi->rsh : "rsh",
+ pi->rsh ? pi->rsh : "rsh",
+ pi->host,
+ pi->path,
+ NULL);
+ } else if (pi->user)
+ execlp ("su",
+ "su",
+ "-c",
+ pi->path,
+ pi->user,
+ NULL);
+ else
+ execlp ("sh",
+ "sh",
+ "-c",
+ pi->path,
+ NULL);
+ }
+
+ close (pair [0][0]); pair [0][0] = 0;
+ close (pair [1][1]); pair [1][1] = 0;
+ close (pair [2][1]); pair [2][1] = 0;
+
+ /* STDIN is created for writing by BonoboProcess clients */
+ io_streams [0] =
+ bonobo_stream_fd_create (pair [0][1],
+ BONOBO_STREAM_FD_WRITE,
+ TRUE);
+
+ /* STDOUT and STDERR are created for reading by BonoboProcess clients */
+ io_streams [1] =
+ bonobo_stream_fd_create (pair [1][0],
+ BONOBO_STREAM_FD_READ,
+ TRUE);
+ io_streams [2] =
+ bonobo_stream_fd_create (pair [2][0],
+ BONOBO_STREAM_FD_READ,
+ TRUE);
+
+ process = bonobo_process_attach_full (pid,
+ BONOBO_OBJREF (io_streams [0]),
+ BONOBO_OBJREF (io_streams [1]),
+ BONOBO_OBJREF (io_streams [2]));
+ if (!process) goto PROCESS_ERROR;
+
+ if (in_stream) {
+ read_state = g_new0 (BonoboExecReader, 1);
+ read_state->in_stream = in_stream;
+ read_state->out_stream =
+ bonobo_object_dup_ref (BONOBO_OBJREF (io_streams [0]),
+ ev);
+ read_state->process =
+ bonobo_object_dup_ref (BONOBO_OBJREF (process),
+ ev);
+
+ g_idle_add ((GSourceFunc) bonobo_moniker_exec_stdin_reader,
+ read_state);
+
+ bonobo_object_release_unref (parent, ev);
+ }
+
+ if (!strcmp (requested_interface, "IDL:Bonobo/Stream:1.0")) {
+ retval = BONOBO_OBJREF (io_streams [1]);
+ bonobo_object_unref (BONOBO_OBJECT (io_streams [0]));
+ bonobo_object_unref (BONOBO_OBJECT (io_streams [2]));
+ } else {
+ retval = BONOBO_OBJREF (process);
+ bonobo_object_unref (BONOBO_OBJECT (io_streams [0]));
+ bonobo_object_unref (BONOBO_OBJECT (io_streams [1]));
+ bonobo_object_unref (BONOBO_OBJECT (io_streams [2]));
+ }
+
+ ERROR:
+ g_free (pi->path);
+ g_free (pi->host);
+ g_free (pi->user);
+ g_free (pi->passwd);
+ g_free (pi->rsh);
+ g_free (pi);
+
+ return retval;
+
+ PIPE_ERROR:
+ {
+ int x;
+ for (x = 0; x < 3; x++) {
+ if (pair [x][0]) close (pair [x][0]);
+ if (pair [x][1]) close (pair [x][1]);
+ }
+ goto ERROR;
+ }
+
+ PROCESS_ERROR:
+ {
+ int x;
+ for (x = 0; x < 3; x++)
+ if (io_streams [x])
+ bonobo_object_unref (
+ BONOBO_OBJECT (io_streams [x]));
+ goto ERROR;
+ }
+}
+
+static BonoboObject *
+bonobo_moniker_exec_factory (BonoboGenericFactory *this, void *closure)
+{
+ BonoboMoniker *moniker;
+ moniker = bonobo_moniker_simple_new ("exec:",
+ bonobo_moniker_exec_resolve);
+ return BONOBO_OBJECT (moniker);
+}
+
+BONOBO_OAF_FACTORY ("OAFIID:Bonobo_Moniker_exec_Factory",
+ "exec-moniker", VERSION,
+ bonobo_moniker_exec_factory,
+ NULL)
+
Index: monikers/moniker-test.c
===================================================================
RCS file: /cvs/gnome/bonobo/monikers/moniker-test.c,v
retrieving revision 1.10
diff -u -r1.10 moniker-test.c
--- monikers/moniker-test.c 2001/01/25 09:26:21 1.10
+++ monikers/moniker-test.c 2001/06/06 18:13:02
@@ -15,6 +15,7 @@
#include <glib.h>
#include <gnome.h>
+#include <unistd.h>
#include <liboaf/liboaf.h>
#include <bonobo.h>
@@ -23,6 +24,7 @@
static void display_as_storage_file_list (const char *moniker, CORBA_Environment *ev);
static void display_as_html (const char *moniker, CORBA_Environment *ev);
static void display_as_control (const char *moniker, CORBA_Environment *ev);
+static void display_as_process (const char *moniker, CORBA_Environment *ev);
typedef enum {
AS_NONE = 0,
@@ -30,7 +32,8 @@
AS_STREAM,
AS_STORAGE_FILE_LIST,
AS_HTML,
- AS_CONTROL
+ AS_CONTROL,
+ AS_PROCESS
} MonikerTestDisplayAs;
typedef void (*MonikerDisplayFunction) (const char *moniker, CORBA_Environment *ev);
@@ -46,6 +49,7 @@
{AS_STORAGE_FILE_LIST, display_as_storage_file_list},
{AS_HTML, display_as_html},
{AS_CONTROL, display_as_control},
+ {AS_PROCESS, display_as_process},
{0}
};
@@ -55,7 +59,7 @@
MonikerTestDisplayAs display_as;
gchar *moniker;
- int ps, pr, pc, ph;
+ int ps, pr, pc, ph, pp;
} MonikerTestOptions;
MonikerTestOptions global_mto = { NULL };
@@ -66,6 +70,7 @@
{"storage", 'r', POPT_ARG_NONE, &global_mto.pr, 'r', "request Bonobo/Storage", NULL },
{"control", 'c', POPT_ARG_NONE, &global_mto.pc, 'c', "request Bonobo/Control", NULL },
{"html", 'h', POPT_ARG_NONE, &global_mto.ph, 'h', "request Bonobo/Stream and display as HTML", NULL },
+ {"process", 'p', POPT_ARG_NONE, &global_mto.pp, 'p', "request Bonobo/Process and display process output", NULL },
{NULL, 0, 0, NULL, 0, 0}
};
@@ -223,6 +228,54 @@
gtk_main ();
}
+static void
+display_as_process (const char *moniker, CORBA_Environment *ev)
+{
+ Bonobo_Process process;
+ Bonobo_Stream stdout;
+ gchar *buf = NULL;
+ gint len;
+
+ process = bonobo_get_object (moniker, "IDL:Bonobo/Process:1.0", ev);
+ if (BONOBO_EX (ev) || !process)
+ g_error ("Couldn't get Bonobo/Process interface");
+
+ g_print ("Waiting for process to die...");
+ while (Bonobo_Process_isRunning (process, ev)) {
+ if (BONOBO_EX (ev))
+ g_error ("Exception in BonoboProcess::isRunning");
+
+ g_print (".");
+ usleep (500);
+ }
+ g_print ("dead.\n\n");
+
+ g_print ("Process output:\n");
+ g_print ("==========================================\n");
+
+ stdout = Bonobo_Process_getOutputStream (process, ev);
+ if (BONOBO_EX (ev) || !stdout)
+ g_error ("Exception in BonoboProcess::getOutputStream.");
+
+ while (1) {
+ buf = bonobo_stream_client_read (stdout, 1024, &len, ev);
+ if (BONOBO_EX (ev))
+ g_error ("Exception while reading process output: %s",
+ bonobo_exception_get_text (ev));
+
+ if (!buf || !len) break;
+
+ g_print ("%*s", len, buf);
+
+ g_free (buf);
+ }
+
+ g_print ("==========================================\n");
+
+ bonobo_object_release_unref (stdout, ev);
+ bonobo_object_release_unref (process, ev);
+}
+
int
main (int argc, char **argv)
{
@@ -261,6 +314,8 @@
global_mto.display_as = AS_HTML;
else if (global_mto.pc)
global_mto.display_as = AS_CONTROL;
+ else if (global_mto.pp)
+ global_mto.display_as = AS_PROCESS;
else {
fprintf (stderr, "Usage: %s [-i interface] [-srch] <moniker>\n", argv [0]);
fprintf (stderr, "Run %s --help for more info\n", argv [0]);
@@ -295,6 +350,9 @@
break;
case AS_CONTROL:
fprintf (stderr, "IDL:Bonobo/Control:1.0");
+ break;
+ case AS_PROCESS:
+ fprintf (stderr, "IDL:Bonobo/Process:1.0");
break;
default:
fprintf (stderr, "???");
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/bonobo/ChangeLog,v
retrieving revision 1.1071
diff -u -r1.1071 ChangeLog
--- ChangeLog 2001/06/05 09:11:21 1.1071
+++ ChangeLog 2001/06/06 18:17:32
@@ -1,3 +1,8 @@
+2001-06-06 Alex Graveley <alex ximian com>
+
+ * bonobo/bonobo-stream-client.c (bonobo_stream_client_read):
+ Handle partial reads correctly.
+
2001-06-05 Dietmar Maurer <dietmar ximian com>
* monikers/bonobo-stream-cache.c (impl_Bonobo_Stream_setInfo):
Index: bonobo/bonobo-stream-client.c
===================================================================
RCS file: /cvs/gnome/bonobo/bonobo/bonobo-stream-client.c,v
retrieving revision 1.17
diff -u -r1.17 bonobo-stream-client.c
--- bonobo/bonobo-stream-client.c 2001/02/22 22:54:40 1.17
+++ bonobo/bonobo-stream-client.c 2001/06/06 18:17:32
@@ -296,11 +296,16 @@
if (buf->_length > 0) {
memcpy (mem + pos, buf->_buffer, buf->_length);
pos += buf->_length;
- } else {
- g_warning ("Buffer length %d", buf->_length);
- goto io_error;
}
+
+ len = buf->_length;
+
CORBA_free (buf);
+
+ if (!len) {
+ *length_read = pos;
+ break;
+ }
}
return mem;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]