summaryrefslogtreecommitdiff
path: root/libmailutils
diff options
context:
space:
mode:
Diffstat (limited to 'libmailutils')
-rw-r--r--libmailutils/base/Makefile.am1
-rw-r--r--libmailutils/base/onexit.c99
-rw-r--r--libmailutils/stdstream/basestr.c37
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

Return to:

Send suggestions and report system problems to the System administrator.