diff --git a/legacy/CMakeLists.txt b/legacy/CMakeLists.txt index 42dd94df1..7485cb456 100644 --- a/legacy/CMakeLists.txt +++ b/legacy/CMakeLists.txt @@ -123,36 +123,6 @@ target_link_libraries(assuan-test PRIVATE GTest::GTest GTest::Main) add_test(AssuanTest assuan-test COMMAND assuan-test test_xml_output --gtest_output=xml:assuan-test.xml) -# npth - -add_library(npth - npth/src/npth.h - npth/src/npth.cpp -) -add_library(neopg::npth ALIAS npth) - -target_include_directories(npth PRIVATE - npth/src - ${CMAKE_BINARY_DIR}/.) -target_compile_definitions(npth PRIVATE - HAVE_CONFIG_H=1) - -target_compile_options(npth PRIVATE -fpermissive -) - -add_executable(npth-test - npth/tests/t-mutex.cpp - npth/tests/t-support.h - npth/tests/t-thread.cpp - npth/tests/npth-test.cpp) -target_include_directories(npth-test PRIVATE - npth/src - ${CMAKE_BINARY_DIR}/.) -target_link_libraries(npth-test PRIVATE - npth - GTest::GTest GTest::Main) -add_test(nPthTest npth-test COMMAND npth-test test_xml_output --gtest_output=xml:npth-test.xml) - # libgcrypt add_library(gcrypt diff --git a/legacy/gnupg/agent/cache.cpp b/legacy/gnupg/agent/cache.cpp index 97756e246..52661b852 100644 --- a/legacy/gnupg/agent/cache.cpp +++ b/legacy/gnupg/agent/cache.cpp @@ -19,8 +19,9 @@ #include +#include + #include -#include #include #include #include @@ -43,7 +44,7 @@ static const size_t ENCRYPTION_KEYSIZE = 128 / 8; static Botan::SymmetricKey *encryption_handle; /* A mutex used to serialize access to the cache. */ -static npth_mutex_t cache_lock; +static std::mutex cache_lock; struct secret_data_s { int totallen; /* This includes the padding and space for AESWRAP. */ @@ -67,16 +68,6 @@ static ITEM thecache; /* NULL or the last cache key stored by agent_store_cache_hit. */ static char *last_stored_cache_key; -/* This function must be called once to initialize this module. It - has to be done before a second thread is spawned. */ -void initialize_module_cache(void) { - int err; - - err = npth_mutex_init(&cache_lock, NULL); - - if (err) log_fatal("error initializing cache module: %s\n", strerror(err)); -} - void deinitialize_module_cache(void) { delete encryption_handle; encryption_handle = NULL; @@ -211,8 +202,7 @@ void agent_flush_cache(void) { if (DBG_CACHE) log_debug("agent_flush_cache\n"); - res = npth_mutex_lock(&cache_lock); - if (res) log_fatal("failed to acquire cache mutex: %s\n", strerror(res)); + std::lock_guard lock(cache_lock); for (r = thecache; r; r = r->next) { if (r->pw) { @@ -222,9 +212,6 @@ void agent_flush_cache(void) { r->accessed = 0; } } - - res = npth_mutex_unlock(&cache_lock); - if (res) log_fatal("failed to release cache mutex: %s\n", strerror(res)); } /* Compare two cache modes. */ @@ -246,8 +233,7 @@ int agent_put_cache(const char *key, cache_mode_t cache_mode, const char *data, ITEM r; int res; - res = npth_mutex_lock(&cache_lock); - if (res) log_fatal("failed to acquire cache mutex: %s\n", strerror(res)); + std::lock_guard lock(cache_lock); if (DBG_CACHE) log_debug("agent_put_cache '%s' (mode %d) requested ttl=%d\n", key, @@ -298,9 +284,6 @@ int agent_put_cache(const char *key, cache_mode_t cache_mode, const char *data, } out: - res = npth_mutex_unlock(&cache_lock); - if (res) log_fatal("failed to release cache mutex: %s\n", strerror(res)); - return err; } @@ -316,8 +299,7 @@ char *agent_get_cache(const char *key, cache_mode_t cache_mode) { if (cache_mode == CACHE_MODE_IGNORE) return NULL; - res = npth_mutex_lock(&cache_lock); - if (res) log_fatal("failed to acquire cache mutex: %s\n", strerror(res)); + std::lock_guard lock(cache_lock); if (!key) { key = last_stored_cache_key; @@ -365,9 +347,6 @@ char *agent_get_cache(const char *key, cache_mode_t cache_mode) { if (DBG_CACHE && value == NULL) log_debug("... miss\n"); out: - res = npth_mutex_unlock(&cache_lock); - if (res) log_fatal("failed to release cache mutex: %s\n", strerror(res)); - return value; } diff --git a/legacy/gnupg/agent/call-pinentry.cpp b/legacy/gnupg/agent/call-pinentry.cpp index 97e311c88..fd0565f42 100644 --- a/legacy/gnupg/agent/call-pinentry.cpp +++ b/legacy/gnupg/agent/call-pinentry.cpp @@ -32,7 +32,6 @@ #include #include #endif -#include #include #include "../common/sysutils.h" @@ -62,18 +61,6 @@ static struct { unsigned int tabbing : 1; } entry_features; -/* The control variable of the connection owning the current pinentry. - This is only valid if ENTRY_CTX is not NULL. Note, that we care - only about the value of the pointer and that it should never be - dereferenced. */ -static ctrl_t entry_owner; - -/* A mutex used to serialize access to the pinentry. */ -static npth_mutex_t entry_lock; - -/* The thread ID of the popup working thread. */ -static npth_t popup_tid; - /* A flag used in communication between the popup working thread and its stop function. */ static int popup_finished; @@ -85,126 +72,18 @@ struct entry_parm_s { unsigned char *buffer; }; -/* This function must be called once to initialize this module. This - has to be done before a second thread is spawned. We can't do the - static initialization because Pth emulation code might not be able - to do a static init; in particular, it is not possible for W32. */ -void initialize_module_call_pinentry(void) { - static int initialized; - - if (!initialized) { - if (npth_mutex_init(&entry_lock, NULL)) initialized = 1; - } -} - /* This function may be called to print information pertaining to the current state of this module to the log. */ void agent_query_dump_state(void) { - log_info("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n", - entry_ctx, (long)assuan_get_pid(entry_ctx), (void *)popup_tid); + log_info("agent_query_dump_state: entry_ctx=%p pid=%ld\n", + entry_ctx, (long)assuan_get_pid(entry_ctx)); } /* Called to make sure that a popup window owned by the current connection gets closed. */ void agent_reset_query(ctrl_t ctrl) { - if (entry_ctx && popup_tid && entry_owner == ctrl) { - agent_popup_message_stop(ctrl); - } -} - -/* Unlock the pinentry so that another thread can start one and - disconnect that pinentry - we do this after the unlock so that a - stalled pinentry does not block other threads. Fixme: We should - have a timeout in Assuan for the disconnect operation. */ -static gpg_error_t unlock_pinentry(gpg_error_t rc) { - assuan_context_t ctx = entry_ctx; - int err; - - if (rc) { - if (DBG_IPC) log_debug("error calling pinentry: %s\n", gpg_strerror(rc)); - } - - entry_ctx = NULL; - err = npth_mutex_unlock(&entry_lock); - if (err) { - log_error("failed to release the entry lock: %s\n", strerror(err)); - if (!rc) rc = gpg_error_from_errno(err); - } - assuan_release(ctx); - return rc; -} - -/* Status line callback for the FEATURES status. */ -static gpg_error_t getinfo_features_cb(void *opaque, const char *line) { - const char *args; - char **tokens; - int i; - - (void)opaque; - - if ((args = has_leading_keyword(line, "FEATURES"))) { - tokens = strtokenize(args, " "); - if (!tokens) return gpg_error_from_syserror(); - for (i = 0; tokens[i]; i++) - if (!strcmp(tokens[i], "tabbing")) entry_features.tabbing = 1; - xfree(tokens); - } - - return 0; -} - -static gpg_error_t getinfo_pid_cb(void *opaque, const void *buffer, - size_t length) { - unsigned long *pid = (long unsigned int *)opaque; - char pidbuf[50]; - - /* There is only the pid in the server's response. */ - if (length >= sizeof pidbuf) length = sizeof pidbuf - 1; - if (length) { - strncpy(pidbuf, (const char *)(buffer), length); - pidbuf[length] = 0; - *pid = strtoul(pidbuf, NULL, 10); - } - return 0; -} - -enum { - PINENTRY_STATUS_CLOSE_BUTTON = 1 << 0, - PINENTRY_STATUS_PIN_REPEATED = 1 << 8, - PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9 -}; - -/* Check the button_info line for a close action. Also check for the - PIN_REPEATED flag. */ -static gpg_error_t pinentry_status_cb(void *opaque, const char *line) { - unsigned int *flag = (unsigned int *)opaque; - const char *args; - - if ((args = has_leading_keyword(line, "BUTTON_INFO"))) { - if (!strcmp(args, "close")) *flag |= PINENTRY_STATUS_CLOSE_BUTTON; - } else if (has_leading_keyword(line, "PIN_REPEATED")) { - *flag |= PINENTRY_STATUS_PIN_REPEATED; - } else if (has_leading_keyword(line, "PASSWORD_FROM_CACHE")) { - *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE; - } - - return 0; } -/* Build a SETDESC command line. This is a dedicated function so that - * it can remove control characters which are not supported by the - * current Pinentry. */ -static void build_cmd_setdesc(char *line, size_t linelen, const char *desc) { - char *src, *dst; - - snprintf(line, linelen, "SETDESC %s", desc); - if (!entry_features.tabbing) { - /* Remove RS and US. */ - for (src = dst = line; *src; src++) - if (!strchr("\x1e\x1f", *src)) *dst++ = *src; - *dst = 0; - } -} /* Call the Entry and ask for the PIN. We do check for a valid PIN number here and repeat it as long as we have invalid formed @@ -215,13 +94,6 @@ gpg_error_t agent_askpin(ctrl_t ctrl, const char *desc_text, struct pin_entry_info_s *pininfo, const char *keyinfo, cache_mode_t cache_mode) { gpg_error_t rc; - char line[ASSUAN_LINELENGTH]; - struct entry_parm_s parm; - const char *errtext = NULL; - int is_pin = 0; - int saveflag; - unsigned int pinentry_status; - if (opt.batch) return 0; /* fixme: we should return BAD PIN */ { @@ -243,176 +115,6 @@ gpg_error_t agent_askpin(ctrl_t ctrl, const char *desc_text, } return rc; } - -#if 0 - if (!pininfo || pininfo->max_length < 1) - return GPG_ERR_INV_VALUE; - if (!desc_text && pininfo->min_digits) - desc_text = L_("Please enter your PIN, so that the secret key " - "can be unlocked for this session"); - else if (!desc_text) - desc_text = L_("Please enter your passphrase, so that the secret key " - "can be unlocked for this session"); - - if (prompt_text) - is_pin = !!strstr (prompt_text, "PIN"); - else - is_pin = desc_text && strstr (desc_text, "PIN"); - - rc = start_pinentry (ctrl); - if (rc) - return rc; - - /* If we have a KEYINFO string and are normal, user, or ssh cache - mode, we tell that the Pinentry so it may use it for own caching - purposes. Most pinentries won't have this implemented and thus - we do not error out in this case. */ - if (keyinfo && (cache_mode == CACHE_MODE_NORMAL - || cache_mode == CACHE_MODE_USER - || cache_mode == CACHE_MODE_SSH)) - snprintf (line, DIM(line), "SETKEYINFO %c/%s", - cache_mode == CACHE_MODE_USER? 'u' : - cache_mode == CACHE_MODE_SSH? 's' : 'n', - keyinfo); - else - snprintf (line, DIM(line), "SETKEYINFO --clear"); - - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc && rc != GPG_ERR_ASS_UNKNOWN_CMD) - return unlock_pinentry (rc); - - build_cmd_setdesc (line, DIM(line), desc_text); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - - snprintf (line, DIM(line), "SETPROMPT %s", - prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:")); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - - if (initial_errtext) - { - snprintf (line, DIM(line), "SETERROR %s", initial_errtext); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - } - - if (pininfo->with_repeat) - { - snprintf (line, DIM(line), "SETREPEATERROR %s", - L_("does not match - try again")); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - pininfo->with_repeat = 0; /* Pinentry does not support it. */ - } - pininfo->repeat_okay = 0; - - for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++) - { - memset (&parm, 0, sizeof parm); - parm.size = pininfo->max_length; - *pininfo->pin = 0; /* Reset the PIN. */ - parm.buffer = (unsigned char*)pininfo->pin; - - if (errtext) - { - /* TRANSLATORS: The string is appended to an error message in - the pinentry. The %s is the actual error message, the - two %d give the current and maximum number of tries. */ - snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"), - errtext, pininfo->failed_tries+1, pininfo->max_tries); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - errtext = NULL; - } - - if (pininfo->with_repeat) - { - snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:")); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - } - - saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); - assuan_begin_confidential (entry_ctx); - pinentry_status = 0; - rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, - NULL, entry_ctx, - pinentry_status_cb, &pinentry_status); - assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); - /* Most pinentries out in the wild return the old Assuan error code - for canceled which gets translated to an assuan Cancel error and - not to the code for a user cancel. Fix this here. */ - if (rc == GPG_ERR_ASS_CANCELED) - rc = GPG_ERR_CANCELED; - - - /* Change error code in case the window close button was clicked - to cancel the operation. */ - if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON) - && rc == GPG_ERR_CANCELED) - rc = GPG_ERR_FULLY_CANCELED; - - if (rc == GPG_ERR_ASS_TOO_MUCH_DATA) - errtext = is_pin? L_("PIN too long") - : L_("Passphrase too long"); - else if (rc) - return unlock_pinentry (rc); - - if (!errtext && pininfo->min_digits) - { - /* do some basic checks on the entered PIN. */ - if (!all_digitsp (pininfo->pin)) - errtext = L_("Invalid characters in PIN"); - else if (pininfo->max_digits - && strlen (pininfo->pin) > pininfo->max_digits) - errtext = L_("PIN too long"); - else if (strlen (pininfo->pin) < pininfo->min_digits) - errtext = L_("PIN too short"); - } - - if (!errtext && pininfo->check_cb) - { - /* More checks by utilizing the optional callback. */ - pininfo->cb_errtext = NULL; - rc = pininfo->check_cb (pininfo); - if (rc == GPG_ERR_BAD_PASSPHRASE - && pininfo->cb_errtext) - errtext = pininfo->cb_errtext; - else if (rc == GPG_ERR_BAD_PASSPHRASE - || rc == GPG_ERR_BAD_PIN) - errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase")); - else if (rc) - return unlock_pinentry (rc); - } - - if (!errtext) - { - if (pininfo->with_repeat - && (pinentry_status & PINENTRY_STATUS_PIN_REPEATED)) - pininfo->repeat_okay = 1; - return unlock_pinentry (0); /* okay, got a PIN or passphrase */ - } - - if ((pinentry_status & PINENTRY_STATUS_PASSWORD_FROM_CACHE)) - /* The password was read from the cache. Don't count this - against the retry count. */ - pininfo->failed_tries --; - } - - return unlock_pinentry (pininfo->min_digits? GPG_ERR_BAD_PIN - : GPG_ERR_BAD_PASSPHRASE); -#endif } /* Ask for the passphrase using the supplied arguments. The returned @@ -420,12 +122,6 @@ gpg_error_t agent_askpin(ctrl_t ctrl, const char *desc_text, int agent_get_passphrase(ctrl_t ctrl, char **retpass, const char *desc, const char *prompt, const char *errtext, const char *keyinfo, cache_mode_t cache_mode) { - int rc; - char line[ASSUAN_LINELENGTH]; - struct entry_parm_s parm; - int saveflag; - unsigned int pinentry_status; - *retpass = NULL; if (opt.batch) return GPG_ERR_BAD_PASSPHRASE; @@ -436,86 +132,6 @@ int agent_get_passphrase(ctrl_t ctrl, char **retpass, const char *desc, &size, MAX_PASSPHRASE_LEN); } -#if 0 - rc = start_pinentry (ctrl); - if (rc) - return rc; - - if (!prompt) - prompt = desc && strstr (desc, "PIN")? L_("PIN:"): L_("Passphrase:"); - - - /* If we have a KEYINFO string and are normal, user, or ssh cache - mode, we tell that the Pinentry so it may use it for own caching - purposes. Most pinentries won't have this implemented and thus - we do not error out in this case. */ - if (keyinfo && (cache_mode == CACHE_MODE_NORMAL - || cache_mode == CACHE_MODE_USER - || cache_mode == CACHE_MODE_SSH)) - snprintf (line, DIM(line), "SETKEYINFO %c/%s", - cache_mode == CACHE_MODE_USER? 'u' : - cache_mode == CACHE_MODE_SSH? 's' : 'n', - keyinfo); - else - snprintf (line, DIM(line), "SETKEYINFO --clear"); - - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc && rc != GPG_ERR_ASS_UNKNOWN_CMD) - return unlock_pinentry (rc); - - - if (desc) - build_cmd_setdesc (line, DIM(line), desc); - else - snprintf (line, DIM(line), "RESET"); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - - snprintf (line, DIM(line), "SETPROMPT %s", prompt); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - - if (errtext) - { - snprintf (line, DIM(line), "SETERROR %s", errtext); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - } - - memset (&parm, 0, sizeof parm); - parm.size = ASSUAN_LINELENGTH/2 - 5; - parm.buffer = (unsigned char*) gcry_malloc_secure (parm.size+10); - if (!parm.buffer) - return unlock_pinentry (gpg_error_from_syserror ()); - - saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); - assuan_begin_confidential (entry_ctx); - pinentry_status = 0; - rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, - NULL, entry_ctx, - pinentry_status_cb, &pinentry_status); - assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); - /* Most pinentries out in the wild return the old Assuan error code - for canceled which gets translated to an assuan Cancel error and - not to the code for a user cancel. Fix this here. */ - if (rc == GPG_ERR_ASS_CANCELED) - rc = GPG_ERR_CANCELED; - /* Change error code in case the window close button was clicked - to cancel the operation. */ - if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON) - && rc == GPG_ERR_CANCELED) - rc = GPG_ERR_FULLY_CANCELED; - - if (rc) - xfree (parm.buffer); - else - *retpass = (char*) parm.buffer; - return unlock_pinentry (rc); -#endif } /* Pop up the PIN-entry, display the text and the prompt and ask the @@ -527,69 +143,7 @@ int agent_get_passphrase(ctrl_t ctrl, char **retpass, const char *desc, closing the Pinentry window. */ int agent_get_confirmation(ctrl_t ctrl, const char *desc, const char *ok, const char *notok, int with_cancel) { - int rc; - char line[ASSUAN_LINELENGTH]; - return GPG_ERR_NO_PIN_ENTRY; - -#if 0 - rc = start_pinentry (ctrl); - if (rc) - return rc; - - if (desc) - build_cmd_setdesc (line, DIM(line), desc); - else - snprintf (line, DIM(line), "RESET"); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - /* Most pinentries out in the wild return the old Assuan error code - for canceled which gets translated to an assuan Cancel error and - not to the code for a user cancel. Fix this here. */ - if (rc && rc == GPG_ERR_ASS_CANCELED) - rc = GPG_ERR_CANCELED; - - if (rc) - return unlock_pinentry (rc); - - if (ok) - { - snprintf (line, DIM(line), "SETOK %s", ok); - rc = assuan_transact (entry_ctx, - line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - } - if (notok) - { - /* Try to use the newer NOTOK feature if a cancel button is - requested. If no cancel button is requested we keep on using - the standard cancel. */ - if (with_cancel) - { - snprintf (line, DIM(line), "SETNOTOK %s", notok); - rc = assuan_transact (entry_ctx, - line, NULL, NULL, NULL, NULL, NULL, NULL); - } - else - rc = GPG_ERR_ASS_UNKNOWN_CMD; - - if (rc == GPG_ERR_ASS_UNKNOWN_CMD) - { - snprintf (line, DIM(line), "SETCANCEL %s", notok); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - } - if (rc) - return unlock_pinentry (rc); - } - - rc = assuan_transact (entry_ctx, "CONFIRM", - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc == GPG_ERR_ASS_CANCELED) - rc = GPG_ERR_CANCELED; - - return unlock_pinentry (rc); -#endif } /* Pop up the PINentry, display the text DESC and a button with the @@ -597,60 +151,7 @@ int agent_get_confirmation(ctrl_t ctrl, const char *desc, const char *ok, for the user to hit this button. The return value is not relevant. */ int agent_show_message(ctrl_t ctrl, const char *desc, const char *ok_btn) { - int rc; - char line[ASSUAN_LINELENGTH]; - return GPG_ERR_CANCELED; - -#if 0 - rc = start_pinentry (ctrl); - if (rc) - return rc; - - if (desc) - build_cmd_setdesc (line, DIM(line), desc); - else - snprintf (line, DIM(line), "RESET"); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - /* Most pinentries out in the wild return the old Assuan error code - for canceled which gets translated to an assuan Cancel error and - not to the code for a user cancel. Fix this here. */ - if (rc == GPG_ERR_ASS_CANCELED) - rc = GPG_ERR_CANCELED; - - if (rc) - return unlock_pinentry (rc); - - if (ok_btn) - { - snprintf (line, DIM(line), "SETOK %s", ok_btn); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, - NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - } - - rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL, - NULL, NULL, NULL); - if (rc == GPG_ERR_ASS_CANCELED) - rc = GPG_ERR_CANCELED; - - return unlock_pinentry (rc); -#endif -} - -/* The thread running the popup message. */ -static void *popup_message_thread(void *arg) { - (void)arg; - - /* We use the --one-button hack instead of the MESSAGE command to - allow the use of old Pinentries. Those old Pinentries will then - show an additional Cancel button but that is mostly a visual - annoyance. */ - assuan_transact(entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL, NULL, - NULL, NULL); - popup_finished = 1; - return NULL; } /* Pop up a message window similar to the confirm one but keep it open @@ -661,134 +162,14 @@ static void *popup_message_thread(void *arg) { (after a timeout). */ int agent_popup_message_start(ctrl_t ctrl, const char *desc, const char *ok_btn) { - int rc; - char line[ASSUAN_LINELENGTH]; - npth_attr_t tattr; - int err; - return GPG_ERR_CANCELED; - -#if 0 - rc = start_pinentry (ctrl); - if (rc) - return rc; - - if (desc) - build_cmd_setdesc (line, DIM(line), desc); - else - snprintf (line, DIM(line), "RESET"); - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (rc); - - if (ok_btn) - { - snprintf (line, DIM(line), "SETOK %s", ok_btn); - rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL); - if (rc) - return unlock_pinentry (rc); - } - - err = npth_attr_init (&tattr); - if (err) - return unlock_pinentry (gpg_error_from_errno (err)); - npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); - - popup_finished = 0; - err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL); - npth_attr_destroy (&tattr); - if (err) - { - rc = gpg_error_from_errno (err); - log_error ("error spawning popup message handler: %s\n", - strerror (err) ); - return unlock_pinentry (rc); - } - npth_setname_np (popup_tid, "popup-message"); - - return 0; -#endif } /* Close a popup window. */ void agent_popup_message_stop(ctrl_t ctrl) { - int rc; - pid_t pid; - - (void)ctrl; - - return; -#if 0 - if (!popup_tid || !entry_ctx) { - log_debug("agent_popup_message_stop called with no active popup\n"); - return; - } - - pid = assuan_get_pid(entry_ctx); - if (pid == (pid_t)(-1)) - ; /* No pid available can't send a kill. */ - else if (popup_finished) - ; /* Already finished and ready for joining. */ -#ifdef HAVE_W32_SYSTEM - /* Older versions of assuan set PID to 0 on Windows to indicate an - invalid value. */ - else if (pid != (pid_t)INVALID_HANDLE_VALUE && pid != 0) { - HANDLE process = (HANDLE)pid; - - /* Arbitrary error code. */ - TerminateProcess(process, 1); - } -#else - else if (pid && ((rc = waitpid(pid, NULL, WNOHANG)) == -1 || - (rc == pid))) { /* The daemon already died. No need to send - a kill. However - because we already waited for the process, - we need to tell - assuan that it should not wait again (done - by - unlock_pinentry). */ - if (rc == pid) assuan_set_flag(entry_ctx, ASSUAN_NO_WAITPID, 1); - } else if (pid > 0) - kill(pid, SIGINT); -#endif - - /* Now wait for the thread to terminate. */ - rc = npth_join(popup_tid, NULL); - if (rc) - log_debug("agent_popup_message_stop: pth_join failed: %s\n", strerror(rc)); - /* Thread IDs are opaque, but we try our best here by resetting it - to the same content that a static global variable has. */ - memset(&popup_tid, '\0', sizeof(popup_tid)); - entry_owner = NULL; - - /* Now we can close the connection. */ - unlock_pinentry(0); -#endif } int agent_clear_passphrase(ctrl_t ctrl, const char *keyinfo, cache_mode_t cache_mode) { -#if 0 - int rc; - char line[ASSUAN_LINELENGTH]; - - if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL - || cache_mode == CACHE_MODE_USER - || cache_mode == CACHE_MODE_SSH))) - return GPG_ERR_NOT_SUPPORTED; - - rc = start_pinentry (ctrl); - if (rc) - return rc; - - snprintf (line, DIM(line), "CLEARPASSPHRASE %c/%s", - cache_mode == CACHE_MODE_USER? 'u' : - cache_mode == CACHE_MODE_SSH? 's' : 'n', - keyinfo); - rc = assuan_transact (entry_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - - return unlock_pinentry (rc); -#endif return 0; } diff --git a/legacy/gnupg/agent/call-scd.cpp b/legacy/gnupg/agent/call-scd.cpp index 8e5044f65..f19168c0c 100644 --- a/legacy/gnupg/agent/call-scd.cpp +++ b/legacy/gnupg/agent/call-scd.cpp @@ -21,6 +21,8 @@ #include +#include + #include #include #include @@ -33,7 +35,6 @@ #ifndef HAVE_W32_SYSTEM #include #endif -#include #include #include "../common/strlist.h" @@ -93,7 +94,7 @@ struct inq_needpin_parm_s { static struct scd_local_s *scd_local_list; /* A Mutex used inside the start_scd function. */ -static npth_mutex_t start_scd_lock; +static std::mutex start_scd_lock; /* The context of the primary connection. This is also used as a flag to indicate whether the scdaemon has been started. */ @@ -106,21 +107,6 @@ static int primary_scd_ctx_reusable; /* Local prototypes. */ -/* This function must be called once to initialize this module. This - has to be done before a second thread is spawned. We can't do the - static initialization because NPth emulation code might not be able - to do a static init; in particular, it is not possible for W32. */ -void initialize_module_call_scd(void) { - static int initialized; - int err; - - if (!initialized) { - err = npth_mutex_init(&start_scd_lock, NULL); - if (err) log_fatal("error initializing mutex: %s\n", strerror(err)); - initialized = 1; - } -} - /* This function may be called to print information pertaining to the current state of this module to the log. */ void agent_scd_dump_state(void) { @@ -199,11 +185,7 @@ static int start_scd(ctrl_t ctrl) { error instead. */ /* We need to protect the following code. */ - rc = npth_mutex_lock(&start_scd_lock); - if (rc) { - log_error("failed to acquire the start_scd lock: %s\n", strerror(rc)); - return GPG_ERR_INTERNAL; - } + std::lock_guard lock(start_scd_lock); /* Check whether the pipe server has already been started and in this case either reuse a lingering pipe connection or establish a @@ -283,8 +265,6 @@ static int start_scd(ctrl_t ctrl) { } else { ctrl->scd_local->ctx = ctx; } - rc = npth_mutex_unlock(&start_scd_lock); - if (rc) log_error("failed to release the start_scd lock: %s\n", strerror(rc)); return err; } diff --git a/legacy/gnupg/agent/findkey.cpp b/legacy/gnupg/agent/findkey.cpp index b2fa43ae7..74c315527 100644 --- a/legacy/gnupg/agent/findkey.cpp +++ b/legacy/gnupg/agent/findkey.cpp @@ -24,7 +24,6 @@ #include #include #include -#include /* (we use pth_sleep) */ #include #include #include diff --git a/legacy/gnupg/agent/gpg-agent.cpp b/legacy/gnupg/agent/gpg-agent.cpp index 65b5908b7..97904ace5 100644 --- a/legacy/gnupg/agent/gpg-agent.cpp +++ b/legacy/gnupg/agent/gpg-agent.cpp @@ -40,7 +40,6 @@ #include #include #endif /*!HAVE_W32_SYSTEM*/ -#include #include #define GNUPG_COMMON_NEED_AFLOCAL @@ -154,29 +153,6 @@ static struct debug_flags_s debug_flags[] = { #define MIN_PASSPHRASE_NONALPHA (1) #define MAX_PASSPHRASE_DAYS (0) -/* The timer tick used for housekeeping stuff. For Windows we use a - longer period as the SetWaitableTimer seems to signal earlier than - the 2 seconds. CHECK_OWN_SOCKET_INTERVAL defines how often we - check our own socket in standard socket mode. If that value is 0 - we don't check at all. All values are in seconds. */ -#if defined(HAVE_W32_SYSTEM) -#define TIMERTICK_INTERVAL (4) -#else -#define TIMERTICK_INTERVAL (2) -#endif - -/* Flag to indicate that a shutdown was requested. */ -static int shutdown_pending; - -/* Counter for the currently running own socket checks. */ -static int check_own_socket_running; - -/* Flag indicating that we are in supervised mode. */ -static int is_supervised; - -/* Flag to inhibit socket removal in cleanup. */ -static int inhibit_socket_removal; - /* Default values for options passed to the pinentry. */ static char *default_lc_ctype; static char *default_lc_messages; @@ -191,36 +167,6 @@ static const char *debug_level; the log file after a SIGHUP if it didn't changed. Malloced. */ static char *current_logfile; -/* The handle_tick() function may test whether a parent is still - running. We record the PID of the parent here or -1 if it should be - watched. */ -static pid_t parent_pid = (pid_t)(-1); - -/* Number of active connections. */ -static int active_connections; - -/* This object is used to dispatch progress messages from Libgcrypt to - * the right thread. Given that we will have at max only a few dozen - * connections at a time, using a linked list is the easiest way to - * handle this. */ -struct progress_dispatch_s { - struct progress_dispatch_s *next; - /* The control object of the connection. If this is NULL no - * connection is associated with this item and it is free for reuse - * by new connections. */ - ctrl_t ctrl; - - /* The thread id of (npth_self) of the connection. */ - npth_t tid; - - /* The callback set by the connection. This is similar to the - * Libgcrypt callback but with the control object passed as the - * first argument. */ - void (*cb)(ctrl_t ctrl, const char *what, int printchar, int current, - int total); -}; -struct progress_dispatch_s *progress_dispatch_list; - /* Local prototypes. */ @@ -230,9 +176,6 @@ static void create_directories(void); static void agent_init_default_ctrl(ctrl_t ctrl); static void agent_deinit_default_ctrl(ctrl_t ctrl); -/* Pth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - /* Return strings describing this program. The case values are described in common/argparse.c:strusage. The values here override the default values given by strusage. */ @@ -419,33 +362,6 @@ static int parse_rereadable_options(ARGPARSE_ARGS *pargs, int reread) { /* Fixup some options after all have been processed. */ static void finalize_rereadable_options(void) {} -static void thread_init_once(void) { - static int npth_initialized = 0; - - if (!npth_initialized) { - npth_initialized++; - npth_init(); - } - gpgrt_set_syscall_clamp(npth_unprotect, npth_protect); -/* Now that we have set the syscall clamp we need to tell Libgcrypt - * that it should get them from libgpg-error. Note that Libgcrypt - * has already been initialized but at that point nPth was not - * initialized and thus Libgcrypt could not set its system call - * clamp. */ -#if GCRYPT_VERSION_NUMBER >= 0x010800 /* 1.8.0 */ - gcry_control(GCRYCTL_REINIT_SYSCALL_CLAMP, 0, 0); -#endif -} - -static void initialize_modules(void) { - thread_init_once(); - assuan_set_system_hooks(ASSUAN_SYSTEM_NPTH); - initialize_module_cache(); - initialize_module_call_pinentry(); - initialize_module_call_scd(); - initialize_module_trustlist(); -} - /* The main entry point. */ int agent_main(int argc, char **argv) { ARGPARSE_ARGS pargs; @@ -458,7 +374,6 @@ int agent_main(int argc, char **argv) { int parse_debug = 0; int default_config = 1; int pipe_server = 0; - int is_daemon = 0; int nodetach = 0; int csh_style = 0; char *logfile = NULL; @@ -641,7 +556,7 @@ int agent_main(int argc, char **argv) { log_info(_("Note: '%s' is not considered an option\n"), argv[i]); } - if (!pipe_server && !is_daemon && !is_supervised) { + if (!pipe_server) { /* We have been called without any command and thus we merely check whether an agent is already running. We do this right here so that we don't clobber a logfile with this check but @@ -663,7 +578,6 @@ int agent_main(int argc, char **argv) { create_directories(); if (debug_wait && pipe_server) { - thread_init_once(); log_debug("waiting for debugger - my pid is %u .....\n", (unsigned int)getpid()); gnupg_sleep(debug_wait); @@ -682,8 +596,6 @@ int agent_main(int argc, char **argv) { /* This is the simple pipe based server */ ctrl_t ctrl; - initialize_modules(); - ctrl = (ctrl_t)xtrycalloc(1, sizeof *ctrl); if (!ctrl) { log_error("error allocating connection control data: %s\n", @@ -694,8 +606,8 @@ int agent_main(int argc, char **argv) { start_command_handler(ctrl); agent_deinit_default_ctrl(ctrl); xfree(ctrl); - } else if (!is_daemon) - ; /* NOTREACHED */ + } + /* NOTREACHED */ return 0; } @@ -742,9 +654,6 @@ static void agent_deinit_default_ctrl(ctrl_t ctrl) { if (ctrl->lc_messages) xfree(ctrl->lc_messages); } -/* Return the number of active connections. */ -int get_agent_active_connection_count(void) { return active_connections; } - /* Under W32, this function returns the handle of the scdaemon notification event. Calling it the first time creates that event. */ diff --git a/legacy/gnupg/agent/trustlist.cpp b/legacy/gnupg/agent/trustlist.cpp index 3cd57baa1..84f51b323 100644 --- a/legacy/gnupg/agent/trustlist.cpp +++ b/legacy/gnupg/agent/trustlist.cpp @@ -18,11 +18,13 @@ * along with this program; if not, see . */ -#include #include + +#include + +#include #include #include -#include #include #include #include @@ -50,7 +52,7 @@ typedef struct trustitem_s trustitem_t; static trustitem_t *trusttable; static size_t trusttablesize; /* A mutex used to protect the table. */ -static npth_mutex_t trusttable_lock; +static std::mutex trusttable_lock; static const char headerblurb[] = "# This is the list of trusted keys. Comment lines, like this one, as\n" @@ -68,38 +70,6 @@ static const char headerblurb[] = "include-default\n" "\n"; -/* This function must be called once to initialize this module. This - has to be done before a second thread is spawned. We can't do the - static initialization because Pth emulation code might not be able - to do a static init; in particular, it is not possible for W32. */ -void initialize_module_trustlist(void) { - static int initialized; - int err; - - if (!initialized) { - err = npth_mutex_init(&trusttable_lock, NULL); - if (err) - log_fatal("failed to init mutex in %s: %s\n", __FILE__, strerror(err)); - initialized = 1; - } -} - -static void lock_trusttable(void) { - int err; - - err = npth_mutex_lock(&trusttable_lock); - if (err) - log_fatal("failed to acquire mutex in %s: %s\n", __FILE__, strerror(err)); -} - -static void unlock_trusttable(void) { - int err; - - err = npth_mutex_unlock(&trusttable_lock); - if (err) - log_fatal("failed to release mutex in %s: %s\n", __FILE__, strerror(err)); -} - /* Clear the trusttable. The caller needs to make sure that the trusttable is locked. */ static inline void clear_trusttable(void) { @@ -353,7 +323,7 @@ static gpg_error_t istrusted_internal(ctrl_t ctrl, const char *fpr, } if (!already_locked) { - lock_trusttable(); + trusttable_lock.lock(); locked = 1; } @@ -375,11 +345,11 @@ static gpg_error_t istrusted_internal(ctrl_t ctrl, const char *fpr, if (already_locked) ; else if (ti->flags.relax) { - unlock_trusttable(); + trusttable_lock.unlock(); locked = 0; err = agent_write_status(ctrl, "TRUSTLISTFLAG", "relax", NULL); } else if (ti->flags.cm) { - unlock_trusttable(); + trusttable_lock.unlock(); locked = 0; err = agent_write_status(ctrl, "TRUSTLISTFLAG", "cm", NULL); } @@ -391,7 +361,7 @@ static gpg_error_t istrusted_internal(ctrl_t ctrl, const char *fpr, err = GPG_ERR_NOT_TRUSTED; leave: - if (locked && !already_locked) unlock_trusttable(); + if (locked && !already_locked) trusttable_lock.unlock(); return err; } @@ -407,12 +377,11 @@ gpg_error_t agent_listtrusted(void *assuan_context) { char key[51]; gpg_error_t err; size_t len; - - lock_trusttable(); + std::lock_guard lock(trusttable_lock); + if (!trusttable) { err = read_trustfiles(); if (err) { - unlock_trusttable(); log_error(_("error reading list of trusted root certificates\n")); return err; } @@ -433,7 +402,6 @@ gpg_error_t agent_listtrusted(void *assuan_context) { } } - unlock_trusttable(); return 0; } @@ -615,10 +583,9 @@ gpg_error_t agent_marktrusted(ctrl_t ctrl, const char *name, const char *fpr, /* Now check again to avoid duplicates. We take the lock to make sure that nobody else plays with our file and force a reread. */ - lock_trusttable(); + std::lock_guard lock(trusttable_lock); clear_trusttable(); if (!istrusted_internal(ctrl, fpr, &is_disabled, 1) || is_disabled) { - unlock_trusttable(); xfree(fprformatted); xfree(nameformatted); return is_disabled ? GPG_ERR_NOT_TRUSTED : 0; @@ -627,7 +594,6 @@ gpg_error_t agent_marktrusted(ctrl_t ctrl, const char *name, const char *fpr, fname = make_filename_try(gnupg_homedir(), "trustlist.txt", NULL); if (!fname) { err = gpg_error_from_syserror(); - unlock_trusttable(); xfree(fprformatted); xfree(nameformatted); return err; @@ -638,7 +604,6 @@ gpg_error_t agent_marktrusted(ctrl_t ctrl, const char *name, const char *fpr, err = gpg_error_from_syserror(); log_error("can't create '%s': %s\n", fname, gpg_strerror(err)); xfree(fname); - unlock_trusttable(); xfree(fprformatted); xfree(nameformatted); return err; @@ -651,7 +616,6 @@ gpg_error_t agent_marktrusted(ctrl_t ctrl, const char *name, const char *fpr, err = gpg_error_from_syserror(); log_error("can't open '%s': %s\n", fname, gpg_strerror(err)); xfree(fname); - unlock_trusttable(); xfree(fprformatted); xfree(nameformatted); return err; @@ -675,7 +639,6 @@ gpg_error_t agent_marktrusted(ctrl_t ctrl, const char *name, const char *fpr, clear_trusttable(); xfree(fname); - unlock_trusttable(); xfree(fprformatted); xfree(nameformatted); return err; @@ -686,7 +649,6 @@ gpg_error_t agent_marktrusted(ctrl_t ctrl, const char *name, const char *fpr, void agent_reload_trustlist(void) { /* All we need to do is to delete the trusttable. At the next access it will get re-read. */ - lock_trusttable(); + std::lock_guard lock(trusttable_lock); clear_trusttable(); - unlock_trusttable(); } diff --git a/legacy/gnupg/common/exechelp-posix.cpp b/legacy/gnupg/common/exechelp-posix.cpp index 477777f94..1a98c17ed 100644 --- a/legacy/gnupg/common/exechelp-posix.cpp +++ b/legacy/gnupg/common/exechelp-posix.cpp @@ -46,14 +46,6 @@ #include #include -#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */ -#undef HAVE_NPTH -#undef USE_NPTH -#endif - -#ifdef HAVE_NPTH -#include -#endif #include #ifdef HAVE_GETRLIMIT @@ -526,13 +518,9 @@ gpg_error_t gnupg_wait_process(const char *pgmname, pid_t pid, int hang, if (pid == (pid_t)(-1)) return GPG_ERR_INV_VALUE; -#ifdef USE_NPTH - i = npth_waitpid(pid, &status, hang ? 0 : WNOHANG); -#else while ((i = waitpid(pid, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1) && errno == EINTR) ; -#endif if (i == (pid_t)(-1)) { ec = gpg_error_from_errno(errno); @@ -588,13 +576,9 @@ gpg_error_t gnupg_wait_processes(const char **pgmnames, pid_t *pids, pid_t pid; int status; -#ifdef USE_NPTH - pid = npth_waitpid(-1, &status, hang ? 0 : WNOHANG); -#else while ((pid = waitpid(-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1) && errno == EINTR) ; -#endif if (pid == (pid_t)(-1)) { ec = gpg_error_from_errno(errno); diff --git a/legacy/gnupg/common/exechelp-w32.cpp b/legacy/gnupg/common/exechelp-w32.cpp index 76c417fc5..5abc63f10 100644 --- a/legacy/gnupg/common/exechelp-w32.cpp +++ b/legacy/gnupg/common/exechelp-w32.cpp @@ -45,15 +45,6 @@ #include #include -#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */ -#undef HAVE_NPTH -#undef USE_NPTH -#endif - -#ifdef HAVE_NPTH -#include -#endif - #ifdef HAVE_STAT #include #endif diff --git a/legacy/gnupg/common/gettime.cpp b/legacy/gnupg/common/gettime.cpp index 48beedab4..80be37688 100644 --- a/legacy/gnupg/common/gettime.cpp +++ b/legacy/gnupg/common/gettime.cpp @@ -73,10 +73,7 @@ time_t gnupg_get_time() { /* Wrapper around gmtime_r. On systems without gmtime_r this implementation works within gnupg - because we use only one thread a time. FIXME: An independent - library may use gmtime in one of its own thread (or via - npth_enter/npth_leave) - in this case we run into a problem. The - solution would be to use a mutex here. */ + because we use only one thread a time. FIXME */ struct tm *gnupg_gmtime(const time_t *timep, struct tm *result) { #ifdef HAVE_GMTIME_R return gmtime_r(timep, result); diff --git a/legacy/gnupg/common/sysutils.cpp b/legacy/gnupg/common/sysutils.cpp index cc6abeacf..258098376 100644 --- a/legacy/gnupg/common/sysutils.cpp +++ b/legacy/gnupg/common/sysutils.cpp @@ -31,11 +31,6 @@ #include -#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */ -#undef HAVE_NPTH -#undef USE_NPTH -#endif - #include #include #include @@ -67,9 +62,6 @@ #ifdef HAVE_INOTIFY_INIT #include #endif /*HAVE_INOTIFY_INIT*/ -#ifdef HAVE_NPTH -#include -#endif #include #include @@ -161,54 +153,12 @@ unsigned int get_uint_nonce(void) { merely calls pth_sleep and thus suspends only the current thread. */ void gnupg_sleep(unsigned int seconds) { -#ifdef USE_NPTH - npth_sleep(seconds); -#else /* Fixme: make sure that a sleep won't wake up to early. */ #ifdef HAVE_W32_SYSTEM Sleep(seconds * 1000); #else sleep(seconds); #endif -#endif -} - -/* Wrapper around the platforms usleep function. This one won't wake - * up before the sleep time has really elapsed. When build with nPth - * it merely calls npth_usleep and thus suspends only the current - * thread. */ -void gnupg_usleep(unsigned int usecs) { -#if defined(USE_NPTH) - - npth_usleep(usecs); - -#elif defined(HAVE_W32_SYSTEM) - - Sleep((usecs + 999) / 1000); - -#elif defined(HAVE_NANOSLEEP) - - if (usecs) { - struct timespec req; - struct timespec rem; - - req.tv_sec = 0; - req.tv_nsec = usecs * 1000; - - while (nanosleep(&req, &rem) < 0 && errno == EINTR) req = rem; - } - -#else /*Standard Unix*/ - - if (usecs) { - struct timeval tv; - - tv.tv_sec = usecs / 1000000; - tv.tv_usec = usecs % 1000000; - select(0, NULL, NULL, NULL, &tv); - } - -#endif } /* This function is a NOP for POSIX systems but required under Windows @@ -768,7 +718,7 @@ gpg_error_t gnupg_inotify_watch_socket(int *r_fd, const char *socket_name) { /* Read an inotify event and return true if it matches NAME or if it * sees an IN_DELETE_SELF event for the directory of NAME. */ int gnupg_inotify_has_name(int fd, const char *name) { -#if USE_NPTH && HAVE_INOTIFY_INIT +#if HAVE_INOTIFY_INIT #define BUFSIZE_FOR_INOTIFY (sizeof(struct inotify_event) + 255 + 1) union { struct inotify_event ev; @@ -777,7 +727,7 @@ int gnupg_inotify_has_name(int fd, const char *name) { struct inotify_event *evp; int n; - n = npth_read(fd, &buf, sizeof buf); + n = read(fd, &buf, sizeof buf); /* log_debug ("notify read: n=%d\n", n); */ evp = &buf.ev; while (n >= sizeof(struct inotify_event)) { @@ -801,14 +751,7 @@ int gnupg_inotify_has_name(int fd, const char *name) { evp = (struct inotify_event *)(void *)((char *)evp + sizeof(*evp) + evp->len); } - -#else /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/ - - (void)fd; - (void)name; - -#endif /*!(USE_NPTH && HAVE_INOTIFY_INIT)*/ - +#endif return 0; /* Not found. */ } diff --git a/legacy/gnupg/common/sysutils.h b/legacy/gnupg/common/sysutils.h index bd723663f..d84a4137f 100644 --- a/legacy/gnupg/common/sysutils.h +++ b/legacy/gnupg/common/sysutils.h @@ -56,7 +56,6 @@ const unsigned char *get_session_marker(size_t *rlen); unsigned int get_uint_nonce(void); /*int check_permissions (const char *path,int extension,int checkonly);*/ void gnupg_sleep(unsigned int seconds); -void gnupg_usleep(unsigned int usecs); int translate_sys2libc_fd(gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int(int fd, int for_write); int check_special_filename(const char *fname, int for_write, int notranslate); diff --git a/legacy/gnupg/dirmngr/certcache.cpp b/legacy/gnupg/dirmngr/certcache.cpp index 48b1adfa3..7739d1204 100644 --- a/legacy/gnupg/dirmngr/certcache.cpp +++ b/legacy/gnupg/dirmngr/certcache.cpp @@ -19,10 +19,11 @@ #include +#include + #include #include #include -#include #include #include #include @@ -80,12 +81,8 @@ typedef struct cert_item_s *cert_item_t; the first byte of the fingerprint. */ static cert_item_t cert_cache[256]; -/* This is the global cache_lock variable. In general locking is not - needed but it would take extra efforts to make sure that no - indirect use of npth functions is done, so we simply lock it - always. Note: We can't use static initialization, as that is not - available through w32-pth. */ -static npth_rwlock_t cert_cache_lock; +/* This is the global cache_lock variable. */ +static std::mutex cache_lock; /* Flag to track whether the cache has been initialized. */ static int initialization_done; @@ -103,43 +100,6 @@ typedef PCCERT_CONTEXT(WINAPI *CERTENUMCERTIFICATESINSTORE)( typedef WINBOOL(WINAPI *CERTCLOSESTORE)(HCERTSTORE hCertStore, DWORD dwFlags); #endif /*HAVE_W32_SYSTEM*/ -/* Helper to do the cache locking. */ -static void init_cache_lock(void) { - int err; - - err = npth_rwlock_init(&cert_cache_lock, NULL); - if (err) - log_fatal(_("can't initialize certificate cache lock: %s\n"), - strerror(err)); -} - -static void acquire_cache_read_lock(void) { - int err; - - err = npth_rwlock_rdlock(&cert_cache_lock); - if (err) - log_fatal(_("can't acquire read lock on the certificate cache: %s\n"), - strerror(err)); -} - -static void acquire_cache_write_lock(void) { - int err; - - err = npth_rwlock_wrlock(&cert_cache_lock); - if (err) - log_fatal(_("can't acquire write lock on the certificate cache: %s\n"), - strerror(err)); -} - -static void release_cache_lock(void) { - int err; - - err = npth_rwlock_unlock(&cert_cache_lock); - if (err) - log_fatal(_("can't release lock on the certificate cache: %s\n"), - strerror(err)); -} - /* Return false if both serial numbers match. Can't be used for sorting. */ static int compare_serialno(ksba_sexp_t serial1, ksba_sexp_t serial2) { @@ -595,28 +555,28 @@ void cert_cache_init(const std::vector &hkp_cacerts) { char *fname; if (initialization_done) return; - init_cache_lock(); - acquire_cache_write_lock(); - - load_certs_from_system(); - - fname = make_filename_try(gnupg_sysconfdir(), "trusted-certs", NULL); - if (fname) load_certs_from_dir(fname, CERTTRUST_CLASS_CONFIG); - xfree(fname); - - fname = make_filename_try(gnupg_sysconfdir(), "extra-certs", NULL); - if (fname) load_certs_from_dir(fname, 0); - xfree(fname); - fname = make_filename_try(gnupg_datadir(), "sks-keyservers.netCA.pem", NULL); - if (fname) load_certs_from_file(fname, CERTTRUST_CLASS_HKPSPOOL, 1); - xfree(fname); - - for (auto cacert : hkp_cacerts) - load_certs_from_file(cacert.c_str(), CERTTRUST_CLASS_HKP, 0); - - initialization_done = 1; - release_cache_lock(); + { + std::lock_guard lock(cache_lock); + load_certs_from_system(); + + fname = make_filename_try(gnupg_sysconfdir(), "trusted-certs", NULL); + if (fname) load_certs_from_dir(fname, CERTTRUST_CLASS_CONFIG); + xfree(fname); + + fname = make_filename_try(gnupg_sysconfdir(), "extra-certs", NULL); + if (fname) load_certs_from_dir(fname, 0); + xfree(fname); + + fname = make_filename_try(gnupg_datadir(), "sks-keyservers.netCA.pem", NULL); + if (fname) load_certs_from_file(fname, CERTTRUST_CLASS_HKPSPOOL, 1); + xfree(fname); + + for (auto cacert : hkp_cacerts) + load_certs_from_file(cacert.c_str(), CERTTRUST_CLASS_HKP, 0); + + initialization_done = 1; + } cert_cache_print_stats(); } @@ -629,7 +589,7 @@ void cert_cache_deinit(int full) { if (!initialization_done) return; - acquire_cache_write_lock(); + std::lock_guard lock(cache_lock); for (i = 0; i < 256; i++) for (ci = cert_cache[i]; ci; ci = ci->next) clean_cache_slot(ci); @@ -646,7 +606,6 @@ void cert_cache_deinit(int full) { total_nonperm_certificates = 0; initialization_done = 0; - release_cache_lock(); } /* Print some statistics to the log file. */ @@ -661,7 +620,7 @@ void cert_cache_print_stats(void) { unsigned int n_trustclass_hkp = 0; unsigned int n_trustclass_hkpspool = 0; - acquire_cache_read_lock(); + std::lock_guard lock(cache_lock); for (idx = 0; idx < 256; idx++) for (ci = cert_cache[idx]; ci; ci = ci->next) if (ci->cert) { @@ -681,8 +640,6 @@ void cert_cache_print_stats(void) { } } - release_cache_lock(); - log_info(_("permanently loaded certificates: %u\n"), n_permanent); log_info(_(" runtime cached certificates: %u\n"), n_nonperm); log_info(_(" trusted certificates: %u (%u,%u,%u,%u)\n"), n_trusted, @@ -694,9 +651,8 @@ void cert_cache_print_stats(void) { gpg_error_t cache_cert(ksba_cert_t cert) { gpg_error_t err; - acquire_cache_write_lock(); + std::lock_guard lock(cache_lock); err = put_cert(cert, 0, 0, NULL); - release_cache_lock(); if (err == GPG_ERR_DUP_VALUE) log_info(_("certificate already cached\n")); else if (!err) @@ -713,9 +669,8 @@ gpg_error_t cache_cert(ksba_cert_t cert) { gpg_error_t cache_cert_silent(ksba_cert_t cert, void *fpr_buffer) { gpg_error_t err; - acquire_cache_write_lock(); + std::lock_guard lock(cache_lock); err = put_cert(cert, 0, 0, fpr_buffer); - release_cache_lock(); if (err == GPG_ERR_DUP_VALUE) err = 0; if (err) log_error(_("error caching certificate: %s\n"), gpg_strerror(err)); return err; @@ -730,15 +685,13 @@ gpg_error_t cache_cert_silent(ksba_cert_t cert, void *fpr_buffer) { ksba_cert_t get_cert_byfpr(const unsigned char *fpr) { cert_item_t ci; - acquire_cache_read_lock(); + std::lock_guard lock(cache_lock); for (ci = cert_cache[*fpr]; ci; ci = ci->next) if (ci->cert && !memcmp(ci->fpr, fpr, 20)) { ksba_cert_ref(ci->cert); - release_cache_lock(); return ci->cert; } - release_cache_lock(); return NULL; } @@ -779,18 +732,16 @@ ksba_cert_t get_cert_bysn(const char *issuer_dn, ksba_sexp_t serialno) { cert_item_t ci; int i; - acquire_cache_read_lock(); + std::lock_guard lock(cache_lock); for (i = 0; i < 256; i++) { for (ci = cert_cache[i]; ci; ci = ci->next) if (ci->cert && !strcmp(ci->issuer_dn, issuer_dn) && !compare_serialno(ci->sn, serialno)) { ksba_cert_ref(ci->cert); - release_cache_lock(); return ci->cert; } } - release_cache_lock(); return NULL; } @@ -801,18 +752,16 @@ ksba_cert_t get_cert_byissuer(const char *issuer_dn, unsigned int seq) { cert_item_t ci; int i; - acquire_cache_read_lock(); + std::lock_guard lock(cache_lock); for (i = 0; i < 256; i++) { for (ci = cert_cache[i]; ci; ci = ci->next) if (ci->cert && !strcmp(ci->issuer_dn, issuer_dn)) if (!seq--) { ksba_cert_ref(ci->cert); - release_cache_lock(); return ci->cert; } } - release_cache_lock(); return NULL; } @@ -825,18 +774,16 @@ ksba_cert_t get_cert_bysubject(const char *subject_dn, unsigned int seq) { if (!subject_dn) return NULL; - acquire_cache_read_lock(); + std::lock_guard lock(cache_lock); for (i = 0; i < 256; i++) { for (ci = cert_cache[i]; ci; ci = ci->next) if (ci->cert && ci->subject_dn && !strcmp(ci->subject_dn, subject_dn)) if (!seq--) { ksba_cert_ref(ci->cert); - release_cache_lock(); return ci->cert; } } - release_cache_lock(); return NULL; } @@ -1213,17 +1160,15 @@ ksba_cert_t find_cert_bysubject(ctrl_t ctrl, const char *subject_dn, int i; /* For efficiency reasons we won't use get_cert_bysubject here. */ - acquire_cache_read_lock(); + std::lock_guard lock(cache_lock); for (i = 0; i < 256; i++) for (ci = cert_cache[i]; ci; ci = ci->next) if (ci->cert && ci->subject_dn && !strcmp(ci->subject_dn, subject_dn)) for (cr = ctrl->ocsp_certs; cr; cr = cr->next) if (!memcmp(ci->fpr, cr->fpr, 20)) { ksba_cert_ref(ci->cert); - release_cache_lock(); return ci->cert; /* We use this certificate. */ } - release_cache_lock(); if (DBG_LOOKUP) log_debug("find_cert_bysubject: certificate not in ocsp_certs\n"); } @@ -1344,19 +1289,17 @@ gpg_error_t is_trusted_cert(ksba_cert_t cert, unsigned int trustclasses) { cert_compute_fpr(cert, fpr); - acquire_cache_read_lock(); + std::lock_guard lock(cache_lock); for (ci = cert_cache[*fpr]; ci; ci = ci->next) if (ci->cert && !memcmp(ci->fpr, fpr, 20)) { if ((ci->trustclasses & trustclasses)) { /* The certificate is trusted in one of the given * TRUSTCLASSES. */ - release_cache_lock(); return 0; /* Yes, it is trusted. */ } break; } - release_cache_lock(); return GPG_ERR_NOT_TRUSTED; } diff --git a/legacy/gnupg/dirmngr/crlfetch.cpp b/legacy/gnupg/dirmngr/crlfetch.cpp index 930b9db05..00e65a303 100644 --- a/legacy/gnupg/dirmngr/crlfetch.cpp +++ b/legacy/gnupg/dirmngr/crlfetch.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include "crlfetch.h" @@ -62,7 +61,7 @@ static void register_file_reader(ksba_reader_t reader, return; } log_info(_("reader to file mapping table full - waiting\n")); - npth_sleep(2); + gnupg_sleep(2); } } diff --git a/legacy/gnupg/dirmngr/dirmngr.cpp b/legacy/gnupg/dirmngr/dirmngr.cpp index 72f088890..248f7c6da 100644 --- a/legacy/gnupg/dirmngr/dirmngr.cpp +++ b/legacy/gnupg/dirmngr/dirmngr.cpp @@ -39,7 +39,6 @@ #ifdef HAVE_INOTIFY_INIT #include #endif /*HAVE_INOTIFY_INIT*/ -#include #include #include @@ -241,28 +240,6 @@ static int network_activity_seen; /* A list of filenames registred with --hkp-cacert. */ static std::vector hkp_cacert_filenames; -/* The timer tick used for housekeeping stuff. */ -#define TIMERTICK_INTERVAL (60) - -/* How oft to run the housekeeping. */ -#define HOUSEKEEPING_INTERVAL (600) - -/* This union is used to avoid compiler warnings in case a pointer is - 64 bit and an int 32 bit. We store an integer in a pointer and get - it back later (npth_getspecific et al.). */ -union int_and_ptr_u { - int aint; - assuan_fd_t afd; - void *aptr; -}; - -/* The key used to store the current file descriptor in the thread - local storage. We use this in conjunction with the - log_set_pid_suffix_cb feature. */ -#ifndef HAVE_W32_SYSTEM -static npth_key_t my_tlskey_current_fd; -#endif - /* Prototypes. */ static void cleanup(void); static fingerprint_list_t parse_ocsp_signer(const char *string); @@ -548,31 +525,6 @@ static void post_option_parsing(void) { set_debug(); } -#ifndef HAVE_W32_SYSTEM -static int pid_suffix_callback(unsigned long *r_suffix) { - union int_and_ptr_u value; - - memset(&value, 0, sizeof value); - value.aptr = npth_getspecific(my_tlskey_current_fd); - *r_suffix = value.aint; - return (*r_suffix != -1); /* Use decimal representation. */ -} -#endif /*!HAVE_W32_SYSTEM*/ - -static void thread_init(void) { - npth_init(); - gpgrt_set_syscall_clamp(npth_unprotect, npth_protect); - -/* Now with NPth running we can set the logging callback. Our - windows implementation does not yet feature the NPth TLS - functions. */ -#ifndef HAVE_W32_SYSTEM - if (npth_key_create(&my_tlskey_current_fd, NULL) == 0) - if (npth_setspecific(my_tlskey_current_fd, NULL) == 0) - log_set_pid_suffix_cb(pid_suffix_callback); -#endif /*!HAVE_W32_SYSTEM*/ -} - int dirmngr_main(int argc, char **argv) { enum cmd_and_opt_values cmd = (cmd_and_opt_values)0; ARGPARSE_ARGS pargs; @@ -614,7 +566,6 @@ int dirmngr_main(int argc, char **argv) { malloc_hooks.free = gcry_free; assuan_set_malloc_hooks(&malloc_hooks); assuan_set_assuan_log_prefix(log_get_prefix(NULL)); - assuan_set_system_hooks(ASSUAN_SYSTEM_NPTH); assuan_sock_init(); setup_libassuan_logging(&opt.debug, dirmngr_assuan_log_monitor); @@ -824,7 +775,6 @@ int dirmngr_main(int argc, char **argv) { log_debug("... okay\n"); } - thread_init(); cert_cache_init(hkp_cacert_filenames); crl_cache_init(); http_register_netactivity_cb(netactivity_action); @@ -840,7 +790,6 @@ int dirmngr_main(int argc, char **argv) { memset(&ctrlbuf, 0, sizeof ctrlbuf); dirmngr_init_default_ctrl(&ctrlbuf); - thread_init(); cert_cache_init(hkp_cacert_filenames); crl_cache_init(); if (!argc) @@ -858,7 +807,6 @@ int dirmngr_main(int argc, char **argv) { memset(&ctrlbuf, 0, sizeof ctrlbuf); dirmngr_init_default_ctrl(&ctrlbuf); - thread_init(); cert_cache_init(hkp_cacert_filenames); crl_cache_init(); rc = crl_fetch(&ctrlbuf, argv[0], &reader); @@ -1032,7 +980,7 @@ static int my_inotify_is_name(int fd, const char *name) { s = strrchr(name, '/'); if (s && s[1]) name = s + 1; - n = npth_read(fd, &buf, sizeof buf); + n = read(fd, &buf, sizeof buf); if (n < sizeof(struct inotify_event)) return 0; if (buf.ev.len < strlen(name) + 1) return 0; if (strcmp(buf.ev.name, name)) return 0; /* Not the desired file. */ diff --git a/legacy/gnupg/dirmngr/dns-stuff.cpp b/legacy/gnupg/dirmngr/dns-stuff.cpp index f0b665b6c..b5d1a01da 100644 --- a/legacy/gnupg/dirmngr/dns-stuff.cpp +++ b/legacy/gnupg/dirmngr/dns-stuff.cpp @@ -63,29 +63,17 @@ * be wrong for dns.c allocated data. */ #define dns_free(a) free((a)) -#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */ -#undef USE_NPTH -#endif -#ifdef USE_NPTH -#include -#endif - #include #include "../common/host2net.h" #include "../common/util.h" #include "dns-stuff.h" -#ifdef USE_NPTH -#define my_unprotect() npth_unprotect() -#define my_protect() npth_protect() -#else #define my_unprotect() \ do { \ } while (0) #define my_protect() \ do { \ } while (0) -#endif /* We allow the use of 0 instead of AF_UNSPEC - check this assumption. */ #if AF_UNSPEC != 0 diff --git a/legacy/gnupg/dirmngr/http.cpp b/legacy/gnupg/dirmngr/http.cpp index 73fce9a28..a00d5df4b 100644 --- a/legacy/gnupg/dirmngr/http.cpp +++ b/legacy/gnupg/dirmngr/http.cpp @@ -74,14 +74,6 @@ #include #endif /*!HAVE_W32_SYSTEM*/ -#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */ -#undef USE_NPTH -#endif - -#ifdef USE_NPTH -#include -#endif - #include #include @@ -93,13 +85,8 @@ #include "http-common.h" #include "http.h" -#ifdef USE_NPTH -#define my_select(a, b, c, d, e) npth_select((a), (b), (c), (d), (e)) -#define my_accept(a, b, c) npth_accept((a), (b), (c)) -#else #define my_select(a, b, c, d, e) select((a), (b), (c), (d), (e)) #define my_accept(a, b, c) accept((a), (b), (c)) -#endif #ifdef HAVE_W32_SYSTEM #define sock_close(a) closesocket(a) @@ -312,12 +299,12 @@ static void _my_socket_unref(int lnr, my_socket_t so, void (*preclose)(void *), static ssize_t my_gnutls_read(gnutls_transport_ptr_t ptr, void *buffer, size_t size) { my_socket_t sock = (my_socket_t)ptr; - return npth_read(sock->fd, buffer, size); + return read(sock->fd, buffer, size); } static ssize_t my_gnutls_write(gnutls_transport_ptr_t ptr, const void *buffer, size_t size) { my_socket_t sock = (my_socket_t)ptr; - return npth_write(sock->fd, buffer, size); + return write(sock->fd, buffer, size); } /* This notification function is called by estream whenever stream is @@ -2065,29 +2052,18 @@ static gpg_error_t connect_server(const char *server, unsigned short port, return 0; } -/* Helper to read from a socket. This handles npth things and - * EINTR. */ +/* Helper to read from a socket. This handles EINTR. */ static gpgrt_ssize_t read_server(assuan_fd_t sock, void *buffer, size_t size) { int nread; do { #ifdef HAVE_W32_SYSTEM /* Under Windows we need to use recv for a socket. */ -#if defined(USE_NPTH) - npth_unprotect(); -#endif nread = recv(FD2INT(sock), buffer, size, 0); -#if defined(USE_NPTH) - npth_protect(); -#endif #else /*!HAVE_W32_SYSTEM*/ -#ifdef USE_NPTH - nread = npth_read(sock, buffer, size); -#else nread = read(sock, buffer, size); -#endif #endif /*!HAVE_W32_SYSTEM*/ } while (nread == -1 && errno == EINTR); @@ -2103,23 +2079,13 @@ static gpg_error_t write_server(assuan_fd_t sock, const char *data, nleft = length; while (nleft > 0) { #if defined(HAVE_W32_SYSTEM) -#if defined(USE_NPTH) - npth_unprotect(); -#endif nwritten = send(FD2INT(sock), data, nleft, 0); -#if defined(USE_NPTH) - npth_protect(); -#endif if (nwritten == SOCKET_ERROR) { log_info("network write failed: ec=%d\n", (int)WSAGetLastError()); return GPG_ERR_NETWORK; } #else /*!HAVE_W32_SYSTEM*/ -#ifdef USE_NPTH - nwritten = npth_write(sock, data, nleft); -#else nwritten = write(sock, data, nleft); -#endif if (nwritten == -1) { if (errno == EINTR) continue; if (errno == EAGAIN) { diff --git a/legacy/gnupg/scd/apdu.cpp b/legacy/gnupg/scd/apdu.cpp index 46515c0a5..46809945a 100644 --- a/legacy/gnupg/scd/apdu.cpp +++ b/legacy/gnupg/scd/apdu.cpp @@ -18,21 +18,17 @@ * along with this program; if not, see . */ -/* NOTE: This module is also used by other software, thus the use of - the macro USE_NPTH is mandatory. For GnuPG this macro is - guaranteed to be defined true. */ +#include + +#include #include -#include #include #include #include #include -#ifdef USE_NPTH #include -#include #include -#endif /* If requested include the definitions for the remote APDU protocol code. */ @@ -115,58 +111,32 @@ struct reader_table_s { size_t atrlen; /* A zero length indicates that the ATR has not yet been read; i.e. the card is not ready for use. */ -#ifdef USE_NPTH - npth_mutex_t lock; -#endif + std::mutex lock; }; typedef struct reader_table_s *reader_table_t; /* A global table to keep track of active readers. */ static struct reader_table_s reader_table[MAX_READER]; -#ifdef USE_NPTH -static npth_mutex_t reader_table_lock; -#endif +static std::mutex reader_table_lock; /* Helper */ static int lock_slot(int slot) { -#ifdef USE_NPTH - int err; - - err = npth_mutex_lock(&reader_table[slot].lock); - if (err) { - log_error("failed to acquire apdu lock: %s\n", strerror(err)); - return SW_HOST_LOCKING_FAILED; - } -#endif /*USE_NPTH*/ + reader_table[slot].lock.lock(); return 0; } static int trylock_slot(int slot) { -#ifdef USE_NPTH - int err; - - err = npth_mutex_trylock(&reader_table[slot].lock); - if (err == EBUSY) + if (!reader_table[slot].lock.try_lock()) return SW_HOST_BUSY; - else if (err) { - log_error("failed to acquire apdu lock: %s\n", strerror(err)); - return SW_HOST_LOCKING_FAILED; - } -#endif /*USE_NPTH*/ return 0; } static void unlock_slot(int slot) { -#ifdef USE_NPTH - int err; - - err = npth_mutex_unlock(&reader_table[slot].lock); - if (err) log_error("failed to release apdu lock: %s\n", strerror(errno)); -#endif /*USE_NPTH*/ + reader_table[slot].lock.unlock(); } /* Find an unused reader slot for PORTSTR and put it into the reader @@ -744,7 +714,7 @@ gpg_error_t apdu_dev_list_start(const char *portstr, struct dev_list **l_p) { dl->portstr = portstr; dl->idx = 0; - npth_mutex_lock(&reader_table_lock); + reader_table_lock.lock(); #ifdef HAVE_LIBUSB if (opt.disable_ccid) { @@ -764,7 +734,7 @@ gpg_error_t apdu_dev_list_start(const char *portstr, struct dev_list **l_p) { log_debug("leave: apdu_open_reader => slot=-1 (no ccid)\n"); xfree(dl); - npth_mutex_unlock(&reader_table_lock); + reader_table_lock.unlock(); return GPG_ERR_ENODEV; } else dl->idx_max = 1; @@ -784,7 +754,7 @@ void apdu_dev_list_finish(struct dev_list *dl) { if (dl->ccid_table) ccid_dev_scan_finish(dl->ccid_table, dl->idx_max); #endif xfree(dl); - npth_mutex_unlock(&reader_table_lock); + reader_table_lock.unlock(); } int apdu_open_reader(struct dev_list *dl, int app_empty) { @@ -937,7 +907,7 @@ void apdu_prepare_exit(void) { if (!sentinel) { sentinel = 1; - npth_mutex_lock(&reader_table_lock); + std::lock_guard lock(reader_table_lock); for (slot = 0; slot < MAX_READER; slot++) if (reader_table[slot].used) { apdu_disconnect(slot); @@ -947,7 +917,6 @@ void apdu_prepare_exit(void) { reader_table[slot].rdrname = NULL; reader_table[slot].used = 0; } - npth_mutex_unlock(&reader_table_lock); sentinel = 0; } } @@ -1769,24 +1738,3 @@ int apdu_send_direct(int slot, size_t extended_length, const char *apdu_get_reader_name(int slot) { return reader_table[slot].rdrname; } - -gpg_error_t apdu_init(void) { -#ifdef USE_NPTH - gpg_error_t err; - int i; - - if (npth_mutex_init(&reader_table_lock, NULL)) goto leave; - - for (i = 0; i < MAX_READER; i++) - if (npth_mutex_init(&reader_table[i].lock, NULL)) goto leave; - - /* All done well. */ - return 0; - -leave: - err = gpg_error_from_syserror(); - log_error("apdu: error initializing mutex: %s\n", gpg_strerror(err)); - return err; -#endif /*USE_NPTH*/ - return 0; -} diff --git a/legacy/gnupg/scd/app-common.h b/legacy/gnupg/scd/app-common.h index e2a24fbf9..a44271353 100644 --- a/legacy/gnupg/scd/app-common.h +++ b/legacy/gnupg/scd/app-common.h @@ -19,11 +19,11 @@ * $Id$ */ -#ifndef GNUPG_SCD_APP_COMMON_H -#define GNUPG_SCD_APP_COMMON_H +#pragma once + +#include #include -#include #include "scdaemon.h" @@ -36,31 +36,31 @@ struct app_local_s; /* Defined by all app-*.c. */ struct app_ctx_s { - struct app_ctx_s *next; + struct app_ctx_s *next{nullptr}; - npth_mutex_t lock; + std::mutex lock; /* Number of connections currently using this application context. If this is not 0 the application has been initialized and the function pointers may be used. Note that for unsupported operations the particular function pointer is set to NULL */ - unsigned int ref_count; + unsigned int ref_count{0}; /* Used reader slot. */ - int slot; - - unsigned char *serialno; /* Serialnumber in raw form, allocated. */ - size_t serialnolen; /* Length in octets of serialnumber. */ - const char *apptype; - unsigned int card_version; - unsigned int card_status; - unsigned int reset_requested : 1; - unsigned int periodical_check_needed : 1; - unsigned int did_chv1 : 1; - unsigned int force_chv1 : 1; /* True if the card does not cache CHV1. */ - unsigned int did_chv2 : 1; - unsigned int did_chv3 : 1; - struct app_local_s *app_local; /* Local to the application. */ + int slot{0}; + + unsigned char *serialno{nullptr}; /* Serialnumber in raw form, allocated. */ + size_t serialnolen{0}; /* Length in octets of serialnumber. */ + const char *apptype{nullptr}; + unsigned int card_version{0}; + unsigned int card_status{0}; + unsigned int reset_requested {0}; + unsigned int periodical_check_needed {0}; + unsigned int did_chv1 {0}; + unsigned int force_chv1 {0}; /* True if the card does not cache CHV1. */ + unsigned int did_chv2 {0}; + unsigned int did_chv3 {0}; + struct app_local_s *app_local{nullptr}; /* Local to the application. */ struct { void (*deinit)(app_t app); gpg_error_t (*learn_status)(app_t app, ctrl_t ctrl, unsigned int flags); @@ -107,7 +107,7 @@ struct app_ctx_s { gpg_error_t (*pincb)(void *, const char *, char **), void *pincb_arg); - } fnc; + } fnc{nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr}; }; /*-- app-help.c --*/ @@ -189,5 +189,3 @@ gpg_error_t app_select_p15(app_t app); /*-- app-sc-hsm.c --*/ gpg_error_t app_select_sc_hsm(app_t app); - -#endif /*GNUPG_SCD_APP_COMMON_H*/ diff --git a/legacy/gnupg/scd/app.cpp b/legacy/gnupg/scd/app.cpp index 88b3f3d77..e8dc0d445 100644 --- a/legacy/gnupg/scd/app.cpp +++ b/legacy/gnupg/scd/app.cpp @@ -18,8 +18,10 @@ */ #include + +#include + #include -#include #include #include #include @@ -31,7 +33,7 @@ #include "iso7816.h" #include "scdaemon.h" -static npth_mutex_t app_list_lock; +static std::mutex app_list_lock; static app_t app_top; static void print_progress_line(void *opaque, const char *what, int pc, int cur, @@ -53,27 +55,15 @@ static void print_progress_line(void *opaque, const char *what, int pc, int cur, success; only then the unlock_reader function must be called after returning from the handler. */ static gpg_error_t lock_app(app_t app, ctrl_t ctrl) { - if (npth_mutex_lock(&app->lock)) { - gpg_error_t err = gpg_error_from_syserror(); - log_error("failed to acquire APP lock for %p: %s\n", app, - gpg_strerror(err)); - return err; - } - + app->lock.lock(); apdu_set_progress_cb(app->slot, print_progress_line, ctrl); - return 0; } /* Release a lock on the reader. See lock_reader(). */ static void unlock_app(app_t app) { apdu_set_progress_cb(app->slot, NULL, NULL); - - if (npth_mutex_unlock(&app->lock)) { - gpg_error_t err = gpg_error_from_syserror(); - log_error("failed to release APP lock for %p: %s\n", app, - gpg_strerror(err)); - } + app->lock.unlock(); } /* This function may be called to print information pertaining to the @@ -81,10 +71,9 @@ static void unlock_app(app_t app) { void app_dump_state(void) { app_t a; - npth_mutex_lock(&app_list_lock); + std::lock_guard lock(app_list_lock); for (a = app_top; a; a = a->next) log_info("app_dump_state: app=%p type='%s'\n", a, a->apptype); - npth_mutex_unlock(&app_list_lock); } static gpg_error_t check_conflict(app_t app, const char *name) { @@ -137,26 +126,13 @@ static gpg_error_t app_new_register(int slot, ctrl_t ctrl, const char *name, int want_undefined; /* Need to allocate a new one. */ - app = (app_t)xtrycalloc(1, sizeof *app); - if (!app) { - err = gpg_error_from_syserror(); - log_info("error allocating context: %s\n", gpg_strerror(err)); - return err; - } - + app = new app_ctx_s; app->slot = slot; app->card_status = (unsigned int)-1; - if (npth_mutex_init(&app->lock, NULL)) { - err = gpg_error_from_syserror(); - log_error("error initializing mutex: %s\n", gpg_strerror(err)); - xfree(app); - return err; - } - err = lock_app(app, ctrl); if (err) { - xfree(app); + delete(app); return err; } @@ -224,16 +200,17 @@ static gpg_error_t app_new_register(int slot, ctrl_t ctrl, const char *name, else log_info("no supported card application found: %s\n", gpg_strerror(err)); unlock_app(app); - xfree(app); + delete(app); return err; } app->periodical_check_needed = periodical_check_needed; - npth_mutex_lock(&app_list_lock); - app->next = app_top; - app_top = app; - npth_mutex_unlock(&app_list_lock); + { + std::lock_guard lock(app_list_lock); + app->next = app_top; + app_top = app; + } unlock_app(app); return 0; } @@ -284,7 +261,7 @@ gpg_error_t select_application(ctrl_t ctrl, const char *name, app_t *r_app, if (periodical_check_needed) scd_kick_the_loop(); } - npth_mutex_lock(&app_list_lock); + std::lock_guard lock(app_list_lock); for (a = app_top; a; a = a->next) { lock_app(a, ctrl); if (serialno_bin == NULL) break; @@ -310,8 +287,6 @@ gpg_error_t select_application(ctrl_t ctrl, const char *name, app_t *r_app, } else err = GPG_ERR_ENODEV; - npth_mutex_unlock(&app_list_lock); - return err; } @@ -363,7 +338,7 @@ static void deallocate_app(app_t app) { xfree(app->serialno); unlock_app(app); - xfree(app); + delete(app); } /* Free the resources associated with the application APP. APP is @@ -794,7 +769,7 @@ int scd_update_reader_status_file(void) { app_t a, app_next; int periodical_check_needed = 0; - npth_mutex_lock(&app_list_lock); + std::lock_guard lock(app_list_lock); for (a = app_top; a; a = app_next) { int sw; unsigned int status; @@ -835,37 +810,19 @@ int scd_update_reader_status_file(void) { unlock_app(a); } } - npth_mutex_unlock(&app_list_lock); return periodical_check_needed; } -/* This function must be called once to initialize this module. This - has to be done before a second thread is spawned. We can't do the - static initialization because Pth emulation code might not be able - to do a static init; in particular, it is not possible for W32. */ -gpg_error_t initialize_module_command(void) { - gpg_error_t err; - - if (npth_mutex_init(&app_list_lock, NULL)) { - err = gpg_error_from_syserror(); - log_error("app: error initializing mutex: %s\n", gpg_strerror(err)); - return err; - } - - return apdu_init(); -} - void app_send_card_list(ctrl_t ctrl) { app_t a; char buf[65]; - npth_mutex_lock(&app_list_lock); + std::lock_guard lock(app_list_lock); for (a = app_top; a; a = a->next) { if (DIM(buf) < 2 * a->serialnolen + 1) continue; bin2hex(a->serialno, a->serialnolen, buf); send_status_direct(ctrl, "SERIALNO", buf); } - npth_mutex_unlock(&app_list_lock); } diff --git a/legacy/gnupg/scd/ccid-driver.cpp b/legacy/gnupg/scd/ccid-driver.cpp index af1ae315d..6e1c3dfa0 100644 --- a/legacy/gnupg/scd/ccid-driver.cpp +++ b/legacy/gnupg/scd/ccid-driver.cpp @@ -71,6 +71,8 @@ #include #endif +#include + #if defined(HAVE_LIBUSB) || defined(TEST) #include @@ -83,9 +85,6 @@ #include #include #include -#ifdef HAVE_NPTH -#include -#endif /*HAVE_NPTH*/ #include #include @@ -868,31 +867,19 @@ static char *get_escaped_usb_string(libusb_device_handle *idev, int idx, /* First get the list of supported languages and use the first one. If we do don't find it we try to use English. Note that this is all in a 2 bute Unicode encoding using little endian. */ -#ifdef USE_NPTH - npth_unprotect(); -#endif rc = libusb_control_transfer(idev, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8), 0, (unsigned char *)buf, sizeof buf, 1000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect(); -#endif if (rc < 4) langid = 0x0409; /* English. */ else langid = (buf[3] << 8) | buf[2]; -#ifdef USE_NPTH - npth_unprotect(); -#endif rc = libusb_control_transfer( idev, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) + idx, langid, (unsigned char *)buf, sizeof buf, 1000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect(); -#endif if (rc < 2 || buf[1] != LIBUSB_DT_STRING) return NULL; /* Error or not a string. */ len = buf[0]; @@ -1355,20 +1342,10 @@ static void ccid_setup_intr(ccid_driver_t handle) { DEBUGOUT_2("CCID submit transfer (%x): %d", handle->ep_intr, err); } -static void *ccid_usb_thread(void *arg) { - libusb_context *ctx = (libusb_context *)arg; - +static void ccid_usb_thread() { while (ccid_usb_thread_is_alive) { -#ifdef USE_NPTH - npth_unprotect(); -#endif - libusb_handle_events_completed(ctx, NULL); -#ifdef USE_NPTH - npth_protect(); -#endif + libusb_handle_events_completed(NULL, NULL); } - - return NULL; } static int ccid_open_usb_reader(const char *spec_reader_name, int idx, @@ -1402,28 +1379,8 @@ static int ccid_open_usb_reader(const char *spec_reader_name, int idx, } if (ccid_usb_thread_is_alive++ == 0) { - npth_t thread; - npth_attr_t tattr; - int err; - - err = npth_attr_init(&tattr); - if (err) { - DEBUGOUT_1("npth_attr_init failed: %s\n", strerror(err)); - free(*handle); - *handle = NULL; - return err; - } - - npth_attr_setdetachstate(&tattr, NPTH_CREATE_DETACHED); - err = npth_create(&thread, &tattr, ccid_usb_thread, NULL); - if (err) { - DEBUGOUT_1("npth_create failed: %s\n", strerror(err)); - free(*handle); - *handle = NULL; - return err; - } - - npth_attr_destroy(&tattr); + std::thread thread(ccid_usb_thread); + thread.detach(); } rc = libusb_get_device_descriptor(dev, &desc); @@ -1568,13 +1525,7 @@ static void do_close_reader(ccid_driver_t handle) { if (rc != LIBUSB_ERROR_NOT_FOUND) while (!handle->powered_off) { DEBUGOUT("libusb_handle_events_completed\n"); -#ifdef USE_NPTH - npth_unprotect(); -#endif libusb_handle_events_completed(NULL, &handle->powered_off); -#ifdef USE_NPTH - npth_protect(); -#endif } } @@ -1672,15 +1623,9 @@ static int bulk_out(ccid_driver_t handle, unsigned char *msg, size_t msglen, } } -#ifdef USE_NPTH - npth_unprotect(); -#endif rc = libusb_bulk_transfer(handle->idev, handle->ep_bulk_out, (unsigned char *)((char *)msg), msglen, &transferred, 5000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect(); -#endif if (rc == 0 && transferred == msglen) return 0; if (rc) { @@ -1712,15 +1657,9 @@ static int bulk_in(ccid_driver_t handle, unsigned char *buffer, size_t length, memset(buffer, 0, length); retry: -#ifdef USE_NPTH - npth_unprotect(); -#endif rc = libusb_bulk_transfer(handle->idev, handle->ep_bulk_in, (unsigned char *)((char *)buffer), length, &msglen, timeout); -#ifdef USE_NPTH - npth_protect(); -#endif if (rc) { DEBUGOUT_1("usb_bulk_read error: %s\n", libusb_error_name(rc)); if (rc == LIBUSB_ERROR_NO_DEVICE) { @@ -1829,18 +1768,12 @@ static int abort_cmd(ccid_driver_t handle, int seqno) { /* Send the abort command to the control pipe. Note that we don't need to keep track of sent abort commands because there should never be another thread using the same slot concurrently. */ -#ifdef USE_NPTH - npth_unprotect(); -#endif rc = libusb_control_transfer( handle->idev, 0x21, /* bmRequestType: host-to-device, class specific, to interface. */ 1, /* ABORT */ (seqno << 8 | 0 /* slot */), handle->ifc_no, (unsigned char *)dummybuf, 0, 1000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect(); -#endif if (rc) { DEBUGOUT_1("usb_control_msg error: %s\n", libusb_error_name(rc)); return CCID_DRIVER_ERR_CARD_IO_ERROR; @@ -1863,15 +1796,9 @@ static int abort_cmd(ccid_driver_t handle, int seqno) { msglen = 10; set_msg_len(msg, 0); -#ifdef USE_NPTH - npth_unprotect(); -#endif rc = libusb_bulk_transfer(handle->idev, handle->ep_bulk_out, (unsigned char *)((char *)msg), msglen, &transferred, 5000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect(); -#endif if (rc == 0 && transferred == msglen) rc = 0; else if (rc) @@ -1880,15 +1807,9 @@ static int abort_cmd(ccid_driver_t handle, int seqno) { if (rc) return rc; -#ifdef USE_NPTH - npth_unprotect(); -#endif rc = libusb_bulk_transfer(handle->idev, handle->ep_bulk_in, (unsigned char *)((char *)msg), sizeof msg, &msglen, 5000 /*ms timeout*/); -#ifdef USE_NPTH - npth_protect(); -#endif if (rc) { DEBUGOUT_1("usb_bulk_read error in abort_cmd: %s\n", libusb_error_name(rc)); @@ -2052,14 +1973,8 @@ int ccid_slot_status(ccid_driver_t handle, int *statusbits, int on_wire) { if (rc == CCID_DRIVER_ERR_CARD_IO_ERROR && retries < 3) { if (!retries) { DEBUGOUT("USB: CALLING USB_CLEAR_HALT\n"); -#ifdef USE_NPTH - npth_unprotect(); -#endif libusb_clear_halt(handle->idev, handle->ep_bulk_in); libusb_clear_halt(handle->idev, handle->ep_bulk_out); -#ifdef USE_NPTH - npth_protect(); -#endif } else DEBUGOUT("USB: RETRYING bulk_in AGAIN\n"); retries++; @@ -2704,13 +2619,7 @@ int ccid_transceive(ccid_driver_t handle, const unsigned char *apdu_buf, resyncing = 0; if (tpdulen < 4) { -#ifdef USE_NPTH - npth_unprotect(); -#endif libusb_clear_halt(handle->idev, handle->ep_bulk_in); -#ifdef USE_NPTH - npth_protect(); -#endif return CCID_DRIVER_ERR_ABORTED; } @@ -3091,13 +3000,7 @@ int ccid_transceive_secure(ccid_driver_t handle, const unsigned char *apdu_buf, } if (tpdulen < 4) { -#ifdef USE_NPTH - npth_unprotect(); -#endif libusb_clear_halt(handle->idev, handle->ep_bulk_in); -#ifdef USE_NPTH - npth_protect(); -#endif return CCID_DRIVER_ERR_ABORTED; } if (debug_level > 1) diff --git a/legacy/gnupg/scd/command.cpp b/legacy/gnupg/scd/command.cpp index a3b8d7fce..48483f52e 100644 --- a/legacy/gnupg/scd/command.cpp +++ b/legacy/gnupg/scd/command.cpp @@ -26,9 +26,6 @@ #include #include #include -#ifdef USE_NPTH -#include -#endif #include #include @@ -1106,18 +1103,6 @@ static gpg_error_t cmd_lock(assuan_context_t ctx, char *line) { } else locked_session = ctrl->server_local; -#ifdef USE_NPTH - if (rc && has_option(line, "--wait")) { - rc = 0; - npth_sleep(1); /* Better implement an event mechanism. However, - for card operations this should be - sufficient. */ - /* FIXME: Need to check that the connection is still alive. - This can be done by issuing status messages. */ - goto retry; - } -#endif /*USE_NPTH*/ - if (rc) log_error("cmd_lock failed: %s\n", gpg_strerror(rc)); return rc; } diff --git a/legacy/gnupg/scd/scdaemon.cpp b/legacy/gnupg/scd/scdaemon.cpp index d811bcaa4..65bdd2471 100644 --- a/legacy/gnupg/scd/scdaemon.cpp +++ b/legacy/gnupg/scd/scdaemon.cpp @@ -33,7 +33,6 @@ #include #include #endif /*HAVE_W32_SYSTEM*/ -#include #include #include @@ -72,7 +71,6 @@ enum cmd_and_opt_values { oDebugWait, oDebugAllowCoreDump, oDebugCCIDDriver, - oDebugLogTid, oDebugAssuanLogCats, oNoGreeting, oNoOptions, @@ -106,7 +104,6 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_i(oDebugWait, "debug-wait", "@"), ARGPARSE_s_n(oDebugAllowCoreDump, "debug-allow-core-dump", "@"), ARGPARSE_s_n(oDebugCCIDDriver, "debug-ccid-driver", "@"), - ARGPARSE_s_n(oDebugLogTid, "debug-log-tid", "@"), ARGPARSE_p_u(oDebugAssuanLogCats, "debug-assuan-log-cats", "@"), ARGPARSE_s_n(oNoDetach, "no-detach", N_("do not detach from the console")), ARGPARSE_s_s(oLogFile, "log-file", N_("|FILE|write a log to FILE")), @@ -151,9 +148,7 @@ static struct debug_flags_s debug_flags[] = { This is not too good for power saving but given that there is no easy way to block on card status changes it is the best we can do. For PC/SC we could in theory use an extra thread to wait for status - changes but that requires a native thread because there is no way - to make the underlying PC/SC card change function block using a Npth - mechanism. Given that a native thread could only be used under W32 + changes. Given that a native thread could only be used under W32 we don't do that at all. */ #define TIMERTICK_INTERVAL_SEC (0) #define TIMERTICK_INTERVAL_USEC (500000) @@ -210,17 +205,6 @@ static const char *my_strusage(int level) { return p; } -static int tid_log_callback(unsigned long *rvalue) { - int len = sizeof(*rvalue); - npth_t thread; - - thread = npth_self(); - if (sizeof(thread) < len) len = sizeof(thread); - memcpy(rvalue, &thread, len); - - return 2; /* Use use hex representation. */ -} - /* Setup the debugging. With a LEVEL of NULL only the active debug flags are propagated to the subsystems. With LEVEL set, a specific set of debug flags is set; thus overriding all flags already @@ -290,7 +274,6 @@ int scd_main(int argc, char **argv) { int allow_coredump = 0; struct assuan_malloc_hooks malloc_hooks; int res; - npth_t pipecon_handler; early_system_init(); set_strusage(my_strusage); @@ -306,7 +289,6 @@ int scd_main(int argc, char **argv) { malloc_hooks.realloc = gcry_realloc; malloc_hooks.free = gcry_free; assuan_set_malloc_hooks(&malloc_hooks); - assuan_set_system_hooks(ASSUAN_SYSTEM_NPTH); assuan_sock_init(); setup_libassuan_logging(&opt.debug, NULL); @@ -408,9 +390,6 @@ int scd_main(int argc, char **argv) { ccid_set_debug_level(ccid_set_debug_level(-1) + 1); #endif /*HAVE_LIBUSB*/ break; - case oDebugLogTid: - log_set_pid_suffix_cb(tid_log_callback); - break; case oDebugAssuanLogCats: set_libassuan_log_cats(pargs.r.ret_ulong); break; @@ -497,11 +476,6 @@ int scd_main(int argc, char **argv) { set_debug(debug_level); - if (initialize_module_command()) { - log_error("initialization failed\n"); - exit(1); - } - /* Now start with logging to a file if this is desired. */ if (logfile) { log_set_file(logfile); @@ -519,7 +493,6 @@ int scd_main(int argc, char **argv) { { /* This is the simple pipe based server */ ctrl_t ctrl; - npth_attr_t tattr; int fd = -1; #ifndef HAVE_W32_SYSTEM @@ -533,9 +506,6 @@ int scd_main(int argc, char **argv) { } #endif - npth_init(); - gpgrt_set_syscall_clamp(npth_unprotect, npth_protect); - /* If --debug-allow-core-dump has been given we also need to switch the working directory to a place where we can actually write. */ @@ -546,13 +516,6 @@ int scd_main(int argc, char **argv) { log_debug("changed working directory to '/tmp'\n"); } - res = npth_attr_init(&tattr); - if (res) { - log_error("error allocating thread attributes: %s\n", strerror(res)); - scd_exit(2); - } - npth_attr_setdetachstate(&tattr, NPTH_CREATE_DETACHED); - ctrl = (ctrl_t)xtrycalloc(1, sizeof *ctrl); if (!ctrl) { log_error("error allocating connection control data: %s\n", diff --git a/legacy/libassuan/src/assuan.h b/legacy/libassuan/src/assuan.h index 41405e968..852d2810f 100644 --- a/legacy/libassuan/src/assuan.h +++ b/legacy/libassuan/src/assuan.h @@ -505,82 +505,6 @@ int __assuan_sendmsg(assuan_context_t ctx, assuan_fd_t fd, pid_t __assuan_waitpid(assuan_context_t ctx, pid_t pid, int nowait, int *status, int options); -#define ASSUAN_SYSTEM_NPTH_IMPL \ - static void _assuan_npth_usleep(assuan_context_t ctx, unsigned int usec) { \ - (void)ctx; \ - npth_usleep(usec); \ - } \ - static ssize_t _assuan_npth_read(assuan_context_t ctx, assuan_fd_t fd, \ - void *buffer, size_t size) { \ - ssize_t res; \ - (void)ctx; \ - npth_unprotect(); \ - res = __assuan_read(ctx, fd, buffer, size); \ - npth_protect(); \ - return res; \ - } \ - static ssize_t _assuan_npth_write(assuan_context_t ctx, assuan_fd_t fd, \ - const void *buffer, size_t size) { \ - ssize_t res; \ - (void)ctx; \ - npth_unprotect(); \ - res = __assuan_write(ctx, fd, buffer, size); \ - npth_protect(); \ - return res; \ - } \ - static int _assuan_npth_recvmsg(assuan_context_t ctx, assuan_fd_t fd, \ - assuan_msghdr_t msg, int flags) { \ - int res; \ - (void)ctx; \ - npth_unprotect(); \ - res = __assuan_recvmsg(ctx, fd, msg, flags); \ - npth_protect(); \ - return res; \ - } \ - static int _assuan_npth_sendmsg(assuan_context_t ctx, assuan_fd_t fd, \ - const assuan_msghdr_t msg, int flags) { \ - int res; \ - (void)ctx; \ - npth_unprotect(); \ - res = __assuan_sendmsg(ctx, fd, msg, flags); \ - npth_protect(); \ - return res; \ - } \ - static pid_t _assuan_npth_waitpid(assuan_context_t ctx, pid_t pid, \ - int nowait, int *status, int options) { \ - pid_t res; \ - (void)ctx; \ - npth_unprotect(); \ - res = __assuan_waitpid(ctx, pid, nowait, status, options); \ - npth_protect(); \ - return res; \ - } \ - static int _assuan_npth_connect(assuan_context_t ctx, int sock, \ - struct sockaddr *addr, socklen_t len) { \ - int res; \ - npth_unprotect(); \ - res = __assuan_connect(ctx, sock, addr, len); \ - npth_protect(); \ - return res; \ - } \ - \ - struct assuan_system_hooks _assuan_system_npth = { \ - ASSUAN_SYSTEM_HOOKS_VERSION, \ - _assuan_npth_usleep, \ - __assuan_pipe, \ - __assuan_close, \ - _assuan_npth_read, \ - _assuan_npth_write, \ - _assuan_npth_recvmsg, \ - _assuan_npth_sendmsg, \ - __assuan_spawn, \ - _assuan_npth_waitpid, \ - __assuan_socketpair, \ - __assuan_socket, \ - _assuan_npth_connect} - -extern struct assuan_system_hooks _assuan_system_npth; -#define ASSUAN_SYSTEM_NPTH &_assuan_system_npth #ifdef __cplusplus } diff --git a/legacy/libgcrypt/src/g10lib.h b/legacy/libgcrypt/src/g10lib.h index a98016200..4b18cb19d 100644 --- a/legacy/libgcrypt/src/g10lib.h +++ b/legacy/libgcrypt/src/g10lib.h @@ -93,8 +93,6 @@ /*-- src/global.c -*/ gpg_error_t _gcry_vcontrol(enum gcry_ctl_cmds cmd, va_list arg_ptr); -void _gcry_pre_syscall(void); -void _gcry_post_syscall(void); int _gcry_get_debug_flag(unsigned int mask); char *_gcry_get_config(int mode, const char *what); diff --git a/legacy/libgcrypt/src/gcrypt.h b/legacy/libgcrypt/src/gcrypt.h index 46579c978..4f59f661c 100644 --- a/legacy/libgcrypt/src/gcrypt.h +++ b/legacy/libgcrypt/src/gcrypt.h @@ -193,8 +193,7 @@ enum gcry_ctl_cmds { GCRYCTL_SET_SBOX = 73, GCRYCTL_DRBG_REINIT = 74, GCRYCTL_SET_TAGLEN = 75, - GCRYCTL_GET_TAGLEN = 76, - GCRYCTL_REINIT_SYSCALL_CLAMP = 77 + GCRYCTL_GET_TAGLEN = 76 }; /* Perform various operations defined by CMD. */ diff --git a/legacy/libgcrypt/src/global.cpp b/legacy/libgcrypt/src/global.cpp index a26943010..3d4d0fc05 100644 --- a/legacy/libgcrypt/src/global.cpp +++ b/legacy/libgcrypt/src/global.cpp @@ -49,14 +49,6 @@ static unsigned int debug_flags; /* Controlled by global_init(). */ static int any_init_done; -/* - * Functions called before and after blocking syscalls. - * Initialized by global_init and used via - * _gcry_pre_syscall and _gcry_post_syscall. - */ -static void (*pre_syscall_func)(void); -static void (*post_syscall_func)(void); - /* Memory management. */ static gcry_handler_no_mem_t outofcore_handler; @@ -71,10 +63,6 @@ static void global_init(void) { if (any_init_done) return; any_init_done = 1; - /* Get the system call clamp functions. */ - if (!pre_syscall_func) - gpgrt_get_syscall_clamp(&pre_syscall_func, &post_syscall_func); - /* Before we do any other initialization we need to test available hardware features. */ _gcry_detect_hw_features(); @@ -404,11 +392,6 @@ gpg_error_t _gcry_vcontrol(enum gcry_ctl_cmds cmd, va_list arg_ptr) { (_gcry_secmem_get_flags() | GCRY_SECMEM_FLAG_NO_PRIV_DROP)); break; - case GCRYCTL_REINIT_SYSCALL_CLAMP: - if (!pre_syscall_func) - gpgrt_get_syscall_clamp(&pre_syscall_func, &post_syscall_func); - break; - default: rc = GPG_ERR_INV_OP; } @@ -660,16 +643,6 @@ char *_gcry_xstrdup(const char *string) { return p; } -/* Used before blocking system calls. */ -void _gcry_pre_syscall(void) { - if (pre_syscall_func) pre_syscall_func(); -} - -/* Used after blocking system calls. */ -void _gcry_post_syscall(void) { - if (post_syscall_func) post_syscall_func(); -} - int _gcry_get_debug_flag(unsigned int mask) { return (debug_flags & mask); } /* It is often useful to get some feedback of long running operations. diff --git a/legacy/libgpg-error/src/estream.cpp b/legacy/libgpg-error/src/estream.cpp index 1f09ca3e1..9f567c312 100644 --- a/legacy/libgpg-error/src/estream.cpp +++ b/legacy/libgpg-error/src/estream.cpp @@ -181,13 +181,6 @@ static unsigned char custom_std_fds_valid[3]; */ std::mutex 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. */ @@ -353,10 +346,6 @@ static void do_deinit(void) { list and the streams with possible undesirable effects. Given that we don't close the stream either, it should not matter that 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; } /* @@ -372,30 +361,6 @@ int _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; -} - -/* - * 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. */ @@ -744,11 +709,9 @@ static gpgrt_ssize_t func_fd_read(void *cookie, void *buffer, size_t size) else if (IS_INVALID_FD(file_cookie->fd)) { bytes_read = 0; } else { - if (pre_syscall_func) pre_syscall_func(); do { bytes_read = read(file_cookie->fd, buffer, size); } while (bytes_read == -1 && errno == EINTR); - if (post_syscall_func) post_syscall_func(); } trace_errno(bytes_read == -1, ("leave: bytes_read=%d", (int)bytes_read)); @@ -768,11 +731,9 @@ static gpgrt_ssize_t func_fd_write(void *cookie, const void *buffer, if (IS_INVALID_FD(file_cookie->fd)) { bytes_written = size; /* Yeah: Success writing to the bit bucket. */ } else if (buffer) { - if (pre_syscall_func) pre_syscall_func(); do { bytes_written = write(file_cookie->fd, buffer, size); } while (bytes_written == -1 && errno == EINTR); - if (post_syscall_func) post_syscall_func(); } else bytes_written = size; /* Note that for a flush SIZE should be 0. */ @@ -793,9 +754,7 @@ static int func_fd_seek(void *cookie, gpgrt_off_t *offset, int whence) { _set_errno(ESPIPE); err = -1; } else { - if (pre_syscall_func) pre_syscall_func(); offset_new = lseek(file_cookie->fd, *offset, whence); - if (post_syscall_func) post_syscall_func(); if (offset_new == -1) err = -1; else { @@ -883,19 +842,17 @@ static struct cookie_io_functions_s estream_functions_fd = { typedef struct estream_cookie_w32 { HANDLE hd; /* The handle we are using for actual output. */ int no_close; /* If set we won't close the handle. */ - int no_syscall_clamp; /* Do not use the syscall clamp. */ } * estream_cookie_w32_t; /* * Create function for w32 handle objects. */ static int func_w32_create(void **cookie, HANDLE hd, unsigned int modeflags, - int no_close, int no_syscall_clamp) { + int no_close) { estream_cookie_w32_t w32_cookie; int err; - trace(("enter: hd=%p mf=%x nc=%d nsc=%d", hd, modeflags, no_close, - no_syscall_clamp)); + trace(("enter: hd=%p mf=%x nc=%d nsc=%d", hd, modeflags, no_close)); w32_cookie = mem_alloc(sizeof(*w32_cookie)); if (!w32_cookie) err = -1; @@ -907,7 +864,6 @@ static int func_w32_create(void **cookie, HANDLE hd, unsigned int modeflags, w32_cookie->hd = hd; w32_cookie->no_close = no_close; - w32_cookie->no_syscall_clamp = no_syscall_clamp; *cookie = w32_cookie; err = 0; } @@ -918,9 +874,6 @@ static int func_w32_create(void **cookie, HANDLE hd, unsigned int modeflags, /* * Read function for W32 handle objects. - * - * Note that this function may also be used by the reader thread of - * w32-stream. In that case the NO_SYSCALL_CLAMP is set. */ static gpgrt_ssize_t func_w32_read(void *cookie, void *buffer, size_t size) { estream_cookie_w32_t w32_cookie = (estream_cookie_w32_t)cookie; @@ -933,7 +886,6 @@ static gpgrt_ssize_t func_w32_read(void *cookie, void *buffer, size_t size) { else if (w32_cookie->hd == INVALID_HANDLE_VALUE) { bytes_read = 0; } else { - if (pre_syscall_func && !w32_cookie->no_syscall_clamp) pre_syscall_func(); do { DWORD nread, ec; @@ -950,7 +902,6 @@ static gpgrt_ssize_t func_w32_read(void *cookie, void *buffer, size_t size) { } else bytes_read = (int)nread; } while (bytes_read == -1 && errno == EINTR); - if (post_syscall_func && !w32_cookie->no_syscall_clamp) post_syscall_func(); } trace_errno(bytes_read == -1, ("leave: bytes_read=%d", (int)bytes_read)); @@ -959,9 +910,6 @@ static gpgrt_ssize_t func_w32_read(void *cookie, void *buffer, size_t size) { /* * Write function for W32 handle objects. - * - * Note that this function may also be used by the writer thread of - * w32-stream. In that case the NO_SYSCALL_CLAMP is set. */ static gpgrt_ssize_t func_w32_write(void *cookie, const void *buffer, size_t size) { @@ -973,7 +921,6 @@ static gpgrt_ssize_t func_w32_write(void *cookie, const void *buffer, if (w32_cookie->hd == INVALID_HANDLE_VALUE) { bytes_written = size; /* Yeah: Success writing to the bit bucket. */ } else if (buffer) { - if (pre_syscall_func && !w32_cookie->no_syscall_clamp) pre_syscall_func(); do { DWORD nwritten; @@ -986,7 +933,6 @@ static gpgrt_ssize_t func_w32_write(void *cookie, const void *buffer, } else bytes_written = (int)nwritten; } while (bytes_written == -1 && errno == EINTR); - if (post_syscall_func && !w32_cookie->no_syscall_clamp) post_syscall_func(); } else bytes_written = size; /* Note that for a flush SIZE should be 0. */ @@ -1021,13 +967,10 @@ static int func_w32_seek(void *cookie, gpgrt_off_t *offset, int whence) { _set_errno(EINVAL); return -1; } - if (pre_syscall_func && !w32_cookie->no_syscall_clamp) pre_syscall_func(); if (!SetFilePointerEx(w32_cookie->hd, distance, &newoff, method)) { _set_errno(map_w32_to_errno(GetLastError())); - if (post_syscall_func) post_syscall_func(); return -1; } - if (post_syscall_func && !w32_cookie->no_syscall_clamp) post_syscall_func(); /* Note that gpgrt_off_t is always 64 bit. */ *offset = (gpgrt_off_t)newoff.QuadPart; @@ -1126,9 +1069,7 @@ static gpgrt_ssize_t func_fp_read(void *cookie, void *buffer, size_t size) if (!size) return -1; /* We don't know whether anything is pending. */ if (file_cookie->fp) { - if (pre_syscall_func) pre_syscall_func(); bytes_read = fread(buffer, 1, size, file_cookie->fp); - if (post_syscall_func) post_syscall_func(); } else bytes_read = 0; if (!bytes_read && ferror(file_cookie->fp)) return -1; @@ -1144,7 +1085,6 @@ static gpgrt_ssize_t func_fp_write(void *cookie, const void *buffer, size_t bytes_written; if (file_cookie->fp) { - if (pre_syscall_func) pre_syscall_func(); if (buffer) { #ifdef HAVE_W32_SYSTEM /* Using an fwrite to stdout connected to the console fails @@ -1168,7 +1108,6 @@ static gpgrt_ssize_t func_fp_write(void *cookie, const void *buffer, bytes_written = size; fflush(file_cookie->fp); - if (post_syscall_func) post_syscall_func(); } else bytes_written = size; /* Successfully written to the bit bucket. */ @@ -1188,16 +1127,13 @@ static int func_fp_seek(void *cookie, gpgrt_off_t *offset, int whence) { return -1; } - if (pre_syscall_func) pre_syscall_func(); 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(); return -1; } offset_new = ftell(file_cookie->fp); - if (post_syscall_func) post_syscall_func(); if (offset_new == -1) { /* fprintf (stderr, "\nftell failed: errno=%d (%s)\n", */ /* errno,strerror (errno)); */ @@ -1216,9 +1152,7 @@ static int func_fp_destroy(void *cookie) { if (fp_cookie) { if (fp_cookie->fp) { - if (pre_syscall_func) pre_syscall_func(); fflush(fp_cookie->fp); - if (post_syscall_func) post_syscall_func(); err = fp_cookie->no_close ? 0 : fclose(fp_cookie->fp); } else err = 0; @@ -1652,9 +1586,7 @@ static int create_stream(estream_t *r_stream, void *cookie, es_syshd_t *syshd, #if HAVE_W32_SYSTEM if ((xmode & X_POLLABLE) && kind != BACKEND_W32) { /* We require the W32 backend, because only that allows us to - * write directly using the native W32 API and to disable the - * system clamp. Note that func_w32_create has already been - * called with the flag to disable the system call clamp. */ + * write directly using the native W32 API. */ _set_errno(EINVAL); err = -1; goto out; diff --git a/legacy/libgpg-error/src/gpg-error.h b/legacy/libgpg-error/src/gpg-error.h index 43325cadb..2a7f5e9c3 100644 --- a/legacy/libgpg-error/src/gpg-error.h +++ b/legacy/libgpg-error/src/gpg-error.h @@ -719,12 +719,6 @@ gpg_error_t gpg_err_init(void) _GPG_ERR_CONSTRUCTOR; } while (0) #endif -/* Register blocking system I/O clamping functions. */ -void gpgrt_set_syscall_clamp(void (*pre)(void), void (*post)(void)); - -/* Get current I/O clamping functions. */ -void gpgrt_get_syscall_clamp(void (**r_pre)(void), void (**r_post)(void)); - /* Register a custom malloc/realloc/free function. */ void gpgrt_set_alloc_func(void *(*f)(void *a, size_t n)); diff --git a/legacy/libgpg-error/src/gpgrt-int.h b/legacy/libgpg-error/src/gpgrt-int.h index cb060e703..d69609a62 100644 --- a/legacy/libgpg-error/src/gpgrt-int.h +++ b/legacy/libgpg-error/src/gpgrt-int.h @@ -122,8 +122,6 @@ typedef struct _gpgrt_stream_internal *estream_internal_t; /* Local prototypes for estream. */ int _gpgrt_estream_init(void); -void _gpgrt_set_syscall_clamp(void (*pre)(void), void (*post)(void)); -void _gpgrt_get_syscall_clamp(void (**r_pre)(void), void (**r_post)(void)); gpgrt_stream_t _gpgrt_fopen(const char *_GPGRT__RESTRICT path, const char *_GPGRT__RESTRICT mode); @@ -249,7 +247,4 @@ gpg_error_t _gpgrt_b64dec_proc(gpgrt_b64state_t state, void *buffer, size_t length, size_t *r_nbytes); gpg_error_t _gpgrt_b64dec_finish(gpgrt_b64state_t state); -void _gpgrt_lock_set_lock_clamp(void (*pre)(void), void (*post)(void)); -void _gpgrt_thread_set_syscall_clamp(void (*pre)(void), void (*post)(void)); - #endif /*_GPGRT_GPGRT_INT_H*/ diff --git a/legacy/libgpg-error/src/visibility.cpp b/legacy/libgpg-error/src/visibility.cpp index de2d14fd1..70a068653 100644 --- a/legacy/libgpg-error/src/visibility.cpp +++ b/legacy/libgpg-error/src/visibility.cpp @@ -27,14 +27,6 @@ const char *gpg_strerror(gpg_error_t err) { return _gpg_strerror(err); } void gpg_err_set_errno(int err) { _gpg_err_set_errno(err); } -void gpgrt_set_syscall_clamp(void (*pre)(void), void (*post)(void)) { - _gpgrt_set_syscall_clamp(pre, post); -} - -void gpgrt_get_syscall_clamp(void (**r_pre)(void), void (**r_post)(void)) { - _gpgrt_get_syscall_clamp(r_pre, r_post); -} - void gpgrt_set_alloc_func(void *(*f)(void *a, size_t n)) { _gpgrt_set_alloc_func(f); } diff --git a/legacy/libgpg-error/src/visibility.h b/legacy/libgpg-error/src/visibility.h index 70060a1f6..c6250f73a 100644 --- a/legacy/libgpg-error/src/visibility.h +++ b/legacy/libgpg-error/src/visibility.h @@ -98,8 +98,6 @@ #define gpgrt_vasprintf _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_snprintf _gpgrt_USE_UNDERSCORED_FUNCTION -#define gpgrt_set_syscall_clamp _gpgrt_USE_UNDERSCORED_FUNCTION -#define gpgrt_get_syscall_clamp _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_set_alloc_func _gpgrt_USE_UNDERSCORED_FUNCTION #endif /*!_GPGRT_INCL_BY_VISIBILITY_C*/ diff --git a/legacy/npth/AUTHORS b/legacy/npth/AUTHORS deleted file mode 100644 index 52c16b9d4..000000000 --- a/legacy/npth/AUTHORS +++ /dev/null @@ -1,51 +0,0 @@ -Package: npth -Download: https://gnupg.org/ftp/gcrypt/npth/ -Repository: git://git.gnupg.org/npth.git -Maintainer: Werner Koch -Bug reports: gnupg-devel@gnupg.org -Security related bug reports: security@gnupg.org -License: LGPLv2+ - - -nPth is free software. See the file COPYING.LIB for copying -conditions. License copyright years may be listed using range -notation, e.g., 2000-2013, indicating that every year in the range, -inclusive, is a copyrightable year that would otherwise be listed -individually. - - -* Authors - - g10 Code GmbH - - Design and implementation. - - - -* Copyright - - nPth is Copyright (C) 2011, 2012, 2014, 2015, 2017 g10 Code GmbH - - nPth 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. - - nPth 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 . - - - -# This file is Copyright 2011, 2012 g10 Code GmbH -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/legacy/npth/COPYING.LIB b/legacy/npth/COPYING.LIB deleted file mode 100644 index 5522aa5f3..000000000 --- a/legacy/npth/COPYING.LIB +++ /dev/null @@ -1,508 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - - Copyright (C) - - 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 2.1 of the License, 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/legacy/npth/src/npth.cpp b/legacy/npth/src/npth.cpp deleted file mode 100644 index 166af75c7..000000000 --- a/legacy/npth/src/npth.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* npth.c - a lightweight implementation of pth over pthread. - * Copyright (C) 2011 g10 Code GmbH - * - * This file is part of nPth. - * - * nPth 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. - * - * nPth 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 . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static int my_usleep(unsigned int usec) { - struct timespec req = {0, ((long)usec) * 1000}; - return nanosleep(&req, NULL); -} - -#include -#ifndef HAVE_PSELECT -#include -#endif - -#include "npth.h" - -/* The global lock that excludes all threads but one. */ -pthread_mutex_t scepter = PTHREAD_MUTEX_INITIALIZER; - -static void enter_npth(void) { - int res; - - res = pthread_mutex_unlock(&scepter); - assert(res == 0); -} - -static void leave_npth(void) { - int res; - int save_errno = errno; - - do { - res = pthread_mutex_lock(&scepter); - } while (res < 0 && errno == EINTR); - - assert(!res); - errno = save_errno; -} - -#define ENTER() enter_npth() -#define LEAVE() leave_npth() - -int npth_init(void) { - int res; - - res = pthread_mutex_init(&scepter, NULL); - if (res < 0) return errno; - - LEAVE(); - return 0; -} - -struct startup_s { - void *(*start_routine)(void *); - void *arg; -}; - -static void *thread_start(void *startup_arg) { - struct startup_s *startup = (startup_s *)startup_arg; - void *(*start_routine)(void *); - void *arg; - void *result; - - start_routine = startup->start_routine; - arg = startup->arg; - free(startup); - - LEAVE(); - result = (*start_routine)(arg); - /* Note: instead of returning here, we might end up in - npth_exit() instead. */ - ENTER(); - - return result; -} - -int npth_create(npth_t *thread, const npth_attr_t *attr, - void *(*start_routine)(void *), void *arg) { - int err; - struct startup_s *startup; - - startup = (startup_s *)malloc(sizeof(*startup)); - if (!startup) return errno; - - startup->start_routine = start_routine; - startup->arg = arg; - err = pthread_create(thread, attr, thread_start, startup); - if (err) { - free(startup); - return err; - } - - /* Memory is released in thread_start. */ - return 0; -} - -int npth_join(npth_t thread, void **retval) { - int err; - -#ifdef HAVE_PTHREAD_TRYJOIN_NP - /* No need to allow competing threads to enter when we can get the - lock immediately. pthread_tryjoin_np is a GNU extension. */ - err = pthread_tryjoin_np(thread, retval); - if (err != EBUSY) return err; -#endif /*HAVE_PTHREAD_TRYJOIN_NP*/ - - ENTER(); - err = pthread_join(thread, retval); - LEAVE(); - return err; -} - -void npth_exit(void *retval) { - ENTER(); - pthread_exit(retval); - /* Never reached. But just in case pthread_exit does return... */ - LEAVE(); -} - -int npth_mutex_lock(npth_mutex_t *mutex) { - int err; - - /* No need to allow competing threads to enter when we can get the - lock immediately. */ - err = pthread_mutex_trylock(mutex); - if (err != EBUSY) return err; - - ENTER(); - err = pthread_mutex_lock(mutex); - LEAVE(); - return err; -} - -#ifndef _NPTH_NO_RWLOCK -int npth_rwlock_rdlock(npth_rwlock_t *rwlock) { - int err; - -#ifdef HAVE_PTHREAD_RWLOCK_TRYRDLOCK - /* No need to allow competing threads to enter when we can get the - lock immediately. */ - err = pthread_rwlock_tryrdlock(rwlock); - if (err != EBUSY) return err; -#endif - - ENTER(); - err = pthread_rwlock_rdlock(rwlock); - LEAVE(); - return err; -} - -int npth_rwlock_wrlock(npth_rwlock_t *rwlock) { - int err; - -#ifdef HAVE_PTHREAD_RWLOCK_TRYWRLOCK - /* No need to allow competing threads to enter when we can get the - lock immediately. */ - err = pthread_rwlock_trywrlock(rwlock); - if (err != EBUSY) return err; -#endif - - ENTER(); - err = pthread_rwlock_wrlock(rwlock); - LEAVE(); - return err; -} - -#endif - -/* Standard POSIX Replacement API */ - -int npth_usleep(unsigned int usec) { - int res; - - ENTER(); - res = my_usleep(usec); - LEAVE(); - return res; -} - -unsigned int npth_sleep(unsigned int sec) { - unsigned res; - - ENTER(); - res = sleep(sec); - LEAVE(); - return res; -} - -int npth_system(const char *cmd) { - int res; - - ENTER(); - res = system(cmd); - LEAVE(); - return res; -} - -pid_t npth_waitpid(pid_t pid, int *status, int options) { - pid_t res; - - ENTER(); - res = waitpid(pid, status, options); - LEAVE(); - return res; -} - -int npth_connect(int s, const struct sockaddr *addr, socklen_t addrlen) { - int res; - - ENTER(); - res = connect(s, addr, addrlen); - LEAVE(); - return res; -} - -int npth_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { - int res; - - ENTER(); - res = accept(s, addr, addrlen); - LEAVE(); - return res; -} - -int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, - struct timeval *timeout) { - int res; - - ENTER(); - res = select(nfd, rfds, wfds, efds, timeout); - LEAVE(); - return res; -} - -ssize_t npth_read(int fd, void *buf, size_t nbytes) { - ssize_t res; - - ENTER(); - res = read(fd, buf, nbytes); - LEAVE(); - return res; -} - -ssize_t npth_write(int fd, const void *buf, size_t nbytes) { - ssize_t res; - - ENTER(); - res = write(fd, buf, nbytes); - LEAVE(); - return res; -} - -int npth_recvmsg(int fd, struct msghdr *msg, int flags) { - int res; - - ENTER(); - res = recvmsg(fd, msg, flags); - LEAVE(); - return res; -} - -int npth_sendmsg(int fd, const struct msghdr *msg, int flags) { - int res; - - ENTER(); - res = sendmsg(fd, msg, flags); - LEAVE(); - return res; -} - -void npth_protect(void) { LEAVE(); } - -void npth_unprotect(void) { ENTER(); } diff --git a/legacy/npth/src/npth.h b/legacy/npth/src/npth.h deleted file mode 100644 index 249c958b2..000000000 --- a/legacy/npth/src/npth.h +++ /dev/null @@ -1,233 +0,0 @@ -/* npth.h - a lightweight implementation of pth over pthread. - * Copyright (C) 2011, 2012, 2015, 2017 g10 Code GmbH - * - * This file is part of nPth. - * - * nPth 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. - * - * nPth 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 . - */ - -/* Changes to GNU Pth: - * - * Return value and arguments follow strictly the pthread format: - * - * - Return the error number instead of setting errno, - * - * - No _new functions. Use _init functions instead. - * - * - Attributes are set by specific instead of generic getter/setter - * functions. - * - * - Offers replacement functions for sendmsg and recvmsg. - */ - -#ifndef _NPTH_H -#define _NPTH_H - -#include -#include -#include -#include -#include -#include -#include -#define _npth_socklen_t socklen_t -#include - -#ifdef __ANDROID__ -#include -#if __ANDROID_API__ < 9 -/* Android 8 and earlier are missing rwlocks. We punt to mutexes in - that case. */ -#define _NPTH_NO_RWLOCK 1 -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#if 0 /* (Keep Emacsens' auto-indent happy.) */ -} -#endif -#endif - -/* Global Library Management */ - -#define npth_t pthread_t - -/* Initialize the library and convert current thread to main thread. - Must be first npth function called in a process. Returns error - number on error and 0 on success. */ - -int npth_init(void); - -/* Thread Attribute Handling */ - -#define npth_attr_t pthread_attr_t -#define npth_attr_init pthread_attr_init -#define npth_attr_destroy pthread_attr_destroy -#define NPTH_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE -#define NPTH_CREATE_DETACHED PTHREAD_CREATE_DETACHED -#define npth_attr_getdetachstate pthread_attr_getdetachstate -#define npth_attr_setdetachstate pthread_attr_setdetachstate - -/* Thread Control */ -int npth_create(npth_t *thread, const npth_attr_t *attr, - void *(*start_routine)(void *), void *arg); - -#define npth_self pthread_self - -int npth_join(npth_t thread, void **retval); -#define npth_detach pthread_detach - -void npth_exit(void *retval); - -/* Key-Based Storage */ - -#define npth_key_t pthread_key_t -#define npth_key_create pthread_key_create -#define npth_key_delete pthread_key_delete -#define npth_setspecific pthread_setspecific -#define npth_getspecific pthread_getspecific - -/* Process Forking */ - -/* POSIX only supports a global atfork handler. So, to implement - per-thread handlers like in Pth, we would need to keep the data in - thread local storage. But, neither pthread_self nor - pthread_getspecific are standardized as async-signal-safe (what a - joke!), and __thread is an ELF extension. Still, using - pthread_self and pthread_getspecific is probably portable - enough to implement the atfork handlers, if required. - - pth_fork is only required because fork() is not pth aware. fork() - is pthread aware though, and already only creates a single thread - in the child process. */ -/* pth_atfork_push, pth_atfork_pop, pth_fork */ - -/* Synchronization */ - -#define npth_mutexattr_t pthread_mutexattr_t -#define npth_mutexattr_init pthread_mutexattr_init -#define npth_mutexattr_destroy pthread_mutexattr_destroy -#define npth_mutexattr_settype pthread_mutexattr_settype -#define npth_mutexattr_gettype pthread_mutexattr_gettype -#define NPTH_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL -#define NPTH_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE -#define NPTH_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK -#define NPTH_MUTEX_DEFAULT PTHREAD_MUTEX_DEFAULT - -#define npth_mutex_t pthread_mutex_t -#define NPTH_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER -#define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP \ - PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP -#define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP \ - PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP -#define npth_mutex_init pthread_mutex_init -#define npth_mutex_destroy pthread_mutex_destroy -#define npth_mutex_trylock pthread_mutex_trylock - -int npth_mutex_lock(npth_mutex_t *mutex); - -#define npth_mutex_unlock pthread_mutex_unlock - -#ifdef _NPTH_NO_RWLOCK - -typedef int npth_rwlockattr_t; -#define npth_rwlockattr_init(attr) -#define npth_rwlockattr_destroy(attr) -#define npth_rwlockattr_gettype_np(attr, kind) -#define npth_rwlockattr_settype_np(attr, kind) -#define NPTH_RWLOCK_PREFER_READER_NP 0 -#define NPTH_RWLOCK_PREFER_WRITER_NP 0 -#define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 0 -#define NPTH_RWLOCK_DEFAULT_NP 0 -#define NPTH_RWLOCK_INITIALIZER NPTH_MUTEX_INITIALIZER -#define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP NPTH_MUTEX_INITIALIZER -typedef npth_mutex_t npth_rwlock_t; -#define npth_rwlock_init(rwlock, attr) npth_mutex_init(rwlock, 0) -#define npth_rwlock_destroy npth_mutex_destroy -#define npth_rwlock_rdlock npth_mutex_lock -#define npth_rwlock_wrlock npth_mutex_lock -#define npth_rwlock_rdlock npth_mutex_lock -#define npth_rwlock_unlock npth_mutex_unlock - -#else /* _NPTH_NO_RWLOCK */ - -#define npth_rwlockattr_t pthread_rwlockattr_t -#define npth_rwlockattr_init pthread_rwlockattr_init -#define npth_rwlockattr_destroy pthread_rwlockattr_destroy -#define npth_rwlockattr_gettype_np pthread_rwlockattr_gettype_np -#define npth_rwlockattr_settype_np pthread_rwlockattr_settype_np -#define NPTH_RWLOCK_PREFER_READER_NP PTHREAD_RWLOCK_PREFER_READER_NP -/* Note: The prefer-writer setting is ineffective and the same as - prefer-reader. This is because reader locks are specified to be - recursive, but for efficiency reasons we do not keep track of which - threads already hold a reader lock. For this reason, we can not - prefer some reader locks over others, and thus a recursive reader - lock could be stalled by a pending writer, leading to a dead - lock. */ -#define NPTH_RWLOCK_PREFER_WRITER_NP PTHREAD_RWLOCK_PREFER_WRITER_NP -/* The non-recursive choise is a promise by the application that it - does not lock the rwlock for reading recursively. In this setting, - writers are preferred, but note that recursive reader locking is - prone to deadlocks in that case. */ -#define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP \ - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP -#define NPTH_RWLOCK_DEFAULT_NP PTHREAD_RWLOCK_DEFAULT_NP -#define NPTH_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER -#define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \ - PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP - -typedef pthread_rwlock_t npth_rwlock_t; -#define npth_rwlock_init pthread_rwlock_init -#define npth_rwlock_destroy pthread_rwlock_destroy - -int npth_rwlock_rdlock(npth_rwlock_t *rwlock); -int npth_rwlock_wrlock(npth_rwlock_t *rwlock); -#define npth_rwlock_unlock pthread_rwlock_unlock - -#endif /* !_NPTH_NO_RWLOCK */ - -/* Standard POSIX Replacement API */ - -int npth_usleep(unsigned int usec); -unsigned int npth_sleep(unsigned int sec); - -pid_t npth_waitpid(pid_t pid, int *status, int options); -int npth_system(const char *cmd); - -int npth_connect(int s, const struct sockaddr *addr, _npth_socklen_t addrlen); -int npth_accept(int s, struct sockaddr *addr, _npth_socklen_t *addrlen); -int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, - struct timeval *timeout); -ssize_t npth_read(int fd, void *buf, size_t nbytes); -ssize_t npth_write(int fd, const void *buf, size_t nbytes); -int npth_recvmsg(int fd, struct msghdr *msg, int flags); -int npth_sendmsg(int fd, const struct msghdr *msg, int flags); - -/* For anything not covered here, you can enter/leave manually at your - own risk. */ -void npth_unprotect(void); -void npth_protect(void); - -/* If you run into problems with the above calls, this function can be - * used to examine in which state nPth is. */ -int npth_is_protected(void); - -#if 0 /* (Keep Emacsens' auto-indent happy.) */ -{ -#endif -#ifdef __cplusplus -} -#endif -#endif /*_NPTH_H*/ diff --git a/legacy/npth/tests/Makefile.am b/legacy/npth/tests/Makefile.am deleted file mode 100644 index 8092a3c96..000000000 --- a/legacy/npth/tests/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -# Makefile.am - Makefile for NPTH tests. -# Copyright (C) 2011 g10 Code GmbH -# -# This file is part of nPth. -# -# nPth 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. -# -# nPth 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 . - -## Process this file with automake to produce Makefile.in - -TESTS = t-mutex t-thread - -# We explicitly require POSIX.1-2001 so that pthread_rwlock_t is -# available when build with c99. -if HAVE_W32_SYSTEM -AM_CPPFLAGS = -I$(top_srcdir)/w32 -AM_LDFLAGS = -LDADD = ../w32/libnpth.la $(LIB_CLOCK_GETTIME) -else -AM_CPPFLAGS = -I../src -D_POSIX_C_SOURCE=200112L -AM_LDFLAGS = -LDADD = ../src/libnpth.la $(LIBSOCKET) $(LIB_CLOCK_GETTIME) -TESTS += t-fork -endif - -noinst_HEADERS = t-support.h - -noinst_PROGRAMS = $(TESTS) diff --git a/legacy/npth/tests/npth-test.cpp b/legacy/npth/tests/npth-test.cpp deleted file mode 100644 index d3cb1a882..000000000 --- a/legacy/npth/tests/npth-test.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "npth.h" - -#include "gtest/gtest.h" - -int mutex_main(int argc, char* argv[]); -int thread_main(int argc, char* argv[]); - -TEST(nPthTest, mutex) { - int result = mutex_main(0, NULL); - ASSERT_EQ(result, 0); -} - -TEST(nPthTest, thread) { - int result = thread_main(0, NULL); - ASSERT_EQ(result, 0); -} diff --git a/legacy/npth/tests/t-mutex.cpp b/legacy/npth/tests/t-mutex.cpp deleted file mode 100644 index 87c033dc9..000000000 --- a/legacy/npth/tests/t-mutex.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* t-mutex.c - * Copyright 2011, 2012 g10 Code GmbH - * - * This file is free software; as a special exception the author gives - * unlimited permission to copy and/or distribute it, with or without - * modifications, as long as this notice is preserved. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "t-support.h" - -int mutex_main(int argc, char *argv[]) { - int rc; - npth_mutex_t mutex; - - rc = npth_init(); - fail_if_err(rc); - - rc = npth_mutex_init(&mutex, NULL); - fail_if_err(rc); - rc = npth_mutex_lock(&mutex); - fail_if_err(rc); - rc = npth_mutex_unlock(&mutex); - fail_if_err(rc); - - return 0; -} diff --git a/legacy/npth/tests/t-support.h b/legacy/npth/tests/t-support.h deleted file mode 100644 index d2e792b06..000000000 --- a/legacy/npth/tests/t-support.h +++ /dev/null @@ -1,43 +0,0 @@ -/* t-support.h - Helper routines for regression tests. - * Copyright (C) 2011 g10 Code GmbH - * - * This file is free software; as a special exception the author gives - * unlimited permission to copy and/or distribute it, with or without - * modifications, as long as this notice is preserved. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include -#include -#include - -#include "npth.h" - -#ifndef DIM -#define DIM(v) (sizeof(v) / sizeof((v)[0])) -#endif - -static int opt_verbose; - -#define fail_if_err(err) \ - do { \ - if (err) { \ - fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, strerror(err)); \ - exit(1); \ - } \ - } while (0) - -#define fail_msg(text) \ - do { \ - fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, text); \ - exit(1); \ - } while (0) - -#define info_msg(text) \ - do { \ - if (opt_verbose) fprintf(stderr, "%s\n", text); \ - } while (0) diff --git a/legacy/npth/tests/t-thread.cpp b/legacy/npth/tests/t-thread.cpp deleted file mode 100644 index a1518a708..000000000 --- a/legacy/npth/tests/t-thread.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* t-thread.c - * Copyright 2012 g10 Code GmbH - * - * This file is free software; as a special exception the author gives - * unlimited permission to copy and/or distribute it, with or without - * modifications, as long as this notice is preserved. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "t-support.h" - -static int counter; -static npth_mutex_t counter_mutex; -static int thread_twoone_ready; - -static void *thread_one(void *arg) { - int rc, i; - - info_msg("thread-one started"); - npth_usleep(10); /* Give the other thread some time to start. */ - for (i = 0; i < 10; i++) { - /* We would not need the mutex here, but we use it to allow the - system to switch to another thread. */ - rc = npth_mutex_lock(&counter_mutex); - fail_if_err(rc); - - counter++; - - rc = npth_mutex_unlock(&counter_mutex); - fail_if_err(rc); - } - info_msg("thread-one terminated"); - - return (void *)4711; -} - -static void *thread_twoone(void *arg) { - int rc, i; - - info_msg("thread-twoone started"); - - rc = npth_detach(npth_self()); - fail_if_err(rc); - - while (counter < 100) { - npth_usleep(1000); - counter++; - } - info_msg("thread-twoone terminated"); - thread_twoone_ready = 1; - - return NULL; -} - -static void *thread_two(void *arg) { - int rc, i; - - info_msg("thread-two started"); - - for (i = 0; i < 10; i++) { - rc = npth_mutex_lock(&counter_mutex); - fail_if_err(rc); - - counter--; - - if (i == 5) { - npth_t tid; - - info_msg("creating thread-twoone"); - rc = npth_create(&tid, NULL, thread_twoone, NULL); - fail_if_err(rc); - npth_usleep(10); /* Give new thread some time to start. */ - } - - rc = npth_mutex_unlock(&counter_mutex); - fail_if_err(rc); - } - - info_msg("busy waiting for thread twoone"); - while (!thread_twoone_ready) npth_sleep(0); - - info_msg("thread-two terminated"); - - return (void *)4722; -} - -int thread_main(int argc, char *argv[]) { - int rc; - npth_attr_t tattr; - int state; - npth_t tid1, tid2; - void *retval; - - if (argc >= 2 && !strcmp(argv[1], "--verbose")) opt_verbose = 1; - - rc = npth_init(); - fail_if_err(rc); - - rc = npth_mutex_init(&counter_mutex, NULL); - fail_if_err(rc); - - rc = npth_attr_init(&tattr); - fail_if_err(rc); - rc = npth_attr_getdetachstate(&tattr, &state); - fail_if_err(rc); - if (state != NPTH_CREATE_JOINABLE) fail_msg("new tattr is not joinable"); - - info_msg("creating thread-one"); - rc = npth_create(&tid1, &tattr, thread_one, NULL); - fail_if_err(rc); - - info_msg("creating thread-two"); - rc = npth_create(&tid2, &tattr, thread_two, NULL); - fail_if_err(rc); - - rc = npth_attr_destroy(&tattr); - fail_if_err(rc); - - info_msg("waiting for thread-one to terminate"); - rc = npth_join(tid1, &retval); - fail_if_err(rc); - if (retval != (void *)4711) - fail_msg("thread-one returned an unexpected value"); - - info_msg("waiting for thread-two to terminate"); - rc = npth_join(tid2, &retval); - fail_if_err(rc); - if (retval != (void *)4722) - fail_msg("thread-two returned an unexpected value"); - - if (counter != 100) fail_msg("counter value not as expected"); - - return 0; -} diff --git a/legacy/npth/w32/npth.cpp b/legacy/npth/w32/npth.cpp deleted file mode 100644 index 1a680547c..000000000 --- a/legacy/npth/w32/npth.cpp +++ /dev/null @@ -1,997 +0,0 @@ -/* npth.c - a lightweight implementation of pth over native threads - * Copyright (C) 2011, 2014 g10 Code GmbH - * - * This file is part of nPth. - * - * nPth 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. - * - * nPth 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 . - */ - -/* We implement the join mechanism ourself. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "npth.h" - -#include -#define DEBUG_CALLS 1 -#define _npth_debug(x, ...) fprintf(stderr, __VA_ARGS__) - -#ifndef TEST -#undef DEBUG_CALLS -#define DEBUG_CALLS 0 -#undef _npth_debug -#define _npth_debug(x, ...) -#endif - -/* This seems to be a common standard. */ -#define THREAD_NAME_MAX 15 - -/* The global lock that excludes all threads but one. Note that this - implements the single-user-thread policy, but also protects all our - global data such as the thread_table. GOT_SCEPTRE is a flag used - for debugging to tell wether we hold SCEPTRE. */ -static CRITICAL_SECTION sceptre; -static int got_sceptre; - -/* This flag is set as soon as npth_init has been called or if any - * thread has been created. It will never be cleared again. The only - * purpose is to make npth_protect and npth_unprotect more robust in - * that they can be shortcut when npth_init has not yet been called. - * This is important for libraries which want to support nPth by using - * those two functions but may have been initialized before nPth. */ -static int initialized_or_any_threads; - -typedef struct npth_impl_s *npth_impl_t; -#define MAX_THREADS 1024 -#define INVALID_THREAD_ID 0 -/* Thread ID to thread context table. We never allocate ID 0. */ -static npth_impl_t thread_table[MAX_THREADS]; - -/* The TLS index to store thread ID of the current thread. Used to - make faster lookups of the thread data. */ -DWORD tls_index; - -/* Map a windows error value (GetLastError) to a POSIX error value. */ -static int map_error(int winerr) { - /* FIXME */ - return EIO; -} - -static int wait_for_single_object(HANDLE obj, DWORD msecs) { - DWORD res; - - res = WaitForSingleObject(obj, msecs); - - if (res == WAIT_ABANDONED) - return EDEADLK; - else if (res == WAIT_TIMEOUT) - return ETIMEDOUT; - else if (res == WAIT_FAILED) - return map_error(GetLastError()); - else if (res != WAIT_OBJECT_0) - return EINTR; - else - return 0; -} - -static void enter_npth(const char *function) { - int res; - - if (DEBUG_CALLS) - _npth_debug(DEBUG_CALLS, "tid %lu: enter_npth (%s)\n", npth_self(), - function ? function : "unknown"); - got_sceptre = 0; - LeaveCriticalSection(&sceptre); -} - -static void leave_npth(const char *function) { - EnterCriticalSection(&sceptre); - got_sceptre = 1; - - if (DEBUG_CALLS) - _npth_debug(DEBUG_CALLS, "tid %lu: leave_npth (%s)\n", npth_self(), - function ? function : ""); -} - -#define ENTER() enter_npth(__FUNCTION__) -#define LEAVE() leave_npth(__FUNCTION__) - -struct npth_impl_s { - /* Usually there is one ref owned by the thread as long as it is - running, and one ref for everybody else as long as the thread is - joinable. */ - int refs; - - HANDLE handle; - - /* True if thread is detached. */ - int detached; - - /* The start routine and arg. */ - void *(*start_routine)(void *); - void *start_arg; - - char name[THREAD_NAME_MAX + 1]; - - /* Doubly-linked list for the waiter queue in condition - variables. */ - npth_impl_t next; - npth_impl_t *prev_ptr; - - /* The event on which this thread waits when it is queued. */ - HANDLE event; - - void *result; -}; - -static void dequeue_thread(npth_impl_t thread) { - /* Unlink the thread from any condition waiter queue. */ - if (thread->next) { - thread->next->prev_ptr = thread->prev_ptr; - thread->next = NULL; - } - if (thread->prev_ptr) { - *(thread->prev_ptr) = thread->next; - thread->prev_ptr = NULL; - } -} - -/* Enqueue THREAD to come after the thread whose next pointer is - prev_ptr. */ -static void enqueue_thread(npth_impl_t thread, npth_impl_t *prev_ptr) { - if (*prev_ptr) (*prev_ptr)->prev_ptr = &thread->next; - thread->prev_ptr = prev_ptr; - thread->next = *prev_ptr; - *prev_ptr = thread; -} - -static int find_thread(npth_t thread_id, npth_impl_t *thread) { - if (thread_id < 1 || thread_id >= MAX_THREADS) return ESRCH; - - if (!thread_table[thread_id]) return ESRCH; - - *thread = thread_table[thread_id]; - return 0; -} - -static int new_thread(npth_t *thread_id) { - npth_impl_t thread; - int id; - - /* ID 0 is never allocated. */ - for (id = 1; id < MAX_THREADS; id++) - if (!thread_table[id]) break; - if (id == MAX_THREADS) return EAGAIN; - - thread = malloc(sizeof(*thread)); - if (!thread) return errno; - - thread->refs = 1; - thread->handle = INVALID_HANDLE_VALUE; - thread->detached = 0; - thread->start_routine = NULL; - thread->start_arg = NULL; - thread->next = NULL; - thread->prev_ptr = NULL; - /* We create the event when it is first needed (not all threads wait - on conditions). */ - thread->event = INVALID_HANDLE_VALUE; - memset(thread->name, '\0', sizeof(thread->name)); - - thread_table[id] = thread; - - *thread_id = id; - return 0; -} - -static void free_thread(npth_t thread_id) { - npth_impl_t thread = thread_table[thread_id]; - - if (thread->handle) CloseHandle(thread->handle); - - /* Unlink the thread from any condition waiter queue. */ - dequeue_thread(thread); - - free(thread); - - thread_table[thread_id] = NULL; -} - -static void deref_thread(npth_t thread_id) { - npth_impl_t thread = thread_table[thread_id]; - - thread->refs -= 1; - if (thread->refs == 0) free_thread(thread_id); -} - -int npth_init(void) { - int err; - npth_t thread_id; - BOOL res; - HANDLE handle; - npth_impl_t thread; - - InitializeCriticalSection(&sceptre); - - /* Track that we have been initialized. */ - initialized_or_any_threads = 1; - - /* Fake a thread table item for the main thread. */ - tls_index = TlsAlloc(); - if (tls_index == TLS_OUT_OF_INDEXES) return map_error(GetLastError()); - - err = new_thread(&thread_id); - if (err) return err; - - /* GetCurrentThread() is not usable by other threads, so it needs to - be duplicated. */ - res = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &handle, 0, FALSE, - DUPLICATE_SAME_ACCESS); - if (!res) { - free_thread(thread_id); - return map_error(GetLastError()); - } - - thread = thread_table[thread_id]; - thread->handle = handle; - - if (!TlsSetValue(tls_index, (LPVOID)thread_id)) - return map_error(GetLastError()); - - LEAVE(); - return 0; -} - -struct npth_attr_s { - int detachstate; -}; - -int npth_attr_init(npth_attr_t *attr_r) { - npth_attr_t attr; - - attr = malloc(sizeof *attr); - if (!attr) return errno; - - attr->detachstate = NPTH_CREATE_JOINABLE; - *attr_r = attr; - return 0; -} - -int npth_attr_destroy(npth_attr_t *attr) { - free(*attr); - return 0; -} - -int npth_attr_getdetachstate(npth_attr_t *attr, int *detachstate) { - *detachstate = (*attr)->detachstate; - return 0; -} - -int npth_attr_setdetachstate(npth_attr_t *attr, int detachstate) { - if (detachstate != NPTH_CREATE_JOINABLE && - detachstate != NPTH_CREATE_DETACHED) - return EINVAL; - - (*attr)->detachstate = detachstate; - return 0; -} - -static DWORD thread_start(void *arg) { - npth_t thread_id = (npth_t)arg; - npth_impl_t thread; - void *result; - - if (!TlsSetValue(tls_index, (LPVOID)thread_id)) - /* FIXME: There is not much we can do here. */ - ; - - LEAVE(); - /* We must be protected here, because we access the global - thread_table. */ - - thread = thread_table[thread_id]; - result = thread->start_routine(thread->start_arg); - /* We might not return here if the thread calls npth_exit(). */ - - thread->result = result; - - /* Any joiner will be signaled once we terminate. */ - deref_thread(thread_id); - - ENTER(); - - /* We can not return result, as that is a void*, not a DWORD. */ - return 0; -} - -int npth_create(npth_t *newthread, const npth_attr_t *user_attr, - void *(*start_routine)(void *), void *start_arg) { - int err = 0; - npth_t thread_id = INVALID_THREAD_ID; - npth_attr_t attr; - int attr_allocated; - npth_impl_t thread; - HANDLE handle; - - /* We must stay protected here, because we access the global - thread_table. Also, creating a new thread is not a blocking - operation. */ - if (user_attr) { - attr = *user_attr; - attr_allocated = 0; - } else { - err = npth_attr_init(&attr); - if (err) return err; - attr_allocated = 1; - } - - err = new_thread(&thread_id); - if (err) goto err_out; - - thread = thread_table[thread_id]; - if (attr->detachstate == NPTH_CREATE_DETACHED) - thread->detached = 1; - else - thread->refs += 1; - - thread->start_routine = start_routine; - thread->start_arg = start_arg; - - handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_start, - (void *)thread_id, CREATE_SUSPENDED, NULL); - if (handle == NULL) { - err = map_error(GetLastError()); - goto err_out; - } - - thread->handle = handle; - *newthread = thread_id; - - ResumeThread(thread->handle); - - return 0; - -err_out: - if (thread_id) free_thread(thread_id); - if (attr_allocated) npth_attr_destroy(&attr); - - return err; -} - -npth_t npth_self(void) { - LPVOID thread_id; - - thread_id = TlsGetValue(tls_index); - if (thread_id == 0 && GetLastError() != ERROR_SUCCESS) - /* FIXME: Log the error. */ - ; - return (npth_t)thread_id; -} - -/* Not part of the public interface at the moment, thus static. */ -static int npth_tryjoin_np(npth_t thread_id, void **thread_return) { - int err; - npth_impl_t thread; - int res; - - err = find_thread(thread_id, &thread); - if (err) return err; - - if (thread->detached) return EINVAL; - - /* No need to allow competing threads to enter when we can get the - lock immediately. */ - err = wait_for_single_object(thread->handle, 0); - if (err == ETIMEDOUT) err = EBUSY; - - if (err) return err; - - if (thread_return) *thread_return = thread->result; - deref_thread(thread_id); - - return 0; -} - -int npth_join(npth_t thread_id, void **thread_return) { - int err; - npth_impl_t thread; - int res; - - /* No need to allow competing threads to enter when we can get the - lock immediately. */ - err = npth_tryjoin_np(thread_id, thread_return); - if (err != EBUSY) return err; - - err = find_thread(thread_id, &thread); - if (err) return err; - - if (thread->detached) return EINVAL; - - ENTER(); - err = wait_for_single_object(thread->handle, INFINITE); - LEAVE(); - - if (err) return err; - - if (thread_return) *thread_return = thread->result; - deref_thread(thread_id); - - return 0; -} - -int npth_detach(npth_t thread_id) { - int err; - npth_impl_t thread; - - err = find_thread(thread_id, &thread); - if (err) return err; - - if (thread->detached) return EINVAL; - - /* The detached flag indicates to other thread that the outside - reference in the global thread table has been consumed. */ - thread->detached = 1; - deref_thread(thread_id); - - return 0; -} - -void npth_exit(void *retval) { - int err; - npth_t thread_id; - npth_impl_t thread; - - thread_id = npth_self(); - err = find_thread(thread_id, &thread); - if (err) /* FIXME: log this? */ - return; - - thread->result = retval; - /* Any joiner will be signaled once we terminate. */ - deref_thread(thread_id); - - ENTER(); - - /* We can not use retval here, as that is a void*, not a DWORD. */ - ExitThread(0); - - /* Never reached. But just in case ExitThread does return... */ - LEAVE(); -} - -int npth_key_create(npth_key_t *key, void (*destr_function)(void *)) { - DWORD idx; - - if (destr_function) return EOPNOTSUPP; - - idx = TlsAlloc(); - if (idx == TLS_OUT_OF_INDEXES) return map_error(GetLastError()); - - *key = idx; - return 0; -} - -int npth_key_delete(npth_key_t key) { - BOOL res; - - res = TlsFree(key); - if (res == 0) return map_error(GetLastError()); - return 0; -} - -void *npth_getspecific(npth_key_t key) { - /* Pthread doesn't support error reporting beyond returning NULL for - an invalid key, which is also what TlsGetValue returns in that - case. */ - return TlsGetValue(key); -} - -int npth_setspecific(npth_key_t key, const void *pointer) { - BOOL res; - - res = TlsSetValue(key, (void *)pointer); - if (res == 0) return map_error(GetLastError()); - - return 0; -} - -struct npth_mutexattr_s { - int kind; -}; - -int npth_mutexattr_init(npth_mutexattr_t *attr_r) { - npth_mutexattr_t attr; - - attr = malloc(sizeof *attr); - if (!attr) return errno; - - attr->kind = NPTH_MUTEX_DEFAULT; - *attr_r = attr; - return 0; -} - -int npth_mutexattr_destroy(npth_mutexattr_t *attr) { - free(*attr); - *attr = NULL; - return 0; -} - -int npth_mutexattr_gettype(const npth_mutexattr_t *attr, int *kind) { - *kind = (*attr)->kind; - return 0; -} - -int npth_mutexattr_settype(npth_mutexattr_t *attr, int kind) { - if (kind != NPTH_MUTEX_NORMAL && kind != NPTH_MUTEX_RECURSIVE && - kind != NPTH_MUTEX_ERRORCHECK) - return EINVAL; - - (*attr)->kind = kind; - return 0; -} - -struct npth_mutex_s { - /* We have to use a mutex, not a CRITICAL_SECTION, because the - latter can not be used with timed waits. */ - HANDLE mutex; -}; - -int npth_mutex_init(npth_mutex_t *mutex_r, const npth_mutexattr_t *mutex_attr) { - npth_mutex_t mutex; - - /* We can not check *mutex_r here, as it may contain random data. */ - mutex = malloc(sizeof(*mutex)); - if (!mutex) return errno; - - /* We ignore MUTEX_ATTR. */ - mutex->mutex = CreateMutex(NULL, FALSE, NULL); - if (!mutex->mutex) { - int err = map_error(GetLastError()); - free(mutex); - return err; - } - - *mutex_r = mutex; - return 0; -} - -int npth_mutex_destroy(npth_mutex_t *mutex) { - BOOL res; - - if (*mutex == 0 || *mutex == NPTH_MUTEX_INITIALIZER || - *mutex == NPTH_RECURSIVE_MUTEX_INITIALIZER_NP) - return EINVAL; - - res = CloseHandle((*mutex)->mutex); - if (res == 0) return map_error(GetLastError()); - - free(*mutex); - *mutex = NULL; - - return 0; -} - -/* Must be called with global lock held. */ -static int mutex_init_check(npth_mutex_t *mutex) { - int err; - npth_mutexattr_t attr; - int kind; - - if (*mutex == 0) return EINVAL; - - if ((*mutex) == NPTH_MUTEX_INITIALIZER) - kind = NPTH_MUTEX_NORMAL; - else if ((*mutex) == NPTH_RECURSIVE_MUTEX_INITIALIZER_NP) - kind = NPTH_MUTEX_RECURSIVE; - else if ((*mutex) == NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP) - kind = NPTH_MUTEX_ERRORCHECK; - else - /* Already initialized. */ - return 0; - - /* Make sure we don't try again in case of error. */ - *mutex = 0; - - err = npth_mutexattr_init(&attr); - if (err) return err; - - err = npth_mutexattr_settype(&attr, kind); - if (err) { - npth_mutexattr_destroy(&attr); - return err; - } - - err = npth_mutex_init(mutex, &attr); - npth_mutexattr_destroy(&attr); - - return err; -} - -int npth_mutex_lock(npth_mutex_t *mutex) { - int err; - - /* While we are protected, let's check for a static initializer. */ - err = mutex_init_check(mutex); - if (err) return err; - - /* No need to allow competing threads to enter when we can get the - lock immediately. */ - err = npth_mutex_trylock(mutex); - if (err != EBUSY) return err; - - ENTER(); - err = wait_for_single_object((*mutex)->mutex, INFINITE); - LEAVE(); - - if (err) return err; - - return 0; -} - -int npth_mutex_trylock(npth_mutex_t *mutex) { - int err; - DWORD res; - - /* While we are protected, let's check for a static initializer. */ - err = mutex_init_check(mutex); - if (err) return err; - - /* We do not leave the global lock for a quick try. */ - err = wait_for_single_object((*mutex)->mutex, 0); - if (err == ETIMEDOUT) err = EBUSY; - - if (err) return err; - - return 0; -} - -int npth_mutex_unlock(npth_mutex_t *mutex) { - BOOL res; - - if (*mutex == 0 || *mutex == NPTH_MUTEX_INITIALIZER || - *mutex == NPTH_RECURSIVE_MUTEX_INITIALIZER_NP) - return EINVAL; - - res = ReleaseMutex((*mutex)->mutex); - if (res == 0) return map_error(GetLastError()); - - return 0; -} - -struct npth_rwlockattr_s { - int kind; -}; - -int npth_rwlockattr_init(npth_rwlockattr_t *attr_r) { - npth_rwlockattr_t attr; - - attr = malloc(sizeof *attr); - if (!attr) return errno; - - attr->kind = NPTH_RWLOCK_DEFAULT_NP; - *attr_r = attr; - return 0; -} - -int npth_rwlockattr_destroy(npth_rwlockattr_t *attr) { - free(*attr); - *attr = NULL; - return 0; -} - -int npth_rwlockattr_gettype_np(const npth_rwlockattr_t *attr, int *kind) { - *kind = (*attr)->kind; - return 0; -} - -int npth_rwlockattr_settype_np(npth_rwlockattr_t *attr, int kind) { - if (kind != NPTH_RWLOCK_PREFER_READER_NP && - kind != NPTH_RWLOCK_PREFER_WRITER_NP && - kind != NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) - return EINVAL; - - (*attr)->kind = kind; - return 0; -} - -struct npth_rwlock_s { - /* Objects are protected by the global lock, so no lock here - necessary. This is even true for the condition (by specifying - NULL as the mutex in npth_cond_wait and npth_cond_timedwait). */ - - /* True if we prefer writers over readers. */ - int prefer_writer; - - /* Readers who want the lock wait on this condition, which is - broadcast when the last writer goes away. */ - npth_cond_t reader_wait; - - /* The number of readers waiting on the condition. */ - int nr_readers_queued; - - /* The number of current readers. */ - int nr_readers; - - /* Writers who want the lock wait on this condition, which is - signaled when the current writer or last reader goes away. */ - npth_cond_t writer_wait; - - /* The number of queued writers. */ - int nr_writers_queued; - - /* The number of current writers. This is either 1 (then nr_readers - is 0) or it is 0. At unlock time this value tells us if the - current lock holder is a writer or a reader. */ - int nr_writers; -}; - -int npth_rwlock_init(npth_rwlock_t *rwlock_r, - const npth_rwlockattr_t *user_attr) { - int err; - npth_rwlock_t rwlock; - npth_rwlockattr_t attr; - int attr_allocated; - - if (user_attr != NULL) { - attr = *user_attr; - attr_allocated = 0; - } else { - err = npth_rwlockattr_init(&attr); - if (err) return err; - } - - /* We can not check *rwlock_r here, as it may contain random data. */ - rwlock = malloc(sizeof(*rwlock)); - if (!rwlock) { - err = errno; - goto err_out; - } - - rwlock->prefer_writer = - (attr->kind == NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - - err = npth_cond_init(&rwlock->reader_wait, NULL); - if (err) { - free(rwlock); - goto err_out; - } - - err = npth_cond_init(&rwlock->writer_wait, NULL); - if (err) { - npth_cond_destroy(&rwlock->reader_wait); - free(rwlock); - goto err_out; - } - - rwlock->nr_readers = 0; - rwlock->nr_readers_queued = 0; - rwlock->nr_writers = 0; - rwlock->nr_writers_queued = 0; - - *rwlock_r = rwlock; - -err_out: - if (attr_allocated) npth_rwlockattr_destroy(&attr); - return err; -} - -/* Must be called with global lock held. */ -static int rwlock_init_check(npth_rwlock_t *rwlock) { - int err; - npth_rwlockattr_t attr; - int kind; - - if (*rwlock == 0) return EINVAL; - - if ((*rwlock) == NPTH_RWLOCK_INITIALIZER) kind = NPTH_RWLOCK_PREFER_READER_NP; - if ((*rwlock) == NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP) - kind = NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP; - else - /* Already initialized. */ - return 0; - - /* Make sure we don't try again in case of error. */ - *rwlock = 0; - - err = npth_rwlockattr_init(&attr); - if (err) return err; - - err = npth_rwlockattr_settype_np(&attr, kind); - if (err) { - npth_rwlockattr_destroy(&attr); - return err; - } - - err = npth_rwlock_init(rwlock, &attr); - npth_rwlockattr_destroy(&attr); - - return err; -} - -int npth_rwlock_destroy(npth_rwlock_t *rwlock) { - int err; - - if (*rwlock == 0 || *rwlock == NPTH_RWLOCK_INITIALIZER) return EINVAL; - - if ((*rwlock)->nr_writers || (*rwlock)->nr_readers || - (*rwlock)->nr_writers_queued || (*rwlock)->nr_readers_queued) - return EBUSY; - - err = npth_cond_destroy(&(*rwlock)->reader_wait); - if (err) /* FIXME: Log this. */ - ; - - err = npth_cond_destroy(&(*rwlock)->writer_wait); - if (err) /* FIXME: Log this. */ - ; - - free(rwlock); - - *rwlock = NULL; - return 0; -} - -int npth_rwlock_rdlock(npth_rwlock_t *rwlock) { - int err; - - while (1) { - /* Quick check. */ - err = npth_rwlock_tryrdlock(rwlock); - if (err != EBUSY) return err; - - (*rwlock)->nr_readers_queued++; - err = npth_cond_wait(&(*rwlock)->reader_wait, NULL); - (*rwlock)->nr_readers_queued--; - if (err) return err; - } -} - -int npth_rwlock_wrlock(npth_rwlock_t *rwlock) { - int err; - - while (1) { - /* Quick check. */ - err = npth_rwlock_trywrlock(rwlock); - if (err != EBUSY) return err; - - (*rwlock)->nr_writers_queued++; - err = npth_cond_wait(&(*rwlock)->writer_wait, NULL); - (*rwlock)->nr_writers_queued--; - if (err) return err; - } -} - -int npth_rwlock_unlock(npth_rwlock_t *rwlock) { - int err; - - if ((*rwlock)->nr_writers) /* We are the writer. */ - (*rwlock)->nr_writers = 0; - else - /* We are the reader. */ - (*rwlock)->nr_readers--; - - if ((*rwlock)->nr_readers == 0) { - if ((*rwlock)->nr_writers_queued) { - err = npth_cond_signal(&(*rwlock)->writer_wait); - if (err) return err; - } else if ((*rwlock)->nr_readers_queued) { - err = npth_cond_broadcast(&(*rwlock)->reader_wait); - return err; - } - } - return 0; -} - -/* Standard POSIX Replacement API */ - -int npth_usleep(unsigned int usec) { - ENTER(); - Sleep((usec + 999) / 1000); - LEAVE(); - return 0; -} - -unsigned int npth_sleep(unsigned int sec) { - ENTER(); - Sleep(sec * 1000); - LEAVE(); - return 0; -} - -int npth_system(const char *cmd) { - int res; - - ENTER(); - res = system(cmd); - LEAVE(); - return res; -} - -pid_t npth_waitpid(pid_t pid, int *status, int options) { return EOPNOTSUPP; } - -int npth_connect(int s, const struct sockaddr *addr, socklen_t addrlen) { - int res; - - ENTER(); - res = connect(s, addr, addrlen); - LEAVE(); - return res; -} - -int npth_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { - int res; - - ENTER(); - res = accept(s, addr, addrlen); - LEAVE(); - return res; -} - -int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, - struct timeval *timeout) { - int res; - - ENTER(); - res = select(nfd, rfds, wfds, efds, timeout); - LEAVE(); - return res; -} - -ssize_t npth_read(int fd, void *buf, size_t nbytes) { - ssize_t res; - - ENTER(); - res = read(fd, buf, nbytes); - LEAVE(); - return res; -} - -ssize_t npth_write(int fd, const void *buf, size_t nbytes) { - ssize_t res; - - ENTER(); - res = write(fd, buf, nbytes); - LEAVE(); - return res; -} - -int npth_recvmsg(int fd, struct msghdr *msg, int flags) { return EOPNOTSUPP; } - -int npth_sendmsg(int fd, const struct msghdr *msg, int flags) { - return EOPNOTSUPP; -} - -void npth_unprotect(void) { - /* If we are not initialized we may not access the semaphore and - * thus we shortcut it. Note that in this case the unprotect/protect - * is not needed. For failsafe reasons if an nPth thread has ever - * been created but nPth has accidentally not initialized we do not - * shortcut so that a stack backtrace (due to the access of the - * uninitialized semaphore) is more expressive. */ - if (initialized_or_any_threads) ENTER(); -} - -void npth_protect(void) { - /* See npth_unprotect for commentary. */ - if (initialized_or_any_threads) LEAVE(); -} - -int npth_is_protected(void) { return got_sceptre; } diff --git a/legacy/npth/w32/npth.h b/legacy/npth/w32/npth.h deleted file mode 100644 index e58fc3b38..000000000 --- a/legacy/npth/w32/npth.h +++ /dev/null @@ -1,154 +0,0 @@ -/* npth.h - a lightweight implementation of pth over native threads - * Copyright (C) 2011, 2015 g10 Code GmbH - * - * This file is part of nPth. - * - * nPth 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. - * - * nPth 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 . - */ - -#ifndef _NPTH_H -#define _NPTH_H - -#include -#include -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#if 0 /* (Keep Emacsens' auto-indent happy.) */ -} -#endif -#endif - -struct msghdr; - -/* The mingw-w64 headers define timespec. For older compilers we keep - our replacement. */ -#ifndef __MINGW64_VERSION_MAJOR -struct timespec { - long tv_sec; /* seconds */ - long tv_nsec; /* nanoseconds */ -}; -#endif /*__MINGW64_VERSION_MAJOR */ - -#ifndef ETIMEDOUT -#define ETIMEDOUT 10060 /* This is WSAETIMEDOUT. */ -#endif -#ifndef EOPNOTSUPP -#define EOPNOTSUPP 10045 /* This is WSAEOPNOTSUPP. */ -#endif - -int npth_init(void); - -typedef struct npth_attr_s *npth_attr_t; -typedef unsigned long int npth_t; -typedef struct npth_mutexattr_s *npth_mutexattr_t; -typedef struct npth_mutex_s *npth_mutex_t; -typedef struct npth_rwlockattr_s *npth_rwlockattr_t; -typedef struct npth_rwlock_s *npth_rwlock_t; - -int npth_attr_init(npth_attr_t *attr); -int npth_attr_destroy(npth_attr_t *attr); -#define NPTH_CREATE_JOINABLE 0 -#define NPTH_CREATE_DETACHED 1 -int npth_attr_getdetachstate(npth_attr_t *attr, int *detachstate); -int npth_attr_setdetachstate(npth_attr_t *attr, int detachstate); - -int npth_create(npth_t *newthread, const npth_attr_t *attr, - void *(*start_routine)(void *), void *arg); - -npth_t npth_self(void); - -int npth_join(npth_t th, void **thread_return); -int npth_detach(npth_t th); -void npth_exit(void *retval); - -typedef DWORD npth_key_t; -int npth_key_create(npth_key_t *key, void (*destr_function)(void *)); -int npth_key_delete(npth_key_t key); -void *npth_getspecific(npth_key_t key); -int npth_setspecific(npth_key_t key, const void *pointer); - -int npth_mutexattr_init(npth_mutexattr_t *attr); -int npth_mutexattr_destroy(npth_mutexattr_t *attr); -int npth_mutexattr_gettype(const npth_mutexattr_t *attr, int *kind); -int npth_mutexattr_settype(npth_mutexattr_t *attr, int kind); -#define NPTH_MUTEX_NORMAL 0 -#define NPTH_MUTEX_RECURSIVE 1 -#define NPTH_MUTEX_ERRORCHECK 2 -#define NPTH_MUTEX_DEFAULT NPTH_MUTEX_NORMAL - -#define NPTH_MUTEX_INITIALIZER ((npth_mutex_t)-1) -#define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP ((npth_mutex_t)-2) -#define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP ((npth_mutex_t)-3) -int npth_mutex_init(npth_mutex_t *mutex, const npth_mutexattr_t *mutexattr); -int npth_mutex_destroy(npth_mutex_t *mutex); -int npth_mutex_trylock(npth_mutex_t *mutex); -int npth_mutex_lock(npth_mutex_t *mutex); -int npth_mutex_unlock(npth_mutex_t *mutex); - -int npth_rwlockattr_init(npth_rwlockattr_t *attr); -int npth_rwlockattr_destroy(npth_rwlockattr_t *attr); -int npth_rwlockattr_gettype_np(const npth_rwlockattr_t *attr, int *kind); -int npth_rwlockattr_settype_np(npth_rwlockattr_t *attr, int kind); -#define NPTH_RWLOCK_PREFER_READER_NP 0 -#define NPTH_RWLOCK_PREFER_WRITER_NP 1 -#define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2 -#define NPTH_RWLOCK_DEFAULT_NP NPTH_RWLOCK_PREFER_READER_NP -#define NPTH_RWLOCK_INITIALIZER ((npth_rwlock_t)-1) -#define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP ((npth_rwlock_t)-2) - -/* For now, we don't support any rwlock attributes. */ -int npth_rwlock_init(npth_rwlock_t *rwlock, const npth_rwlockattr_t *attr); -int npth_rwlock_destroy(npth_rwlock_t *rwlock); -int npth_rwlock_rdlock(npth_rwlock_t *rwlock); - -int npth_rwlock_wrlock(npth_rwlock_t *rwlock); -int npth_rwlock_unlock(npth_rwlock_t *rwlock); - -int npth_usleep(unsigned int usec); -unsigned int npth_sleep(unsigned int sec); - -pid_t npth_waitpid(pid_t pid, int *status, int options); -int npth_system(const char *cmd); - -int npth_connect(int s, const struct sockaddr *addr, socklen_t addrlen); -int npth_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -/* Only good for sockets! */ -int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, - struct timeval *timeout); - -ssize_t npth_read(int fd, void *buf, size_t nbytes); -ssize_t npth_write(int fd, const void *buf, size_t nbytes); -int npth_recvmsg(int fd, struct msghdr *msg, int flags); -int npth_sendmsg(int fd, const struct msghdr *msg, int flags); - -void npth_unprotect(void); -void npth_protect(void); - -/* Return true when we hold the sceptre. This is used to debug - * problems with npth_unprotect and npth_protect. */ -int npth_is_protected(void); - -#if 0 /* (Keep Emacsens' auto-indent happy.) */ -{ -#endif -#ifdef __cplusplus -} -#endif -#endif /*_NPTH_H*/ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 35efd3d50..96bdba750 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -215,7 +215,6 @@ target_include_directories(neopg PRIVATE ../legacy/libgpg-error/src ../legacy/libassuan/src ../legacy/libgcrypt/src - ../legacy/npth/src ../legacy/libksba/src ${CMAKE_BINARY_DIR}/. ${Boost_INCLUDE_DIR} @@ -236,7 +235,6 @@ target_link_libraries(neopg PRIVATE gpg-error assuan gcrypt - npth ksba ${Boost_LIBRARIES} ${SQLITE3_LDFLAGS} ${SQLITE3_LIBRARIES}