summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2017-11-29 20:22:06 +0100
committerWerner Koch <wk@gnupg.org>2017-11-29 20:22:06 +0100
commitadc786d034b63176b941a1ef8d996acbf8d0ea5d (patch)
treeb19d82491cc7666f18cb44d2f7458f2f28fbe936
parent1865c0ba1769b407a3c504f1ab0a4278704a9fc1 (diff)
downloadlibgpg-error-adc786d034b63176b941a1ef8d996acbf8d0ea5d.tar.gz
core: Unify syscall_clamp functions.
* src/estream.c (_gpgrt_set_syscall_clamp) (_gpgrt_get_syscall_clamp): Move to ... * src/syscall-clamp.c: new file. (_gpgrt_pre_syscall, _gpgrt_post_syscall): New. * src/Makefile.am (libgpg_error_la_SOURCES): Add that file. * src/estream.c: Replace the syscall wrapper with the new functions. * src/posix-lock.c: Ditto. * src/w32-lock.c: Ditto. * src/posix-thread.c: Ditto. * src/w32-thread.c: Ditto. Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--src/Makefile.am1
-rw-r--r--src/estream.c124
-rw-r--r--src/gpgrt-int.h3
-rw-r--r--src/lock.h2
-rw-r--r--src/posix-lock.c37
-rw-r--r--src/posix-thread.c35
-rw-r--r--src/syscall-clamp.c80
-rw-r--r--src/thread.h2
-rw-r--r--src/w32-lock.c31
-rw-r--r--src/w32-thread.c26
10 files changed, 138 insertions, 203 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ac13e70..4446612 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -187,6 +187,7 @@ libgpg_error_la_SOURCES = gettext.h $(arch_sources) \
strsource.c strerror.c code-to-errno.c code-from-errno.c \
visibility.c visibility.h \
sysutils.c \
+ syscall-clamp.c \
logging.c \
b64dec.c
diff --git a/src/estream.c b/src/estream.c
index 2f29cdb..dd2b289 100644
--- a/src/estream.c
+++ b/src/estream.c
@@ -201,14 +201,6 @@ GPGRT_LOCK_DEFINE (estream_list_lock);
/*
- * Functions called before and after blocking syscalls.
- * gpgrt_set_syscall_clamp is used to set them.
- */
-static void (*pre_syscall_func)(void);
-static void (*post_syscall_func)(void);
-
-
-/*
* Error code replacements.
*/
#ifndef EOPNOTSUPP
@@ -491,7 +483,7 @@ do_list_remove (estream_t stream, int with_locked_list)
/*
- * The atexit handler for this estream module.
+ * The atexit handler for the entire gpgrt.
*/
static void
do_deinit (void)
@@ -508,10 +500,7 @@ do_deinit (void)
we keep the list and let the OS clean it up at process end. */
/* Reset the syscall clamp. */
- pre_syscall_func = NULL;
- post_syscall_func = NULL;
- _gpgrt_thread_set_syscall_clamp (NULL, NULL);
- _gpgrt_lock_set_lock_clamp (NULL, NULL);
+ _gpgrt_set_syscall_clamp (NULL, NULL);
}
@@ -531,37 +520,6 @@ _gpgrt_estream_init (void)
return 0;
}
-/*
- * Register the syscall clamp. These two functions are called
- * immediately before and after a possible blocking system call. This
- * should be used before any I/O happens. The function is commonly
- * used with the nPth library:
- *
- * gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
- *
- * These functions may not modify ERRNO.
- */
-void
-_gpgrt_set_syscall_clamp (void (*pre)(void), void (*post)(void))
-{
- pre_syscall_func = pre;
- post_syscall_func = post;
- _gpgrt_thread_set_syscall_clamp (pre, post);
- _gpgrt_lock_set_lock_clamp (pre, post);
-}
-
-/*
- * Return the current sycall clamp functions. This can be used by
- * other libraries which have blocking functions.
- */
-void
-_gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void))
-{
- *r_pre = pre_syscall_func;
- *r_post = post_syscall_func;
-}
-
-
/*
* Implementation of memory based I/O.
@@ -971,15 +929,13 @@ func_fd_read (void *cookie, void *buffer, size_t size)
}
else
{
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
do
{
bytes_read = read (file_cookie->fd, buffer, size);
}
while (bytes_read == -1 && errno == EINTR);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
}
trace_errno (bytes_read == -1, ("leave: bytes_read=%d", (int)bytes_read));
@@ -1005,15 +961,13 @@ func_fd_write (void *cookie, const void *buffer, size_t size)
}
else if (buffer)
{
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
do
{
bytes_written = write (file_cookie->fd, buffer, size);
}
while (bytes_written == -1 && errno == EINTR);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
}
else
bytes_written = size; /* Note that for a flush SIZE should be 0. */
@@ -1041,11 +995,9 @@ func_fd_seek (void *cookie, gpgrt_off_t *offset, int whence)
}
else
{
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
offset_new = lseek (file_cookie->fd, *offset, whence);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
if (offset_new == -1)
err = -1;
else
@@ -1216,8 +1168,8 @@ func_w32_read (void *cookie, void *buffer, size_t size)
}
else
{
- if (pre_syscall_func && !w32_cookie->no_syscall_clamp)
- pre_syscall_func ();
+ if (!w32_cookie->no_syscall_clamp)
+ _gpgrt_pre_syscall ();
do
{
DWORD nread, ec;
@@ -1239,8 +1191,8 @@ func_w32_read (void *cookie, void *buffer, size_t size)
bytes_read = (int)nread;
}
while (bytes_read == -1 && errno == EINTR);
- if (post_syscall_func && !w32_cookie->no_syscall_clamp)
- post_syscall_func ();
+ if (!w32_cookie->no_syscall_clamp)
+ _gpgrt_post_syscall ();
}
trace_errno (bytes_read==-1,("leave: bytes_read=%d", (int)bytes_read));
@@ -1269,8 +1221,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size)
}
else if (buffer)
{
- if (pre_syscall_func && !w32_cookie->no_syscall_clamp)
- pre_syscall_func ();
+ if (!w32_cookie->no_syscall_clamp)
+ _gpgrt_pre_syscall ();
do
{
DWORD nwritten;
@@ -1287,8 +1239,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size)
bytes_written = (int)nwritten;
}
while (bytes_written == -1 && errno == EINTR);
- if (post_syscall_func && !w32_cookie->no_syscall_clamp)
- post_syscall_func ();
+ if (!w32_cookie->no_syscall_clamp)
+ _gpgrt_post_syscall ();
}
else
bytes_written = size; /* Note that for a flush SIZE should be 0. */
@@ -1338,17 +1290,16 @@ func_w32_seek (void *cookie, gpgrt_off_t *offset, int whence)
#ifdef HAVE_W32CE_SYSTEM
# warning need to use SetFilePointer
#else
- if (pre_syscall_func && !w32_cookie->no_syscall_clamp)
- pre_syscall_func ();
+ if (!w32_cookie->no_syscall_clamp)
+ _gpgrt_pre_syscall ();
if (!SetFilePointerEx (w32_cookie->hd, distance, &newoff, method))
{
_set_errno (map_w32_to_errno (GetLastError ()));
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
return -1;
}
- if (post_syscall_func && !w32_cookie->no_syscall_clamp)
- post_syscall_func ();
+ if (!w32_cookie->no_syscall_clamp)
+ _gpgrt_post_syscall ();
#endif
/* Note that gpgrt_off_t is always 64 bit. */
*offset = (gpgrt_off_t)newoff.QuadPart;
@@ -1473,11 +1424,9 @@ func_fp_read (void *cookie, void *buffer, size_t size)
if (file_cookie->fp)
{
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
bytes_read = fread (buffer, 1, size, file_cookie->fp);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
}
else
bytes_read = 0;
@@ -1498,8 +1447,7 @@ func_fp_write (void *cookie, const void *buffer, size_t size)
if (file_cookie->fp)
{
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
if (buffer)
{
#ifdef HAVE_W32_SYSTEM
@@ -1527,8 +1475,7 @@ func_fp_write (void *cookie, const void *buffer, size_t size)
bytes_written = size;
fflush (file_cookie->fp);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
}
else
bytes_written = size; /* Successfully written to the bit bucket. */
@@ -1554,20 +1501,17 @@ func_fp_seek (void *cookie, gpgrt_off_t *offset, int whence)
return -1;
}
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
if ( fseek (file_cookie->fp, (long int)*offset, whence) )
{
/* fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", */
/* errno,strerror (errno)); */
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
return -1;
}
offset_new = ftell (file_cookie->fp);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
if (offset_new == -1)
{
/* fprintf (stderr, "\nftell failed: errno=%d (%s)\n", */
@@ -1592,11 +1536,9 @@ func_fp_destroy (void *cookie)
{
if (fp_cookie->fp)
{
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
fflush (fp_cookie->fp);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp);
}
else
@@ -4909,8 +4851,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
}
}
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
do
{
struct timeval timeout_val;
@@ -4924,8 +4865,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
timeout == -1 ? NULL : &timeout_val);
}
while (ret == -1 && errno == EINTR);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
if (ret == -1)
{
diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index 2413257..fcce082 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -124,7 +124,8 @@ char *_gpgrt_strconcat_core (const char *s1, va_list arg_ptr);
#define xtryrealloc(a,b) _gpgrt_realloc ((a),(b))
#define xtrystrdup(a) _gpgrt_strdup ((a))
-
+void _gpgrt_pre_syscall (void);
+void _gpgrt_post_syscall (void);
const char *_gpg_error_check_version (const char *req_version);
diff --git a/src/lock.h b/src/lock.h
index b7395db..a830b36 100644
--- a/src/lock.h
+++ b/src/lock.h
@@ -20,7 +20,5 @@
#ifndef LOCK_H
#define LOCK_H
-void _gpgrt_lock_set_lock_clamp (void (*pre)(void), void (*post)(void));
-
#endif /*LOCK_H*/
diff --git a/src/posix-lock.c b/src/posix-lock.c
index d251d2f..b5e6916 100644
--- a/src/posix-lock.c
+++ b/src/posix-lock.c
@@ -39,19 +39,11 @@
# include <pthread.h>
#endif
-#include "gpg-error.h"
+#include "gpgrt-int.h"
#include "lock.h"
#include "posix-lock-obj.h"
-/*
- * Functions called before and after blocking syscalls.
- * gpgrt_set_syscall_clamp is used to set them.
- */
-static void (*pre_lock_func)(void);
-static void (*post_lock_func)(void);
-
-
#if USE_POSIX_THREADS
# if USE_POSIX_THREADS_WEAK
/* On ELF systems it is easy to use pthreads using weak
@@ -111,17 +103,6 @@ use_pthread_p (void)
#endif /*USE_POSIX_THREADS*/
-/* Helper to set the clamp functions. This is called as a helper from
- * _gpgrt_set_syscall_clamp to keep the function pointers local. */
-void
-_gpgrt_lock_set_lock_clamp (void (*pre)(void), void (*post)(void))
-{
- pre_lock_func = pre;
- post_lock_func = post;
-}
-
-
-
static _gpgrt_lock_t *
get_lock_object (gpgrt_lock_t *lockhd)
{
@@ -168,7 +149,7 @@ _gpgrt_lock_init (gpgrt_lock_t *lockhd)
{
rc = pthread_mutex_init (&lock->u.mtx, NULL);
if (rc)
- rc = gpg_err_code_from_errno (rc);
+ rc = _gpg_err_code_from_errno (rc);
}
else
rc = 0; /* Threads are not used. */
@@ -189,13 +170,11 @@ _gpgrt_lock_lock (gpgrt_lock_t *lockhd)
#if USE_POSIX_THREADS
if (use_pthread_p())
{
- if (pre_lock_func)
- pre_lock_func ();
+ _gpgrt_pre_syscall ();
rc = pthread_mutex_lock (&lock->u.mtx);
if (rc)
- rc = gpg_err_code_from_errno (rc);
- if (post_lock_func)
- post_lock_func ();
+ rc = _gpg_err_code_from_errno (rc);
+ _gpgrt_post_syscall ();
}
else
rc = 0; /* Threads are not used. */
@@ -218,7 +197,7 @@ _gpgrt_lock_trylock (gpgrt_lock_t *lockhd)
{
rc = pthread_mutex_trylock (&lock->u.mtx);
if (rc)
- rc = gpg_err_code_from_errno (rc);
+ rc = _gpg_err_code_from_errno (rc);
}
else
rc = 0; /* Threads are not used. */
@@ -241,7 +220,7 @@ _gpgrt_lock_unlock (gpgrt_lock_t *lockhd)
{
rc = pthread_mutex_unlock (&lock->u.mtx);
if (rc)
- rc = gpg_err_code_from_errno (rc);
+ rc = _gpg_err_code_from_errno (rc);
}
else
rc = 0; /* Threads are not used. */
@@ -266,7 +245,7 @@ _gpgrt_lock_destroy (gpgrt_lock_t *lockhd)
{
rc = pthread_mutex_destroy (&lock->u.mtx);
if (rc)
- rc = gpg_err_code_from_errno (rc);
+ rc = _gpg_err_code_from_errno (rc);
else
{
/* Re-init the mutex so that it can be re-used. */
diff --git a/src/posix-thread.c b/src/posix-thread.c
index 00a43e2..36c81ba 100644
--- a/src/posix-thread.c
+++ b/src/posix-thread.c
@@ -39,27 +39,10 @@
# include <thread.h>
#endif
-#include "gpg-error.h"
+#include "gpgrt-int.h"
#include "thread.h"
-/*
- * Functions called before and after blocking syscalls.
- * gpgrt_set_syscall_clamp is used to set them.
- */
-static void (*pre_syscall_func)(void);
-static void (*post_syscall_func)(void);
-
-
-/* Helper to set the clamp functions. This is called as a helper from
- * _gpgrt_set_syscall_clamp to keep the function pointers local. */
-void
-_gpgrt_thread_set_syscall_clamp (void (*pre)(void), void (*post)(void))
-{
- pre_syscall_func = pre;
- post_syscall_func = post;
-}
-
gpg_err_code_t
@@ -67,20 +50,16 @@ _gpgrt_yield (void)
{
#if USE_POSIX_THREADS
# ifdef _POSIX_PRIORITY_SCHEDULING
- if (pre_syscall_func)
- pre_syscall_func ();
- sched_yield ();
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_pre_syscall ();
+ sched_yield ();
+ _gpgrt_post_syscall ();
# else
- return GPG_ERR_NOT_SUPPORTED;
+ return GPG_ERR_NOT_SUPPORTED;
# endif
#elif USE_SOLARIS_THREADS
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
thr_yield ();
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
#else
return GPG_ERR_NOT_SUPPORTED;
#endif
diff --git a/src/syscall-clamp.c b/src/syscall-clamp.c
new file mode 100644
index 0000000..99748f4
--- /dev/null
+++ b/src/syscall-clamp.c
@@ -0,0 +1,80 @@
+/* syscall-clamp.c - Syscall clamp related stuff
+ * Copyright (C) 2016, 2017 g10 Code GmbH
+ *
+ * This file is part of Libgpg-error.
+ *
+ * Libgpg-error 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 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgpg-error 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 this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include <config.h>
+
+#include "gpgrt-int.h"
+
+/*
+ * Functions called before and after blocking syscalls.
+ * gpgrt_set_syscall_clamp is used to set them.
+ */
+static void (*pre_syscall_func)(void);
+static void (*post_syscall_func)(void);
+
+
+/*
+ * Register the syscall clamp. These two functions are called
+ * immediately before and after a possible blocking system call. This
+ * should be used before any I/O happens. The function is commonly
+ * used with the nPth library:
+ *
+ * gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
+ *
+ * These functions may not modify ERRNO.
+ *
+ * Setting the clamp is not thread-safe and should thus be done as
+ * early as possible.
+ */
+void
+_gpgrt_set_syscall_clamp (void (*pre)(void), void (*post)(void))
+{
+ pre_syscall_func = pre;
+ post_syscall_func = post;
+}
+
+/*
+ * Return the current sycall clamp functions. This can be used by
+ * other libraries which have blocking functions.
+ */
+void
+_gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void))
+{
+ *r_pre = pre_syscall_func;
+ *r_post = post_syscall_func;
+}
+
+
+/* Call this function before a blocking system or libc call. */
+void
+_gpgrt_pre_syscall (void)
+{
+ if (pre_syscall_func)
+ pre_syscall_func ();
+}
+
+
+/* Call this function after a blocking system or libc call. */
+void
+_gpgrt_post_syscall (void)
+{
+ if (post_syscall_func)
+ post_syscall_func ();
+}
diff --git a/src/thread.h b/src/thread.h
index f064cce..c650a99 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -20,7 +20,5 @@
#ifndef THREAD_H
#define THREAD_H
-void _gpgrt_thread_set_syscall_clamp (void (*pre)(void), void (*post)(void));
-
#endif /*THREAD_H*/
diff --git a/src/w32-lock.c b/src/w32-lock.c
index 51b13a1..a55f932 100644
--- a/src/w32-lock.c
+++ b/src/w32-lock.c
@@ -29,34 +29,15 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
-#include <gpg-error.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include "gpgrt-int.h"
#include "lock.h"
#include "w32-lock-obj.h"
-/*
- * Functions called before and after blocking syscalls.
- * gpgrt_set_syscall_clamp is used to set them.
- */
-static void (*pre_lock_func)(void);
-static void (*post_lock_func)(void);
-
-
-/* Helper to set the clamp functions. This is called as a helper from
- * _gpgrt_set_syscall_clamp to keep the function pointers local. */
-void
-_gpgrt_lock_set_lock_clamp (void (*pre)(void), void (*post)(void))
-{
- pre_lock_func = pre;
- post_lock_func = post;
-}
-
-
-
static _gpgrt_lock_t *
get_lock_object (gpgrt_lock_t *lockhd)
{
@@ -112,7 +93,7 @@ _gpgrt_lock_lock (gpgrt_lock_t *lockhd)
and thus fall into the wait loop below. We ignore that
STARTED may in theory overflow if this thread starves for
too long. */
- gpgrt_lock_init (lockhd);
+ _gpgrt_lock_init (lockhd);
}
else
{
@@ -121,11 +102,9 @@ _gpgrt_lock_lock (gpgrt_lock_t *lockhd)
}
}
- if (pre_lock_func)
- pre_lock_func ();
+ _gpgrt_pre_syscall ();
EnterCriticalSection (&lock->csec);
- if (post_lock_func)
- post_lock_func ();
+ _gpgrt_post_syscall ();
return 0;
}
@@ -139,7 +118,7 @@ _gpgrt_lock_trylock (gpgrt_lock_t *lockhd)
{
if (!InterlockedIncrement (&lock->started))
{
- gpgrt_lock_init (lockhd);
+ _gpgrt_lock_init (lockhd);
}
else
{
diff --git a/src/w32-thread.c b/src/w32-thread.c
index aef421f..c389635 100644
--- a/src/w32-thread.c
+++ b/src/w32-thread.c
@@ -29,38 +29,18 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
-#include <gpg-error.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include "gpgrt-int.h"
#include "thread.h"
-/*
- * Functions called before and after blocking syscalls.
- * gpgrt_set_syscall_clamp is used to set them.
- */
-static void (*pre_syscall_func)(void);
-static void (*post_syscall_func)(void);
-
-
-/* Helper to set the clamp functions. This is called as a helper from
- * _gpgrt_set_syscall_clamp to keep the function pointers local. */
-void
-_gpgrt_thread_set_syscall_clamp (void (*pre)(void), void (*post)(void))
-{
- pre_syscall_func = pre;
- post_syscall_func = post;
-}
-
-
gpg_err_code_t
_gpgrt_yield (void)
{
- if (pre_syscall_func)
- pre_syscall_func ();
+ _gpgrt_pre_syscall ();
Sleep (0);
- if (post_syscall_func)
- post_syscall_func ();
+ _gpgrt_post_syscall ();
return 0;
}