summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2003-03-03 22:53:15 +0000
committerJeffrey Stedfast <fejj@src.gnome.org>2003-03-03 22:53:15 +0000
commite99cb1d093f3a0fc33babf1ea04bae09814408d7 (patch)
tree91af0c95955f1de5249152d0b3619e7be25cca57
parentc96487bfac1b4a85a92b29de298d8e2dab73da58 (diff)
downloadevolution-data-server-e99cb1d093f3a0fc33babf1ea04bae09814408d7.tar.gz
Updated to use the new API from a fe commits ago for the NSS stream. This
2003-03-03 Jeffrey Stedfast <fejj@ximian.com> * camel-tcp-stream-openssl.c (camel_tcp_stream_ssl_new): Updated to use the new API from a fe commits ago for the NSS stream. This is just to make it compile, but does not update the behaviour to act like the NSS stream. Note that people shouldn't be using OpenSSL anyway. (camel_tcp_stream_ssl_new_raw): Same. * camel-process.[c,h]: New source file containing convenience functions for process creation/termination mainly for use with Pipe filters but should be usable for anything we want. * camel-io.[c,h]: New source files implementing read/write system calls with proper error checking and cancellation (ie. StreamFs::read/write and CamelTcpStreamRaw::read/write). No sense duplicating the same code over and over. Now I can use this same code easily in other i/o code (such as Pipe filters and gpg code?).
-rw-r--r--camel/ChangeLog20
-rw-r--r--camel/camel-io.c166
-rw-r--r--camel/camel-io.h42
-rw-r--r--camel/camel-process.c153
-rw-r--r--camel/camel-process.h44
-rw-r--r--camel/camel-tcp-stream-openssl.c9
-rw-r--r--camel/camel-tcp-stream-raw.c4
7 files changed, 434 insertions, 4 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index c3fb16e43..345a653cb 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,23 @@
+2003-03-03 Jeffrey Stedfast <fejj@ximian.com>
+
+ * camel-tcp-stream-openssl.c (camel_tcp_stream_ssl_new): Updated
+ to use the new API from a fe commits ago for the NSS stream. This
+ is just to make it compile, but does not update the behaviour to
+ act like the NSS stream. Note that people shouldn't be using
+ OpenSSL anyway.
+ (camel_tcp_stream_ssl_new_raw): Same.
+
+ * camel-process.[c,h]: New source file containing convenience
+ functions for process creation/termination mainly for use with
+ Pipe filters but should be usable for anything we want.
+
+ * camel-io.[c,h]: New source files implementing read/write system
+ calls with proper error checking and cancellation
+ (ie. StreamFs::read/write and CamelTcpStreamRaw::read/write). No
+ sense duplicating the same code over and over. Now I can use this
+ same code easily in other i/o code (such as Pipe filters and gpg
+ code?).
+
2003-03-03 Not Zed <NotZed@Ximian.com>
* camel-store.c (camel_store_unsubscribe_folder): Do similar
diff --git a/camel/camel-io.c b/camel/camel-io.c
new file mode 100644
index 000000000..88ddcf692
--- /dev/null
+++ b/camel/camel-io.c
@@ -0,0 +1,166 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2003 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "camel-io.h"
+#include "camel-operation.h"
+
+
+/* FIXME: should we trade out select() for a poll() instead? */
+
+ssize_t
+camel_read (int fd, char *buf, size_t n)
+{
+ ssize_t nread;
+ int cancel_fd;
+
+ if (camel_operation_cancel_check (NULL)) {
+ errno = EINTR;
+ return -1;
+ }
+
+ cancel_fd = camel_operation_cancel_fd (NULL);
+ if (cancel_fd == -1) {
+ do {
+ nread = read (fd, buf, n);
+ } while (nread == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
+ } else {
+ int errnosav, flags, fdmax;
+ fd_set rdset;
+
+ flags = fcntl (fd, F_GETFL);
+ fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+
+ do {
+ FD_ZERO (&rdset);
+ FD_SET (fd, &rdset);
+ FD_SET (cancel_fd, &rdset);
+ fdmax = MAX (fd, cancel_fd) + 1;
+
+ nread = -1;
+ if (select (fdmax, &rdset, 0, 0, NULL) != -1) {
+ if (FD_ISSET (cancel_fd, &rdset)) {
+ fcntl (fd, F_SETFL, flags);
+ errno = EINTR;
+ return -1;
+ }
+
+ do {
+ nread = read (fd, buf, n);
+ } while (nread == -1 && errno == EINTR);
+ } else if (errno == EINTR) {
+ errno = EAGAIN;
+ }
+ } while (nread == -1 && (errno == EAGAIN || errno == EWOULDBLOCK));
+
+ errnosav = errno;
+ fcntl (fd, F_SETFL, flags);
+ errno = errnosav;
+ }
+
+ return nread;
+}
+
+
+ssize_t
+camel_write (int fd, const char *buf, size_t n)
+{
+ ssize_t w, written = 0;
+ int cancel_fd;
+
+ if (camel_operation_cancel_check (NULL)) {
+ errno = EINTR;
+ return -1;
+ }
+
+ cancel_fd = camel_operation_cancel_fd (NULL);
+ if (cancel_fd == -1) {
+ do {
+ do {
+ w = write (fd, buf + written, n - written);
+ } while (w == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
+
+ if (w > 0)
+ written += w;
+ } while (w != -1 && written < n);
+ } else {
+ int errnosav, flags, fdmax;
+ fd_set rdset, wrset;
+
+ flags = fcntl (fd, F_GETFL);
+ fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+
+ fdmax = MAX (fd, cancel_fd) + 1;
+ do {
+ FD_ZERO (&rdset);
+ FD_ZERO (&wrset);
+ FD_SET (fd, &wrset);
+ FD_SET (cancel_fd, &rdset);
+
+ w = -1;
+ if (select (fdmax, &rdset, &wrset, 0, NULL) != -1) {
+ if (FD_ISSET (cancel_fd, &rdset)) {
+ fcntl (fd, F_SETFL, flags);
+ errno = EINTR;
+ return -1;
+ }
+
+ do {
+ w = write (fd, buf + written, n - written);
+ } while (w == -1 && errno == EINTR);
+
+ if (w == -1) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ w = 0;
+ } else {
+ errnosav = errno;
+ fcntl (fd, F_SETFL, flags);
+ errno = errnosav;
+ return -1;
+ }
+ } else
+ written += w;
+ } else if (errno == EINTR) {
+ w = 0;
+ }
+ } while (w != -1 && written < n);
+
+ errnosav = errno;
+ fcntl (fd, F_SETFL, flags);
+ errno = errnosav;
+ }
+
+ if (w == -1)
+ return -1;
+
+ return written;
+}
diff --git a/camel/camel-io.h b/camel/camel-io.h
new file mode 100644
index 000000000..a4e47c018
--- /dev/null
+++ b/camel/camel-io.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2003 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef __CAMEL_IO_H__
+#define __CAMEL_IO_H__
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+ssize_t camel_read (int fd, char *buf, size_t n);
+
+ssize_t camel_write (int fd, const char *buf, size_t n);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CAMEL_IO_H__ */
diff --git a/camel/camel-process.c b/camel/camel-process.c
new file mode 100644
index 000000000..01c1e3be3
--- /dev/null
+++ b/camel/camel-process.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2003 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "camel-process.h"
+
+
+pid_t
+camel_process_fork (const char *path, char **argv, int *infd, int *outfd, int *errfd, CamelException *ex)
+{
+ int errnosav, fd[6], i;
+ pid_t pid;
+
+ for (i = 0; i < 6; i++)
+ fds[i] = -1;
+
+ for (i = 0; i < 6; i += 2) {
+ if (pipe (fd + i) == -1) {
+ errnosav = errno;
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to create pipe to '%s': %s"),
+ argv[0], strerror (errno));
+
+ for (i = 0; i < 6; i++) {
+ if (fd[i] == -1)
+ break;
+ close (fd[i]);
+ }
+
+ errno = errnosav;
+
+ return -1;
+ }
+ }
+
+ if (!(pid = fork ())) {
+ /* child process */
+ int maxfd, nullfd = -1;
+
+ if (!outfd || !errfd)
+ nullfd = open ("/dev/null", O_WRONLY);
+
+ if (dup2 (fd[0], STDIN_FILENO) == -1)
+ _exit (255);
+
+ if (dup2 (outfd ? fd[3] : nullfd, STDOUT_FILENO) == -1)
+ _exit (255);
+
+ if (dup2 (errfd ? fd[5] : nullfd, STDERR_FILENO) == -1)
+ _exit (255);
+
+ setsid ();
+
+ if ((maxfd = sysconf (_SC_OPEN_MAX)) > 0) {
+ for (i = 0; i < maxfd; i++) {
+ if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
+ close (i);
+ }
+ }
+
+ execv (path, argv);
+ _exit (255);
+ } else if (pid == -1) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to create create child process '%s': %s"),
+ argv[0], strerror (errno));
+ return -1;
+ }
+
+ /* parent process */
+ close (fd[0]);
+ close (fd[3]);
+ close (fd[5]);
+
+ if (infd)
+ *infd = fd[1];
+ else
+ close (fd[1]);
+
+ if (outfd)
+ *outfd = fd[2];
+ else
+ close (fd[2]);
+
+ if (errfd)
+ *errfd = fd[4];
+ else
+ close (fd[4]);
+
+ return pid;
+}
+
+
+int
+camel_process_wait (pid_t pid)
+{
+ sigset_t mask, omask;
+ int status;
+ pid_t r;
+
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGALRM);
+ sigprocmask (SIG_BLOCK, &mask, &omask);
+ alarm (1);
+
+ r = waitpid (pid, &status, 0);
+
+ alarm (0);
+ sigprocmask (SIG_SETMASK, &omask, NULL);
+
+ if (r == (pid_t) -1 && errno == EINTR) {
+ kill (pid, SIGTERM);
+ sleep (1);
+ r = waitpid (pid, &status, WNOHANG);
+ if (r == (pid_t) 0) {
+ kill (pid, SIGKILL);
+ sleep (1);
+ r = waitpid (pid, &status, WNOHANG);
+ }
+ }
+
+ if (r != (pid_t) -1 && WIFEXITED (status))
+ return WEXITSTATUS (status);
+ else
+ return -1;
+}
diff --git a/camel/camel-process.h b/camel/camel-process.h
new file mode 100644
index 000000000..a87db24d5
--- /dev/null
+++ b/camel/camel-process.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2003 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef __CAMEL_PROCESS_H__
+#define __CAMEL_PROCESS_H__
+
+#include <sys/types.h>
+
+#include <camel/camel-exception.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+pid_t camel_process_fork (const char *path, char **argv, int *infd, int *outfd, int *errfd, CamelException *ex);
+
+int camel_process_wait (pid_t pid);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CAMEL_PROCESS_H__ */
diff --git a/camel/camel-tcp-stream-openssl.c b/camel/camel-tcp-stream-openssl.c
index abd2e5d9c..f83a6d0d7 100644
--- a/camel/camel-tcp-stream-openssl.c
+++ b/camel/camel-tcp-stream-openssl.c
@@ -76,6 +76,7 @@ struct _CamelTcpStreamSSLPrivate {
CamelService *service;
char *expected_host;
gboolean ssl_mode;
+ guint32 flags;
};
static void
@@ -162,6 +163,7 @@ camel_tcp_stream_ssl_get_type (void)
* camel_tcp_stream_ssl_new:
* @service: camel service
* @expected_host: host that the stream is expecting to connect with.
+ * @flags: flags
*
* Since the SSL certificate authenticator may need to prompt the
* user, a CamelService is needed. @expected_host is needed as a
@@ -170,7 +172,7 @@ camel_tcp_stream_ssl_get_type (void)
* Return value: a ssl stream (in ssl mode)
**/
CamelStream *
-camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host)
+camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host, guint32 flags)
{
CamelTcpStreamSSL *stream;
@@ -179,6 +181,7 @@ camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host)
stream->priv->service = service;
stream->priv->expected_host = g_strdup (expected_host);
stream->priv->ssl_mode = TRUE;
+ stream->priv->flags = flags;
return CAMEL_STREAM (stream);
}
@@ -188,6 +191,7 @@ camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host)
* camel_tcp_stream_ssl_new_raw:
* @service: camel service
* @expected_host: host that the stream is expecting to connect with.
+ * @flags: flags
*
* Since the SSL certificate authenticator may need to prompt the
* user, a CamelService is needed. @expected_host is needed as a
@@ -196,7 +200,7 @@ camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host)
* Return value: a ssl-capable stream (in non ssl mode)
**/
CamelStream *
-camel_tcp_stream_ssl_new_raw (CamelService *service, const char *expected_host)
+camel_tcp_stream_ssl_new_raw (CamelService *service, const char *expected_host, guint32 flags)
{
CamelTcpStreamSSL *stream;
@@ -205,6 +209,7 @@ camel_tcp_stream_ssl_new_raw (CamelService *service, const char *expected_host)
stream->priv->service = service;
stream->priv->expected_host = g_strdup (expected_host);
stream->priv->ssl_mode = FALSE;
+ stream->priv->flags = flags;
return CAMEL_STREAM (stream);
}
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index 04dcb0d3c..cf6a1f539 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -25,14 +25,14 @@
#include <config.h>
#endif
+#include <stdio.h>
+#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
-#include <string.h>
#include "camel-tcp-stream-raw.h"
#include "camel-operation.h"