diff options
author | Jeffrey Stedfast <fejj@ximian.com> | 2003-03-04 06:53:15 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2003-03-04 06:53:15 +0800 |
commit | a11414daf66216c29aa64147de4b4327176a06ad (patch) | |
tree | a3ac85bece6fc89f4cb47c256378dcc77a16d19c /camel | |
parent | 53457a736667fad6397ec6cf9f163ff5c64423c0 (diff) | |
download | gsoc2013-evolution-a11414daf66216c29aa64147de4b4327176a06ad.tar.gz gsoc2013-evolution-a11414daf66216c29aa64147de4b4327176a06ad.tar.zst gsoc2013-evolution-a11414daf66216c29aa64147de4b4327176a06ad.zip |
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?).
svn path=/trunk/; revision=20132
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 20 | ||||
-rw-r--r-- | camel/camel-io.c | 166 | ||||
-rw-r--r-- | camel/camel-io.h | 42 | ||||
-rw-r--r-- | camel/camel-process.c | 153 | ||||
-rw-r--r-- | camel/camel-process.h | 44 | ||||
-rw-r--r-- | camel/camel-tcp-stream-openssl.c | 9 | ||||
-rw-r--r-- | camel/camel-tcp-stream-raw.c | 4 |
7 files changed, 434 insertions, 4 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index c3fb16e43e..345a653cb8 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 0000000000..88ddcf692d --- /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 0000000000..a4e47c018f --- /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 0000000000..01c1e3be3d --- /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 0000000000..a87db24d5c --- /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 abd2e5d9c0..f83a6d0d72 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 04dcb0d3cb..cf6a1f539d 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" |