diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-12-11 01:16:33 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-12-11 11:06:48 +0200 |
commit | 5416e044b0995e3f49676152da15866fcf29d323 (patch) | |
tree | 7cb60898b934e573a0e3c0a299e458d76117c5e1 /libmailutils | |
parent | 1ef742582942bb2a7ef4ce8531cf3b306b3f82d7 (diff) | |
download | mailutils-5416e044b0995e3f49676152da15866fcf29d323.tar.gz mailutils-5416e044b0995e3f49676152da15866fcf29d323.tar.bz2 |
Implement mu_onexit functions; use MU stdstream in mh and mimeview.
* include/mailutils/types.hin (mu_onexit_t): New typedef.
* include/mailutils/util.h (mu_onexit_reset, mu_onexit): New protos.
* libmailutils/base/onexit.c: New file.
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Add onexit.c
* libmailutils/stdstream/basestr.c (stdstream_flushall): New function.
(mu_stdstream_setup): Rewrite the fd checking algorithm.
Register stdstream_flushall as an onexit function.
* mh/anno.c: Use MU stdstream.
* mh/mh.h: Include mailutils/stdstream.h.
* mh/mh_init.c (mh_init): Call mu_stdstream_setup; use MU stdstream.
* mh/mh_whatnow.c (_whatnow): Use MU stdstream.
* mh/mhl.c (open_output,list_message): Likewise.
* mh/mhn.c (mhn_show,store_handler): Likewise.
* pop3d/popauth.c: Use MU stdstream.
* mimeview/mimetypes.y: Use MU stdstream.
* mimeview/mimeview.c: Likewise.
(mimeview_fp): Remove.
(mimeview_stream): New variable.
* mimeview/mimeview.h (mimeview_fp): Remove.
(mimeview_stream): New variable.
* lib/mailcap.c (find_entry): Don't report ENOENT.
Diffstat (limited to 'libmailutils')
-rw-r--r-- | libmailutils/base/Makefile.am | 1 | ||||
-rw-r--r-- | libmailutils/base/onexit.c | 99 | ||||
-rw-r--r-- | libmailutils/stdstream/basestr.c | 37 |
3 files changed, 128 insertions, 9 deletions
diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am index 0fdc1a412..c2a49766f 100644 --- a/libmailutils/base/Makefile.am +++ b/libmailutils/base/Makefile.am @@ -49,6 +49,7 @@ libbase_la_SOURCES = \ nls.c\ nullrec.c\ observer.c\ + onexit.c\ opool.c\ parsedate.c\ permstr.c\ diff --git a/libmailutils/base/onexit.c b/libmailutils/base/onexit.c new file mode 100644 index 000000000..81193ee10 --- /dev/null +++ b/libmailutils/base/onexit.c @@ -0,0 +1,99 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <unistd.h> +#include <stdlib.h> +#include <mailutils/types.h> +#include <mailutils/errno.h> +#include <mailutils/error.h> +#include <mailutils/list.h> +#include <mailutils/iterator.h> +#include <mailutils/nls.h> +#include <mailutils/stream.h> +#include <mailutils/stdstream.h> + +struct onexit_closure +{ + mu_onexit_t function; + void *data; +}; + +static mu_list_t onexit_list; + +void +_mu_onexit_run (void) +{ + mu_iterator_t itr; + int rc, status = 0; + + rc = mu_list_get_iterator (onexit_list, &itr); + if (rc) + { + mu_error (_("cannot create iterator, onexit aborted: %s"), + mu_strerror (rc)); + mu_stream_destroy (&mu_strerr); + _exit (127); + } + + for (mu_iterator_first (itr); !mu_iterator_is_done (itr); + mu_iterator_next (itr)) + { + struct onexit_closure *cp; + int rc = mu_iterator_current (itr, (void**)&cp); + if (rc) + { + status = 127; + mu_error (_("cannot obtain current item while traversing the" + " onexit action list: %s"), mu_strerror (rc)); + } + else + cp->function (cp->data); + mu_iterator_ctl (itr, mu_itrctl_delete, NULL); + } + mu_iterator_destroy (&itr); + mu_list_destroy (&onexit_list); + if (status) + _exit (status); +} + +int +mu_onexit (mu_onexit_t func, void *data) +{ + struct onexit_closure *clos = malloc (sizeof (*clos)); + if (!clos) + return ENOMEM; + clos->function = func; + clos->data = data; + if (!onexit_list) + { + int rc = mu_list_create (&onexit_list); + mu_list_set_destroy_item (onexit_list, mu_list_free_item); + if (rc) + return rc; + atexit (_mu_onexit_run); + } + return mu_list_append (onexit_list, clos); +} + +void +mu_onexit_reset (void) +{ + mu_list_clear (onexit_list); +} diff --git a/libmailutils/stdstream/basestr.c b/libmailutils/stdstream/basestr.c index ea9479f10..a845927a8 100644 --- a/libmailutils/stdstream/basestr.c +++ b/libmailutils/stdstream/basestr.c @@ -27,11 +27,20 @@ #include <mailutils/log.h> #include <mailutils/stream.h> #include <mailutils/stdstream.h> +#include <mailutils/util.h> mu_stream_t mu_strin; mu_stream_t mu_strout; mu_stream_t mu_strerr; +static void +stdstream_flushall (void *data MU_ARG_UNUSED) +{ + mu_stream_flush (mu_strin); + mu_stream_flush (mu_strout); + mu_stream_flush (mu_strerr); +} + void mu_stdstream_setup () { @@ -44,20 +53,30 @@ mu_stdstream_setup () mu_stream_destroy (&mu_strerr); /* Ensure that first 3 descriptors are open in proper mode */ - fd = open ("/dev/null", O_WRONLY); + fd = open ("/dev/null", O_RDWR); switch (fd) { - case 2: - /* keep it open */; - break; + case 0: + /* Keep it and try to open 1 */ + fd = open ("/dev/null", O_WRONLY); + if (fd != 1) + { + if (fd > 2) + close (fd); + break; + } case 1: - /* keep it open and try 0 */ - fd = open ("/dev/null", O_RDONLY); - if (fd != 0) + /* keep it open and try 2 */ + fd = open ("/dev/null", O_WRONLY); + if (fd != 2) close (fd); break; - + + case 2: + /* keep it open */; + break; + default: close (fd); break; @@ -82,7 +101,7 @@ mu_stdstream_setup () if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0, mu_program_name, NULL)) abort (); - /* FIXME: atexit (flushall) */ + mu_onexit (stdstream_flushall, NULL); } int |