├── autogen.rc ├── .gitignore ├── npth.pc.in ├── ChangeLog ├── m4 ├── ltversion.m4 ├── libsocket.m4 ├── socklen.m4 ├── ltsugar.m4 ├── lt~obsolete.m4 └── ltoptions.m4 ├── HACKING ├── tests ├── t-mutex.c ├── Makefile.am ├── t-fork.c ├── t-support.h ├── t-thread.c └── t-cond.c ├── README ├── npth.spec.in ├── src ├── getversion.c ├── libnpth.vers ├── Makefile.am ├── npth-sigev.c ├── npth.h.in └── npth.c ├── AUTHORS ├── w32 ├── versioninfo.rc.in ├── Makefile.am ├── npth.def └── npth.h.in ├── npth-config.in ├── NEWS ├── npth.m4 ├── Makefile.am ├── INSTALL ├── autogen.sh ├── configure.ac └── COPYING.LIB /autogen.rc: -------------------------------------------------------------------------------- 1 | # autogen.sh configuration for nPth -*- sh -*- 2 | 3 | final_info="./configure --enable-maintainer-mode && make" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /aclocal.m4 2 | /autom4te.cache 3 | /config.h.in 4 | /configure 5 | /config.log 6 | /config.status 7 | /libtool 8 | /stamp-h1 9 | /config.h 10 | src/npth.h 11 | src/npth-config 12 | w32/npth-config 13 | Makefile.in 14 | Makefile 15 | .deps/ 16 | .libs/ 17 | *~ 18 | /VERSION 19 | -------------------------------------------------------------------------------- /npth.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | api_version=@NPTH_CONFIG_API_VERSION@ 6 | host=@NPTH_CONFIG_HOST@ 7 | 8 | Name: npth 9 | Description: New GNU Portable Threads Library 10 | Version: @PACKAGE_VERSION@ 11 | Libs: -L${libdir} @NPTH_CONFIG_LIBS@ 12 | Cflags: -I${includedir} @NPTH_CONFIG_CFLAGS@ 13 | URL: https://www.gnupg.org/software/npth/index.html 14 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | No ChangeLog files 2 | =================== 3 | 4 | Do not write a ChangeLog file for npth. We put change information 5 | only in the GIT commit log, and generate a top-level ChangeLog file 6 | from logs at "make dist" time. As such, there are strict requirements 7 | on the form of the commit log messages. See HACKING for details. 8 | 9 | 10 | 11 | Local Variables: 12 | buffer-read-only: t 13 | mode: text 14 | End: 15 | -------------------------------------------------------------------------------- /m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # @configure_input@ 11 | 12 | # serial 3337 ltversion.m4 13 | # This file is part of GNU Libtool 14 | 15 | m4_define([LT_PACKAGE_VERSION], [2.4.2]) 16 | m4_define([LT_PACKAGE_REVISION], [1.3337]) 17 | 18 | AC_DEFUN([LTVERSION_VERSION], 19 | [macro_version='2.4.2' 20 | macro_revision='1.3337' 21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 22 | _LT_DECL(, macro_revision, 0) 23 | ]) 24 | -------------------------------------------------------------------------------- /HACKING: -------------------------------------------------------------------------------- 1 | # HACKING -*- org -*- 2 | #+TITLE: Hacking notes for nPth 3 | #+STARTUP: showall 4 | 5 | * No ChangeLog files 6 | 7 | Do not write ChangeLog files for NPTH. We put change information 8 | only in the GIT commit log, and generate a top-level ChangeLog file 9 | from logs at "make dist" time. As such, there are strict 10 | requirements on the form of the commit log messages. 11 | 12 | 13 | * Commit log requirements 14 | 15 | Your commit log should always start with a one-line summary, the 16 | second line should be blank, and the remaining lines are usually 17 | ChangeLog-style entries for all affected files. However, it's fine 18 | -- even recommended -- to write a few lines of prose describing the 19 | change, when the summary and ChangeLog entries don't give enough of 20 | the big picture. Omit the leading TABs that you're used to seeing 21 | in a "real" ChangeLog file, but keep the maximum line length at 72 22 | or smaller, so that the generated ChangeLog lines, each with its 23 | leading TAB, will not exceed 80 columns. 24 | -------------------------------------------------------------------------------- /tests/t-mutex.c: -------------------------------------------------------------------------------- 1 | /* t-mutex.c 2 | * Copyright 2011, 2012 g10 Code GmbH 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This file is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include "t-support.h" 14 | 15 | 16 | int 17 | main (int argc, char *argv[]) 18 | { 19 | int rc; 20 | npth_mutex_t mutex; 21 | 22 | if (argc >= 2 && !strcmp (argv[1], "--verbose")) 23 | opt_verbose = 1; 24 | 25 | rc = npth_init (); 26 | fail_if_err (rc); 27 | 28 | rc = npth_mutex_init (&mutex, NULL); 29 | fail_if_err (rc); 30 | info_msg ("mutex initialized"); 31 | rc = npth_mutex_lock (&mutex); 32 | fail_if_err (rc); 33 | info_msg ("mutex locked"); 34 | rc = npth_mutex_unlock (&mutex); 35 | fail_if_err (rc); 36 | info_msg ("mutex unlocked"); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | nPth - The New GNU Portable Threads Library 2 | 3 | * Overview 4 | 5 | This is a library to provide the GNU Pth API and thus a 6 | non-preemptive threads implementation. 7 | 8 | In contrast to GNU Pth is is based on the system's standard threads 9 | implementation. This allows the use of libraries which are not 10 | compatible to GNU Pth. Experience with a Windows Pth emulation 11 | showed that this is a solid way to provide a co-routine based 12 | framework. 13 | 14 | See the file AUTHORS for contact and copyright information. 15 | 16 | * License 17 | 18 | nPth is released under the LGPLv2+ license. 19 | 20 | * Porting hints 21 | 22 | Documentation is currently missing. If you are using GNU Pth you 23 | should be able to understand the API. Given that GNU Pth is rarely 24 | used, we hestitate to spend work on a migration guide. If you have 25 | questions, please ask on gnupg-devel. Here are some hints: 26 | 27 | - Pth mutexes are recursive, that is they will not block if called 28 | by the same thread. In contrast, nPth mutexes are not recursive; 29 | it is best to change your code to avoid recursive use of mutexes. 30 | nPth uses non-recursive mutexes for performance reasons. 31 | -------------------------------------------------------------------------------- /npth.spec.in: -------------------------------------------------------------------------------- 1 | # This is a template. The dist target uses it to create the real file. 2 | Summary: NPTH - the new GNU Portable Threads Library 3 | Name: npth 4 | Version: @pkg_version@ 5 | Release: 1 6 | URL: http://www.gnupg.org/ 7 | Source: ftp://ftp.gnupg.org/gcrypt/alpha 8 | Group: Development/Libraries 9 | Copyright: LGPLv2+ 10 | BuildRoot: %{_tmppath}/%{name}-%{version} 11 | BuildRequires: make 12 | Prereq: /sbin/ldconfig /sbin/install-info 13 | 14 | %description 15 | NPTH is a cooperative thread library. 16 | 17 | %prep 18 | %setup -q 19 | 20 | %build 21 | CFLAGS="$RPM_OPT_FLAGS"; export CFLAGS 22 | ./configure --prefix=/usr 23 | make 24 | 25 | %install 26 | rm -fr $RPM_BUILD_ROOT 27 | mkdir -p $RPM_BUILD_ROOT 28 | make install prefix=$RPM_BUILD_ROOT/usr 29 | 30 | %clean 31 | rm -fr $RPM_BUILD_ROOT 32 | make distclean 33 | 34 | %post 35 | /sbin/ldconfig 36 | 37 | %preun 38 | 39 | %postun 40 | /sbin/ldconfig 41 | 42 | %files 43 | %defattr(-,root,root) 44 | %doc COPYING COPYING.LESSER AUTHORS README INSTALL NEWS ChangeLog TODO THANKS 45 | %attr(0755,root,root) %{_bindir}/npth-config 46 | %attr(0755,root,root) %{_libdir}/*npth.so* 47 | %attr(0755,root,root) %{_libdir}/*npth.la 48 | %attr(0644,root,root) %{_libdir}/*npth.a 49 | %{_includedir}/npth.h 50 | %{_datadir}/aclocal/npth.m4 51 | 52 | %changelog 53 | * Thu Oct 06 2011 Marcus Brinkmann 54 | - initial specfile release for npth. 55 | 56 | # EOF 57 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am - Makefile for NPTH tests. 2 | # Copyright (C) 2011 g10 Code GmbH 3 | # 4 | # This file is part of nPth. 5 | # 6 | # nPth is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as 8 | # published by the Free Software Foundation; either version 2.1 of the 9 | # License, or (at your option) any later version. 10 | # 11 | # nPth is distributed in the hope that it will be useful, but WITHOUT 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14 | # Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this program; if not, see . 18 | 19 | ## Process this file with automake to produce Makefile.in 20 | 21 | TESTS = t-mutex t-thread t-cond 22 | XFAIL_TESTS = 23 | 24 | if HAVE_W32_SYSTEM 25 | AM_CPPFLAGS = -I$(top_builddir)/w32 26 | LDADD = ../w32/libnpth.la $(LIB_CLOCK_GETTIME) 27 | else 28 | AM_CPPFLAGS = -I../src 29 | LDADD = ../src/libnpth.la $(LIBSOCKET) $(LIB_CLOCK_GETTIME) 30 | if NPTH_FORK_FAILURE 31 | # Fork failure is expected on such a system 32 | XFAIL_TESTS += t-fork 33 | else 34 | TESTS += t-fork 35 | endif 36 | endif 37 | 38 | LDADD += @LDADD_FOR_TESTS_KLUDGE@ 39 | if HAVE_W32_SYSTEM 40 | AM_LDFLAGS = -no-fast-install 41 | else 42 | AM_LDFLAGS = -no-install 43 | endif 44 | 45 | noinst_HEADERS = t-support.h 46 | 47 | noinst_PROGRAMS = $(TESTS) 48 | -------------------------------------------------------------------------------- /tests/t-fork.c: -------------------------------------------------------------------------------- 1 | /* t-fork.c 2 | * Copyright 2016 g10 Code GmbH 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This file is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include "t-support.h" 17 | 18 | /* This is a test if nPth can allow daemon-like applications 19 | initializing earlier. 20 | 21 | For daemon-like applications, ideally, it is expected to call 22 | npth_init after fork. This condition is not satisfied sometimes. 23 | 24 | Failure of this test means nPth implementation doesn't allow 25 | npth_init after fork. In such a case, application should be 26 | modified. 27 | */ 28 | 29 | int 30 | main (int argc, const char *argv[]) 31 | { 32 | int rc; 33 | pid_t pid; 34 | 35 | if (argc >= 2 && !strcmp (argv[1], "--verbose")) 36 | opt_verbose = 1; 37 | 38 | rc = npth_init (); 39 | fail_if_err (rc); 40 | 41 | pid = fork (); 42 | if (pid == (pid_t)-1) 43 | fail_msg ("fork failed"); 44 | else if (pid) 45 | { 46 | int status; 47 | 48 | info_msg ("forked"); 49 | wait (&status); 50 | fail_if_err (status); 51 | } 52 | else 53 | { 54 | info_msg ("child exit"); 55 | npth_usleep (1000); /* Let NPTH enter, sleep, and leave. */ 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /src/getversion.c: -------------------------------------------------------------------------------- 1 | /* getversion.c - Return the npth version (source included) 2 | * Copyright (C) 2024 g10 Code GmbH 3 | * 4 | * This file is part of nPth. 5 | * 6 | * nPth is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation; either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * nPth is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 | * the GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, see . 18 | */ 19 | 20 | #ifndef BUILD_COMMITID 21 | #error This file must be included from the C source 22 | #endif 23 | 24 | static const char * 25 | cright_blurb (void) 26 | { 27 | static const char blurb[] = 28 | "\n\n" 29 | "This is nPth " PACKAGE_VERSION " - The New GNU Portable Threads Library\n" 30 | CRIGHTBLURB 31 | "\n" 32 | "(" BUILD_COMMITID " " BUILD_TIMESTAMP ")\n" 33 | "\n\n"; 34 | return blurb; 35 | } 36 | 37 | /* Return the version of the libarry as a string. DUMMY is only used 38 | * to be similar to the other libraries version function. */ 39 | const char * 40 | npth_get_version (const char *dummy) 41 | { 42 | if (dummy && dummy[0] == 1 && dummy[1] == 1) 43 | return cright_blurb (); 44 | else if (dummy && dummy[0] == 1 && dummy[1] == 2) 45 | return BUILD_COMMITID; 46 | return PACKAGE_VERSION; 47 | } 48 | -------------------------------------------------------------------------------- /tests/t-support.h: -------------------------------------------------------------------------------- 1 | /* t-support.h - Helper routines for regression tests. 2 | * Copyright (C) 2011 g10 Code GmbH 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This file is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "npth.h" 19 | 20 | #ifndef DIM 21 | #define DIM(v) (sizeof(v)/sizeof((v)[0])) 22 | #endif 23 | 24 | static int opt_verbose; 25 | 26 | 27 | #define fail_if_err(err) \ 28 | do \ 29 | { \ 30 | if (err) \ 31 | { \ 32 | fprintf (stderr, "%s:%d: %s\n", \ 33 | __FILE__, __LINE__, strerror(err)); \ 34 | exit (1); \ 35 | } \ 36 | } \ 37 | while (0) 38 | 39 | #define fail_msg(text) \ 40 | do \ 41 | { \ 42 | fprintf (stderr, "%s:%d: %s\n", \ 43 | __FILE__, __LINE__, text); \ 44 | exit (1); \ 45 | } \ 46 | while (0) 47 | 48 | #define info_msg(text) \ 49 | do \ 50 | { \ 51 | if (opt_verbose) \ 52 | fprintf (stderr, "%s\n", text); \ 53 | } \ 54 | while (0) 55 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Package: npth 2 | Download: https://gnupg.org/ftp/gcrypt/npth/ 3 | Repository: git://git.gnupg.org/npth.git 4 | Maintainer: Werner Koch 5 | Bug reports: gnupg-devel@gnupg.org 6 | Security related bug reports: security@gnupg.org 7 | License: LGPLv2+ 8 | 9 | 10 | nPth is free software. See the file COPYING.LIB for copying 11 | conditions. License copyright years may be listed using range 12 | notation, e.g., 2000-2013, indicating that every year in the range, 13 | inclusive, is a copyrightable year that would otherwise be listed 14 | individually. 15 | 16 | 17 | * Authors 18 | 19 | g10 Code GmbH 20 | - Design and implementation. 21 | 22 | 23 | 24 | * Copyright 25 | 26 | nPth is Copyright (C) 2011, 2012, 2014, 2015, 2017, 2024 g10 Code GmbH 27 | 28 | nPth is free software; you can redistribute it and/or modify 29 | it under the terms of the GNU Lesser General Public License as 30 | published by the Free Software Foundation; either version 2.1 of 31 | the License, or (at your option) any later version. 32 | 33 | nPth is distributed in the hope that it will be useful, but 34 | WITHOUT ANY WARRANTY; without even the implied warranty of 35 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 36 | the GNU Lesser General Public License for more details. 37 | 38 | You should have received a copy of the GNU Lesser General Public 39 | License along with this program; if not, see . 40 | 41 | 42 | 43 | # This file is Copyright 2011, 2012 g10 Code GmbH 44 | # 45 | # This file is free software; as a special exception the author gives 46 | # unlimited permission to copy and/or distribute it, with or without 47 | # modifications, as long as this notice is preserved. 48 | # 49 | # This file is distributed in the hope that it will be useful, but 50 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 51 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 52 | -------------------------------------------------------------------------------- /src/libnpth.vers: -------------------------------------------------------------------------------- 1 | # libnpth.vers - List of symbols to export. 2 | # Copyright (C) 2002, 2004, 2005, 2009 g10 Code GmbH 3 | # 4 | # This file is part of nPth. 5 | # 6 | # nPth is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as 8 | # published by the Free Software Foundation; either version 2.1 of the 9 | # License, or (at your option) any later version. 10 | # 11 | # nPth is distributed in the hope that it will be useful, but WITHOUT 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14 | # Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this program; if not, see . 18 | 19 | #------------------------------------------------------- 20 | # Please remember to add new functions also to npth.def 21 | #------------------------------------------------------- 22 | 23 | NPTH_1.0 { 24 | global: 25 | npth_init; 26 | npth_create; 27 | npth_join; 28 | npth_exit; 29 | npth_mutex_lock; 30 | npth_mutex_timedlock; 31 | npth_rwlock_rdlock; 32 | npth_rwlock_timedrdlock; 33 | npth_rwlock_wrlock; 34 | npth_rwlock_timedwrlock; 35 | npth_cond_wait; 36 | npth_cond_timedwait; 37 | npth_usleep; 38 | npth_sleep; 39 | npth_waitpid; 40 | npth_system; 41 | npth_connect; 42 | npth_accept; 43 | npth_select; 44 | npth_pselect; 45 | npth_read; 46 | npth_write; 47 | npth_recvmsg; 48 | npth_sendmsg; 49 | npth_unprotect; 50 | npth_protect; 51 | npth_is_protected; 52 | npth_clock_gettime; 53 | 54 | npth_sigev_init; 55 | npth_sigev_add; 56 | npth_sigev_fini; 57 | npth_sigev_sigmask; 58 | npth_sigev_get_pending; 59 | 60 | npth_getname_np; 61 | npth_setname_np; 62 | 63 | npth_poll; 64 | npth_ppoll; 65 | 66 | npth_get_version; 67 | 68 | local: 69 | *; 70 | 71 | }; 72 | -------------------------------------------------------------------------------- /w32/versioninfo.rc.in: -------------------------------------------------------------------------------- 1 | /* versioninfo.rc.in - for nPth 2 | * Copyright (C) 2024 g10 Code GmbH 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | /* This file is processed by configure to create versioninfo.rc */ 14 | 15 | #line __LINE__ "versioninfo.rc.in" 16 | 17 | #include 18 | 19 | 20 | VS_VERSION_INFO VERSIONINFO 21 | FILEVERSION @BUILD_FILEVERSION@ 22 | PRODUCTVERSION @BUILD_FILEVERSION@ 23 | FILEFLAGSMASK 0x3fL 24 | #ifdef _DEBUG 25 | FILEFLAGS 0x21L 26 | #else 27 | FILEFLAGS 0x20L 28 | #endif 29 | FILEOS 0x40004L 30 | FILETYPE 0x1L 31 | FILESUBTYPE 0x0L 32 | BEGIN 33 | BLOCK "StringFileInfo" 34 | BEGIN 35 | BLOCK "040904b0" 36 | BEGIN 37 | VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License, version 2.1 or later\0" 38 | VALUE "CompanyName", "g10 Code GmbH\0" 39 | VALUE "FileDescription", "nPth - The New GNU Portable Threads Library\0" 40 | VALUE "FileVersion", "@LIBNPTH_LT_CURRENT@.@LIBNPTH_LT_AGE@.@LIBNPTH_LT_REVISION@.@BUILD_REVISION@\0" 41 | VALUE "InternalName", "libnpth\0" 42 | VALUE "LegalCopyright", "Copyright \xa9 2024 g10 Code GmbH\0" 43 | VALUE "LegalTrademarks", "\0" 44 | VALUE "OriginalFilename", "libnpth.dll\0" 45 | VALUE "PrivateBuild", "\0" 46 | VALUE "ProductName", "nPth\0" 47 | VALUE "ProductVersion", "@PACKAGE_VERSION@\0" 48 | VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0" 49 | END 50 | END 51 | BLOCK "VarFileInfo" 52 | BEGIN 53 | VALUE "Translation", 0x409, 0x4b0 54 | END 55 | END 56 | -------------------------------------------------------------------------------- /w32/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am - w32 Makefile for nPth. 2 | # Copyright (C) 2011 g10 Code GmbH 3 | # 4 | # This file is part of nPth. 5 | # 6 | # nPth is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as 8 | # published by the Free Software Foundation; either version 2.1 of the 9 | # License, or (at your option) any later version. 10 | # 11 | # nPth is distributed in the hope that it will be useful, but WITHOUT 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14 | # Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this program; if not, see . 18 | 19 | ## Process this file with automake to produce Makefile.in 20 | 21 | # Note: This directory is only used for W32 22 | 23 | EXTRA_DIST = npth.def 24 | nodist_include_HEADERS = npth.h 25 | 26 | lib_LTLIBRARIES = libnpth.la 27 | 28 | libnpth_la_SOURCES = npth.h npth.c 29 | 30 | # AM_CPPFLAGS = 31 | # AM_CFLAGS = 32 | 33 | RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 34 | LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) 35 | 36 | SUFFIXES = .rc .lo 37 | 38 | .rc.lo: 39 | $(LTRCCOMPILE) -i "$<" -o "$@" 40 | 41 | npth_res = versioninfo.lo 42 | no_undefined = -no-undefined 43 | export_symbols = -export-symbols $(srcdir)/npth.def 44 | extra_ltoptions = -XCClinker -static-libgcc 45 | 46 | install-def-file: 47 | $(INSTALL) $(srcdir)/npth.def $(DESTDIR)$(libdir)/npth.def 48 | 49 | uninstall-def-file: 50 | -rm $(DESTDIR)$(libdir)/npth.def 51 | 52 | npth_deps = $(npth_res) npth.def 53 | 54 | 55 | libnpth_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \ 56 | -version-info \ 57 | @LIBNPTH_LT_CURRENT@:@LIBNPTH_LT_REVISION@:@LIBNPTH_LT_AGE@ 58 | libnpth_la_DEPENDENCIES = $(npth_deps) 59 | libnpth_la_LIBADD = $(npth_res) @NETLIBS@ 60 | 61 | install-data-local: install-def-file 62 | 63 | uninstall-local: uninstall-def-file 64 | -------------------------------------------------------------------------------- /m4/libsocket.m4: -------------------------------------------------------------------------------- 1 | # libsocket.m4 serial 1 - based on gnulib socketlib.m4 2 | dnl Copyright (C) 2008-2012 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl npth_SOCKETLIB 8 | dnl Determines the library to use for socket functions. 9 | dnl Sets and AC_SUBSTs LIBSOCKET. 10 | AC_DEFUN([npth_LIBSOCKET], 11 | [ 12 | LIBSOCKET= 13 | dnl Unix API. 14 | dnl Solaris has most socket functions in libsocket. 15 | dnl Haiku has most socket functions in libnetwork. 16 | dnl BeOS has most socket functions in libnet. 17 | AC_CACHE_CHECK([for library containing setsockopt], [npth_cv_lib_socket], [ 18 | npth_cv_lib_socket= 19 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern 20 | #ifdef __cplusplus 21 | "C" 22 | #endif 23 | char setsockopt();]], [[setsockopt();]])], 24 | [], 25 | [npth_save_LIBS="$LIBS" 26 | LIBS="$npth_save_LIBS -lsocket" 27 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern 28 | #ifdef __cplusplus 29 | "C" 30 | #endif 31 | char setsockopt();]], [[setsockopt();]])], 32 | [npth_cv_lib_socket="-lsocket"]) 33 | if test -z "$npth_cv_lib_socket"; then 34 | LIBS="$npth_save_LIBS -lnetwork" 35 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern 36 | #ifdef __cplusplus 37 | "C" 38 | #endif 39 | char setsockopt();]], [[setsockopt();]])], 40 | [npth_cv_lib_socket="-lnetwork"]) 41 | if test -z "$npth_cv_lib_socket"; then 42 | LIBS="$npth_save_LIBS -lnet" 43 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern 44 | #ifdef __cplusplus 45 | "C" 46 | #endif 47 | char setsockopt();]], [[setsockopt();]])], 48 | [npth_cv_lib_socket="-lnet"]) 49 | fi 50 | fi 51 | LIBS="$npth_save_LIBS" 52 | ]) 53 | if test -z "$npth_cv_lib_socket"; then 54 | npth_cv_lib_socket="none needed" 55 | fi 56 | ]) 57 | if test "$npth_cv_lib_socket" != "none needed"; then 58 | LIBSOCKET="$npth_cv_lib_socket" 59 | fi 60 | AC_SUBST([LIBSOCKET]) 61 | ]) 62 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am - src/ Makefile for npth. 2 | # Copyright (C) 2011 g10 Code GmbH 3 | # 4 | # This file is part of nPth. 5 | # 6 | # nPth is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as 8 | # published by the Free Software Foundation; either version 2.1 of the 9 | # License, or (at your option) any later version. 10 | # 11 | # nPth is distributed in the hope that it will be useful, but WITHOUT 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14 | # Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this program; if not, see . 18 | 19 | ## Process this file with automake to produce Makefile.in 20 | 21 | EXTRA_DIST = libnpth.vers getversion.c 22 | # versioninfo.rc.in 23 | nodist_include_HEADERS = npth.h 24 | 25 | lib_LTLIBRARIES = libnpth.la 26 | 27 | if HAVE_LD_VERSION_SCRIPT 28 | libnpth_version_script_cmd = -Wl,--version-script=$(srcdir)/libnpth.vers 29 | else 30 | libnpth_version_script_cmd = 31 | endif 32 | 33 | libnpth_la_SOURCES = npth.c npth-sigev.c 34 | 35 | # AM_CPPFLAGS = 36 | # AM_CFLAGS = 37 | 38 | if HAVE_W32_SYSTEM 39 | RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 40 | LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) 41 | 42 | SUFFIXES = .rc .lo 43 | 44 | .rc.lo: 45 | $(LTRCCOMPILE) -i "$<" -o "$@" 46 | 47 | npth_res = versioninfo.lo 48 | no_undefined = -no-undefined 49 | export_symbols = -export-symbols $(srcdir)/npth.def 50 | 51 | install-def-file: 52 | $(INSTALL) $(srcdir)/npth.def $(DESTDIR)$(libdir)/npth.def 53 | 54 | uninstall-def-file: 55 | -rm $(DESTDIR)$(libdir)/npth.def 56 | 57 | gpgme_deps = $(gpgme_res) npth.def 58 | 59 | else 60 | npth_res = 61 | no_undefined = 62 | export_symbols = 63 | install-def-file: 64 | uninstall-def-file: 65 | 66 | npth_deps = 67 | endif 68 | 69 | libnpth_la_LDFLAGS = $(no_undefined) $(export_symbols) \ 70 | $(libnpth_version_script_cmd) -version-info \ 71 | @LIBNPTH_LT_CURRENT@:@LIBNPTH_LT_REVISION@:@LIBNPTH_LT_AGE@ 72 | 73 | libnpth_la_DEPENDENCIES = $(srcdir)/libnpth.vers $(npth_deps) 74 | 75 | install-data-local: install-def-file 76 | 77 | uninstall-local: uninstall-def-file 78 | -------------------------------------------------------------------------------- /w32/npth.def: -------------------------------------------------------------------------------- 1 | ; npth.def - List of symbols to export. 2 | ; Copyright (C) 2011 g10 Code GmbH 3 | ; 4 | ; This file is part of NPTH. 5 | ; 6 | ; NPTH is free software; you can redistribute it and/or modify 7 | ; it under the terms of the GNU Lesser General Public License as 8 | ; published by the Free Software Foundation; either version 2.1 of 9 | ; the License, or (at your option) any later version. 10 | ; 11 | ; NPTH is distributed in the hope that it will be useful, but 12 | ; WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 | ; the GNU Lesser General Public License for more details. 15 | ; 16 | ; You should have received a copy of the GNU Lesser General Public 17 | ; License along with this program; if not, see . 18 | 19 | 20 | EXPORTS 21 | npth_init @1 22 | npth_attr_init @2 23 | npth_attr_destroy @3 24 | npth_attr_getdetachstate @4 25 | npth_attr_setdetachstate @5 26 | npth_getname_np @6 27 | npth_setname_np @7 28 | npth_create @8 29 | npth_self @9 30 | npth_join @10 31 | npth_detach @11 32 | npth_exit @12 33 | npth_key_create @13 34 | npth_key_delete @14 35 | npth_getspecific @15 36 | npth_setspecific @16 37 | npth_mutexattr_init @17 38 | npth_mutexattr_destroy @18 39 | npth_mutexattr_gettype @19 40 | npth_mutexattr_settype @20 41 | npth_mutex_init @21 42 | npth_mutex_destroy @22 43 | npth_mutex_trylock @23 44 | npth_mutex_lock @24 45 | npth_mutex_timedlock @25 46 | npth_mutex_unlock @26 47 | npth_rwlockattr_init @27 48 | npth_rwlockattr_destroy @28 49 | npth_rwlockattr_gettype_np @29 50 | npth_rwlockattr_settype_np @30 51 | npth_rwlock_init @31 52 | npth_rwlock_destroy @32 53 | npth_rwlock_tryrdlock @33 54 | npth_rwlock_rdlock @34 55 | npth_rwlock_timedrdlock @35 56 | npth_rwlock_trywrlock @36 57 | npth_rwlock_wrlock @37 58 | npth_rwlock_timedwrlock @38 59 | npth_rwlock_unlock @39 60 | npth_cond_init @40 61 | npth_cond_broadcast @41 62 | npth_cond_signal @42 63 | npth_cond_destroy @43 64 | npth_cond_wait @44 65 | npth_cond_timedwait @45 66 | npth_usleep @46 67 | npth_sleep @47 68 | npth_waitpid @48 69 | npth_system @49 70 | npth_connect @50 71 | npth_accept @51 72 | npth_select @52 73 | npth_read @53 74 | npth_write @54 75 | npth_recvmsg @55 76 | npth_sendmsg @56 77 | npth_clock_gettime @57 78 | npth_eselect @58 79 | npth_unprotect @59 80 | npth_protect @60 81 | npth_is_protected @61 82 | npth_get_version @62 83 | 84 | ; END 85 | -------------------------------------------------------------------------------- /m4/socklen.m4: -------------------------------------------------------------------------------- 1 | # socklen.m4 serial 11 2 | dnl Copyright (C) 2005-2007, 2009-2020 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Albert Chin, Windows fixes from Simon Josefsson. 8 | 9 | dnl Check for socklen_t: historically on BSD it is an int, and in 10 | dnl POSIX 1g it is a type of its own, but some platforms use different 11 | dnl types for the argument to getsockopt, getpeername, etc.: 12 | dnl HP-UX 10.20, IRIX 6.5, OSF/1 4.0, Interix 3.5, BeOS. 13 | dnl So we have to test to find something that will work. 14 | 15 | AC_DEFUN([gl_TYPE_SOCKLEN_T], 16 | [AC_REQUIRE([gl_CHECK_SOCKET_HEADERS])dnl 17 | AC_CHECK_TYPE([socklen_t], , 18 | [AC_CACHE_CHECK([for socklen_t equivalent], 19 | [gl_cv_socklen_t_equiv], 20 | [# Systems have either "struct sockaddr *" or 21 | # "void *" as the second argument to getpeername 22 | gl_cv_socklen_t_equiv= 23 | for arg2 in "struct sockaddr" void; do 24 | for t in int size_t "unsigned int" "long int" "unsigned long int"; do 25 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM( 26 | [[#include 27 | #include 28 | 29 | int getpeername (int, $arg2 *, $t *);]], 30 | [[$t len; 31 | getpeername (0, 0, &len);]])], 32 | [gl_cv_socklen_t_equiv="$t"]) 33 | test "$gl_cv_socklen_t_equiv" != "" && break 34 | done 35 | test "$gl_cv_socklen_t_equiv" != "" && break 36 | done 37 | if test "$gl_cv_socklen_t_equiv" = ""; then 38 | AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) 39 | fi 40 | ]) 41 | AC_DEFINE_UNQUOTED([socklen_t], [$gl_cv_socklen_t_equiv], 42 | [type to use in place of socklen_t if not defined])], 43 | [gl_SOCKET_HEADERS])]) 44 | 45 | dnl On mingw32, socklen_t is in ws2tcpip.h ('int'), so we try to find 46 | dnl it there too. But on Cygwin, wc2tcpip.h must not be included. Users 47 | dnl of this module should use the same include pattern as gl_SOCKET_HEADERS. 48 | dnl When you change this macro, keep also in sync: 49 | dnl - gl_CHECK_SOCKET_HEADERS, 50 | dnl - the Include section of modules/socklen. 51 | AC_DEFUN([gl_SOCKET_HEADERS], 52 | [ 53 | /* is not needed according to POSIX, but the 54 | in i386-unknown-freebsd4.10 and 55 | powerpc-apple-darwin5.5 required it. */ 56 | #include 57 | #if HAVE_SYS_SOCKET_H 58 | # include 59 | #elif HAVE_WS2TCPIP_H 60 | # include 61 | #endif 62 | ]) 63 | 64 | dnl Tests for the existence of the header for socket facilities. 65 | dnl Defines the C macros HAVE_SYS_SOCKET_H, HAVE_WS2TCPIP_H. 66 | dnl This macro must match gl_SOCKET_HEADERS. 67 | AC_DEFUN([gl_CHECK_SOCKET_HEADERS], 68 | [AC_CHECK_HEADERS_ONCE([sys/socket.h]) 69 | if test $ac_cv_header_sys_socket_h = no; then 70 | dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make 71 | dnl the check for those headers unconditional; yet cygwin reports 72 | dnl that the headers are present but cannot be compiled (since on 73 | dnl cygwin, all socket information should come from sys/socket.h). 74 | AC_CHECK_HEADERS([ws2tcpip.h]) 75 | fi 76 | ]) 77 | -------------------------------------------------------------------------------- /npth-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. 3 | # 4 | # This file is free software; as a special exception the author gives 5 | # unlimited permission to copy and/or distribute it, with or without 6 | # modifications, as long as this notice is preserved. 7 | # 8 | # This file is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | 12 | prefix=@prefix@ 13 | exec_prefix=@exec_prefix@ 14 | 15 | # Make sure that no weird locale setting messes up our sed regexps etc. 16 | LC_COLLATE=C 17 | LC_ALL=C 18 | LANG=C 19 | 20 | # NPTH's own cflags and libs 21 | cflags="-I@includedir@ @NPTH_CONFIG_CFLAGS@" 22 | libs="-L@libdir@ @NPTH_CONFIG_LIBS@" 23 | 24 | output="" 25 | 26 | usage() 27 | { 28 | cat <&2 45 | fi 46 | 47 | while test $# -gt 0; do 48 | case "$1" in 49 | -*=*) 50 | optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` 51 | ;; 52 | *) 53 | optarg= 54 | ;; 55 | esac 56 | 57 | case $1 in 58 | --prefix=*) 59 | # For compatibility reasons with old M4 macros, we ignore 60 | # setting of prefix. 61 | ;; 62 | --prefix) 63 | output="$output $prefix" 64 | ;; 65 | --exec-prefix=*) 66 | ;; 67 | --exec-prefix) 68 | output="$output $exec_prefix" 69 | ;; 70 | --glib) 71 | with_glib=yes 72 | ;; 73 | --variable=*) 74 | case "${1#*=}" in 75 | prefix) echo "$prefix" ;; 76 | exec_prefix) echo "$exec_prefix" ;; 77 | host) echo "@NPTH_CONFIG_HOST@" ;; 78 | api_version) echo "@NPTH_CONFIG_API_VERSION@" ;; 79 | esac 80 | exit 0 81 | ;; 82 | --modversion|--version) 83 | echo "@PACKAGE_VERSION@" 84 | exit 0 85 | ;; 86 | --api-version) 87 | echo "@NPTH_CONFIG_API_VERSION@" 88 | exit 0 89 | ;; 90 | --host) 91 | echo "@NPTH_CONFIG_HOST@" 92 | exit 0 93 | ;; 94 | --cflags) 95 | result= 96 | for i in $cflags ; do 97 | skip=no 98 | case $i in 99 | -I/usr/include|-I/include) 100 | skip=yes 101 | ;; 102 | -I*) 103 | for j in $result ; do 104 | if test x"$j" = x"$i" ; then 105 | skip=yes 106 | break; 107 | fi 108 | done 109 | ;; 110 | esac 111 | if test $skip = no ; then 112 | result="$result $i" 113 | fi 114 | done 115 | output="$output $result" 116 | ;; 117 | --libs) 118 | result= 119 | for i in $libs ; do 120 | skip=no 121 | case $i in 122 | -L/usr/lib|-L/lib) 123 | skip=yes 124 | ;; 125 | -L*|-l*) 126 | for j in $result ; do 127 | if test x"$j" = x"$i" ; then 128 | skip=yes 129 | break; 130 | fi 131 | done 132 | ;; 133 | esac 134 | if test $skip = no ; then 135 | result="$result $i" 136 | fi 137 | done 138 | output="$output $result" 139 | ;; 140 | *) 141 | usage 1 1>&2 142 | ;; 143 | esac 144 | shift 145 | done 146 | 147 | echo $output 148 | -------------------------------------------------------------------------------- /tests/t-thread.c: -------------------------------------------------------------------------------- 1 | /* t-thread.c 2 | * Copyright 2012 g10 Code GmbH 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This file is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include "t-support.h" 14 | 15 | 16 | static int counter; 17 | static npth_mutex_t counter_mutex; 18 | static int thread_twoone_ready; 19 | 20 | static void * 21 | thread_one (void *arg) 22 | { 23 | int rc, i; 24 | 25 | info_msg ("thread-one started"); 26 | npth_usleep (10); /* Give the other thread some time to start. */ 27 | for (i=0; i < 10; i++) 28 | { 29 | /* We would not need the mutex here, but we use it to allow the 30 | system to switch to another thread. */ 31 | rc = npth_mutex_lock (&counter_mutex); 32 | fail_if_err (rc); 33 | 34 | counter++; 35 | 36 | rc = npth_mutex_unlock (&counter_mutex); 37 | fail_if_err (rc); 38 | } 39 | info_msg ("thread-one terminated"); 40 | 41 | return (void*)4711; 42 | } 43 | 44 | 45 | static void * 46 | thread_twoone (void *arg) 47 | { 48 | int rc; 49 | 50 | npth_setname_np (npth_self (), "thread-twoone"); 51 | info_msg ("thread-twoone started"); 52 | 53 | rc = npth_detach (npth_self ()); 54 | fail_if_err (rc); 55 | 56 | while (counter < 100) 57 | { 58 | npth_usleep (1000); 59 | counter++; 60 | } 61 | info_msg ("thread-twoone terminated"); 62 | thread_twoone_ready = 1; 63 | 64 | return NULL; 65 | } 66 | 67 | 68 | static void * 69 | thread_two (void *arg) 70 | { 71 | int rc, i; 72 | 73 | info_msg ("thread-two started"); 74 | 75 | for (i=0; i < 10; i++) 76 | { 77 | rc = npth_mutex_lock (&counter_mutex); 78 | fail_if_err (rc); 79 | 80 | counter--; 81 | 82 | if (i == 5) 83 | { 84 | npth_t tid; 85 | 86 | info_msg ("creating thread-twoone"); 87 | rc = npth_create (&tid, NULL, thread_twoone, NULL); 88 | fail_if_err (rc); 89 | npth_usleep (10); /* Give new thread some time to start. */ 90 | } 91 | 92 | rc = npth_mutex_unlock (&counter_mutex); 93 | fail_if_err (rc); 94 | } 95 | 96 | info_msg ("busy waiting for thread twoone"); 97 | while (!thread_twoone_ready) 98 | npth_sleep (0); 99 | 100 | info_msg ("thread-two terminated"); 101 | 102 | return (void*)4722; 103 | } 104 | 105 | 106 | 107 | 108 | 109 | int 110 | main (int argc, char *argv[]) 111 | { 112 | int rc; 113 | npth_attr_t tattr; 114 | int state; 115 | npth_t tid1, tid2; 116 | void *retval; 117 | 118 | if (argc >= 2 && !strcmp (argv[1], "--verbose")) 119 | opt_verbose = 1; 120 | 121 | rc = npth_init (); 122 | fail_if_err (rc); 123 | 124 | rc = npth_mutex_init (&counter_mutex, NULL); 125 | fail_if_err (rc); 126 | 127 | rc = npth_attr_init (&tattr); 128 | fail_if_err (rc); 129 | rc = npth_attr_getdetachstate (&tattr, &state); 130 | fail_if_err (rc); 131 | if ( state != NPTH_CREATE_JOINABLE ) 132 | fail_msg ("new tattr is not joinable"); 133 | 134 | info_msg ("creating thread-one"); 135 | rc = npth_create (&tid1, &tattr, thread_one, NULL); 136 | fail_if_err (rc); 137 | npth_setname_np (tid1, "thread-one"); 138 | 139 | info_msg ("creating thread-two"); 140 | rc = npth_create (&tid2, &tattr, thread_two, NULL); 141 | fail_if_err (rc); 142 | npth_setname_np (tid2, "thread-two"); 143 | 144 | rc = npth_attr_destroy (&tattr); 145 | fail_if_err (rc); 146 | 147 | info_msg ("waiting for thread-one to terminate"); 148 | rc = npth_join (tid1, &retval); 149 | fail_if_err (rc); 150 | if (retval != (void*)4711) 151 | fail_msg ("thread-one returned an unexpected value"); 152 | 153 | info_msg ("waiting for thread-two to terminate"); 154 | rc = npth_join (tid2, &retval); 155 | fail_if_err (rc); 156 | if (retval != (void*)4722) 157 | fail_msg ("thread-two returned an unexpected value"); 158 | 159 | if (counter != 100) 160 | fail_msg ("counter value not as expected"); 161 | 162 | return 0; 163 | } 164 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Noteworthy changes in version 1.9 (unreleased) [C3/A3/R_] 2 | ---------------------------------------------- 3 | 4 | 5 | Noteworthy changes in version 1.8 (2024-11-12) [C3/A3/R0] 6 | ---------------------------------------------- 7 | 8 | * Fix npth_cond_signal and npth_cond_broadcast on Windows. [T7386] 9 | 10 | * New function npth_get_version. New macros NPTH_VERSION and 11 | NPTH_VERSION_NUMBER. 12 | 13 | * Fix INSERT_EXPOSE_RWLOCK_API for musl C library. [T5664] 14 | 15 | * Add fallback implementation for POSIX semaphore API on macOS. 16 | [T7057] 17 | 18 | * Return a run-time error if npth_rwlock_timedrdlock is not 19 | supported. [T7109] 20 | 21 | Release-info: https://dev.gnupg.org/T7387 22 | 23 | 24 | Noteworthy changes in version 1.7 (2024-02-23) [C2/A2/R0] 25 | ---------------------------------------------- 26 | 27 | * The npth-config command is not installed by default, because it is 28 | now replaced by use of pkg-config/gpgrt-config with npth.pc. 29 | Supply --enable-install-npth-config configure option, if needed. 30 | 31 | * Support for legacy systems w/o pthread_rwlock_t support. [T4306] 32 | 33 | * New functions npth_poll and npth_ppoll for Unix. [T5748] 34 | 35 | * Fixes to improve support for 64 bit Windows. 36 | 37 | * Fix declaration conflict using newer mingw versions. [T5889] 38 | 39 | * Fix build problems on Solaris 11. [T4491] 40 | 41 | * Fix detecting of the pthread library. [rPTH6629a4b801] 42 | 43 | * Clean up handling of unsafe semaphores on AIX. [T6947] 44 | 45 | * Link without -flat_namespace to support macOS 11. [T5610] 46 | 47 | Release-info: https://dev.gnupg.org/T7010 48 | 49 | 50 | Noteworthy changes in version 1.6 (2018-07-16) [C1/A1/R2] 51 | ---------------------------------------------- 52 | 53 | * Fix library requirements for HPUX. [#3980] 54 | 55 | * Fix a minor memory leak on Windows. 56 | 57 | 58 | Noteworthy changes in version 1.5 (2017-06-02) [C1/A1/R1] 59 | ---------------------------------------------- 60 | 61 | * Fix the busy waiting emulation of pthread_mutex_timedlock for 62 | Unices lacking that function; e.g. macOS Sierra. 63 | 64 | 65 | Noteworthy changes in version 1.4 (2017-05-16) [C1/A1/R0] 66 | ---------------------------------------------- 67 | 68 | * On macOS make use of an unnamed semaphore. 69 | 70 | * Build fixes for FreeBSD, NetBSD, and DragonFlyBSD. 71 | 72 | * New function npth_is_protected to help debugging. 73 | 74 | * Change license from LGPLv3+/GPLv2+ to LGPLv2+. 75 | 76 | 77 | Noteworthy changes in version 1.3 (2016-11-22) 78 | ---------------------------------------------- 79 | 80 | * Bypass npth_protect/npth_unprotect iff the library has not yet been 81 | initialized. 82 | 83 | * Fix problems on macOS and AIX 84 | 85 | * Improve detection of clock_gettime 86 | 87 | 88 | Noteworthy changes in version 1.2 (2015-04-11) 89 | ---------------------------------------------- 90 | 91 | * Fix possible clobbering of ERRNO. 92 | 93 | * Improved building on Windows with newer versions of Mingw. 94 | 95 | 96 | Noteworthy changes in version 1.1 (2014-10-31) 97 | ---------------------------------------------- 98 | 99 | * Make it work on OS X and some other systems. 100 | 101 | 102 | Noteworthy changes in version 1.0 (2014-09-18) 103 | ---------------------------------------------- 104 | 105 | * Various fixes for the Windows port. 106 | 107 | 108 | Noteworthy changes in version 0.91 (2012-08-08) 109 | ----------------------------------------------- 110 | 111 | * Fixed a flaw in the initialization code. 112 | 113 | * npth_init does now return an error on failure. 114 | 115 | * Various fixes for better portability. 116 | 117 | * Provide a pselect emulation for OpenBSD et al. 118 | 119 | 120 | Noteworthy changes in version 0.90 (2012-05-03) 121 | ----------------------------------------------- 122 | 123 | * First tarball release. 124 | 125 | 126 | Copyright 2011, 2012, 2014 g10 Code GmbH 127 | 128 | This file is free software; as a special exception the author gives 129 | unlimited permission to copy and/or distribute it, with or without 130 | modifications, as long as this notice is preserved. 131 | 132 | This file is distributed in the hope that it will be useful, but 133 | WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 134 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 135 | -------------------------------------------------------------------------------- /m4/ltsugar.m4: -------------------------------------------------------------------------------- 1 | # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. 4 | # Written by Gary V. Vaughan, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 6 ltsugar.m4 11 | 12 | # This is to help aclocal find these macros, as it can't see m4_define. 13 | AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) 14 | 15 | 16 | # lt_join(SEP, ARG1, [ARG2...]) 17 | # ----------------------------- 18 | # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their 19 | # associated separator. 20 | # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier 21 | # versions in m4sugar had bugs. 22 | m4_define([lt_join], 23 | [m4_if([$#], [1], [], 24 | [$#], [2], [[$2]], 25 | [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) 26 | m4_define([_lt_join], 27 | [m4_if([$#$2], [2], [], 28 | [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) 29 | 30 | 31 | # lt_car(LIST) 32 | # lt_cdr(LIST) 33 | # ------------ 34 | # Manipulate m4 lists. 35 | # These macros are necessary as long as will still need to support 36 | # Autoconf-2.59 which quotes differently. 37 | m4_define([lt_car], [[$1]]) 38 | m4_define([lt_cdr], 39 | [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], 40 | [$#], 1, [], 41 | [m4_dquote(m4_shift($@))])]) 42 | m4_define([lt_unquote], $1) 43 | 44 | 45 | # lt_append(MACRO-NAME, STRING, [SEPARATOR]) 46 | # ------------------------------------------ 47 | # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. 48 | # Note that neither SEPARATOR nor STRING are expanded; they are appended 49 | # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). 50 | # No SEPARATOR is output if MACRO-NAME was previously undefined (different 51 | # than defined and empty). 52 | # 53 | # This macro is needed until we can rely on Autoconf 2.62, since earlier 54 | # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. 55 | m4_define([lt_append], 56 | [m4_define([$1], 57 | m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) 58 | 59 | 60 | 61 | # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) 62 | # ---------------------------------------------------------- 63 | # Produce a SEP delimited list of all paired combinations of elements of 64 | # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list 65 | # has the form PREFIXmINFIXSUFFIXn. 66 | # Needed until we can rely on m4_combine added in Autoconf 2.62. 67 | m4_define([lt_combine], 68 | [m4_if(m4_eval([$# > 3]), [1], 69 | [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl 70 | [[m4_foreach([_Lt_prefix], [$2], 71 | [m4_foreach([_Lt_suffix], 72 | ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, 73 | [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) 74 | 75 | 76 | # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) 77 | # ----------------------------------------------------------------------- 78 | # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited 79 | # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. 80 | m4_define([lt_if_append_uniq], 81 | [m4_ifdef([$1], 82 | [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], 83 | [lt_append([$1], [$2], [$3])$4], 84 | [$5])], 85 | [lt_append([$1], [$2], [$3])$4])]) 86 | 87 | 88 | # lt_dict_add(DICT, KEY, VALUE) 89 | # ----------------------------- 90 | m4_define([lt_dict_add], 91 | [m4_define([$1($2)], [$3])]) 92 | 93 | 94 | # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) 95 | # -------------------------------------------- 96 | m4_define([lt_dict_add_subkey], 97 | [m4_define([$1($2:$3)], [$4])]) 98 | 99 | 100 | # lt_dict_fetch(DICT, KEY, [SUBKEY]) 101 | # ---------------------------------- 102 | m4_define([lt_dict_fetch], 103 | [m4_ifval([$3], 104 | m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), 105 | m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) 106 | 107 | 108 | # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) 109 | # ----------------------------------------------------------------- 110 | m4_define([lt_if_dict_fetch], 111 | [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], 112 | [$5], 113 | [$6])]) 114 | 115 | 116 | # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) 117 | # -------------------------------------------------------------- 118 | m4_define([lt_dict_filter], 119 | [m4_if([$5], [], [], 120 | [lt_join(m4_quote(m4_default([$4], [[, ]])), 121 | lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), 122 | [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl 123 | ]) 124 | -------------------------------------------------------------------------------- /npth.m4: -------------------------------------------------------------------------------- 1 | # npth.m4 - autoconf macro to detect NPTH. 2 | # Copyright (C) 2002, 2003, 2004, 2011, 2018 g10 Code GmbH 3 | # 4 | # This file is free software; as a special exception the author gives 5 | # unlimited permission to copy and/or distribute it, with or without 6 | # modifications, as long as this notice is preserved. 7 | # 8 | # This file is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | 12 | # Last-changed: 2025-09-25 13 | 14 | AC_DEFUN([_AM_PATH_NPTH_CONFIG], 15 | [ AC_ARG_WITH(npth-prefix, 16 | AS_HELP_STRING([--with-npth-prefix=PFX], 17 | [prefix where NPTH is installed (optional)]), 18 | npth_config_prefix="$withval", npth_config_prefix="") 19 | if test "x$npth_config_prefix" != x ; then 20 | NPTH_CONFIG="$npth_config_prefix/bin/npth-config" 21 | fi 22 | 23 | use_gpgrt_config="" 24 | if test x"$GPGRT_CONFIG" != x && test "$GPGRT_CONFIG" != "no"; then 25 | if $GPGRT_CONFIG npth --exists; then 26 | NPTH_CONFIG="$GPGRT_CONFIG npth" 27 | AC_MSG_NOTICE([Use gpgrt-config as npth-config]) 28 | use_gpgrt_config=yes 29 | fi 30 | fi 31 | if test -z "$use_gpgrt_config"; then 32 | AC_PATH_PROG(NPTH_CONFIG, npth-config, no) 33 | fi 34 | 35 | if test "$NPTH_CONFIG" != "no" ; then 36 | if test -z "$use_gpgrt_config"; then 37 | npth_version=`$NPTH_CONFIG --version` 38 | else 39 | npth_version=`$NPTH_CONFIG --modversion` 40 | fi 41 | fi 42 | npth_version_major=`echo $npth_version | \ 43 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` 44 | npth_version_minor=`echo $npth_version | \ 45 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` 46 | ]) 47 | 48 | dnl AM_PATH_NPTH([MINIMUM-VERSION, 49 | dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) 50 | dnl Test for libnpth and define NPTH_CFLAGS and NPTH_LIBS. 51 | dnl 52 | AC_DEFUN([AM_PATH_NPTH], 53 | [ AC_REQUIRE([_AM_PATH_NPTH_CONFIG])dnl 54 | tmp=ifelse([$1], ,1:0.91,$1) 55 | if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then 56 | req_npth_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` 57 | min_npth_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` 58 | else 59 | req_npth_api=1 60 | min_npth_version="$tmp" 61 | fi 62 | 63 | AC_MSG_CHECKING(for NPTH - version >= $min_npth_version) 64 | ok=no 65 | if test "$NPTH_CONFIG" != "no" ; then 66 | req_major=`echo $min_npth_version | \ 67 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` 68 | req_minor=`echo $min_npth_version | \ 69 | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` 70 | if test "$npth_version_major" -gt "$req_major"; then 71 | ok=yes 72 | else 73 | if test "$npth_version_major" -eq "$req_major"; then 74 | if test "$npth_version_minor" -gt "$req_minor"; then 75 | ok=yes 76 | else 77 | if test "$npth_version_minor" -eq "$req_minor"; then 78 | ok=yes 79 | fi 80 | fi 81 | fi 82 | fi 83 | fi 84 | if test $ok = yes; then 85 | AC_MSG_RESULT([yes ($npth_version)]) 86 | else 87 | AC_MSG_RESULT(no) 88 | fi 89 | if test $ok = yes; then 90 | # If we have a recent NPTH, we should also check that the 91 | # API is compatible. 92 | if test "$req_npth_api" -gt 0 ; then 93 | if test -z "$use_gpgrt_config"; then 94 | tmp=`$NPTH_CONFIG --api-version 2>/dev/null || echo 0` 95 | else 96 | tmp=`$NPTH_CONFIG --variable=api_version 2>/dev/null || echo 0` 97 | fi 98 | if test "$tmp" -gt 0 ; then 99 | AC_MSG_CHECKING([NPTH API version]) 100 | if test "$req_npth_api" -eq "$tmp" ; then 101 | AC_MSG_RESULT([okay]) 102 | else 103 | ok=no 104 | AC_MSG_RESULT([does not match. want=$req_npth_api got=$tmp]) 105 | fi 106 | fi 107 | fi 108 | fi 109 | if test $ok = yes; then 110 | NPTH_CFLAGS=`$NPTH_CONFIG --cflags` 111 | NPTH_LIBS=`$NPTH_CONFIG --libs` 112 | ifelse([$2], , :, [$2]) 113 | if test -z "$use_gpgrt_config"; then 114 | npth_config_host=`$NPTH_CONFIG --host 2>/dev/null || echo none` 115 | else 116 | npth_config_host=`$NPTH_CONFIG --variable=host 2>/dev/null || echo none` 117 | fi 118 | if test x"$npth_config_host" != xnone ; then 119 | if test x"$npth_config_host" != x"$host" ; then 120 | AC_MSG_WARN([[ 121 | *** 122 | *** The config script "$NPTH_CONFIG" was 123 | *** built for $npth_config_host and thus may not match the 124 | *** used host $host. 125 | *** You may want to use the configure option --with-npth-prefix 126 | *** to specify a matching config script. 127 | ***]]) 128 | fi 129 | fi 130 | else 131 | NPTH_CFLAGS="" 132 | NPTH_LIBS="" 133 | ifelse([$3], , :, [$3]) 134 | fi 135 | AC_SUBST(NPTH_CFLAGS) 136 | AC_SUBST(NPTH_LIBS) 137 | ]) 138 | -------------------------------------------------------------------------------- /tests/t-cond.c: -------------------------------------------------------------------------------- 1 | /* t-cond.c - Test condition variable 2 | * Copyright 2024 g10 Code GmbH 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This file is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * You can also use this file under the licence of CC0. 13 | * SPDX-License-Identifier: CC0 14 | */ 15 | 16 | #include "t-support.h" 17 | 18 | static npth_mutex_t mutex; 19 | static npth_cond_t cond; 20 | static int counter_waiting; 21 | 22 | #define MAX_THREAD 17 /* Cerebrating Shohei's 50/50 accomplishment in 2024. */ 23 | 24 | static void * 25 | fn_testing_cond_signal (void *arg) 26 | { 27 | int rc; 28 | int *thread_number = arg; 29 | char msg[256]; 30 | int signal_invoked = 0; 31 | 32 | snprintf (msg, DIM (msg), "thread %d: start", *thread_number); 33 | info_msg (msg); 34 | 35 | rc = npth_mutex_lock (&mutex); 36 | fail_if_err (rc); 37 | 38 | if (counter_waiting < MAX_THREAD - 1) 39 | { 40 | snprintf (msg, DIM (msg), "thread %d: wait", *thread_number); 41 | info_msg (msg); 42 | counter_waiting++; 43 | rc = npth_cond_wait (&cond, &mutex); 44 | fail_if_err (rc); 45 | counter_waiting--; 46 | } 47 | else 48 | { 49 | rc = npth_mutex_unlock (&mutex); 50 | fail_if_err (rc); 51 | 52 | again: 53 | if (++signal_invoked > MAX_THREAD * 10) 54 | fail_msg ("Many cond_signal invoked, but no success."); 55 | 56 | rc = npth_mutex_lock (&mutex); 57 | fail_if_err (rc); 58 | if (counter_waiting) 59 | { 60 | snprintf (msg, DIM (msg), "thread %d: signal: %d", *thread_number, 61 | counter_waiting); 62 | info_msg (msg); 63 | rc = npth_cond_signal (&cond); 64 | fail_if_err (rc); 65 | 66 | rc = npth_mutex_unlock (&mutex); 67 | fail_if_err (rc); 68 | 69 | npth_usleep (10); /* Give the other threads some time to run. */ 70 | goto again; 71 | } 72 | } 73 | 74 | rc = npth_mutex_unlock (&mutex); 75 | fail_if_err (rc); 76 | 77 | snprintf (msg, DIM (msg), "thread %d: done", *thread_number); 78 | info_msg (msg); 79 | 80 | return NULL; 81 | } 82 | 83 | 84 | static void * 85 | fn_testing_cond_broadcast (void *arg) 86 | { 87 | int rc; 88 | int *thread_number = arg; 89 | char msg[256]; 90 | 91 | snprintf (msg, DIM (msg), "thread %d: start", *thread_number); 92 | info_msg (msg); 93 | 94 | rc = npth_mutex_lock (&mutex); 95 | fail_if_err (rc); 96 | 97 | if (counter_waiting < MAX_THREAD - 1) 98 | { 99 | snprintf (msg, DIM (msg), "thread %d: wait", *thread_number); 100 | info_msg (msg); 101 | counter_waiting++; 102 | rc = npth_cond_wait (&cond, &mutex); 103 | fail_if_err (rc); 104 | counter_waiting--; 105 | } 106 | else 107 | { 108 | snprintf (msg, DIM (msg), "thread %d: broadcast: %d", *thread_number, 109 | counter_waiting); 110 | info_msg (msg); 111 | rc = npth_cond_broadcast (&cond); 112 | fail_if_err (rc); 113 | } 114 | 115 | rc = npth_mutex_unlock (&mutex); 116 | fail_if_err (rc); 117 | 118 | snprintf (msg, DIM (msg), "thread %d: done", *thread_number); 119 | info_msg (msg); 120 | 121 | return NULL; 122 | } 123 | 124 | 125 | static void 126 | run_test_with_fn (npth_attr_t tattr, void * (*func)(void *arg)) 127 | { 128 | int rc; 129 | int i; 130 | int id[MAX_THREAD]; 131 | npth_t tid[MAX_THREAD]; 132 | void *retval; 133 | 134 | info_msg ("creating threads"); 135 | for (i = 0; i < MAX_THREAD; i++) 136 | { 137 | id[i] = i; 138 | rc = npth_create (&tid[i], &tattr, func, &id[i]); 139 | fail_if_err (rc); 140 | } 141 | 142 | for (i = 0; i < MAX_THREAD; i++) 143 | { 144 | rc = npth_join (tid[i], &retval); 145 | fail_if_err (rc); 146 | } 147 | info_msg ("joined threads"); 148 | } 149 | 150 | 151 | int 152 | main (int argc, char *argv[]) 153 | { 154 | int rc; 155 | npth_attr_t tattr; 156 | 157 | if (argc >= 2 && !strcmp (argv[1], "--verbose")) 158 | opt_verbose = 1; 159 | 160 | rc = npth_init (); 161 | fail_if_err (rc); 162 | 163 | rc = npth_mutex_init (&mutex, NULL); 164 | fail_if_err (rc); 165 | info_msg ("mutex initialized"); 166 | 167 | rc = npth_cond_init (&cond, NULL); 168 | fail_if_err (rc); 169 | info_msg ("cond initialized"); 170 | 171 | rc = npth_attr_init (&tattr); 172 | fail_if_err (rc); 173 | rc = npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); 174 | fail_if_err (rc); 175 | 176 | run_test_with_fn (tattr, fn_testing_cond_signal); 177 | run_test_with_fn (tattr, fn_testing_cond_broadcast); 178 | 179 | rc = npth_attr_destroy (&tattr); 180 | fail_if_err (rc); 181 | 182 | rc = npth_mutex_destroy (&mutex); 183 | fail_if_err (rc); 184 | info_msg ("mutex destroyed"); 185 | 186 | rc = npth_cond_destroy (&cond); 187 | fail_if_err (rc); 188 | info_msg ("cond destroyed"); 189 | 190 | return 0; 191 | } 192 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am - Top level Makefile for npth. 2 | # Copyright (C) 2011 g10 Code GmbH 3 | # 4 | # This file is part of nPth. 5 | # 6 | # nPth is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as 8 | # published by the Free Software Foundation; either version 2.1 of the 9 | # License, or (at your option) any later version. 10 | # 11 | # nPth is distributed in the hope that it will be useful, but WITHOUT 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14 | # Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this program; if not, see . 18 | 19 | ## Process this file with automake to produce Makefile.in 20 | 21 | # Location of the released tarball archives. This is prefixed by 22 | # the variable RELEASE_ARCHIVE in ~/.gnupg-autogen.rc. For example: 23 | # RELEASE_ARCHIVE=wk@somehost:archive/tarballs 24 | RELEASE_ARCHIVE_SUFFIX = npth 25 | # Macro to help the release target. 26 | RELEASE_NAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION) 27 | 28 | ACLOCAL_AMFLAGS = -I m4 29 | 30 | pkgconfigdir = $(libdir)/pkgconfig 31 | pkgconfig_DATA = npth.pc 32 | 33 | EXTRA_DIST = npth-config.in npth.m4 npth.spec.in autogen.sh autogen.rc \ 34 | HACKING VERSION npth.pc.in build-aux/libtool-patch.sed 35 | if INSTALL_NPTH_CONFIG 36 | bin_SCRIPTS = npth-config 37 | else 38 | noinst_SCRIPTS = npth-config 39 | endif 40 | m4datadir = $(datadir)/aclocal 41 | m4data_DATA = npth.m4 42 | 43 | if RUN_TESTS 44 | tests = tests 45 | else 46 | tests = 47 | endif 48 | 49 | if HAVE_W32_SYSTEM 50 | npthdir = w32 51 | else 52 | npthdir = src 53 | endif 54 | 55 | SUBDIRS = ${npthdir} ${tests} 56 | 57 | # Fix the version of the spec file and create a file named VERSION 58 | # to be used for patch's Prereq: feature. 59 | dist-hook: gen-ChangeLog 60 | @set -e; \ 61 | sed -e 's/@pkg_version@/$(VERSION)/g' \ 62 | $(top_srcdir)/npth.spec.in > $(distdir)/npth.spec 63 | 64 | distcheck-hook: 65 | set -e; ( \ 66 | pref="#+macro: $$(echo $(PACKAGE_NAME)|tr '-' '_')_" ;\ 67 | reldate="$$(date -u +%Y-%m-%d)" ;\ 68 | echo "$${pref}ver $(PACKAGE_VERSION)" ;\ 69 | echo "$${pref}date $${reldate}" ;\ 70 | list='$(DIST_ARCHIVES)'; for i in $$list; do \ 71 | case "$$i" in *.tar.bz2) \ 72 | echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\ 73 | echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\ 74 | echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\ 75 | esac;\ 76 | done ) | tee $(distdir).swdb 77 | 78 | 79 | gen_start_date = 2011-12-01T00:00:00 80 | .PHONY: gen-ChangeLog 81 | gen-ChangeLog: 82 | if test -d $(top_srcdir)/.git; then \ 83 | (cd $(top_srcdir) && \ 84 | gitlog-to-changelog \ 85 | --append-dot --tear-off \ 86 | --amend=build-aux/git-log-fix \ 87 | --since=$(gen_start_date) ) > $(distdir)/cl-t; \ 88 | cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\ 89 | rm -f $(distdir)/ChangeLog; \ 90 | mv $(distdir)/cl-t $(distdir)/ChangeLog; \ 91 | fi 92 | 93 | 94 | 95 | release: 96 | +(set -e;\ 97 | if [ "$(abs_top_builddir)" = "$(abs_top_srcdir)" ]; then \ 98 | echo "error: build directory must not be the source directory" >&2;\ 99 | exit 2;\ 100 | fi ;\ 101 | echo "/* Build started at $$(date -uIseconds) */" ;\ 102 | cd $(top_srcdir); \ 103 | ./autogen.sh --force; \ 104 | cd $(abs_top_builddir); \ 105 | rm -rf dist; mkdir dist ; cd dist ; \ 106 | $(abs_top_srcdir)/configure --enable-maintainer-mode; \ 107 | $(MAKE) distcheck; \ 108 | echo "/* Build finished at $$(date -uIseconds) */" ;\ 109 | echo "/*" ;\ 110 | echo " * Please run the final step interactivly:" ;\ 111 | echo " * make sign-release" ;\ 112 | echo " */" ;\ 113 | ) 2>&1 | tee "$(RELEASE_NAME).buildlog" 114 | 115 | sign-release: 116 | +(set -e; \ 117 | test $$(pwd | sed 's,.*/,,') = dist || cd dist; \ 118 | x=$$(grep '^[[:blank:]]*RELEASE_ARCHIVE[[:blank:]]*=' \ 119 | $$HOME/.gnupg-autogen.rc|cut -d= -f2|xargs);\ 120 | if [ -z "$$x" ]; then \ 121 | echo "error: RELEASE_ARCHIVE missing in ~/.gnupg-autogen.rc">&2; \ 122 | exit 2;\ 123 | fi;\ 124 | myarchive="$$x/$(RELEASE_ARCHIVE_SUFFIX)";\ 125 | x=$$(grep '^[[:blank:]]*RELEASE_SIGNKEY[[:blank:]]*=' \ 126 | $$HOME/.gnupg-autogen.rc|cut -d= -f2|xargs);\ 127 | if [ -z "$$x" ]; then \ 128 | echo "error: RELEASE_SIGNKEY missing in ~/.gnupg-autogen.rc">&2; \ 129 | exit 2;\ 130 | fi;\ 131 | mysignkey="$$x";\ 132 | files1="$(RELEASE_NAME).tar.bz2" ; \ 133 | files2="$(RELEASE_NAME).tar.bz2.sig \ 134 | $(RELEASE_NAME).swdb \ 135 | $(RELEASE_NAME).buildlog" ;\ 136 | echo "/* Signing the source tarball ..." ;\ 137 | gpg -sbu $$mysignkey $(RELEASE_NAME).tar.bz2 ;\ 138 | cat $(RELEASE_NAME).swdb >swdb.snippet;\ 139 | echo >>swdb.snippet ;\ 140 | sha1sum $${files1} >>swdb.snippet ;\ 141 | cat "../$(RELEASE_NAME).buildlog" swdb.snippet \ 142 | | gzip >$(RELEASE_NAME).buildlog ;\ 143 | echo "Copying to archive $$myarchive ..." ;\ 144 | scp -p $${files1} $${files2} $${myarchive}/ || true;\ 145 | echo '/*' ;\ 146 | echo ' * All done; for checksums see dist/swdb.snippet' ;\ 147 | echo ' */' ;\ 148 | ) 149 | -------------------------------------------------------------------------------- /src/npth-sigev.c: -------------------------------------------------------------------------------- 1 | /* npth-sigev.c - signal handling interface 2 | * Copyright (C) 2011 g10 Code GmbH 3 | * 4 | * This file is part of nPth. 5 | * 6 | * nPth is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation; either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * nPth is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 | * the GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, see . 18 | */ 19 | 20 | /* This is a support interface to make it easier to handle signals. 21 | * 22 | * The interfaces here support one (and only one) thread (here called 23 | * "main thread") in the application to monitor several signals while 24 | * selecting on filedescriptors. 25 | * 26 | * First, the main thread should call npth_sigev_init. This 27 | * initializes some global data structures used to record interesting 28 | * and pending signals. 29 | * 30 | * Then, the main thread should call npth_sigev_add for every signal 31 | * it is interested in observing, and finally npth_sigev_fini. This 32 | * will block the signal in the main threads sigmask. Note that these 33 | * signals should also be blocked in all other threads. Since they 34 | * are blocked in the main thread after calling npth_sigev_add, it is 35 | * recommended to call npth_sigev_add in the main thread before 36 | * creating any threads. 37 | * 38 | * The function npth_sigev_sigmask is a convenient function that 39 | * returns the sigmask of the thread at time of npth_sigev_init, but 40 | * with all registered signals unblocked. It is recommended to do all 41 | * other changes to the main thread's sigmask before calling 42 | * npth_sigev_init, so that the return value of npth_sigev_sigmask can 43 | * be used in the npth_pselect invocation. 44 | * 45 | * In any case, the main thread should invoke npth_pselect with a 46 | * sigmask that has all signals that should be monitored unblocked. 47 | * 48 | * After npth_pselect returns, npth_sigev_get_pending can be called in 49 | * a loop until it returns 0 to iterate over the list of pending 50 | * signals. Each time a signal is returned by that function, its 51 | * status is reset to non-pending. 52 | */ 53 | 54 | #ifdef HAVE_CONFIG_H 55 | #include 56 | #endif 57 | 58 | #include 59 | #include 60 | 61 | #include "npth.h" 62 | 63 | /* Record events that have been noticed. */ 64 | static sigset_t sigev_pending; 65 | 66 | /* The signal mask during normal operation. */ 67 | static sigset_t sigev_block; 68 | 69 | /* The signal mask during pselect. */ 70 | static sigset_t sigev_unblock; 71 | 72 | /* Registered signal numbers. Needed to iterate over sigset_t. 73 | Bah. */ 74 | #define SIGEV_MAX 32 75 | static int sigev_signum[SIGEV_MAX]; 76 | static int sigev_signum_cnt; 77 | 78 | /* The internal handler which just sets a global flag. */ 79 | static void 80 | _sigev_handler (int signum) 81 | { 82 | sigaddset (&sigev_pending, signum); 83 | } 84 | 85 | 86 | /* Start setting up signal event handling. */ 87 | void 88 | npth_sigev_init (void) 89 | { 90 | sigemptyset (&sigev_pending); 91 | pthread_sigmask (SIG_SETMASK, NULL, &sigev_block); 92 | pthread_sigmask (SIG_SETMASK, NULL, &sigev_unblock); 93 | } 94 | 95 | 96 | /* Add signal SIGNUM to the list of watched signals. */ 97 | void 98 | npth_sigev_add (int signum) 99 | { 100 | struct sigaction sa; 101 | sigset_t ss; 102 | 103 | sigemptyset(&ss); 104 | 105 | assert (sigev_signum_cnt < SIGEV_MAX); 106 | sigev_signum[sigev_signum_cnt++] = signum; 107 | 108 | /* Make sure we can receive it. */ 109 | sigdelset (&sigev_unblock, signum); 110 | sigaddset (&sigev_block, signum); 111 | 112 | sa.sa_handler = _sigev_handler; 113 | sa.sa_mask = ss; 114 | sa.sa_flags = 0; /* NOT setting SA_RESTART! */ 115 | 116 | sigaction (signum, &sa, NULL); 117 | } 118 | 119 | 120 | #ifdef HAVE_PTHREAD_ATFORK 121 | /* There is non-POSIX operating system where fork is not available to 122 | applications. There, we have no pthread_atfork either. In such a 123 | case, we don't call pthread_atfork. */ 124 | static void 125 | restore_sigmask_for_child_process (void) 126 | { 127 | pthread_sigmask (SIG_SETMASK, &sigev_unblock, NULL); 128 | } 129 | #endif 130 | 131 | /* Finish the list of watched signals. This starts to block them, 132 | too. */ 133 | void 134 | npth_sigev_fini (void) 135 | { 136 | /* Block the interesting signals. */ 137 | pthread_sigmask (SIG_SETMASK, &sigev_block, NULL); 138 | #ifdef HAVE_PTHREAD_ATFORK 139 | pthread_atfork (NULL, NULL, restore_sigmask_for_child_process); 140 | #endif 141 | } 142 | 143 | 144 | /* Get the sigmask as needed for pselect. */ 145 | sigset_t * 146 | npth_sigev_sigmask (void) 147 | { 148 | return &sigev_unblock; 149 | } 150 | 151 | 152 | /* Return the next signal event that occured. Returns if none are 153 | left, 1 on success. */ 154 | int 155 | npth_sigev_get_pending (int *r_signum) 156 | { 157 | int i; 158 | for (i = 0; i < sigev_signum_cnt; i++) 159 | { 160 | int signum = sigev_signum[i]; 161 | if (sigismember (&sigev_pending, signum)) 162 | { 163 | sigdelset (&sigev_pending, signum); 164 | *r_signum = signum; 165 | return 1; 166 | } 167 | } 168 | return 0; 169 | } 170 | 171 | -------------------------------------------------------------------------------- /m4/lt~obsolete.m4: -------------------------------------------------------------------------------- 1 | # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004. 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 5 lt~obsolete.m4 11 | 12 | # These exist entirely to fool aclocal when bootstrapping libtool. 13 | # 14 | # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) 15 | # which have later been changed to m4_define as they aren't part of the 16 | # exported API, or moved to Autoconf or Automake where they belong. 17 | # 18 | # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN 19 | # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us 20 | # using a macro with the same name in our local m4/libtool.m4 it'll 21 | # pull the old libtool.m4 in (it doesn't see our shiny new m4_define 22 | # and doesn't know about Autoconf macros at all.) 23 | # 24 | # So we provide this file, which has a silly filename so it's always 25 | # included after everything else. This provides aclocal with the 26 | # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything 27 | # because those macros already exist, or will be overwritten later. 28 | # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 29 | # 30 | # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. 31 | # Yes, that means every name once taken will need to remain here until 32 | # we give up compatibility with versions before 1.7, at which point 33 | # we need to keep only those names which we still refer to. 34 | 35 | # This is to help aclocal find these macros, as it can't see m4_define. 36 | AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) 37 | 38 | m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) 39 | m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) 40 | m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) 41 | m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) 42 | m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) 43 | m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) 44 | m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) 45 | m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) 46 | m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) 47 | m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) 48 | m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) 49 | m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) 50 | m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) 51 | m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) 52 | m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) 53 | m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) 54 | m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) 55 | m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) 56 | m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) 57 | m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) 58 | m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) 59 | m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) 60 | m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) 61 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) 62 | m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) 63 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) 64 | m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) 65 | m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) 66 | m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) 67 | m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) 68 | m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) 69 | m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) 70 | m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) 71 | m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) 72 | m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) 73 | m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) 74 | m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) 75 | m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) 76 | m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) 77 | m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) 78 | m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) 79 | m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) 80 | m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) 81 | m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) 82 | m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) 83 | m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) 84 | m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) 85 | m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) 86 | m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) 87 | m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) 88 | m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) 89 | m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) 90 | m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) 91 | m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) 92 | m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) 93 | m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) 94 | m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) 95 | m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) 96 | m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) 97 | m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) 98 | m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) 99 | -------------------------------------------------------------------------------- /w32/npth.h.in: -------------------------------------------------------------------------------- 1 | /* npth.h - a lightweight implementation of pth over native threads 2 | * Copyright (C) 2011, 2015, 2024 g10 Code GmbH 3 | * 4 | * This file is part of nPth. 5 | * 6 | * nPth is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation; either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * nPth is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 | * the GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, see . 18 | */ 19 | 20 | #ifndef _NPTH_H 21 | #define _NPTH_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #if 0 /* (Keep Emacsens' auto-indent happy.) */ 34 | } 35 | #endif 36 | #endif 37 | 38 | /* The version and the version number of this header should match the 39 | * one of the library. Use the latter in your application to test for 40 | * minor API changes. Use npth_get_version for the lib version. */ 41 | #define NPTH_VERSION "@PACKAGE_VERSION@" 42 | #define NPTH_VERSION_NUMBER @VERSION_NUMBER@ 43 | 44 | 45 | struct msghdr; 46 | 47 | #ifndef ETIMEDOUT 48 | #define ETIMEDOUT 10060 /* This is WSAETIMEDOUT. */ 49 | #endif 50 | #ifndef EOPNOTSUPP 51 | #define EOPNOTSUPP 10045 /* This is WSAEOPNOTSUPP. */ 52 | #endif 53 | 54 | 55 | int npth_init (void); 56 | 57 | typedef struct npth_attr_s *npth_attr_t; 58 | typedef unsigned long int npth_t; 59 | typedef struct npth_mutexattr_s *npth_mutexattr_t; 60 | typedef struct npth_mutex_s *npth_mutex_t; 61 | typedef struct npth_rwlockattr_s *npth_rwlockattr_t; 62 | typedef struct npth_rwlock_s *npth_rwlock_t; 63 | typedef struct npth_condattr_s *npth_condattr_t; 64 | typedef struct npth_cond_s *npth_cond_t; 65 | 66 | int npth_attr_init (npth_attr_t *attr); 67 | int npth_attr_destroy (npth_attr_t *attr); 68 | #define NPTH_CREATE_JOINABLE 0 69 | #define NPTH_CREATE_DETACHED 1 70 | int npth_attr_getdetachstate(npth_attr_t *attr, int *detachstate); 71 | int npth_attr_setdetachstate(npth_attr_t *attr, int detachstate); 72 | int npth_getname_np (npth_t target_thread, char *buf, size_t buflen); 73 | int npth_setname_np (npth_t target_thread, const char *name); 74 | 75 | int npth_create (npth_t *newthread, const npth_attr_t *attr, 76 | void *(*start_routine) (void *), void *arg); 77 | 78 | npth_t npth_self (void); 79 | 80 | int npth_join (npth_t th, void **thread_return); 81 | int npth_detach (npth_t th); 82 | void npth_exit (void *retval); 83 | 84 | typedef DWORD npth_key_t; 85 | int npth_key_create (npth_key_t *key, 86 | void (*destr_function) (void *)); 87 | int npth_key_delete (npth_key_t key); 88 | void *npth_getspecific (npth_key_t key); 89 | int npth_setspecific (npth_key_t key, const void *pointer); 90 | 91 | int npth_mutexattr_init (npth_mutexattr_t *attr); 92 | int npth_mutexattr_destroy (npth_mutexattr_t *attr); 93 | int npth_mutexattr_gettype (const npth_mutexattr_t *attr, 94 | int *kind); 95 | int npth_mutexattr_settype (npth_mutexattr_t *attr, int kind); 96 | #define NPTH_MUTEX_NORMAL 0 97 | #define NPTH_MUTEX_RECURSIVE 1 98 | #define NPTH_MUTEX_ERRORCHECK 2 99 | #define NPTH_MUTEX_DEFAULT NPTH_MUTEX_NORMAL 100 | 101 | #define NPTH_MUTEX_INITIALIZER ((npth_mutex_t) -1) 102 | #define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP ((npth_mutex_t) -2) 103 | #define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP ((npth_mutex_t) -3) 104 | int npth_mutex_init (npth_mutex_t *mutex, const npth_mutexattr_t *mutexattr); 105 | int npth_mutex_destroy (npth_mutex_t *mutex); 106 | int npth_mutex_trylock(npth_mutex_t *mutex); 107 | int npth_mutex_lock(npth_mutex_t *mutex); 108 | int npth_mutex_timedlock(npth_mutex_t *mutex, const struct timespec *abstime); 109 | int npth_mutex_unlock(npth_mutex_t *mutex); 110 | 111 | int npth_rwlockattr_init (npth_rwlockattr_t *attr); 112 | int npth_rwlockattr_destroy (npth_rwlockattr_t *attr); 113 | int npth_rwlockattr_gettype_np (const npth_rwlockattr_t *attr, 114 | int *kind); 115 | int npth_rwlockattr_settype_np (npth_rwlockattr_t *attr, int kind); 116 | #define NPTH_RWLOCK_PREFER_READER_NP 0 117 | #define NPTH_RWLOCK_PREFER_WRITER_NP 1 118 | #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2 119 | #define NPTH_RWLOCK_DEFAULT_NP NPTH_RWLOCK_PREFER_READER_NP 120 | #define NPTH_RWLOCK_INITIALIZER ((npth_rwlock_t) -1) 121 | #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP ((npth_rwlock_t) -2) 122 | 123 | /* For now, we don't support any rwlock attributes. */ 124 | int npth_rwlock_init (npth_rwlock_t *rwlock, 125 | const npth_rwlockattr_t *attr); 126 | int npth_rwlock_destroy (npth_rwlock_t *rwlock); 127 | int npth_rwlock_tryrdlock (npth_rwlock_t *rwlock); 128 | int npth_rwlock_rdlock (npth_rwlock_t *rwlock); 129 | int npth_rwlock_timedrdlock (npth_rwlock_t *rwlock, 130 | const struct timespec *abstime); 131 | int npth_rwlock_trywrlock (npth_rwlock_t *rwlock); 132 | 133 | int npth_rwlock_wrlock (npth_rwlock_t *rwlock); 134 | int npth_rwlock_timedwrlock (npth_rwlock_t *rwlock, 135 | const struct timespec *abstime); 136 | int npth_rwlock_unlock (npth_rwlock_t *rwlock); 137 | 138 | #define NPTH_COND_INITIALIZER ((npth_cond_t) -1) 139 | /* For now, we don't support any cond attributes. */ 140 | int npth_cond_init (npth_cond_t *cond, 141 | const npth_condattr_t *cond_attr); 142 | int npth_cond_broadcast (npth_cond_t *cond); 143 | int npth_cond_signal (npth_cond_t *cond); 144 | int npth_cond_destroy (npth_cond_t *cond); 145 | int npth_cond_wait (npth_cond_t *cond, npth_mutex_t *mutex); 146 | int npth_cond_timedwait (npth_cond_t *cond, npth_mutex_t *mutex, 147 | const struct timespec *abstime); 148 | 149 | int npth_usleep(unsigned int usec); 150 | unsigned int npth_sleep(unsigned int sec); 151 | 152 | pid_t npth_waitpid(pid_t pid, int *status, int options); 153 | int npth_system(const char *cmd); 154 | 155 | #if 0 156 | /* We do not support this on windows. */ 157 | int npth_sigmask(int how, const sigset_t *set, sigset_t *oldset); 158 | int npth_sigwait(const sigset_t *set, int *sig); 159 | #endif 160 | 161 | int npth_connect(int s, const struct sockaddr *addr, socklen_t addrlen); 162 | int npth_accept(int s, struct sockaddr *addr, socklen_t *addrlen); 163 | /* Only good for sockets! */ 164 | int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, 165 | struct timeval *timeout); 166 | #if 0 167 | /* We do not support this on windows. */ 168 | int npth_pselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, 169 | const struct timespec *timeout, const sigset_t *sigmask); 170 | #endif 171 | /* Wait on the FDs (only good for sockets!) and the 172 | INVALID_HANDLE_VALUE terminated list of extra events. On return 173 | (even on error), the bits in EVENTS_SET will contain the extra 174 | events that occured (which means that there can only be up to 31 175 | extra events). */ 176 | int npth_eselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, 177 | const struct timespec *timeout, 178 | HANDLE *events, unsigned int *events_set); 179 | 180 | ssize_t npth_read(int fd, void *buf, size_t nbytes); 181 | ssize_t npth_write(int fd, const void *buf, size_t nbytes); 182 | int npth_recvmsg (int fd, struct msghdr *msg, int flags); 183 | int npth_sendmsg (int fd, const struct msghdr *msg, int flags); 184 | 185 | void npth_unprotect (void); 186 | void npth_protect (void); 187 | 188 | /* Return true when we hold the sceptre. This is used to debug 189 | * problems with npth_unprotect and npth_protect. */ 190 | int npth_is_protected (void); 191 | 192 | /* Return the version of the library. WHAT is in general NULL. */ 193 | const char *npth_get_version (const char *what); 194 | 195 | /* Because the timed functions work on timespec, we provide a clock 196 | interface for convenience and portability. */ 197 | int npth_clock_gettime(struct timespec *tp); 198 | 199 | /* CMP may be ==, < or >. Do not use <= or >=. */ 200 | #define npth_timercmp(t1, t2, cmp) \ 201 | (((t1)->tv_sec == (t2)->tv_sec) ? \ 202 | ((t1)->tv_nsec cmp (t2)->tv_nsec) : \ 203 | ((t1)->tv_sec cmp (t2)->tv_sec)) 204 | #define npth_timeradd(t1, t2, result) \ 205 | do { \ 206 | (result)->tv_sec = (t1)->tv_sec + (t2)->tv_sec; \ 207 | (result)->tv_nsec = (t1)->tv_nsec + (t2)->tv_nsec; \ 208 | if ((result)->tv_nsec >= 1000000000) \ 209 | { \ 210 | ++(result)->tv_sec; \ 211 | (result)->tv_nsec -= 1000000000; \ 212 | } \ 213 | } while (0) 214 | #define npth_timersub(t1, t2, result) \ 215 | do { \ 216 | (result)->tv_sec = (t1)->tv_sec - (t2)->tv_sec; \ 217 | (result)->tv_nsec = (t1)->tv_nsec - (t2)->tv_nsec; \ 218 | if ((result)->tv_nsec < 0) { \ 219 | --(result)->tv_sec; \ 220 | (result)->tv_nsec += 1000000000; \ 221 | } \ 222 | } while (0) 223 | 224 | 225 | #if 0 226 | /* We do not support this on windows. */ 227 | void npth_sigev_init (void); 228 | void npth_sigev_add (int signum); 229 | void npth_sigev_fini (void); 230 | sigset_t *npth_sigev_sigmask (void); 231 | int npth_sigev_get_pending (int *r_signum); 232 | #endif 233 | 234 | #if 0 /* (Keep Emacsens' auto-indent happy.) */ 235 | { 236 | #endif 237 | #ifdef __cplusplus 238 | } 239 | #endif 240 | #endif /*_NPTH_H*/ 241 | -------------------------------------------------------------------------------- /m4/ltoptions.m4: -------------------------------------------------------------------------------- 1 | # Helper functions for option handling. -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, 4 | # Inc. 5 | # Written by Gary V. Vaughan, 2004 6 | # 7 | # This file is free software; the Free Software Foundation gives 8 | # unlimited permission to copy and/or distribute it, with or without 9 | # modifications, as long as this notice is preserved. 10 | 11 | # serial 7 ltoptions.m4 12 | 13 | # This is to help aclocal find these macros, as it can't see m4_define. 14 | AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) 15 | 16 | 17 | # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) 18 | # ------------------------------------------ 19 | m4_define([_LT_MANGLE_OPTION], 20 | [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) 21 | 22 | 23 | # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) 24 | # --------------------------------------- 25 | # Set option OPTION-NAME for macro MACRO-NAME, and if there is a 26 | # matching handler defined, dispatch to it. Other OPTION-NAMEs are 27 | # saved as a flag. 28 | m4_define([_LT_SET_OPTION], 29 | [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl 30 | m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), 31 | _LT_MANGLE_DEFUN([$1], [$2]), 32 | [m4_warning([Unknown $1 option `$2'])])[]dnl 33 | ]) 34 | 35 | 36 | # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) 37 | # ------------------------------------------------------------ 38 | # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. 39 | m4_define([_LT_IF_OPTION], 40 | [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) 41 | 42 | 43 | # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) 44 | # ------------------------------------------------------- 45 | # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME 46 | # are set. 47 | m4_define([_LT_UNLESS_OPTIONS], 48 | [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), 49 | [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), 50 | [m4_define([$0_found])])])[]dnl 51 | m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 52 | ])[]dnl 53 | ]) 54 | 55 | 56 | # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) 57 | # ---------------------------------------- 58 | # OPTION-LIST is a space-separated list of Libtool options associated 59 | # with MACRO-NAME. If any OPTION has a matching handler declared with 60 | # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about 61 | # the unknown option and exit. 62 | m4_defun([_LT_SET_OPTIONS], 63 | [# Set options 64 | m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), 65 | [_LT_SET_OPTION([$1], _LT_Option)]) 66 | 67 | m4_if([$1],[LT_INIT],[ 68 | dnl 69 | dnl Simply set some default values (i.e off) if boolean options were not 70 | dnl specified: 71 | _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no 72 | ]) 73 | _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no 74 | ]) 75 | dnl 76 | dnl If no reference was made to various pairs of opposing options, then 77 | dnl we run the default mode handler for the pair. For example, if neither 78 | dnl `shared' nor `disable-shared' was passed, we enable building of shared 79 | dnl archives by default: 80 | _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) 81 | _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) 82 | _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) 83 | _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], 84 | [_LT_ENABLE_FAST_INSTALL]) 85 | ]) 86 | ])# _LT_SET_OPTIONS 87 | 88 | 89 | ## --------------------------------- ## 90 | ## Macros to handle LT_INIT options. ## 91 | ## --------------------------------- ## 92 | 93 | # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) 94 | # ----------------------------------------- 95 | m4_define([_LT_MANGLE_DEFUN], 96 | [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) 97 | 98 | 99 | # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) 100 | # ----------------------------------------------- 101 | m4_define([LT_OPTION_DEFINE], 102 | [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl 103 | ])# LT_OPTION_DEFINE 104 | 105 | 106 | # dlopen 107 | # ------ 108 | LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes 109 | ]) 110 | 111 | AU_DEFUN([AC_LIBTOOL_DLOPEN], 112 | [_LT_SET_OPTION([LT_INIT], [dlopen]) 113 | AC_DIAGNOSE([obsolete], 114 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 115 | put the `dlopen' option into LT_INIT's first parameter.]) 116 | ]) 117 | 118 | dnl aclocal-1.4 backwards compatibility: 119 | dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) 120 | 121 | 122 | # win32-dll 123 | # --------- 124 | # Declare package support for building win32 dll's. 125 | LT_OPTION_DEFINE([LT_INIT], [win32-dll], 126 | [enable_win32_dll=yes 127 | 128 | case $host in 129 | *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) 130 | AC_CHECK_TOOL(AS, as, false) 131 | AC_CHECK_TOOL(DLLTOOL, dlltool, false) 132 | AC_CHECK_TOOL(OBJDUMP, objdump, false) 133 | ;; 134 | esac 135 | 136 | test -z "$AS" && AS=as 137 | _LT_DECL([], [AS], [1], [Assembler program])dnl 138 | 139 | test -z "$DLLTOOL" && DLLTOOL=dlltool 140 | _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl 141 | 142 | test -z "$OBJDUMP" && OBJDUMP=objdump 143 | _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl 144 | ])# win32-dll 145 | 146 | AU_DEFUN([AC_LIBTOOL_WIN32_DLL], 147 | [AC_REQUIRE([AC_CANONICAL_HOST])dnl 148 | _LT_SET_OPTION([LT_INIT], [win32-dll]) 149 | AC_DIAGNOSE([obsolete], 150 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 151 | put the `win32-dll' option into LT_INIT's first parameter.]) 152 | ]) 153 | 154 | dnl aclocal-1.4 backwards compatibility: 155 | dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) 156 | 157 | 158 | # _LT_ENABLE_SHARED([DEFAULT]) 159 | # ---------------------------- 160 | # implement the --enable-shared flag, and supports the `shared' and 161 | # `disable-shared' LT_INIT options. 162 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 163 | m4_define([_LT_ENABLE_SHARED], 164 | [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl 165 | AC_ARG_ENABLE([shared], 166 | [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], 167 | [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], 168 | [p=${PACKAGE-default} 169 | case $enableval in 170 | yes) enable_shared=yes ;; 171 | no) enable_shared=no ;; 172 | *) 173 | enable_shared=no 174 | # Look at the argument we got. We use all the common list separators. 175 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 176 | for pkg in $enableval; do 177 | IFS="$lt_save_ifs" 178 | if test "X$pkg" = "X$p"; then 179 | enable_shared=yes 180 | fi 181 | done 182 | IFS="$lt_save_ifs" 183 | ;; 184 | esac], 185 | [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) 186 | 187 | _LT_DECL([build_libtool_libs], [enable_shared], [0], 188 | [Whether or not to build shared libraries]) 189 | ])# _LT_ENABLE_SHARED 190 | 191 | LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) 192 | LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) 193 | 194 | # Old names: 195 | AC_DEFUN([AC_ENABLE_SHARED], 196 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) 197 | ]) 198 | 199 | AC_DEFUN([AC_DISABLE_SHARED], 200 | [_LT_SET_OPTION([LT_INIT], [disable-shared]) 201 | ]) 202 | 203 | AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) 204 | AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) 205 | 206 | dnl aclocal-1.4 backwards compatibility: 207 | dnl AC_DEFUN([AM_ENABLE_SHARED], []) 208 | dnl AC_DEFUN([AM_DISABLE_SHARED], []) 209 | 210 | 211 | 212 | # _LT_ENABLE_STATIC([DEFAULT]) 213 | # ---------------------------- 214 | # implement the --enable-static flag, and support the `static' and 215 | # `disable-static' LT_INIT options. 216 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 217 | m4_define([_LT_ENABLE_STATIC], 218 | [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl 219 | AC_ARG_ENABLE([static], 220 | [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], 221 | [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], 222 | [p=${PACKAGE-default} 223 | case $enableval in 224 | yes) enable_static=yes ;; 225 | no) enable_static=no ;; 226 | *) 227 | enable_static=no 228 | # Look at the argument we got. We use all the common list separators. 229 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 230 | for pkg in $enableval; do 231 | IFS="$lt_save_ifs" 232 | if test "X$pkg" = "X$p"; then 233 | enable_static=yes 234 | fi 235 | done 236 | IFS="$lt_save_ifs" 237 | ;; 238 | esac], 239 | [enable_static=]_LT_ENABLE_STATIC_DEFAULT) 240 | 241 | _LT_DECL([build_old_libs], [enable_static], [0], 242 | [Whether or not to build static libraries]) 243 | ])# _LT_ENABLE_STATIC 244 | 245 | LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) 246 | LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) 247 | 248 | # Old names: 249 | AC_DEFUN([AC_ENABLE_STATIC], 250 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) 251 | ]) 252 | 253 | AC_DEFUN([AC_DISABLE_STATIC], 254 | [_LT_SET_OPTION([LT_INIT], [disable-static]) 255 | ]) 256 | 257 | AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) 258 | AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) 259 | 260 | dnl aclocal-1.4 backwards compatibility: 261 | dnl AC_DEFUN([AM_ENABLE_STATIC], []) 262 | dnl AC_DEFUN([AM_DISABLE_STATIC], []) 263 | 264 | 265 | 266 | # _LT_ENABLE_FAST_INSTALL([DEFAULT]) 267 | # ---------------------------------- 268 | # implement the --enable-fast-install flag, and support the `fast-install' 269 | # and `disable-fast-install' LT_INIT options. 270 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 271 | m4_define([_LT_ENABLE_FAST_INSTALL], 272 | [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl 273 | AC_ARG_ENABLE([fast-install], 274 | [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], 275 | [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], 276 | [p=${PACKAGE-default} 277 | case $enableval in 278 | yes) enable_fast_install=yes ;; 279 | no) enable_fast_install=no ;; 280 | *) 281 | enable_fast_install=no 282 | # Look at the argument we got. We use all the common list separators. 283 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 284 | for pkg in $enableval; do 285 | IFS="$lt_save_ifs" 286 | if test "X$pkg" = "X$p"; then 287 | enable_fast_install=yes 288 | fi 289 | done 290 | IFS="$lt_save_ifs" 291 | ;; 292 | esac], 293 | [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) 294 | 295 | _LT_DECL([fast_install], [enable_fast_install], [0], 296 | [Whether or not to optimize for fast installation])dnl 297 | ])# _LT_ENABLE_FAST_INSTALL 298 | 299 | LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) 300 | LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) 301 | 302 | # Old names: 303 | AU_DEFUN([AC_ENABLE_FAST_INSTALL], 304 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) 305 | AC_DIAGNOSE([obsolete], 306 | [$0: Remove this warning and the call to _LT_SET_OPTION when you put 307 | the `fast-install' option into LT_INIT's first parameter.]) 308 | ]) 309 | 310 | AU_DEFUN([AC_DISABLE_FAST_INSTALL], 311 | [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) 312 | AC_DIAGNOSE([obsolete], 313 | [$0: Remove this warning and the call to _LT_SET_OPTION when you put 314 | the `disable-fast-install' option into LT_INIT's first parameter.]) 315 | ]) 316 | 317 | dnl aclocal-1.4 backwards compatibility: 318 | dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) 319 | dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) 320 | 321 | 322 | # _LT_WITH_PIC([MODE]) 323 | # -------------------- 324 | # implement the --with-pic flag, and support the `pic-only' and `no-pic' 325 | # LT_INIT options. 326 | # MODE is either `yes' or `no'. If omitted, it defaults to `both'. 327 | m4_define([_LT_WITH_PIC], 328 | [AC_ARG_WITH([pic], 329 | [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], 330 | [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], 331 | [lt_p=${PACKAGE-default} 332 | case $withval in 333 | yes|no) pic_mode=$withval ;; 334 | *) 335 | pic_mode=default 336 | # Look at the argument we got. We use all the common list separators. 337 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 338 | for lt_pkg in $withval; do 339 | IFS="$lt_save_ifs" 340 | if test "X$lt_pkg" = "X$lt_p"; then 341 | pic_mode=yes 342 | fi 343 | done 344 | IFS="$lt_save_ifs" 345 | ;; 346 | esac], 347 | [pic_mode=default]) 348 | 349 | test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) 350 | 351 | _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl 352 | ])# _LT_WITH_PIC 353 | 354 | LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) 355 | LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) 356 | 357 | # Old name: 358 | AU_DEFUN([AC_LIBTOOL_PICMODE], 359 | [_LT_SET_OPTION([LT_INIT], [pic-only]) 360 | AC_DIAGNOSE([obsolete], 361 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 362 | put the `pic-only' option into LT_INIT's first parameter.]) 363 | ]) 364 | 365 | dnl aclocal-1.4 backwards compatibility: 366 | dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) 367 | 368 | ## ----------------- ## 369 | ## LTDL_INIT Options ## 370 | ## ----------------- ## 371 | 372 | m4_define([_LTDL_MODE], []) 373 | LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], 374 | [m4_define([_LTDL_MODE], [nonrecursive])]) 375 | LT_OPTION_DEFINE([LTDL_INIT], [recursive], 376 | [m4_define([_LTDL_MODE], [recursive])]) 377 | LT_OPTION_DEFINE([LTDL_INIT], [subproject], 378 | [m4_define([_LTDL_MODE], [subproject])]) 379 | 380 | m4_define([_LTDL_TYPE], []) 381 | LT_OPTION_DEFINE([LTDL_INIT], [installable], 382 | [m4_define([_LTDL_TYPE], [installable])]) 383 | LT_OPTION_DEFINE([LTDL_INIT], [convenience], 384 | [m4_define([_LTDL_TYPE], [convenience])]) 385 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell commands `./configure; make; make install' should 16 | configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the `README' file for 18 | instructions specific to this package. Some packages provide this 19 | `INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The `configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a `Makefile' in each directory of the package. 27 | It may also create one or more `.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script `config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file `config.log' containing compiler output (useful mainly for 31 | debugging `configure'). 32 | 33 | It can also use an optional file (typically called `config.cache' 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 35 | the results of its tests to speed up reconfiguring. Caching is 36 | disabled by default to prevent problems with accidental use of stale 37 | cache files. 38 | 39 | If you need to do unusual things to compile the package, please try 40 | to figure out how `configure' could check whether to do them, and mail 41 | diffs or instructions to the address given in the `README' so they can 42 | be considered for the next release. If you are using the cache, and at 43 | some point `config.cache' contains results you don't want to keep, you 44 | may remove or edit it. 45 | 46 | The file `configure.ac' (or `configure.in') is used to create 47 | `configure' by a program called `autoconf'. You need `configure.ac' if 48 | you want to change it or regenerate `configure' using a newer version 49 | of `autoconf'. 50 | 51 | The simplest way to compile this package is: 52 | 53 | 1. `cd' to the directory containing the package's source code and type 54 | `./configure' to configure the package for your system. 55 | 56 | Running `configure' might take a while. While running, it prints 57 | some messages telling which features it is checking for. 58 | 59 | 2. Type `make' to compile the package. 60 | 61 | 3. Optionally, type `make check' to run any self-tests that come with 62 | the package, generally using the just-built uninstalled binaries. 63 | 64 | 4. Type `make install' to install the programs and any data files and 65 | documentation. When installing into a prefix owned by root, it is 66 | recommended that the package be configured and built as a regular 67 | user, and only the `make install' phase executed with root 68 | privileges. 69 | 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but 71 | this time using the binaries in their final installed location. 72 | This target does not install anything. Running this target as a 73 | regular user, particularly if the prior `make install' required 74 | root privileges, verifies that the installation completed 75 | correctly. 76 | 77 | 6. You can remove the program binaries and object files from the 78 | source code directory by typing `make clean'. To also remove the 79 | files that `configure' created (so you can compile the package for 80 | a different kind of computer), type `make distclean'. There is 81 | also a `make maintainer-clean' target, but that is intended mainly 82 | for the package's developers. If you use it, you may have to get 83 | all sorts of other programs in order to regenerate files that came 84 | with the distribution. 85 | 86 | 7. Often, you can also type `make uninstall' to remove the installed 87 | files again. In practice, not all packages have tested that 88 | uninstallation works correctly, even though it is required by the 89 | GNU Coding Standards. 90 | 91 | 8. Some packages, particularly those that use Automake, provide `make 92 | distcheck', which can by used by developers to test that all other 93 | targets like `make install' and `make uninstall' work correctly. 94 | This target is generally not run by end users. 95 | 96 | Compilers and Options 97 | ===================== 98 | 99 | Some systems require unusual options for compilation or linking that 100 | the `configure' script does not know about. Run `./configure --help' 101 | for details on some of the pertinent environment variables. 102 | 103 | You can give `configure' initial values for configuration parameters 104 | by setting variables in the command line or in the environment. Here 105 | is an example: 106 | 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 108 | 109 | *Note Defining Variables::, for more details. 110 | 111 | Compiling For Multiple Architectures 112 | ==================================== 113 | 114 | You can compile the package for more than one kind of computer at the 115 | same time, by placing the object files for each architecture in their 116 | own directory. To do this, you can use GNU `make'. `cd' to the 117 | directory where you want the object files and executables to go and run 118 | the `configure' script. `configure' automatically checks for the 119 | source code in the directory that `configure' is in and in `..'. This 120 | is known as a "VPATH" build. 121 | 122 | With a non-GNU `make', it is safer to compile the package for one 123 | architecture at a time in the source code directory. After you have 124 | installed the package for one architecture, use `make distclean' before 125 | reconfiguring for another architecture. 126 | 127 | On MacOS X 10.5 and later systems, you can create libraries and 128 | executables that work on multiple system types--known as "fat" or 129 | "universal" binaries--by specifying multiple `-arch' options to the 130 | compiler but only a single `-arch' option to the preprocessor. Like 131 | this: 132 | 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 135 | CPP="gcc -E" CXXCPP="g++ -E" 136 | 137 | This is not guaranteed to produce working output in all cases, you 138 | may have to build one architecture at a time and combine the results 139 | using the `lipo' tool if you have problems. 140 | 141 | Installation Names 142 | ================== 143 | 144 | By default, `make install' installs the package's commands under 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You 146 | can specify an installation prefix other than `/usr/local' by giving 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an 148 | absolute file name. 149 | 150 | You can specify separate installation prefixes for 151 | architecture-specific files and architecture-independent files. If you 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 153 | PREFIX as the prefix for installing programs and libraries. 154 | Documentation and other data files still use the regular prefix. 155 | 156 | In addition, if you use an unusual directory layout you can give 157 | options like `--bindir=DIR' to specify different values for particular 158 | kinds of files. Run `configure --help' for a list of the directories 159 | you can set and what kinds of files go in them. In general, the 160 | default for these options is expressed in terms of `${prefix}', so that 161 | specifying just `--prefix' will affect all of the other directory 162 | specifications that were not explicitly provided. 163 | 164 | The most portable way to affect installation locations is to pass the 165 | correct locations to `configure'; however, many packages provide one or 166 | both of the following shortcuts of passing variable assignments to the 167 | `make install' command line to change installation locations without 168 | having to reconfigure or recompile. 169 | 170 | The first method involves providing an override variable for each 171 | affected directory. For example, `make install 172 | prefix=/alternate/directory' will choose an alternate location for all 173 | directory configuration variables that were expressed in terms of 174 | `${prefix}'. Any directories that were specified during `configure', 175 | but not in terms of `${prefix}', must each be overridden at install 176 | time for the entire installation to be relocated. The approach of 177 | makefile variable overrides for each directory variable is required by 178 | the GNU Coding Standards, and ideally causes no recompilation. 179 | However, some platforms have known limitations with the semantics of 180 | shared libraries that end up requiring recompilation when using this 181 | method, particularly noticeable in packages that use GNU Libtool. 182 | 183 | The second method involves providing the `DESTDIR' variable. For 184 | example, `make install DESTDIR=/alternate/directory' will prepend 185 | `/alternate/directory' before all installation names. The approach of 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and 187 | does not work on platforms that have drive letters. On the other hand, 188 | it does better at avoiding recompilation issues, and works well even 189 | when some directory options were not specified in terms of `${prefix}' 190 | at `configure' time. 191 | 192 | Optional Features 193 | ================= 194 | 195 | If the package supports it, you can cause programs to be installed 196 | with an extra prefix or suffix on their names by giving `configure' the 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 198 | 199 | Some packages pay attention to `--enable-FEATURE' options to 200 | `configure', where FEATURE indicates an optional part of the package. 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 202 | is something like `gnu-as' or `x' (for the X Window System). The 203 | `README' should mention any `--enable-' and `--with-' options that the 204 | package recognizes. 205 | 206 | For packages that use the X Window System, `configure' can usually 207 | find the X include and library files automatically, but if it doesn't, 208 | you can use the `configure' options `--x-includes=DIR' and 209 | `--x-libraries=DIR' to specify their locations. 210 | 211 | Some packages offer the ability to configure how verbose the 212 | execution of `make' will be. For these packages, running `./configure 213 | --enable-silent-rules' sets the default to minimal output, which can be 214 | overridden with `make V=1'; while running `./configure 215 | --disable-silent-rules' sets the default to verbose, which can be 216 | overridden with `make V=0'. 217 | 218 | Particular systems 219 | ================== 220 | 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU 222 | CC is not installed, it is recommended to use the following options in 223 | order to use an ANSI C compiler: 224 | 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 226 | 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 228 | 229 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 230 | parse its `' header file. The option `-nodtk' can be used as 231 | a workaround. If GNU CC is not installed, it is therefore recommended 232 | to try 233 | 234 | ./configure CC="cc" 235 | 236 | and if that doesn't work, try 237 | 238 | ./configure CC="cc -nodtk" 239 | 240 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 241 | directory contains several dysfunctional programs; working variants of 242 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 243 | in your `PATH', put it _after_ `/usr/bin'. 244 | 245 | On Haiku, software installed for all users goes in `/boot/common', 246 | not `/usr/local'. It is recommended to use the following options: 247 | 248 | ./configure --prefix=/boot/common 249 | 250 | Specifying the System Type 251 | ========================== 252 | 253 | There may be some features `configure' cannot figure out 254 | automatically, but needs to determine by the type of machine the package 255 | will run on. Usually, assuming the package is built to be run on the 256 | _same_ architectures, `configure' can figure that out, but if it prints 257 | a message saying it cannot guess the machine type, give it the 258 | `--build=TYPE' option. TYPE can either be a short name for the system 259 | type, such as `sun4', or a canonical name which has the form: 260 | 261 | CPU-COMPANY-SYSTEM 262 | 263 | where SYSTEM can have one of these forms: 264 | 265 | OS 266 | KERNEL-OS 267 | 268 | See the file `config.sub' for the possible values of each field. If 269 | `config.sub' isn't included in this package, then this package doesn't 270 | need to know the machine type. 271 | 272 | If you are _building_ compiler tools for cross-compiling, you should 273 | use the option `--target=TYPE' to select the type of system they will 274 | produce code for. 275 | 276 | If you want to _use_ a cross compiler, that generates code for a 277 | platform different from the build platform, you should specify the 278 | "host" platform (i.e., that on which the generated programs will 279 | eventually be run) with `--host=TYPE'. 280 | 281 | Sharing Defaults 282 | ================ 283 | 284 | If you want to set default values for `configure' scripts to share, 285 | you can create a site shell script called `config.site' that gives 286 | default values for variables like `CC', `cache_file', and `prefix'. 287 | `configure' looks for `PREFIX/share/config.site' if it exists, then 288 | `PREFIX/etc/config.site' if it exists. Or, you can set the 289 | `CONFIG_SITE' environment variable to the location of the site script. 290 | A warning: not all `configure' scripts look for a site script. 291 | 292 | Defining Variables 293 | ================== 294 | 295 | Variables not defined in a site shell script can be set in the 296 | environment passed to `configure'. However, some packages may run 297 | configure again during the build, and the customized values of these 298 | variables may be lost. In order to avoid this problem, you should set 299 | them in the `configure' command line, using `VAR=value'. For example: 300 | 301 | ./configure CC=/usr/local2/bin/gcc 302 | 303 | causes the specified `gcc' to be used as the C compiler (unless it is 304 | overridden in the site shell script). 305 | 306 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 307 | an Autoconf bug. Until the bug is fixed you can use this workaround: 308 | 309 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 310 | 311 | `configure' Invocation 312 | ====================== 313 | 314 | `configure' recognizes the following options to control how it 315 | operates. 316 | 317 | `--help' 318 | `-h' 319 | Print a summary of all of the options to `configure', and exit. 320 | 321 | `--help=short' 322 | `--help=recursive' 323 | Print a summary of the options unique to this package's 324 | `configure', and exit. The `short' variant lists options used 325 | only in the top level, while the `recursive' variant lists options 326 | also present in any nested packages. 327 | 328 | `--version' 329 | `-V' 330 | Print the version of Autoconf used to generate the `configure' 331 | script, and exit. 332 | 333 | `--cache-file=FILE' 334 | Enable the cache: use and save the results of the tests in FILE, 335 | traditionally `config.cache'. FILE defaults to `/dev/null' to 336 | disable caching. 337 | 338 | `--config-cache' 339 | `-C' 340 | Alias for `--cache-file=config.cache'. 341 | 342 | `--quiet' 343 | `--silent' 344 | `-q' 345 | Do not print messages saying which checks are being made. To 346 | suppress all normal output, redirect it to `/dev/null' (any error 347 | messages will still be shown). 348 | 349 | `--srcdir=DIR' 350 | Look for the package's source code in directory DIR. Usually 351 | `configure' can determine that directory automatically. 352 | 353 | `--prefix=DIR' 354 | Use DIR as the installation prefix. *note Installation Names:: 355 | for more details, including other options available for fine-tuning 356 | the installation locations. 357 | 358 | `--no-create' 359 | `-n' 360 | Run the configure checks, but stop before creating any output 361 | files. 362 | 363 | `configure' also accepts some other, not widely useful, options. Run 364 | `configure --help' for more details. 365 | 366 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # autogen.sh 3 | # Copyright (C) 2003, 2014, 2017, 2018, 2022 g10 Code GmbH 4 | # 5 | # This file is free software; as a special exception the author gives 6 | # unlimited permission to copy and/or distribute it, with or without 7 | # modifications, as long as this notice is preserved. 8 | # 9 | # This program is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 11 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | # 13 | # This is a generic script to create the configure script and handle cross 14 | # build environments. It requires the presence of a autogen.rc file to 15 | # configure it for the respective package. It is maintained as part of 16 | # GnuPG and source copied by other packages. 17 | # 18 | # Version: 2024-07-04 19 | 20 | configure_ac="configure.ac" 21 | 22 | cvtver () { 23 | awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}' 24 | } 25 | 26 | check_version () { 27 | if [ $(( `("$1" --version || echo "0") | cvtver` >= $2 )) = 1 ]; then 28 | return 0 29 | fi 30 | echo "**Error**: "\`$1\'" not installed or too old." >&2 31 | echo ' Version '$3' or newer is required.' >&2 32 | [ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2 33 | DIE="yes" 34 | return 1 35 | } 36 | 37 | fatal () { 38 | echo "autogen.sh:" "$*" >&2 39 | DIE=yes 40 | } 41 | 42 | info () { 43 | if [ -z "${SILENT}" ]; then 44 | echo "autogen.sh:" "$*" >&2 45 | fi 46 | } 47 | 48 | die_p () { 49 | if [ "$DIE" = "yes" ]; then 50 | echo "autogen.sh: Stop." >&2 51 | exit 1 52 | fi 53 | } 54 | 55 | replace_sysroot () { 56 | configure_opts=$(echo $configure_opts | sed "s#@SYSROOT@#${w32root}#g") 57 | extraoptions=$(echo $extraoptions | sed "s#@SYSROOT@#${w32root}#g") 58 | } 59 | 60 | # Allow to override the default tool names 61 | AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX} 62 | AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX} 63 | 64 | AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX} 65 | ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX} 66 | 67 | GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX} 68 | MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX} 69 | 70 | DIE=no 71 | FORCE= 72 | SILENT= 73 | PRINT_HOST=no 74 | PRINT_BUILD=no 75 | tmp=$(dirname "$0") 76 | tsdir=$(cd "${tmp}"; pwd) 77 | 78 | if [ -n "${AUTOGEN_SH_SILENT}" ]; then 79 | SILENT=" --silent" 80 | fi 81 | if test x"$1" = x"--help"; then 82 | echo "usage: ./autogen.sh [OPTIONS] [ARGS]" 83 | echo " Options:" 84 | echo " --silent Silent operation" 85 | echo " --force Pass --force to autoconf" 86 | echo " --find-version Helper for configure.ac" 87 | echo " --git-build Run all commands to build from a Git" 88 | echo " --print-host Print only the host triplet" 89 | echo " --print-build Print only the build platform triplet" 90 | echo " --build-TYPE Configure to cross build for TYPE" 91 | echo "" 92 | echo " ARGS are passed to configure in --build-TYPE mode." 93 | echo " Configuration for this script is expected in autogen.rc" 94 | exit 0 95 | fi 96 | if test x"$1" = x"--silent"; then 97 | SILENT=" --silent" 98 | shift 99 | fi 100 | if test x"$1" = x"--force"; then 101 | FORCE=" --force" 102 | shift 103 | fi 104 | if test x"$1" = x"--print-host"; then 105 | PRINT_HOST=yes 106 | shift 107 | fi 108 | if test x"$1" = x"--print-build"; then 109 | PRINT_BUILD=yes 110 | shift 111 | fi 112 | 113 | 114 | # Reject unsafe characters in $HOME, $tsdir and cwd. We consider spaces 115 | # as unsafe because it is too easy to get scripts wrong in this regard. 116 | am_lf=' 117 | ' 118 | case `pwd` in 119 | *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) 120 | fatal "unsafe working directory name" ;; 121 | esac 122 | case $tsdir in 123 | *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) 124 | fatal "unsafe source directory: \`$tsdir'" ;; 125 | esac 126 | case $HOME in 127 | *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) 128 | fatal "unsafe home directory: \`$HOME'" ;; 129 | esac 130 | die_p 131 | 132 | 133 | # List of variables sourced from autogen.rc. The strings '@SYSROOT@' in 134 | # these variables are replaced by the actual system root. 135 | configure_opts= 136 | extraoptions= 137 | # List of optional variables sourced from autogen.rc and ~/.gnupg-autogen.rc 138 | w32_toolprefixes= 139 | w32_extraoptions= 140 | w64_toolprefixes= 141 | w64_extraoptions= 142 | amd64_toolprefixes= 143 | disable_gettext_checks= 144 | # End list of optional variables sourced from ~/.gnupg-autogen.rc 145 | # What follows are variables which are sourced but default to 146 | # environment variables or lacking them hardcoded values. 147 | #w32root= 148 | #w64root= 149 | #amd64root= 150 | 151 | # Convenience option to use certain configure options for some hosts. 152 | myhost="" 153 | myhostsub="" 154 | case "$1" in 155 | --find-version) 156 | myhost="find-version" 157 | SILENT=" --silent" 158 | shift 159 | ;; 160 | --git-build) 161 | myhost="git-build" 162 | shift 163 | ;; 164 | --build-w32) 165 | myhost="w32" 166 | shift 167 | ;; 168 | --build-w64) 169 | myhost="w32" 170 | myhostsub="64" 171 | shift 172 | ;; 173 | --build-amd64) 174 | myhost="amd64" 175 | shift 176 | ;; 177 | --build*) 178 | fatal "**Error**: invalid build option $1" 179 | shift 180 | ;; 181 | *) 182 | ;; 183 | esac 184 | die_p 185 | 186 | 187 | # **** GIT BUILD **** 188 | # This is a helper to build from git. 189 | if [ "$myhost" = "git-build" ]; then 190 | tmp="$(pwd)" 191 | cd "$tsdir" || fatal "error cd-ing to $tsdir" 192 | ./autogen.sh || fatal "error running ./autogen.sh" 193 | cd "$tmp" || fatal "error cd-ing back to $tmp" 194 | die_p 195 | "$tsdir"/configure || fatal "error running $tsdir/configure" 196 | die_p 197 | make || fatal "error running make" 198 | die_p 199 | make check || fatal "error running make check" 200 | die_p 201 | exit 0 202 | fi 203 | # **** end GIT BUILD **** 204 | 205 | 206 | # Source our configuration 207 | if [ -f "${tsdir}/autogen.rc" ]; then 208 | . "${tsdir}/autogen.rc" 209 | fi 210 | 211 | # Source optional site specific configuration 212 | if [ -f "$HOME/.gnupg-autogen.rc" ]; then 213 | info "sourcing extra definitions from $HOME/.gnupg-autogen.rc" 214 | . "$HOME/.gnupg-autogen.rc" 215 | fi 216 | 217 | 218 | # **** FIND VERSION **** 219 | # This is a helper for the configure.ac M4 magic 220 | # Called 221 | # ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO] 222 | # returns a complete version string with automatic beta numbering. 223 | if [ "$myhost" = "find-version" ]; then 224 | package="$1" 225 | major="$2" 226 | minor="$3" 227 | micro="$4" 228 | 229 | if [ -z "$package" -o -z "$major" -o -z "$minor" ]; then 230 | echo "usage: ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO]" >&2 231 | exit 1 232 | fi 233 | 234 | if [ -z "$micro" ]; then 235 | matchstr1="$package-$major.[0-9]*" 236 | matchstr2="$package-$major-base" 237 | matchstr3="" 238 | vers="$major.$minor" 239 | else 240 | matchstr1="$package-$major.$minor.[0-9]*" 241 | matchstr2="$package-$major.[0-9]*-base" 242 | matchstr3="$package-$major-base" 243 | vers="$major.$minor.$micro" 244 | fi 245 | 246 | beta=no 247 | if [ -e .git ]; then 248 | ingit=yes 249 | tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null) 250 | if [ -n "$tmp" ]; then 251 | tmp=$(echo "$tmp" | sed s/^"$package"// \ 252 | | awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}') 253 | else 254 | # (due tof "-base" in the tag we need to take the 4th field) 255 | tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null) 256 | if [ -n "$tmp" ]; then 257 | tmp=$(echo "$tmp" | sed s/^"$package"// \ 258 | | awk -F- '$4!=0 && $4 !~ /^beta/ {print"-beta"$4}') 259 | elif [ -n "${matchstr3}" ]; then 260 | tmp=$(git describe --match "${matchstr3}" --long 2>/dev/null) 261 | if [ -n "$tmp" ]; then 262 | tmp=$(echo "$tmp" | sed s/^"$package"// \ 263 | | awk -F- '$4!=0 && $4 !~ /^beta/ {print"-beta"$4}') 264 | fi 265 | fi 266 | fi 267 | [ -n "$tmp" ] && beta=yes 268 | cid=$(git rev-parse --verify HEAD | tr -d '\n\r') 269 | rev=$(git rev-parse --short HEAD | tr -d '\n\r') 270 | rvd=$((0x$(echo ${rev} | dd bs=1 count=4 2>/dev/null))) 271 | else 272 | ingit=no 273 | beta=yes 274 | tmp="-unknown" 275 | cid="0000000" 276 | rev="0000000" 277 | rvd="0" 278 | fi 279 | 280 | echo "$package-$vers$tmp:$beta:$ingit:$vers$tmp:$vers:$tmp:$rev:$rvd:$cid:" 281 | exit 0 282 | fi 283 | # **** end FIND VERSION **** 284 | 285 | 286 | if [ ! -f "$tsdir/build-aux/config.guess" ]; then 287 | fatal "$tsdir/build-aux/config.guess not found" 288 | exit 1 289 | fi 290 | build=`$tsdir/build-aux/config.guess` 291 | if [ $PRINT_BUILD = yes ]; then 292 | echo "$build" 293 | exit 0 294 | fi 295 | 296 | 297 | 298 | # ****************** 299 | # W32 build script 300 | # ****************** 301 | if [ "$myhost" = "w32" ]; then 302 | case $myhostsub in 303 | 64) 304 | w32root="$w64root" 305 | [ -z "$w32root" ] && w32root="$HOME/w64root" 306 | toolprefixes="$w64_toolprefixes x86_64-w64-mingw32" 307 | extraoptions="$extraoptions $w64_extraoptions" 308 | ;; 309 | *) 310 | [ -z "$w32root" ] && w32root="$HOME/w32root" 311 | toolprefixes="$w32_toolprefixes i686-w64-mingw32 i586-mingw32msvc" 312 | toolprefixes="$toolprefixes i386-mingw32msvc mingw32" 313 | extraoptions="$extraoptions $w32_extraoptions" 314 | ;; 315 | esac 316 | info "Using $w32root as standard install directory" 317 | replace_sysroot 318 | 319 | # Locate the cross compiler 320 | crossbindir= 321 | for host in $toolprefixes; do 322 | if ${host}-gcc --version >/dev/null 2>&1 ; then 323 | crossbindir=/usr/${host}/bin 324 | conf_CC="CC=${host}-gcc" 325 | break; 326 | fi 327 | done 328 | if [ -z "$crossbindir" ]; then 329 | fatal "cross compiler kit not installed" 330 | if [ -z "$myhostsub" ]; then 331 | info "Under Debian GNU/Linux, you may install it using" 332 | info " apt-get install mingw32 mingw32-runtime mingw32-binutils" 333 | fi 334 | die_p 335 | fi 336 | if [ $PRINT_HOST = yes ]; then 337 | echo "$host" 338 | exit 0 339 | fi 340 | 341 | if [ -f "$tsdir/config.log" ]; then 342 | if ! head $tsdir/config.log | grep "$host" >/dev/null; then 343 | fatal "Please run a 'make distclean' first" 344 | die_p 345 | fi 346 | fi 347 | 348 | $tsdir/configure --enable-maintainer-mode ${SILENT} \ 349 | --prefix=${w32root} \ 350 | --host=${host} --build=${build} SYSROOT=${w32root} \ 351 | PKG_CONFIG_LIBDIR=${w32root}/lib/pkgconfig \ 352 | ${configure_opts} ${extraoptions} "$@" 353 | rc=$? 354 | exit $rc 355 | fi 356 | # ***** end W32 build script ******* 357 | 358 | # ***** AMD64 cross build script ******* 359 | # Used to cross-compile for AMD64 (for testing) 360 | if [ "$myhost" = "amd64" ]; then 361 | [ -z "$amd64root" ] && amd64root="$HOME/amd64root" 362 | info "Using $amd64root as standard install directory" 363 | replace_sysroot 364 | 365 | toolprefixes="$amd64_toolprefixes x86_64-linux-gnu amd64-linux-gnu" 366 | 367 | # Locate the cross compiler 368 | crossbindir= 369 | for host in $toolprefixes ; do 370 | if ${host}-gcc --version >/dev/null 2>&1 ; then 371 | crossbindir=/usr/${host}/bin 372 | conf_CC="CC=${host}-gcc" 373 | break; 374 | fi 375 | done 376 | if [ -z "$crossbindir" ]; then 377 | echo "Cross compiler kit not installed" >&2 378 | echo "Stop." >&2 379 | exit 1 380 | fi 381 | if [ $PRINT_HOST = yes ]; then 382 | echo "$host" 383 | exit 0 384 | fi 385 | 386 | if [ -f "$tsdir/config.log" ]; then 387 | if ! head $tsdir/config.log | grep "$host" >/dev/null; then 388 | echo "Please run a 'make distclean' first" >&2 389 | exit 1 390 | fi 391 | fi 392 | 393 | $tsdir/configure --enable-maintainer-mode ${SILENT} \ 394 | --prefix=${amd64root} \ 395 | --host=${host} --build=${build} \ 396 | ${configure_opts} ${extraoptions} "$@" 397 | rc=$? 398 | exit $rc 399 | fi 400 | # ***** end AMD64 cross build script ******* 401 | 402 | 403 | # Grep the required versions from configure.ac 404 | autoconf_vers=`sed -n '/^AC_PREREQ(/ { 405 | s/^.*(\(.*\))/\1/p 406 | q 407 | }' ${configure_ac}` 408 | autoconf_vers_num=`echo "$autoconf_vers" | cvtver` 409 | 410 | automake_vers=`sed -n '/^min_automake_version=/ { 411 | s/^.*="\(.*\)"/\1/p 412 | q 413 | }' ${configure_ac}` 414 | automake_vers_num=`echo "$automake_vers" | cvtver` 415 | 416 | gettext_vers="n/a" 417 | if [ -d "${tsdir}/po" ]; then 418 | gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ { 419 | s/^.*\[\(.*\)])/\1/p 420 | q 421 | }' ${configure_ac}` 422 | gettext_vers_num=`echo "$gettext_vers" | cvtver` 423 | fi 424 | 425 | if [ -z "$autoconf_vers" -o -z "$automake_vers" ] 426 | then 427 | echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2 428 | exit 1 429 | fi 430 | 431 | 432 | if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then 433 | check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf 434 | fi 435 | if check_version $AUTOMAKE $automake_vers_num $automake_vers; then 436 | check_version $ACLOCAL $automake_vers_num $autoconf_vers automake 437 | fi 438 | if [ "$gettext_vers" != "n/a" ]; then 439 | if check_version $GETTEXT $gettext_vers_num $gettext_vers; then 440 | check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext 441 | fi 442 | fi 443 | 444 | if [ "$DIE" = "yes" ]; then 445 | cat </dev/null 2>/dev/null; then 459 | [ -z "${SILENT}" ] && CP="$CP -v" 460 | fi 461 | if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then 462 | [ -z "${SILENT}" ] && cat <. 18 | 19 | # Process this file with autoconf to produce a configure script. 20 | 21 | AC_PREREQ([2.69]) 22 | min_automake_version="1.14" 23 | 24 | # To build a release you need to create a tag with the version number 25 | # (git tag -s npth-n.m) and run "./autogen.sh --force". Please bump 26 | # the version number immediately after the release and do another 27 | # commit and push so that the git magic is able to work. 28 | # See below for the LT versions. 29 | m4_define([mym4_package],[npth]) 30 | m4_define([mym4_major], [1]) 31 | m4_define([mym4_minor], [9]) 32 | 33 | # To start a new development series, i.e a new major or minor number 34 | # you need to mark an arbitrary commit before the first beta release 35 | # with an annotated tag. For example a 2.1 branch starts off with 36 | # the tag "foo-2.1-base". This is used as the base for counting 37 | # beta numbers before the first release of a series. 38 | 39 | # Below is m4 magic to extract and compute the git revision number, 40 | # the decimalized short revision number, a beta version string and a 41 | # flag indicating a development version (mym4_isbeta). Note that the 42 | # m4 processing is done by autoconf and not during the configure run. 43 | m4_define([mym4_verslist], m4_split(m4_esyscmd([./autogen.sh --find-version] \ 44 | mym4_package mym4_major mym4_minor),[:])) 45 | m4_define([mym4_isbeta], m4_argn(2, mym4_verslist)) 46 | m4_define([mym4_version], m4_argn(4, mym4_verslist)) 47 | m4_define([mym4_revision], m4_argn(7, mym4_verslist)) 48 | m4_define([mym4_revision_dec], m4_argn(8, mym4_verslist)) 49 | m4_define([mym4_commitid], m4_argn(9, mym4_verslist)) 50 | m4_esyscmd([echo ]mym4_version[>VERSION]) 51 | m4_esyscmd([echo ]mym4_commitid[>>VERSION]) 52 | AC_INIT([mym4_package],[mym4_version],[https://bugs.gnupg.org]) 53 | # LT Version numbers, remember to change them just *before* a release. 54 | # (Code changed: REVISION++) 55 | # (Interfaces added/removed/changed: CURRENT++, REVISION=0) 56 | # (Interfaces added: AGE++) 57 | # (Interfaces removed: AGE=0) 58 | # 59 | LIBNPTH_LT_CURRENT=3 60 | LIBNPTH_LT_AGE=3 61 | LIBNPTH_LT_REVISION=0 62 | ################################################ 63 | 64 | AC_SUBST(LIBNPTH_LT_CURRENT) 65 | AC_SUBST(LIBNPTH_LT_AGE) 66 | AC_SUBST(LIBNPTH_LT_REVISION) 67 | 68 | VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x00" mym4_major mym4_minor) 69 | AC_SUBST(VERSION_NUMBER) 70 | 71 | # If the API is changed in an incompatible way: increment the next counter. 72 | NPTH_CONFIG_API_VERSION=1 73 | ############################################## 74 | 75 | AC_CONFIG_AUX_DIR([build-aux]) 76 | AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip]) 77 | AM_MAINTAINER_MODE 78 | AC_CONFIG_SRCDIR([src/npth.c]) 79 | AC_CONFIG_HEADERS([config.h]) 80 | AC_CONFIG_MACRO_DIR([m4]) 81 | AC_CANONICAL_HOST 82 | AM_SILENT_RULES 83 | 84 | # Enable GNU extensions on systems that have them. 85 | AC_USE_SYSTEM_EXTENSIONS 86 | 87 | # Taken from mpfr-4.0.1, then modified for LDADD_FOR_TESTS_KLUDGE 88 | dnl Under Linux, make sure that the old dtags are used if LD_LIBRARY_PATH 89 | dnl is defined. The issue is that with the new dtags, LD_LIBRARY_PATH has 90 | dnl the precedence over the run path, so that if a compatible MPFR library 91 | dnl is installed in some directory from $LD_LIBRARY_PATH, then the tested 92 | dnl MPFR library will be this library instead of the MPFR library from the 93 | dnl build tree. Other OS with the same issue might be added later. 94 | dnl 95 | dnl References: 96 | dnl https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=859732 97 | dnl http://lists.gnu.org/archive/html/libtool/2017-05/msg00000.html 98 | dnl 99 | dnl We need to check whether --disable-new-dtags is supported as alternate 100 | dnl linkers may be used (e.g., with tcc: CC=tcc LD=tcc). 101 | dnl 102 | case $host in 103 | *-*-linux*) 104 | if test -n "$LD_LIBRARY_PATH"; then 105 | saved_LDFLAGS="$LDFLAGS" 106 | LDADD_FOR_TESTS_KLUDGE="-Wl,--disable-new-dtags" 107 | LDFLAGS="$LDFLAGS $LDADD_FOR_TESTS_KLUDGE" 108 | AC_MSG_CHECKING(whether --disable-new-dtags is supported by the linker) 109 | AC_LINK_IFELSE([AC_LANG_SOURCE([[ 110 | int main (void) { return 0; } 111 | ]])], 112 | [AC_MSG_RESULT(yes (use it since LD_LIBRARY_PATH is set))], 113 | [AC_MSG_RESULT(no) 114 | LDADD_FOR_TESTS_KLUDGE="" 115 | ]) 116 | LDFLAGS="$saved_LDFLAGS" 117 | fi 118 | ;; 119 | esac 120 | AC_SUBST([LDADD_FOR_TESTS_KLUDGE]) 121 | 122 | AH_VERBATIM([_REENTRANT], 123 | [#ifndef _REENTRANT 124 | # define _REENTRANT 1 125 | #endif]) 126 | 127 | # Checks for programs. 128 | AC_PROG_CC 129 | 130 | if test "$GCC" = yes; then 131 | CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" 132 | 133 | AC_MSG_CHECKING([if gcc supports -Wpointer-arith]) 134 | _gcc_cflags_save=$CFLAGS 135 | CFLAGS="-Wpointer-arith" 136 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],_gcc_wopt=yes,_gcc_wopt=no) 137 | AC_MSG_RESULT($_gcc_wopt) 138 | CFLAGS=$_gcc_cflags_save; 139 | if test x"$_gcc_wopt" = xyes ; then 140 | CFLAGS="$CFLAGS -Wpointer-arith" 141 | fi 142 | fi 143 | 144 | # We used to provide npth-config command always. Now, it's 145 | # gpgrt-config command with npth.pc configuration file, which does 146 | # same thing. 147 | AC_ARG_ENABLE(install-npth-config, 148 | AS_HELP_STRING([--enable-install-npth-config],[install npth-config command]), 149 | install_npth_config=$enableval) 150 | AM_CONDITIONAL(INSTALL_NPTH_CONFIG, test "$install_npth_config" = "yes") 151 | 152 | 153 | run_tests="yes" 154 | AC_ARG_ENABLE(tests, 155 | AS_HELP_STRING([--disable-tests],[disable tests]), 156 | run_tests=$enableval) 157 | AM_CONDITIONAL(RUN_TESTS, test "$run_tests" = "yes") 158 | 159 | 160 | # Don't default to build static libs. 161 | LT_PREREQ([2.2.6]) 162 | LT_INIT([win32-dll disable-static]) 163 | LT_LANG([Windows Resource]) 164 | 165 | 166 | # For now we hardcode the use of version scripts. It would be better 167 | # to write a test for this or even implement this within libtool. 168 | have_ld_version_script=no 169 | have_fork_unsafe_semaphore=no 170 | case "${host}" in 171 | *-*-linux*) 172 | have_ld_version_script=yes 173 | ;; 174 | *-*-gnu*) 175 | have_ld_version_script=yes 176 | ;; 177 | *-apple-darwin*) 178 | AC_SEARCH_LIBS([dispatch_semaphore_create],[dispatch], 179 | [AC_DEFINE([HAVE_LIB_DISPATCH],1,[Defined if we have libdispatch])]) 180 | if test "$ac_cv_search_dispatch_semaphore_create" = no; then 181 | AC_DEFINE(HAVE_NO_POSIX_SEMAPHORE,1,[Define if no good semaphore.]) 182 | fi 183 | ;; 184 | *-*-aix*) 185 | have_fork_unsafe_semaphore=yes 186 | ;; 187 | *-*-dragonfly*|*-*-freebsd*|*-*-netbsd*|*-*-hpux*) 188 | LIBS="-lpthread $LIBS" 189 | AC_SEARCH_LIBS([sem_init],[rt]) 190 | ;; 191 | esac 192 | 193 | AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") 194 | 195 | # 196 | # Specify how we support our local modification of libtool for Windows 197 | # 64-bit. Options are: 198 | # 199 | # (1) apply: when appying patch fails, it results failure of entire build 200 | # (2) never: never apply the patch (no try) 201 | # (3) try: use patched if it goes well, use original if fails 202 | # 203 | AC_ARG_WITH([libtool-modification], 204 | AS_HELP_STRING([--with-libtool-modification=apply|never|try], 205 | [how to handle libtool modification (default=never)]), 206 | build_libtool_modification=$withval, 207 | build_libtool_modification=never) 208 | 209 | # 210 | # Apply a patch (locally maintained one of ours) to libtool 211 | # 212 | case $host in 213 | x86_64-*mingw32*) 214 | AC_CONFIG_COMMANDS([libtool-patch],[[ 215 | if test "$build_selection" = never; then 216 | echo "patch not applied" 217 | elif (mv -f libtool libtool.orig; \ 218 | sed -f $srcdir/build-aux/libtool-patch.sed libtool.orig >libtool); then 219 | echo "applied successfully" 220 | elif test "$build_selection" = try; then 221 | mv -f libtool.orig libtool 222 | echo "patch failed, thus, using original" 223 | else 224 | echo "patch failed" 225 | as_fn_exit 1 226 | fi 227 | ]],[build_selection=$build_libtool_modification]) 228 | ;; 229 | *) 230 | ;; 231 | esac 232 | 233 | AM_CONDITIONAL(NPTH_FORK_FAILURE, test "$have_fork_unsafe_semaphore" = "yes") 234 | 235 | 236 | # Set some default values 237 | config_libs="-lnpth $LIBS" 238 | have_w32_system=no 239 | have_w32ce_system=no 240 | have_w64_system=no 241 | 242 | # Define OS macros 243 | case "${host}" in 244 | x86_64-*mingw32*) 245 | have_w64_system=yes 246 | ;; 247 | *-mingw32ce*) 248 | have_w32ce_system=yes 249 | ;; 250 | esac 251 | case "${host}" in 252 | *-mingw32ce*|*-mingw32*) 253 | have_w32_system=yes 254 | ;; 255 | *) 256 | ;; 257 | esac 258 | 259 | if test "$have_w32_system" = yes; then 260 | AC_DEFINE(HAVE_W32_SYSTEM,1, 261 | [Defined if we run on any kind of W32 API based system]) 262 | fi 263 | AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) 264 | 265 | if test "$have_w64_system" = yes; then 266 | AC_DEFINE(HAVE_W64_SYSTEM,1, 267 | [Defined if we run on a 64 bit W32 API based system]) 268 | fi 269 | AM_CONDITIONAL(HAVE_W64_SYSTEM, test "$have_w64_system" = yes) 270 | 271 | # 272 | # Provide information about the build. 273 | # 274 | BUILD_REVISION="mym4_revision" 275 | AC_SUBST(BUILD_REVISION) 276 | BUILD_ISODATE=`date --iso-8601` 277 | AC_SUBST(BUILD_ISODATE) 278 | changequote(,)dnl 279 | BUILD_VERSION=`echo "$PACKAGE_VERSION" | sed 's/\([0-9.]*\).*/\1./'` 280 | changequote([,])dnl 281 | BUILD_VERSION="${BUILD_VERSION}0.mym4_revision_dec" 282 | BUILD_FILEVERSION=`echo "${BUILD_VERSION}" | tr . ,` 283 | AC_SUBST(BUILD_VERSION) 284 | AC_SUBST(BUILD_FILEVERSION) 285 | 286 | AC_ARG_ENABLE([build-timestamp], 287 | AS_HELP_STRING([--enable-build-timestamp],[set an explicit build timestamp for reproducibility. 288 | (default is the current time in ISO-8601 format)]), 289 | [if test "$enableval" = "yes"; then 290 | BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date` 291 | else 292 | BUILD_TIMESTAMP="$enableval" 293 | fi], 294 | [BUILD_TIMESTAMP=""]) 295 | AC_SUBST(BUILD_TIMESTAMP) 296 | AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP", 297 | [The time this package was configured for a build]) 298 | BUILD_COMMITID="mym4_commitid" 299 | AC_DEFINE_UNQUOTED(BUILD_COMMITID, "$BUILD_COMMITID", 300 | [Git commit id used to build this package]) 301 | 302 | VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x00" mym4_major mym4_minor) 303 | AC_SUBST(VERSION_NUMBER) 304 | 305 | 306 | # 307 | # Checks for header files. 308 | # 309 | # fixme: For what do we need the sys/socket test? 310 | AC_CHECK_HEADERS([sys/socket.h sys/select.h unistd.h sys/time.h time.h \ 311 | signal.h poll.h]) 312 | INSERT_SYS_SELECT_H= 313 | if test x"$ac_cv_header_sys_select_h" = xyes; then 314 | INSERT_SYS_SELECT_H="include " 315 | fi 316 | AC_SUBST(INSERT_SYS_SELECT_H) 317 | 318 | if test x"$ac_cv_header_sys_time_h" = xyes; then 319 | INSERT_SYS_TIME_H="include " 320 | fi 321 | AC_SUBST(INSERT_SYS_TIME_H) 322 | 323 | if test x"$ac_cv_header_time_h" = xyes; then 324 | INSERT_TIME_H="include " 325 | fi 326 | AC_SUBST(INSERT_TIME_H) 327 | 328 | if test x"$ac_cv_header_signal_h" = xyes; then 329 | INSERT_SIGNAL_H="include " 330 | fi 331 | AC_SUBST(INSERT_SIGNAL_H) 332 | 333 | 334 | # Some systems lack socklen_t - provide a replacement. 335 | gl_TYPE_SOCKLEN_T 336 | case "${host}" in 337 | *-*-mingw32*) 338 | # socklen_t may or may not be defined depending on what headers 339 | # are included. To be safe we use int as this is the actual type. 340 | INSERT_SOCKLEN_T="define _npth_socklen_t int" 341 | ;; 342 | *) 343 | if test ".$gl_cv_socklen_t_equiv" = "."; then 344 | INSERT_SOCKLEN_T="define _npth_socklen_t socklen_t" 345 | else 346 | INSERT_SOCKLEN_T="define _npth_socklen_t ${gl_cv_socklen_t_equiv}" 347 | fi 348 | esac 349 | AC_SUBST(INSERT_SOCKLEN_T) 350 | 351 | 352 | # 353 | # Checks for typedefs, structures, and compiler characteristics. 354 | # 355 | AC_TYPE_PID_T 356 | AC_TYPE_SIZE_T 357 | AC_TYPE_SSIZE_T 358 | 359 | 360 | # 361 | # Checks for libraries and functions. 362 | # 363 | # We test for pthread_cancel because in glibc 2.34, libc includes 364 | # pthread_create and pthread_detach, but not pthread_cancel. 365 | if test "$have_w32_system" = no; then 366 | AC_SEARCH_LIBS([pthread_cancel],[pthread]) 367 | case "x$ac_cv_search_pthread_cancel" in 368 | xno) 369 | have_pthread=no 370 | ;; 371 | xnone\ required) 372 | have_pthread=yes 373 | ;; 374 | *) 375 | have_pthread=yes 376 | config_libs="$config_libs $ac_cv_search_pthread_cancel" 377 | ;; 378 | esac 379 | if test "$have_pthread" != no; then 380 | AC_DEFINE(HAVE_PTHREAD,1,[Define if we have pthread.]) 381 | AC_CHECK_TYPE([pthread_rwlock_t]) 382 | AC_CHECK_FUNCS([pthread_tryjoin_np pthread_setname_np pthread_getname_np]) 383 | AC_CHECK_FUNCS([pthread_mutex_timedlock]) 384 | AC_CHECK_FUNCS([pthread_rwlock_rdlock pthread_rwlock_wrlock]) 385 | AC_CHECK_FUNCS([pthread_rwlock_timedrdlock pthread_rwlock_timedwrlock]) 386 | AC_CHECK_FUNCS([pthread_rwlock_tryrdlock pthread_rwlock_trywrlock]) 387 | AC_CHECK_FUNCS([pthread_atfork]) 388 | fi 389 | fi 390 | 391 | INSERT_NO_RWLOCK="undef _NPTH_NO_RWLOCK" 392 | if test x"$ac_cv_type_pthread_rwlock_t" = xno; then 393 | INSERT_NO_RWLOCK="define _NPTH_NO_RWLOCK 1" 394 | fi 395 | AC_SUBST(INSERT_NO_RWLOCK) 396 | 397 | case "${host}" in 398 | *-*-linux-musl*) 399 | INSERT_EXPOSE_RWLOCK_API="1" 400 | ;; 401 | *-*-linux-gnu*|*-*-gnu*) 402 | INSERT_EXPOSE_RWLOCK_API="defined(__USE_UNIX98) || defined(__USE_XOPEN2K)" 403 | ;; 404 | *) 405 | INSERT_EXPOSE_RWLOCK_API="1" 406 | ;; 407 | esac 408 | AC_SUBST(INSERT_EXPOSE_RWLOCK_API) 409 | 410 | AC_CHECK_FUNCS([select pselect gettimeofday ppoll]) 411 | 412 | npth_LIBSOCKET 413 | config_libs="$config_libs $LIBSOCKET" 414 | 415 | # Save and restore LIBS so e.g., -lrt, isn't added to it. Otherwise, *all* 416 | # programs in the package would end up linked with that potentially-shared 417 | # library, inducing unnecessary run-time overhead. 418 | LIB_CLOCK_GETTIME= 419 | AC_SUBST([LIB_CLOCK_GETTIME]) 420 | gl_saved_libs=$LIBS 421 | AC_SEARCH_LIBS([clock_gettime], [rt posix4], 422 | [if test "$ac_cv_search_clock_gettime" != "none required"; then 423 | LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime 424 | config_libs="$config_libs $LIB_CLOCK_GETTIME" 425 | fi 426 | AC_DEFINE([HAVE_CLOCK_GETTIME],1, 427 | [Define to 1 if you have the `clock_gettime' function.]) 428 | ]) 429 | LIBS=$gl_saved_libs 430 | 431 | 432 | # 433 | # Set NETLIBS 434 | # 435 | if test "$have_w32ce_system" = yes; then 436 | NETLIBS="-lws2 $NETLIBS" 437 | elif test "$have_w32_system" = yes; then 438 | NETLIBS="-lws2_32 $NETLIBS" 439 | fi 440 | AC_SUBST(NETLIBS) 441 | 442 | 443 | # 444 | # Substitutions to set generated files in a Emacs buffer to read-only. 445 | # 446 | AC_SUBST(emacs_local_vars_begin, [['Local][ ][Variables:']]) 447 | AC_SUBST(emacs_local_vars_read_only, ['buffer-read-only: t']) 448 | AC_SUBST(emacs_local_vars_end, ['End:']) 449 | 450 | 451 | # 452 | # Substitution used for npth-config 453 | # 454 | NPTH_CONFIG_LIBS="$config_libs" 455 | NPTH_CONFIG_CFLAGS="" 456 | NPTH_CONFIG_HOST="$host" 457 | AC_SUBST(NPTH_CONFIG_API_VERSION) 458 | AC_SUBST(NPTH_CONFIG_LIBS) 459 | AC_SUBST(NPTH_CONFIG_CFLAGS) 460 | AC_SUBST(NPTH_CONFIG_HOST) 461 | 462 | 463 | AH_BOTTOM([ 464 | #define CRIGHTBLURB "Copyright (C) 2011, 2012, 2014, 2015, 2017, 2024" \ 465 | " g10 Code GmbH\n" 466 | ]) 467 | 468 | 469 | 470 | # 471 | # Last check. 472 | # 473 | die=no 474 | if test "$have_w32_system" = no; then 475 | if test "$have_pthread" = "no"; then 476 | die=yes 477 | AC_MSG_NOTICE([[ 478 | *** 479 | *** You need Pthread to build this program. 480 | *** Normally, this library comes with your system. On Windows, you can use: 481 | *** http://sourceware.org/pthreads-win32/ 482 | ***]]) 483 | fi 484 | fi 485 | 486 | if test "$die" = "yes"; then 487 | AC_MSG_ERROR([[ 488 | *** 489 | *** Required libraries not found. Please consult the above messages 490 | *** and install them before running configure again. 491 | ***]]) 492 | fi 493 | 494 | # 495 | # Write output 496 | # 497 | AC_CONFIG_FILES([Makefile 498 | npth.pc 499 | src/npth.h 500 | w32/npth.h 501 | src/Makefile 502 | w32/Makefile 503 | w32/versioninfo.rc 504 | tests/Makefile]) 505 | AC_CONFIG_FILES(npth-config, chmod +x npth-config) 506 | AC_OUTPUT 507 | 508 | echo " 509 | $PACKAGE_NAME v$PACKAGE_VERSION prepared for make 510 | 511 | Revision: mym4_revision (mym4_revision_dec) 512 | Platform: $host 513 | " 514 | -------------------------------------------------------------------------------- /src/npth.h.in: -------------------------------------------------------------------------------- 1 | /* npth.h - a lightweight implementation of pth over pthread. 2 | * Configured for: @NPTH_CONFIG_HOST@. 3 | * Copyright (C) 2011, 2012, 2015, 2017, 2024 g10 Code GmbH 4 | * 5 | * This file is part of nPth. 6 | * 7 | * nPth is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as 9 | * published by the Free Software Foundation; either version 2.1 of 10 | * the License, or (at your option) any later version. 11 | * 12 | * nPth is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 | * the GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this program; if not, see . 19 | */ 20 | 21 | /* Changes to GNU Pth: 22 | * 23 | * Return value and arguments follow strictly the pthread format: 24 | * 25 | * - Return the error number instead of setting errno, 26 | * 27 | * - have timedlock function instead of extra event argument, 28 | * 29 | * - have trylock function instead of extra event argument. Can't mix 30 | * timed and try. 31 | * 32 | * - No _new functions. Use _init functions instead. 33 | * 34 | * - Attributes are set by specific instead of generic getter/setter 35 | * functions. 36 | * 37 | * - Offers replacement functions for sendmsg and recvmsg. 38 | */ 39 | 40 | #ifndef _NPTH_H 41 | #define _NPTH_H 42 | 43 | #include 44 | #include 45 | #@INSERT_SYS_TIME_H@ 46 | #@INSERT_TIME_H@ 47 | #include 48 | #@INSERT_SOCKLEN_T@ 49 | #@INSERT_SYS_SELECT_H@ 50 | #@INSERT_SIGNAL_H@ 51 | 52 | #include 53 | 54 | #@INSERT_NO_RWLOCK@ 55 | #ifdef __ANDROID__ 56 | #include 57 | #if __ANDROID_API__ < 9 58 | /* Android 8 and earlier are missing rwlocks. We punt to mutexes in 59 | that case. */ 60 | #define _NPTH_NO_RWLOCK 1 61 | #endif 62 | #endif 63 | 64 | #ifdef __cplusplus 65 | extern "C" { 66 | #if 0 /* (Keep Emacsens' auto-indent happy.) */ 67 | } 68 | #endif 69 | #endif 70 | 71 | /* The version and the version number of this header should match the 72 | * one of the library. Use the latter in your application to test for 73 | * minor API changes. Use npth_get_version for the lib version. */ 74 | #define NPTH_VERSION "@PACKAGE_VERSION@" 75 | #define NPTH_VERSION_NUMBER @VERSION_NUMBER@ 76 | 77 | 78 | 79 | /* Global Library Management */ 80 | 81 | #define npth_t pthread_t 82 | 83 | /* Initialize the library and convert current thread to main thread. 84 | Must be first npth function called in a process. Returns error 85 | number on error and 0 on success. */ 86 | 87 | int npth_init(void); 88 | 89 | /* Not needed. */ 90 | /* pth_kill, pth_ctrl, pth_version */ 91 | 92 | 93 | /* Thread Attribute Handling */ 94 | 95 | /* Can't do that. */ 96 | /* pth_attr_of */ 97 | 98 | #define npth_attr_t pthread_attr_t 99 | #define npth_attr_init pthread_attr_init 100 | #define npth_attr_destroy pthread_attr_destroy 101 | #define NPTH_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE 102 | #define NPTH_CREATE_DETACHED PTHREAD_CREATE_DETACHED 103 | #define npth_attr_getdetachstate pthread_attr_getdetachstate 104 | #define npth_attr_setdetachstate pthread_attr_setdetachstate 105 | int npth_getname_np (npth_t target_thread, char *buf, size_t buflen); 106 | int npth_setname_np (npth_t target_thread, const char *name); 107 | 108 | 109 | /* Thread Control */ 110 | int npth_create(npth_t *thread, const npth_attr_t *attr, 111 | void *(*start_routine) (void *), void *arg); 112 | 113 | 114 | /* The Pth version of pth_once supports passing an argument, the 115 | pthread version does not. We would have to reimplement the whole 116 | feature with a global table. Not needed. */ 117 | /* pth_once */ 118 | 119 | #define npth_self pthread_self 120 | 121 | /* No can do! */ 122 | /* pth_suspend, pth_resume */ 123 | 124 | /* Yield is considered harmful and should never be used in high-level 125 | applications. Use a condition instead to wait for a specific event 126 | to happen, or, as a last resort, use npth_usleep to back off a hard 127 | busy wait. */ 128 | /* pth_yield */ 129 | 130 | /* Not needed. */ 131 | /* pth_nap */ 132 | 133 | /* pth_wait, pth_cancel, pth_abort, pth_raise */ 134 | 135 | int npth_join(npth_t thread, void **retval); 136 | #define npth_detach pthread_detach 137 | 138 | void npth_exit(void *retval); 139 | 140 | 141 | /* Utilities */ 142 | 143 | /* pth_fdmode, pth_time, pth_timeout, pth_sfiodisc */ 144 | 145 | 146 | /* Cancellation Management */ 147 | 148 | /* Not needed. */ 149 | /* pth_cancel_state. npth_cancel_point */ 150 | 151 | 152 | /* Event Handling */ 153 | 154 | /* No equivalent in pthread. */ 155 | /* pth_event, pth_event_typeof, pth_event_extract, pth_event_concat, pth_event_isolate, 156 | pth_event_walk, pth_event_status, pth_event_free */ 157 | 158 | 159 | /* Key-Based Storage */ 160 | 161 | #define npth_key_t pthread_key_t 162 | #define npth_key_create pthread_key_create 163 | #define npth_key_delete pthread_key_delete 164 | #define npth_setspecific pthread_setspecific 165 | #define npth_getspecific pthread_getspecific 166 | 167 | 168 | /* Message Port Communication */ 169 | 170 | /* No equivalent in pthread. */ 171 | /* pth_msgport_create, pth_msgport_destroy, pth_msgport_find, 172 | pth_msgport_pending, pth_msgport_put, pth_msgport_get, 173 | pth_msgport_reply. */ 174 | 175 | 176 | /* Thread Cleanups */ 177 | 178 | /* Not needed. */ 179 | /* pth_cleanup_push, pth_cleanup_pop */ 180 | 181 | 182 | /* Process Forking */ 183 | 184 | /* POSIX only supports a global atfork handler. So, to implement 185 | per-thread handlers like in Pth, we would need to keep the data in 186 | thread local storage. But, neither pthread_self nor 187 | pthread_getspecific are standardized as async-signal-safe (what a 188 | joke!), and __thread is an ELF extension. Still, using 189 | pthread_self and pthread_getspecific is probably portable 190 | enough to implement the atfork handlers, if required. 191 | 192 | pth_fork is only required because fork() is not pth aware. fork() 193 | is pthread aware though, and already only creates a single thread 194 | in the child process. */ 195 | /* pth_atfork_push, pth_atfork_pop, pth_fork */ 196 | 197 | 198 | /* Synchronization */ 199 | 200 | #define npth_mutexattr_t pthread_mutexattr_t 201 | #define npth_mutexattr_init pthread_mutexattr_init 202 | #define npth_mutexattr_destroy pthread_mutexattr_destroy 203 | #define npth_mutexattr_settype pthread_mutexattr_settype 204 | #define npth_mutexattr_gettype pthread_mutexattr_gettype 205 | #define NPTH_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL 206 | #define NPTH_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE 207 | #define NPTH_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK 208 | #define NPTH_MUTEX_DEFAULT PTHREAD_MUTEX_DEFAULT 209 | 210 | #define npth_mutex_t pthread_mutex_t 211 | #define NPTH_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 212 | #define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP \ 213 | PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 214 | #define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP \ 215 | PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 216 | #define npth_mutex_init pthread_mutex_init 217 | #define npth_mutex_destroy pthread_mutex_destroy 218 | #define npth_mutex_trylock pthread_mutex_trylock 219 | 220 | int npth_mutex_lock(npth_mutex_t *mutex); 221 | int npth_mutex_timedlock(npth_mutex_t *mutex, const struct timespec *abstime); 222 | 223 | #define npth_mutex_unlock pthread_mutex_unlock 224 | 225 | #if @INSERT_EXPOSE_RWLOCK_API@ 226 | #ifdef _NPTH_NO_RWLOCK 227 | 228 | typedef int npth_rwlockattr_t; 229 | #define npth_rwlockattr_init(attr) 230 | #define npth_rwlockattr_destroy(attr) 231 | #define npth_rwlockattr_gettype_np(attr,kind) 232 | #define npth_rwlockattr_settype_np(attr,kind) 233 | #define NPTH_RWLOCK_PREFER_READER_NP 0 234 | #define NPTH_RWLOCK_PREFER_WRITER_NP 0 235 | #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 0 236 | #define NPTH_RWLOCK_DEFAULT_NP 0 237 | #define NPTH_RWLOCK_INITIALIZER NPTH_MUTEX_INITIALIZER 238 | #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP NPTH_MUTEX_INITIALIZER 239 | typedef npth_mutex_t npth_rwlock_t; 240 | #define npth_rwlock_init(rwlock,attr) npth_mutex_init(rwlock,0) 241 | #define npth_rwlock_destroy npth_mutex_destroy 242 | #define npth_rwlock_tryrdlock npth_mutex_trylock 243 | #define npth_rwlock_rdlock npth_mutex_lock 244 | #define npth_rwlock_trywrlock npth_mutex_trylock 245 | #define npth_rwlock_timedrdlock npth_mutex_timedlock 246 | #define npth_rwlock_wrlock npth_mutex_lock 247 | #define npth_rwlock_rdlock npth_mutex_lock 248 | #define npth_rwlock_timedwrlock npth_mutex_timedlock 249 | #define npth_rwlock_unlock npth_mutex_unlock 250 | 251 | #else /* _NPTH_NO_RWLOCK */ 252 | 253 | #define npth_rwlockattr_t pthread_rwlockattr_t 254 | #define npth_rwlockattr_init pthread_rwlockattr_init 255 | #define npth_rwlockattr_destroy pthread_rwlockattr_destroy 256 | #define npth_rwlockattr_gettype_np pthread_rwlockattr_gettype_np 257 | #define npth_rwlockattr_settype_np pthread_rwlockattr_settype_np 258 | #define NPTH_RWLOCK_PREFER_READER_NP PTHREAD_RWLOCK_PREFER_READER_NP 259 | /* Note: The prefer-writer setting is ineffective and the same as 260 | prefer-reader. This is because reader locks are specified to be 261 | recursive, but for efficiency reasons we do not keep track of which 262 | threads already hold a reader lock. For this reason, we can not 263 | prefer some reader locks over others, and thus a recursive reader 264 | lock could be stalled by a pending writer, leading to a dead 265 | lock. */ 266 | #define NPTH_RWLOCK_PREFER_WRITER_NP PTHREAD_RWLOCK_PREFER_WRITER_NP 267 | /* The non-recursive choise is a promise by the application that it 268 | does not lock the rwlock for reading recursively. In this setting, 269 | writers are preferred, but note that recursive reader locking is 270 | prone to deadlocks in that case. */ 271 | #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP \ 272 | PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 273 | #define NPTH_RWLOCK_DEFAULT_NP PTHREAD_RWLOCK_DEFAULT_NP 274 | #define NPTH_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER 275 | #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \ 276 | PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP 277 | 278 | typedef pthread_rwlock_t npth_rwlock_t; 279 | #define npth_rwlock_init pthread_rwlock_init 280 | #define npth_rwlock_destroy pthread_rwlock_destroy 281 | #define npth_rwlock_tryrdlock pthread_rwlock_tryrdlock 282 | 283 | int npth_rwlock_rdlock (npth_rwlock_t *rwlock); 284 | 285 | int npth_rwlock_timedrdlock (npth_rwlock_t *rwlock, 286 | const struct timespec *abstime); 287 | 288 | #define npth_rwlock_trywrlock pthread_rwlock_trywrlock 289 | int npth_rwlock_wrlock (npth_rwlock_t *rwlock); 290 | int npth_rwlock_timedwrlock (npth_rwlock_t *rwlock, 291 | const struct timespec *abstime); 292 | #define npth_rwlock_unlock pthread_rwlock_unlock 293 | 294 | #endif /* !_NPTH_NO_RWLOCK */ 295 | #endif 296 | 297 | 298 | typedef pthread_cond_t npth_cond_t; 299 | #define NPTH_COND_INITIALIZER PTHREAD_COND_INITIALIZER 300 | /* For now, we don't support any cond attributes. */ 301 | #define npth_cond_init pthread_cond_init 302 | #define npth_cond_broadcast pthread_cond_broadcast 303 | #define npth_cond_signal pthread_cond_signal 304 | #define npth_cond_destroy pthread_cond_destroy 305 | int npth_cond_wait(npth_cond_t *cond, npth_mutex_t *mutex); 306 | int npth_cond_timedwait(npth_cond_t *cond, npth_mutex_t *mutex, 307 | const struct timespec *abstime); 308 | 309 | /* Not needed. */ 310 | 311 | /* pth_barrier_t, pth_barrier_init, pth_barrier_reach */ 312 | 313 | 314 | /* User-Space Context */ 315 | 316 | /* Can not be implemented. */ 317 | /* pth_uctx_create, pth_uctx_make, pth_uctx_switch, pth_uctx_destroy */ 318 | 319 | 320 | /* Generalized POSIX Replacement API */ 321 | 322 | /* In general, we can not support these easily. */ 323 | /* pth_sigwait_ev, pth_accept_ev, pth_connect_ev, pth_select_ev, 324 | pth_poll_ev, pth_read_ev, pth_readv_ev, pth_write_ev, 325 | pth_writev_ev, pth_recv_ev, pth_recvfrom_ev, pth_send_ev, 326 | pth_sendto_ev */ 327 | 328 | 329 | /* Standard POSIX Replacement API */ 330 | 331 | /* We will provide a more specific way to handle signals. */ 332 | /* pth_sigmask, pth_sigwait */ 333 | 334 | /* Not needed. */ 335 | /* pth_nanosleep, pth_system, pth_readv, pth_writev, pth_poll, 336 | pth_recv, pth_send, pth_recvfrom, pth_sendto */ 337 | 338 | int npth_usleep(unsigned int usec); 339 | unsigned int npth_sleep(unsigned int sec); 340 | 341 | pid_t npth_waitpid(pid_t pid, int *status, int options); 342 | int npth_system(const char *cmd); 343 | #define npth_sigmask pthread_sigmask 344 | int npth_sigwait(const sigset_t *set, int *sig); 345 | 346 | int npth_connect(int s, const struct sockaddr *addr, _npth_socklen_t addrlen); 347 | int npth_accept(int s, struct sockaddr *addr, _npth_socklen_t *addrlen); 348 | int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, 349 | struct timeval *timeout); 350 | int npth_pselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, 351 | const struct timespec *timeout, const sigset_t *sigmask); 352 | ssize_t npth_read(int fd, void *buf, size_t nbytes); 353 | ssize_t npth_write(int fd, const void *buf, size_t nbytes); 354 | int npth_recvmsg (int fd, struct msghdr *msg, int flags); 355 | int npth_sendmsg (int fd, const struct msghdr *msg, int flags); 356 | 357 | struct pollfd; 358 | int npth_poll (struct pollfd *fds, unsigned long nfds, int timeout); 359 | int npth_ppoll (struct pollfd *fds, unsigned long nfds, 360 | const struct timespec *timeout, const sigset_t *sigmask); 361 | 362 | /* For anything not covered here, you can enter/leave manually at your 363 | own risk. */ 364 | void npth_unprotect (void); 365 | void npth_protect (void); 366 | 367 | /* If you run into problems with the above calls, this function can be 368 | * used to examine in which state nPth is. */ 369 | int npth_is_protected (void); 370 | 371 | /* Return the version of the library. WHAT is in general NULL. */ 372 | const char *npth_get_version (const char *what); 373 | 374 | 375 | /* Because the timed functions work on timespec, we provide a clock 376 | interface for convenience and portability. */ 377 | int npth_clock_gettime (struct timespec *tp); 378 | 379 | /* CMP may be ==, < or >. Do not use <= or >=. */ 380 | #define npth_timercmp(t1, t2, cmp) \ 381 | (((t1)->tv_sec == (t2)->tv_sec) ? \ 382 | ((t1)->tv_nsec cmp (t2)->tv_nsec) : \ 383 | ((t1)->tv_sec cmp (t2)->tv_sec)) 384 | #define npth_timeradd(t1, t2, result) \ 385 | do { \ 386 | (result)->tv_sec = (t1)->tv_sec + (t2)->tv_sec; \ 387 | (result)->tv_nsec = (t1)->tv_nsec + (t2)->tv_nsec; \ 388 | if ((result)->tv_nsec >= 1000000000) \ 389 | { \ 390 | ++(result)->tv_sec; \ 391 | (result)->tv_nsec -= 1000000000; \ 392 | } \ 393 | } while (0) 394 | #define npth_timersub(t1, t2, result) \ 395 | do { \ 396 | (result)->tv_sec = (t1)->tv_sec - (t2)->tv_sec; \ 397 | (result)->tv_nsec = (t1)->tv_nsec - (t2)->tv_nsec; \ 398 | if ((result)->tv_nsec < 0) { \ 399 | --(result)->tv_sec; \ 400 | (result)->tv_nsec += 1000000000; \ 401 | } \ 402 | } while (0) 403 | 404 | 405 | 406 | /* This is a support interface to make it easier to handle signals. 407 | * 408 | * The interfaces here support one (and only one) thread (here called 409 | * "main thread") in the application to monitor several signals while 410 | * selecting on filedescriptors. 411 | * 412 | * First, the main thread should call npth_sigev_init. This 413 | * initializes some global data structures used to record interesting 414 | * and pending signals. 415 | * 416 | * Then, the main thread should call npth_sigev_add for every signal 417 | * it is interested in observing, and finally npth_sigev_fini. This 418 | * will block the signal in the main threads sigmask. Note that these 419 | * signals should also be blocked in all other threads. Since they 420 | * are blocked in the main thread after calling npth_sigev_add, it is 421 | * recommended to call npth_sigev_add in the main thread before 422 | * creating any threads. 423 | * 424 | * The function npth_sigev_sigmask is a convenient function that 425 | * returns the sigmask of the thread at time of npth_sigev_init, but 426 | * with all registered signals unblocked. It is recommended to do all 427 | * other changes to the main thread's sigmask before calling 428 | * npth_sigev_init, so that the return value of npth_sigev_sigmask can 429 | * be used in the npth_pselect invocation. 430 | * 431 | * In any case, the main thread should invoke npth_pselect with a 432 | * sigmask that has all signals that should be monitored unblocked. 433 | * 434 | * After npth_pselect returns, npth_sigev_get_pending can be called in 435 | * a loop until it returns 0 to iterate over the list of pending 436 | * signals. Each time a signal is returned by that function, its 437 | * status is reset to non-pending. 438 | */ 439 | 440 | /* Start setting up signal event handling. */ 441 | void npth_sigev_init (void); 442 | 443 | /* Add signal SIGNUM to the list of watched signals. */ 444 | void npth_sigev_add (int signum); 445 | 446 | /* Finish the list of watched signals. This starts to block them, 447 | too. */ 448 | void npth_sigev_fini (void); 449 | 450 | /* Get the sigmask as needed for pselect. */ 451 | sigset_t *npth_sigev_sigmask (void); 452 | 453 | /* Return the next signal event that occured. Returns if none are 454 | left, 1 on success. */ 455 | int npth_sigev_get_pending (int *r_signum); 456 | 457 | 458 | #if 0 /* (Keep Emacsens' auto-indent happy.) */ 459 | { 460 | #endif 461 | #ifdef __cplusplus 462 | } 463 | #endif 464 | #endif /*_NPTH_H*/ 465 | /* 466 | @emacs_local_vars_begin@ 467 | @emacs_local_vars_read_only@ 468 | @emacs_local_vars_end@ 469 | */ 470 | -------------------------------------------------------------------------------- /src/npth.c: -------------------------------------------------------------------------------- 1 | /* npth.c - a lightweight implementation of pth over pthread. 2 | * Copyright (C) 2011 g10 Code GmbH 3 | * 4 | * This file is part of nPth. 5 | * 6 | * nPth is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation; either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * nPth is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 | * the GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this program; if not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | /* nPth uses the API of sem_init, sem_post, and sem_wait. */ 34 | #ifdef HAVE_LIB_DISPATCH 35 | /* This glue code is for macOS which does not have full implementation 36 | of POSIX semaphore. On macOS, using semaphore in Grand Central 37 | Dispatch library is better than using the partial implementation of 38 | POSIX semaphore where sem_init doesn't work well. 39 | */ 40 | # include 41 | typedef dispatch_semaphore_t sem_t; 42 | 43 | static int 44 | sem_init (sem_t *sem, int is_shared, unsigned int value) 45 | { 46 | (void)is_shared; 47 | if ((*sem = dispatch_semaphore_create (value)) == NULL) 48 | return -1; 49 | else 50 | return 0; 51 | } 52 | 53 | static int 54 | sem_post (sem_t *sem) 55 | { 56 | dispatch_semaphore_signal (*sem); 57 | return 0; 58 | } 59 | 60 | static int 61 | sem_wait (sem_t *sem) 62 | { 63 | dispatch_semaphore_wait (*sem, DISPATCH_TIME_FOREVER); 64 | return 0; 65 | } 66 | #elif HAVE_NO_POSIX_SEMAPHORE 67 | /* Fallback implementation without POSIX semaphore, 68 | for a system like MacOS Tiger and Leopard. */ 69 | typedef struct { 70 | pthread_mutex_t mutex; 71 | pthread_cond_t cond; 72 | unsigned int value; 73 | } sem_t; 74 | 75 | static int 76 | sem_init (sem_t *sem, int is_shared, unsigned int value) 77 | { 78 | int r; 79 | 80 | (void)is_shared; /* Not supported. */ 81 | r = pthread_mutex_init (&sem->mutex, NULL); 82 | if (r) 83 | return r; 84 | r = pthread_cond_init (&sem->cond, NULL); 85 | if (r) 86 | return r; 87 | sem->value = value; 88 | return 0; 89 | } 90 | 91 | static int 92 | sem_post (sem_t *sem) 93 | { 94 | int r; 95 | 96 | r = pthread_mutex_lock (&sem->mutex); 97 | if (r) 98 | return r; 99 | 100 | sem->value++; 101 | pthread_cond_signal (&sem->cond); 102 | 103 | r = pthread_mutex_unlock (&sem->mutex); 104 | if (r) 105 | return r; 106 | return 0; 107 | } 108 | 109 | static int 110 | sem_wait (sem_t *sem) 111 | { 112 | int r; 113 | 114 | r = pthread_mutex_lock (&sem->mutex); 115 | if (r) 116 | return r; 117 | 118 | while (sem->value == 0) 119 | pthread_cond_wait (&sem->cond, &sem->mutex); 120 | sem->value--; 121 | 122 | r = pthread_mutex_unlock (&sem->mutex); 123 | if (r) 124 | return r; 125 | return 0; 126 | } 127 | #else 128 | /* Use POSIX semaphore when available. */ 129 | # include 130 | #endif 131 | 132 | #ifdef HAVE_UNISTD_H 133 | # include 134 | #endif 135 | #ifndef HAVE_PSELECT 136 | # include 137 | #endif 138 | #ifdef HAVE_POLL_H 139 | #include 140 | #endif 141 | 142 | #include "npth.h" 143 | 144 | 145 | /* The global lock that excludes all threads but one. This is a 146 | semaphore, because these can be safely used in a library even if 147 | the application or other libraries call fork(), including from a 148 | signal handler. sem_post is async-signal-safe. (The reason a 149 | semaphore is safe and a mutex is not safe is that a mutex has an 150 | owner, while a semaphore does not.) We init sceptre to a static 151 | buffer for use by sem_init; in case sem_open is used instead 152 | SCEPTRE will changed to the value returned by sem_open. 153 | GOT_SCEPTRE is a flag used for debugging to tell wether we hold 154 | SCEPTRE. */ 155 | static sem_t sceptre_buffer; 156 | static sem_t *sceptre = &sceptre_buffer; 157 | static int got_sceptre; 158 | 159 | /* The main thread is the active thread at the time pth_init was 160 | called. As of now it is only useful for debugging. The volatile 161 | make sure the compiler does not eliminate this set but not used 162 | variable. */ 163 | static volatile pthread_t main_thread; 164 | 165 | /* This flag is set as soon as npth_init has been called or if any 166 | * thread has been created. It will never be cleared again. The only 167 | * purpose is to make npth_protect and npth_unprotect more robust in 168 | * that they can be shortcut when npth_init has not yet been called. 169 | * This is important for libraries which want to support nPth by using 170 | * those two functions but may have be initialized before pPth. */ 171 | static int initialized_or_any_threads; 172 | 173 | /* Systems that don't have pthread_mutex_timedlock get a busy wait 174 | implementation that probes the lock every BUSY_WAIT_INTERVAL 175 | milliseconds. */ 176 | #define BUSY_WAIT_INTERVAL 200 177 | 178 | typedef int (*trylock_func_t) (void *); 179 | 180 | #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK 181 | #define REQUIRE_THE_BUSY_WAIT_FOR_IMPLEMENTATION 1 182 | #endif 183 | 184 | #if !HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK && HAVE_PTHREAD_RWLOCK_TRYRDLOCK 185 | #define REQUIRE_THE_BUSY_WAIT_FOR_IMPLEMENTATION 1 186 | #endif 187 | 188 | #if !HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK && HAVE_PTHREAD_RWLOCK_TRYWRLOCK 189 | #define REQUIRE_THE_BUSY_WAIT_FOR_IMPLEMENTATION 1 190 | #endif 191 | 192 | #if REQUIRE_THE_BUSY_WAIT_FOR_IMPLEMENTATION 193 | static int 194 | busy_wait_for (trylock_func_t trylock, void *lock, 195 | const struct timespec *abstime) 196 | { 197 | int err; 198 | 199 | /* This is not great, but better than nothing. Only works for locks 200 | which are mostly uncontested. Provides absolutely no fairness at 201 | all. Creates many wake-ups. */ 202 | while (1) 203 | { 204 | struct timespec ts; 205 | err = npth_clock_gettime (&ts); 206 | if (err < 0) 207 | { 208 | /* Just for safety make sure we return some error. */ 209 | err = errno ? errno : EINVAL; 210 | break; 211 | } 212 | 213 | if (npth_timercmp (abstime, &ts, <)) 214 | { 215 | err = ETIMEDOUT; 216 | break; 217 | } 218 | 219 | err = (*trylock) (lock); 220 | if (err != EBUSY) 221 | break; 222 | 223 | /* Try again after waiting a bit. We could calculate the 224 | maximum wait time from ts and abstime, but we don't 225 | bother, as our granularity is pretty fine. */ 226 | usleep (BUSY_WAIT_INTERVAL * 1000); 227 | } 228 | 229 | return err; 230 | } 231 | #endif 232 | 233 | static void 234 | enter_npth (void) 235 | { 236 | int res; 237 | 238 | got_sceptre = 0; 239 | res = sem_post (sceptre); 240 | assert (res == 0); 241 | } 242 | 243 | 244 | static void 245 | leave_npth (void) 246 | { 247 | int res; 248 | int save_errno = errno; 249 | 250 | do { 251 | res = sem_wait (sceptre); 252 | } while (res < 0 && errno == EINTR); 253 | 254 | assert (!res); 255 | got_sceptre = 1; 256 | errno = save_errno; 257 | } 258 | 259 | #define ENTER() enter_npth () 260 | #define LEAVE() leave_npth () 261 | 262 | 263 | int 264 | npth_init (void) 265 | { 266 | int res; 267 | 268 | main_thread = pthread_self(); 269 | 270 | /* Track that we have been initialized. */ 271 | initialized_or_any_threads |= 1; 272 | 273 | /* Better reset ERRNO so that we know that it has been set by 274 | sem_init. */ 275 | errno = 0; 276 | 277 | /* The semaphore is not shared and binary. */ 278 | res = sem_init (sceptre, 0, 1); 279 | /* There are some versions of operating systems which have sem_init 280 | symbol defined but the call actually returns ENOSYS at runtime. 281 | We know this problem for older versions of AIX (<= 4.3.3) and 282 | macOS. For macOS, we use semaphore in Grand Central Dispatch 283 | library, so ENOSYS doesn't happen. We only support AIX >= 5.2, 284 | where sem_init is supported. 285 | */ 286 | if (res < 0) 287 | { 288 | /* POSIX.1-2001 defines the semaphore interface but does not 289 | specify the return value for success. Thus we better 290 | bail out on error only on a POSIX.1-2008 system. */ 291 | #if _POSIX_C_SOURCE >= 200809L 292 | return errno; 293 | #endif 294 | } 295 | 296 | LEAVE(); 297 | return 0; 298 | } 299 | 300 | 301 | int 302 | npth_getname_np (npth_t target_thread, char *buf, size_t buflen) 303 | { 304 | #ifdef HAVE_PTHREAD_GETNAME_NP 305 | return pthread_getname_np (target_thread, buf, buflen); 306 | #else 307 | (void)target_thread; 308 | (void)buf; 309 | (void)buflen; 310 | return ENOSYS; 311 | #endif 312 | } 313 | 314 | 315 | int 316 | npth_setname_np (npth_t target_thread, const char *name) 317 | { 318 | #ifdef HAVE_PTHREAD_SETNAME_NP 319 | #ifdef __NetBSD__ 320 | return pthread_setname_np (target_thread, "%s", (void*) name); 321 | #else 322 | #ifdef __APPLE__ 323 | if (target_thread == npth_self ()) 324 | return pthread_setname_np (name); 325 | else 326 | return ENOTSUP; 327 | #else 328 | return pthread_setname_np (target_thread, name); 329 | #endif 330 | #endif 331 | #else 332 | (void)target_thread; 333 | (void)name; 334 | return ENOSYS; 335 | #endif 336 | } 337 | 338 | 339 | 340 | struct startup_s 341 | { 342 | void *(*start_routine) (void *); 343 | void *arg; 344 | }; 345 | 346 | 347 | static void * 348 | thread_start (void *startup_arg) 349 | { 350 | struct startup_s *startup = startup_arg; 351 | void *(*start_routine) (void *); 352 | void *arg; 353 | void *result; 354 | 355 | start_routine = startup->start_routine; 356 | arg = startup->arg; 357 | free (startup); 358 | 359 | LEAVE(); 360 | result = (*start_routine) (arg); 361 | /* Note: instead of returning here, we might end up in 362 | npth_exit() instead. */ 363 | ENTER(); 364 | 365 | return result; 366 | } 367 | 368 | 369 | int 370 | npth_create (npth_t *thread, const npth_attr_t *attr, 371 | void *(*start_routine) (void *), void *arg) 372 | { 373 | int err; 374 | struct startup_s *startup; 375 | 376 | startup = malloc (sizeof (*startup)); 377 | if (!startup) 378 | return errno; 379 | 380 | initialized_or_any_threads |= 2; 381 | 382 | startup->start_routine = start_routine; 383 | startup->arg = arg; 384 | err = pthread_create (thread, attr, thread_start, startup); 385 | if (err) 386 | { 387 | free (startup); 388 | return err; 389 | } 390 | 391 | /* Memory is released in thread_start. */ 392 | return 0; 393 | } 394 | 395 | 396 | int 397 | npth_join (npth_t thread, void **retval) 398 | { 399 | int err; 400 | 401 | #ifdef HAVE_PTHREAD_TRYJOIN_NP 402 | /* No need to allow competing threads to enter when we can get the 403 | lock immediately. pthread_tryjoin_np is a GNU extension. */ 404 | err = pthread_tryjoin_np (thread, retval); 405 | if (err != EBUSY) 406 | return err; 407 | #endif /*HAVE_PTHREAD_TRYJOIN_NP*/ 408 | 409 | ENTER(); 410 | err = pthread_join (thread, retval); 411 | LEAVE(); 412 | return err; 413 | } 414 | 415 | 416 | void 417 | npth_exit (void *retval) 418 | { 419 | ENTER(); 420 | pthread_exit (retval); 421 | /* Never reached. But just in case pthread_exit does return... */ 422 | LEAVE(); 423 | } 424 | 425 | 426 | int 427 | npth_mutex_lock (npth_mutex_t *mutex) 428 | { 429 | int err; 430 | 431 | /* No need to allow competing threads to enter when we can get the 432 | lock immediately. */ 433 | err = pthread_mutex_trylock (mutex); 434 | if (err != EBUSY) 435 | return err; 436 | 437 | ENTER(); 438 | err = pthread_mutex_lock (mutex); 439 | LEAVE(); 440 | return err; 441 | } 442 | 443 | 444 | int 445 | npth_mutex_timedlock (npth_mutex_t *mutex, const struct timespec *abstime) 446 | { 447 | int err; 448 | 449 | /* No need to allow competing threads to enter when we can get the 450 | lock immediately. */ 451 | err = pthread_mutex_trylock (mutex); 452 | if (err != EBUSY) 453 | return err; 454 | 455 | ENTER(); 456 | #if HAVE_PTHREAD_MUTEX_TIMEDLOCK 457 | err = pthread_mutex_timedlock (mutex, abstime); 458 | #else 459 | err = busy_wait_for ((trylock_func_t) pthread_mutex_trylock, mutex, abstime); 460 | #endif 461 | LEAVE(); 462 | return err; 463 | } 464 | 465 | 466 | #ifndef _NPTH_NO_RWLOCK 467 | int 468 | npth_rwlock_rdlock (npth_rwlock_t *rwlock) 469 | { 470 | int err; 471 | 472 | #ifdef HAVE_PTHREAD_RWLOCK_TRYRDLOCK 473 | /* No need to allow competing threads to enter when we can get the 474 | lock immediately. */ 475 | err = pthread_rwlock_tryrdlock (rwlock); 476 | if (err != EBUSY) 477 | return err; 478 | #endif 479 | 480 | ENTER(); 481 | err = pthread_rwlock_rdlock (rwlock); 482 | LEAVE(); 483 | return err; 484 | } 485 | 486 | 487 | int 488 | npth_rwlock_timedrdlock (npth_rwlock_t *rwlock, const struct timespec *abstime) 489 | { 490 | int err; 491 | 492 | #ifdef HAVE_PTHREAD_RWLOCK_TRYRDLOCK 493 | /* No need to allow competing threads to enter when we can get the 494 | lock immediately. */ 495 | err = pthread_rwlock_tryrdlock (rwlock); 496 | if (err != EBUSY) 497 | return err; 498 | #endif 499 | 500 | ENTER(); 501 | #if HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK 502 | err = pthread_rwlock_timedrdlock (rwlock, abstime); 503 | #elif HAVE_PTHREAD_RWLOCK_TRYRDLOCK 504 | err = busy_wait_for ((trylock_func_t) pthread_rwlock_tryrdlock, rwlock, 505 | abstime); 506 | #else 507 | err = ENOSYS; 508 | #endif 509 | LEAVE(); 510 | return err; 511 | } 512 | 513 | 514 | int 515 | npth_rwlock_wrlock (npth_rwlock_t *rwlock) 516 | { 517 | int err; 518 | 519 | #ifdef HAVE_PTHREAD_RWLOCK_TRYWRLOCK 520 | /* No need to allow competing threads to enter when we can get the 521 | lock immediately. */ 522 | err = pthread_rwlock_trywrlock (rwlock); 523 | if (err != EBUSY) 524 | return err; 525 | #endif 526 | 527 | ENTER(); 528 | err = pthread_rwlock_wrlock (rwlock); 529 | LEAVE(); 530 | return err; 531 | } 532 | 533 | 534 | int 535 | npth_rwlock_timedwrlock (npth_rwlock_t *rwlock, const struct timespec *abstime) 536 | { 537 | int err; 538 | 539 | #ifdef HAVE_PTHREAD_RWLOCK_TRYWRLOCK 540 | /* No need to allow competing threads to enter when we can get the 541 | lock immediately. */ 542 | err = pthread_rwlock_trywrlock (rwlock); 543 | if (err != EBUSY) 544 | return err; 545 | #endif 546 | 547 | ENTER(); 548 | #if HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK 549 | err = pthread_rwlock_timedwrlock (rwlock, abstime); 550 | #elif HAVE_PTHREAD_RWLOCK_TRYWRLOCK 551 | err = busy_wait_for ((trylock_func_t) pthread_rwlock_trywrlock, rwlock, 552 | abstime); 553 | #else 554 | err = ENOSYS; 555 | #endif 556 | LEAVE(); 557 | return err; 558 | } 559 | #endif 560 | 561 | 562 | int 563 | npth_cond_wait (npth_cond_t *cond, npth_mutex_t *mutex) 564 | { 565 | int err; 566 | 567 | ENTER(); 568 | err = pthread_cond_wait (cond, mutex); 569 | LEAVE(); 570 | return err; 571 | } 572 | 573 | 574 | int 575 | npth_cond_timedwait (npth_cond_t *cond, npth_mutex_t *mutex, 576 | const struct timespec *abstime) 577 | { 578 | int err; 579 | 580 | ENTER(); 581 | err = pthread_cond_timedwait (cond, mutex, abstime); 582 | LEAVE(); 583 | return err; 584 | } 585 | 586 | 587 | /* Standard POSIX Replacement API */ 588 | 589 | int 590 | npth_usleep(unsigned int usec) 591 | { 592 | int res; 593 | 594 | ENTER(); 595 | res = usleep(usec); 596 | LEAVE(); 597 | return res; 598 | } 599 | 600 | 601 | unsigned int 602 | npth_sleep(unsigned int sec) 603 | { 604 | unsigned res; 605 | 606 | ENTER(); 607 | res = sleep(sec); 608 | LEAVE(); 609 | return res; 610 | } 611 | 612 | 613 | int 614 | npth_system(const char *cmd) 615 | { 616 | int res; 617 | 618 | ENTER(); 619 | res = system(cmd); 620 | LEAVE(); 621 | return res; 622 | } 623 | 624 | 625 | pid_t 626 | npth_waitpid(pid_t pid, int *status, int options) 627 | { 628 | pid_t res; 629 | 630 | ENTER(); 631 | res = waitpid(pid,status, options); 632 | LEAVE(); 633 | return res; 634 | } 635 | 636 | 637 | int 638 | npth_connect(int s, const struct sockaddr *addr, socklen_t addrlen) 639 | { 640 | int res; 641 | 642 | ENTER(); 643 | res = connect(s, addr, addrlen); 644 | LEAVE(); 645 | return res; 646 | } 647 | 648 | 649 | int 650 | npth_accept(int s, struct sockaddr *addr, socklen_t *addrlen) 651 | { 652 | int res; 653 | 654 | ENTER(); 655 | res = accept(s, addr, addrlen); 656 | LEAVE(); 657 | return res; 658 | } 659 | 660 | 661 | int 662 | npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, 663 | struct timeval *timeout) 664 | { 665 | int res; 666 | 667 | ENTER(); 668 | res = select(nfd, rfds, wfds, efds, timeout); 669 | LEAVE(); 670 | return res; 671 | } 672 | 673 | 674 | int 675 | npth_pselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, 676 | const struct timespec *timeout, const sigset_t *sigmask) 677 | { 678 | int res; 679 | 680 | ENTER(); 681 | #ifdef HAVE_PSELECT 682 | res = pselect (nfd, rfds, wfds, efds, timeout, sigmask); 683 | #else /*!HAVE_PSELECT*/ 684 | { 685 | /* A better emulation of pselect would be to create a pipe, wait 686 | in the select for one end and have a signal handler write to 687 | the other end. However, this is non-trivial to implement and 688 | thus we only print a compile time warning. */ 689 | # ifdef __GNUC__ 690 | # warning Using a non race free pselect emulation. 691 | # endif 692 | 693 | struct timeval t, *tp; 694 | 695 | tp = NULL; 696 | if (!timeout) 697 | ; 698 | else if (timeout->tv_nsec >= 0 && timeout->tv_nsec < 1000000000) 699 | { 700 | t.tv_sec = timeout->tv_sec; 701 | t.tv_usec = (timeout->tv_nsec + 999) / 1000; 702 | tp = &t; 703 | } 704 | else 705 | { 706 | errno = EINVAL; 707 | res = -1; 708 | goto leave; 709 | } 710 | 711 | if (sigmask) 712 | { 713 | int save_errno; 714 | sigset_t savemask; 715 | 716 | pthread_sigmask (SIG_SETMASK, sigmask, &savemask); 717 | res = select (nfd, rfds, wfds, efds, tp); 718 | save_errno = errno; 719 | pthread_sigmask (SIG_SETMASK, &savemask, NULL); 720 | errno = save_errno; 721 | } 722 | else 723 | res = select (nfd, rfds, wfds, efds, tp); 724 | 725 | leave: 726 | ; 727 | } 728 | #endif /*!HAVE_PSELECT*/ 729 | LEAVE(); 730 | return res; 731 | } 732 | 733 | 734 | int 735 | npth_poll (struct pollfd *fds, unsigned long nfds, int timeout) 736 | { 737 | int res; 738 | 739 | ENTER(); 740 | res = poll (fds, (nfds_t)nfds, timeout); 741 | LEAVE(); 742 | return res; 743 | } 744 | 745 | 746 | int 747 | npth_ppoll (struct pollfd *fds, unsigned long nfds, 748 | const struct timespec *timeout, const sigset_t *sigmask) 749 | { 750 | int res; 751 | 752 | ENTER(); 753 | #ifdef HAVE_PPOLL 754 | res = ppoll (fds, (nfds_t)nfds, timeout, sigmask); 755 | #else /*!HAVE_PPOLL*/ 756 | { 757 | # ifdef __GNUC__ 758 | # warning Using a non race free ppoll emulation. 759 | # endif 760 | 761 | int t; 762 | 763 | if (!timeout) 764 | t = -1; 765 | else if (timeout->tv_nsec >= 0 && timeout->tv_nsec < 1000000000) 766 | t = timeout->tv_sec * 1000 + (timeout->tv_nsec + 999999) / 1000000; 767 | else 768 | { 769 | errno = EINVAL; 770 | res = -1; 771 | goto leave; 772 | } 773 | 774 | if (sigmask) 775 | { 776 | int save_errno; 777 | sigset_t savemask; 778 | 779 | pthread_sigmask (SIG_SETMASK, sigmask, &savemask); 780 | res = poll (fds, (nfds_t)nfds, t); 781 | save_errno = errno; 782 | pthread_sigmask (SIG_SETMASK, &savemask, NULL); 783 | errno = save_errno; 784 | } 785 | else 786 | res = poll (fds, (nfds_t)nfds, t); 787 | 788 | leave: 789 | ; 790 | } 791 | #endif 792 | LEAVE(); 793 | return res; 794 | } 795 | 796 | 797 | ssize_t 798 | npth_read(int fd, void *buf, size_t nbytes) 799 | { 800 | ssize_t res; 801 | 802 | ENTER(); 803 | res = read(fd, buf, nbytes); 804 | LEAVE(); 805 | return res; 806 | } 807 | 808 | 809 | ssize_t 810 | npth_write(int fd, const void *buf, size_t nbytes) 811 | { 812 | ssize_t res; 813 | 814 | ENTER(); 815 | res = write(fd, buf, nbytes); 816 | LEAVE(); 817 | return res; 818 | } 819 | 820 | 821 | int 822 | npth_recvmsg (int fd, struct msghdr *msg, int flags) 823 | { 824 | int res; 825 | 826 | ENTER(); 827 | res = recvmsg (fd, msg, flags); 828 | LEAVE(); 829 | return res; 830 | } 831 | 832 | 833 | int 834 | npth_sendmsg (int fd, const struct msghdr *msg, int flags) 835 | { 836 | int res; 837 | 838 | ENTER(); 839 | res = sendmsg (fd, msg, flags); 840 | LEAVE(); 841 | return res; 842 | } 843 | 844 | 845 | void 846 | npth_unprotect (void) 847 | { 848 | /* If we are not initialized we may not access the semaphore and 849 | * thus we shortcut it. Note that in this case the unprotect/protect 850 | * is not needed. For failsafe reasons if an nPth thread has ever 851 | * been created but nPth has accidentally not initialized we do not 852 | * shortcut so that a stack backtrace (due to the access of the 853 | * uninitialized semaphore) is more expressive. */ 854 | if (initialized_or_any_threads) 855 | ENTER(); 856 | } 857 | 858 | 859 | void 860 | npth_protect (void) 861 | { 862 | /* See npth_unprotect for commentary. */ 863 | if (initialized_or_any_threads) 864 | LEAVE(); 865 | } 866 | 867 | 868 | int 869 | npth_is_protected (void) 870 | { 871 | return got_sceptre; 872 | } 873 | 874 | 875 | int 876 | npth_clock_gettime (struct timespec *ts) 877 | { 878 | #if defined(CLOCK_REALTIME) && HAVE_CLOCK_GETTIME 879 | return clock_gettime (CLOCK_REALTIME, ts); 880 | #elif HAVE_GETTIMEOFDAY 881 | { 882 | struct timeval tv; 883 | 884 | if (gettimeofday (&tv, NULL)) 885 | return -1; 886 | ts->tv_sec = tv.tv_sec; 887 | ts->tv_nsec = tv.tv_usec * 1000; 888 | return 0; 889 | } 890 | #else 891 | /* FIXME: fall back on time() with seconds resolution. */ 892 | # error clock_gettime not available - please provide a fallback. 893 | #endif 894 | } 895 | 896 | 897 | #include "getversion.c" 898 | /* end of file */ 899 | -------------------------------------------------------------------------------- /COPYING.LIB: -------------------------------------------------------------------------------- 1 | 2 | GNU LESSER GENERAL PUBLIC LICENSE 3 | Version 2.1, February 1999 4 | 5 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 6 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 7 | Everyone is permitted to copy and distribute verbatim copies 8 | of this license document, but changing it is not allowed. 9 | 10 | [This is the first released version of the Lesser GPL. It also counts 11 | as the successor of the GNU Library Public License, version 2, hence 12 | the version number 2.1.] 13 | 14 | Preamble 15 | 16 | The licenses for most software are designed to take away your 17 | freedom to share and change it. By contrast, the GNU General Public 18 | Licenses are intended to guarantee your freedom to share and change 19 | free software--to make sure the software is free for all its users. 20 | 21 | This license, the Lesser General Public License, applies to some 22 | specially designated software packages--typically libraries--of the 23 | Free Software Foundation and other authors who decide to use it. You 24 | can use it too, but we suggest you first think carefully about whether 25 | this license or the ordinary General Public License is the better 26 | strategy to use in any particular case, based on the explanations 27 | below. 28 | 29 | When we speak of free software, we are referring to freedom of use, 30 | not price. Our General Public Licenses are designed to make sure that 31 | you have the freedom to distribute copies of free software (and charge 32 | for this service if you wish); that you receive source code or can get 33 | it if you want it; that you can change the software and use pieces of 34 | it in new free programs; and that you are informed that you can do 35 | these things. 36 | 37 | To protect your rights, we need to make restrictions that forbid 38 | distributors to deny you these rights or to ask you to surrender these 39 | rights. These restrictions translate to certain responsibilities for 40 | you if you distribute copies of the library or if you modify it. 41 | 42 | For example, if you distribute copies of the library, whether gratis 43 | or for a fee, you must give the recipients all the rights that we gave 44 | you. You must make sure that they, too, receive or can get the source 45 | code. If you link other code with the library, you must provide 46 | complete object files to the recipients, so that they can relink them 47 | with the library after making changes to the library and recompiling 48 | it. And you must show them these terms so they know their rights. 49 | 50 | We protect your rights with a two-step method: (1) we copyright the 51 | library, and (2) we offer you this license, which gives you legal 52 | permission to copy, distribute and/or modify the library. 53 | 54 | To protect each distributor, we want to make it very clear that 55 | there is no warranty for the free library. Also, if the library is 56 | modified by someone else and passed on, the recipients should know 57 | that what they have is not the original version, so that the original 58 | author's reputation will not be affected by problems that might be 59 | introduced by others. 60 | 61 | Finally, software patents pose a constant threat to the existence of 62 | any free program. We wish to make sure that a company cannot 63 | effectively restrict the users of a free program by obtaining a 64 | restrictive license from a patent holder. Therefore, we insist that 65 | any patent license obtained for a version of the library must be 66 | consistent with the full freedom of use specified in this license. 67 | 68 | Most GNU software, including some libraries, is covered by the 69 | ordinary GNU General Public License. This license, the GNU Lesser 70 | General Public License, applies to certain designated libraries, and 71 | is quite different from the ordinary General Public License. We use 72 | this license for certain libraries in order to permit linking those 73 | libraries into non-free programs. 74 | 75 | When a program is linked with a library, whether statically or using 76 | a shared library, the combination of the two is legally speaking a 77 | combined work, a derivative of the original library. The ordinary 78 | General Public License therefore permits such linking only if the 79 | entire combination fits its criteria of freedom. The Lesser General 80 | Public License permits more lax criteria for linking other code with 81 | the library. 82 | 83 | We call this license the "Lesser" General Public License because it 84 | does Less to protect the user's freedom than the ordinary General 85 | Public License. It also provides other free software developers Less 86 | of an advantage over competing non-free programs. These disadvantages 87 | are the reason we use the ordinary General Public License for many 88 | libraries. However, the Lesser license provides advantages in certain 89 | special circumstances. 90 | 91 | For example, on rare occasions, there may be a special need to 92 | encourage the widest possible use of a certain library, so that it 93 | becomes a de-facto standard. To achieve this, non-free programs must 94 | be allowed to use the library. A more frequent case is that a free 95 | library does the same job as widely used non-free libraries. In this 96 | case, there is little to gain by limiting the free library to free 97 | software only, so we use the Lesser General Public License. 98 | 99 | In other cases, permission to use a particular library in non-free 100 | programs enables a greater number of people to use a large body of 101 | free software. For example, permission to use the GNU C Library in 102 | non-free programs enables many more people to use the whole GNU 103 | operating system, as well as its variant, the GNU/Linux operating 104 | system. 105 | 106 | Although the Lesser General Public License is Less protective of the 107 | users' freedom, it does ensure that the user of a program that is 108 | linked with the Library has the freedom and the wherewithal to run 109 | that program using a modified version of the Library. 110 | 111 | The precise terms and conditions for copying, distribution and 112 | modification follow. Pay close attention to the difference between a 113 | "work based on the library" and a "work that uses the library". The 114 | former contains code derived from the library, whereas the latter must 115 | be combined with the library in order to run. 116 | 117 | GNU LESSER GENERAL PUBLIC LICENSE 118 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 119 | 120 | 0. This License Agreement applies to any software library or other 121 | program which contains a notice placed by the copyright holder or 122 | other authorized party saying it may be distributed under the terms of 123 | this Lesser General Public License (also called "this License"). 124 | Each licensee is addressed as "you". 125 | 126 | A "library" means a collection of software functions and/or data 127 | prepared so as to be conveniently linked with application programs 128 | (which use some of those functions and data) to form executables. 129 | 130 | The "Library", below, refers to any such software library or work 131 | which has been distributed under these terms. A "work based on the 132 | Library" means either the Library or any derivative work under 133 | copyright law: that is to say, a work containing the Library or a 134 | portion of it, either verbatim or with modifications and/or translated 135 | straightforwardly into another language. (Hereinafter, translation is 136 | included without limitation in the term "modification".) 137 | 138 | "Source code" for a work means the preferred form of the work for 139 | making modifications to it. For a library, complete source code means 140 | all the source code for all modules it contains, plus any associated 141 | interface definition files, plus the scripts used to control 142 | compilation and installation of the library. 143 | 144 | Activities other than copying, distribution and modification are not 145 | covered by this License; they are outside its scope. The act of 146 | running a program using the Library is not restricted, and output from 147 | such a program is covered only if its contents constitute a work based 148 | on the Library (independent of the use of the Library in a tool for 149 | writing it). Whether that is true depends on what the Library does 150 | and what the program that uses the Library does. 151 | 152 | 1. You may copy and distribute verbatim copies of the Library's 153 | complete source code as you receive it, in any medium, provided that 154 | you conspicuously and appropriately publish on each copy an 155 | appropriate copyright notice and disclaimer of warranty; keep intact 156 | all the notices that refer to this License and to the absence of any 157 | warranty; and distribute a copy of this License along with the 158 | Library. 159 | 160 | You may charge a fee for the physical act of transferring a copy, 161 | and you may at your option offer warranty protection in exchange for a 162 | fee. 163 | 164 | 2. You may modify your copy or copies of the Library or any portion 165 | of it, thus forming a work based on the Library, and copy and 166 | distribute such modifications or work under the terms of Section 1 167 | above, provided that you also meet all of these conditions: 168 | 169 | a) The modified work must itself be a software library. 170 | 171 | b) You must cause the files modified to carry prominent notices 172 | stating that you changed the files and the date of any change. 173 | 174 | c) You must cause the whole of the work to be licensed at no 175 | charge to all third parties under the terms of this License. 176 | 177 | d) If a facility in the modified Library refers to a function or a 178 | table of data to be supplied by an application program that uses 179 | the facility, other than as an argument passed when the facility 180 | is invoked, then you must make a good faith effort to ensure that, 181 | in the event an application does not supply such function or 182 | table, the facility still operates, and performs whatever part of 183 | its purpose remains meaningful. 184 | 185 | (For example, a function in a library to compute square roots has 186 | a purpose that is entirely well-defined independent of the 187 | application. Therefore, Subsection 2d requires that any 188 | application-supplied function or table used by this function must 189 | be optional: if the application does not supply it, the square 190 | root function must still compute square roots.) 191 | 192 | These requirements apply to the modified work as a whole. If 193 | identifiable sections of that work are not derived from the Library, 194 | and can be reasonably considered independent and separate works in 195 | themselves, then this License, and its terms, do not apply to those 196 | sections when you distribute them as separate works. But when you 197 | distribute the same sections as part of a whole which is a work based 198 | on the Library, the distribution of the whole must be on the terms of 199 | this License, whose permissions for other licensees extend to the 200 | entire whole, and thus to each and every part regardless of who wrote 201 | it. 202 | 203 | Thus, it is not the intent of this section to claim rights or contest 204 | your rights to work written entirely by you; rather, the intent is to 205 | exercise the right to control the distribution of derivative or 206 | collective works based on the Library. 207 | 208 | In addition, mere aggregation of another work not based on the Library 209 | with the Library (or with a work based on the Library) on a volume of 210 | a storage or distribution medium does not bring the other work under 211 | the scope of this License. 212 | 213 | 3. You may opt to apply the terms of the ordinary GNU General Public 214 | License instead of this License to a given copy of the Library. To do 215 | this, you must alter all the notices that refer to this License, so 216 | that they refer to the ordinary GNU General Public License, version 2, 217 | instead of to this License. (If a newer version than version 2 of the 218 | ordinary GNU General Public License has appeared, then you can specify 219 | that version instead if you wish.) Do not make any other change in 220 | these notices. 221 | 222 | Once this change is made in a given copy, it is irreversible for 223 | that copy, so the ordinary GNU General Public License applies to all 224 | subsequent copies and derivative works made from that copy. 225 | 226 | This option is useful when you wish to copy part of the code of 227 | the Library into a program that is not a library. 228 | 229 | 4. You may copy and distribute the Library (or a portion or 230 | derivative of it, under Section 2) in object code or executable form 231 | under the terms of Sections 1 and 2 above provided that you accompany 232 | it with the complete corresponding machine-readable source code, which 233 | must be distributed under the terms of Sections 1 and 2 above on a 234 | medium customarily used for software interchange. 235 | 236 | If distribution of object code is made by offering access to copy 237 | from a designated place, then offering equivalent access to copy the 238 | source code from the same place satisfies the requirement to 239 | distribute the source code, even though third parties are not 240 | compelled to copy the source along with the object code. 241 | 242 | 5. A program that contains no derivative of any portion of the 243 | Library, but is designed to work with the Library by being compiled or 244 | linked with it, is called a "work that uses the Library". Such a 245 | work, in isolation, is not a derivative work of the Library, and 246 | therefore falls outside the scope of this License. 247 | 248 | However, linking a "work that uses the Library" with the Library 249 | creates an executable that is a derivative of the Library (because it 250 | contains portions of the Library), rather than a "work that uses the 251 | library". The executable is therefore covered by this License. 252 | Section 6 states terms for distribution of such executables. 253 | 254 | When a "work that uses the Library" uses material from a header file 255 | that is part of the Library, the object code for the work may be a 256 | derivative work of the Library even though the source code is not. 257 | Whether this is true is especially significant if the work can be 258 | linked without the Library, or if the work is itself a library. The 259 | threshold for this to be true is not precisely defined by law. 260 | 261 | If such an object file uses only numerical parameters, data 262 | structure layouts and accessors, and small macros and small inline 263 | functions (ten lines or less in length), then the use of the object 264 | file is unrestricted, regardless of whether it is legally a derivative 265 | work. (Executables containing this object code plus portions of the 266 | Library will still fall under Section 6.) 267 | 268 | Otherwise, if the work is a derivative of the Library, you may 269 | distribute the object code for the work under the terms of Section 6. 270 | Any executables containing that work also fall under Section 6, 271 | whether or not they are linked directly with the Library itself. 272 | 273 | 6. As an exception to the Sections above, you may also combine or 274 | link a "work that uses the Library" with the Library to produce a 275 | work containing portions of the Library, and distribute that work 276 | under terms of your choice, provided that the terms permit 277 | modification of the work for the customer's own use and reverse 278 | engineering for debugging such modifications. 279 | 280 | You must give prominent notice with each copy of the work that the 281 | Library is used in it and that the Library and its use are covered by 282 | this License. You must supply a copy of this License. If the work 283 | during execution displays copyright notices, you must include the 284 | copyright notice for the Library among them, as well as a reference 285 | directing the user to the copy of this License. Also, you must do one 286 | of these things: 287 | 288 | a) Accompany the work with the complete corresponding 289 | machine-readable source code for the Library including whatever 290 | changes were used in the work (which must be distributed under 291 | Sections 1 and 2 above); and, if the work is an executable linked 292 | with the Library, with the complete machine-readable "work that 293 | uses the Library", as object code and/or source code, so that the 294 | user can modify the Library and then relink to produce a modified 295 | executable containing the modified Library. (It is understood 296 | that the user who changes the contents of definitions files in the 297 | Library will not necessarily be able to recompile the application 298 | to use the modified definitions.) 299 | 300 | b) Use a suitable shared library mechanism for linking with the 301 | Library. A suitable mechanism is one that (1) uses at run time a 302 | copy of the library already present on the user's computer system, 303 | rather than copying library functions into the executable, and (2) 304 | will operate properly with a modified version of the library, if 305 | the user installs one, as long as the modified version is 306 | interface-compatible with the version that the work was made with. 307 | 308 | c) Accompany the work with a written offer, valid for at least 309 | three years, to give the same user the materials specified in 310 | Subsection 6a, above, for a charge no more than the cost of 311 | performing this distribution. 312 | 313 | d) If distribution of the work is made by offering access to copy 314 | from a designated place, offer equivalent access to copy the above 315 | specified materials from the same place. 316 | 317 | e) Verify that the user has already received a copy of these 318 | materials or that you have already sent this user a copy. 319 | 320 | For an executable, the required form of the "work that uses the 321 | Library" must include any data and utility programs needed for 322 | reproducing the executable from it. However, as a special exception, 323 | the materials to be distributed need not include anything that is 324 | normally distributed (in either source or binary form) with the major 325 | components (compiler, kernel, and so on) of the operating system on 326 | which the executable runs, unless that component itself accompanies 327 | the executable. 328 | 329 | It may happen that this requirement contradicts the license 330 | restrictions of other proprietary libraries that do not normally 331 | accompany the operating system. Such a contradiction means you cannot 332 | use both them and the Library together in an executable that you 333 | distribute. 334 | 335 | 7. You may place library facilities that are a work based on the 336 | Library side-by-side in a single library together with other library 337 | facilities not covered by this License, and distribute such a combined 338 | library, provided that the separate distribution of the work based on 339 | the Library and of the other library facilities is otherwise 340 | permitted, and provided that you do these two things: 341 | 342 | a) Accompany the combined library with a copy of the same work 343 | based on the Library, uncombined with any other library 344 | facilities. This must be distributed under the terms of the 345 | Sections above. 346 | 347 | b) Give prominent notice with the combined library of the fact 348 | that part of it is a work based on the Library, and explaining 349 | where to find the accompanying uncombined form of the same work. 350 | 351 | 8. You may not copy, modify, sublicense, link with, or distribute 352 | the Library except as expressly provided under this License. Any 353 | attempt otherwise to copy, modify, sublicense, link with, or 354 | distribute the Library is void, and will automatically terminate your 355 | rights under this License. However, parties who have received copies, 356 | or rights, from you under this License will not have their licenses 357 | terminated so long as such parties remain in full compliance. 358 | 359 | 9. You are not required to accept this License, since you have not 360 | signed it. However, nothing else grants you permission to modify or 361 | distribute the Library or its derivative works. These actions are 362 | prohibited by law if you do not accept this License. Therefore, by 363 | modifying or distributing the Library (or any work based on the 364 | Library), you indicate your acceptance of this License to do so, and 365 | all its terms and conditions for copying, distributing or modifying 366 | the Library or works based on it. 367 | 368 | 10. Each time you redistribute the Library (or any work based on the 369 | Library), the recipient automatically receives a license from the 370 | original licensor to copy, distribute, link with or modify the Library 371 | subject to these terms and conditions. You may not impose any further 372 | restrictions on the recipients' exercise of the rights granted herein. 373 | You are not responsible for enforcing compliance by third parties with 374 | this License. 375 | 376 | 11. If, as a consequence of a court judgment or allegation of patent 377 | infringement or for any other reason (not limited to patent issues), 378 | conditions are imposed on you (whether by court order, agreement or 379 | otherwise) that contradict the conditions of this License, they do not 380 | excuse you from the conditions of this License. If you cannot 381 | distribute so as to satisfy simultaneously your obligations under this 382 | License and any other pertinent obligations, then as a consequence you 383 | may not distribute the Library at all. For example, if a patent 384 | license would not permit royalty-free redistribution of the Library by 385 | all those who receive copies directly or indirectly through you, then 386 | the only way you could satisfy both it and this License would be to 387 | refrain entirely from distribution of the Library. 388 | 389 | If any portion of this section is held invalid or unenforceable under 390 | any particular circumstance, the balance of the section is intended to 391 | apply, and the section as a whole is intended to apply in other 392 | circumstances. 393 | 394 | It is not the purpose of this section to induce you to infringe any 395 | patents or other property right claims or to contest validity of any 396 | such claims; this section has the sole purpose of protecting the 397 | integrity of the free software distribution system which is 398 | implemented by public license practices. Many people have made 399 | generous contributions to the wide range of software distributed 400 | through that system in reliance on consistent application of that 401 | system; it is up to the author/donor to decide if he or she is willing 402 | to distribute software through any other system and a licensee cannot 403 | impose that choice. 404 | 405 | This section is intended to make thoroughly clear what is believed to 406 | be a consequence of the rest of this License. 407 | 408 | 12. If the distribution and/or use of the Library is restricted in 409 | certain countries either by patents or by copyrighted interfaces, the 410 | original copyright holder who places the Library under this License 411 | may add an explicit geographical distribution limitation excluding those 412 | countries, so that distribution is permitted only in or among 413 | countries not thus excluded. In such case, this License incorporates 414 | the limitation as if written in the body of this License. 415 | 416 | 13. The Free Software Foundation may publish revised and/or new 417 | versions of the Lesser General Public License from time to time. 418 | Such new versions will be similar in spirit to the present version, 419 | but may differ in detail to address new problems or concerns. 420 | 421 | Each version is given a distinguishing version number. If the Library 422 | specifies a version number of this License which applies to it and 423 | "any later version", you have the option of following the terms and 424 | conditions either of that version or of any later version published by 425 | the Free Software Foundation. If the Library does not specify a 426 | license version number, you may choose any version ever published by 427 | the Free Software Foundation. 428 | 429 | 14. If you wish to incorporate parts of the Library into other free 430 | programs whose distribution conditions are incompatible with these, 431 | write to the author to ask for permission. For software which is 432 | copyrighted by the Free Software Foundation, write to the Free 433 | Software Foundation; we sometimes make exceptions for this. Our 434 | decision will be guided by the two goals of preserving the free status 435 | of all derivatives of our free software and of promoting the sharing 436 | and reuse of software generally. 437 | 438 | NO WARRANTY 439 | 440 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 441 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 442 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 443 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 444 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 445 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 446 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 447 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 448 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 449 | 450 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 451 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 452 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 453 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 454 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 455 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 456 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 457 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 458 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 459 | DAMAGES. 460 | 461 | END OF TERMS AND CONDITIONS 462 | 463 | How to Apply These Terms to Your New Libraries 464 | 465 | If you develop a new library, and you want it to be of the greatest 466 | possible use to the public, we recommend making it free software that 467 | everyone can redistribute and change. You can do so by permitting 468 | redistribution under these terms (or, alternatively, under the terms 469 | of the ordinary General Public License). 470 | 471 | To apply these terms, attach the following notices to the library. 472 | It is safest to attach them to the start of each source file to most 473 | effectively convey the exclusion of warranty; and each file should 474 | have at least the "copyright" line and a pointer to where the full 475 | notice is found. 476 | 477 | 478 | 479 | Copyright (C) 480 | 481 | This library is free software; you can redistribute it and/or 482 | modify it under the terms of the GNU Lesser General Public 483 | License as published by the Free Software Foundation; either 484 | version 2.1 of the License, or (at your option) any later version. 485 | 486 | This library is distributed in the hope that it will be useful, 487 | but WITHOUT ANY WARRANTY; without even the implied warranty of 488 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 489 | Lesser General Public License for more details. 490 | 491 | You should have received a copy of the GNU Lesser General Public 492 | License along with this library; if not, write to the Free Software 493 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 494 | 495 | Also add information on how to contact you by electronic and paper mail. 496 | 497 | You should also get your employer (if you work as a programmer) or 498 | your school, if any, to sign a "copyright disclaimer" for the library, 499 | if necessary. Here is a sample; alter the names: 500 | 501 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 502 | library `Frob' (a library for tweaking knobs) written by James 503 | Random Hacker. 504 | 505 | , 1 April 1990 506 | Ty Coon, President of Vice 507 | 508 | That's all there is to it! 509 | --------------------------------------------------------------------------------