mirror of
https://abf.rosa.ru/djam/libressl.git
synced 2025-02-23 08:02:54 +00:00
Init
This commit is contained in:
commit
709fb483dc
8 changed files with 990 additions and 0 deletions
2
.abf.yml
Normal file
2
.abf.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
sources:
|
||||
libressl-3.0.2.tar.gz: 3d025eb32b0304b5b1c317bb59add037680e3298
|
56
0001-Allow-custom-config-location.patch
Normal file
56
0001-Allow-custom-config-location.patch
Normal file
|
@ -0,0 +1,56 @@
|
|||
From 4074611c49806fa5e8937a5aa24d9084235a89a5 Mon Sep 17 00:00:00 2001
|
||||
From: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
|
||||
Date: Fri, 29 Nov 2019 21:24:49 +0300
|
||||
Subject: [PATCH] Allow custom config location
|
||||
|
||||
I want LibreSSL to:
|
||||
- coexist with OpenSSL
|
||||
- be installed into /opt
|
||||
- do not conflict with OpenSSL devel packages
|
||||
- use /etc/ssl (/etc/pki/tls in ROSA) from OpenSSL
|
||||
|
||||
For this purpose, it is required to be able to separate configs of OpenSSL and LibreSSL.
|
||||
|
||||
Example:
|
||||
export CFLAGS="$CFLAGS -DX509_CONF_FILE='\"/etc/ssl/libressl.cnf\"'"
|
||||
---
|
||||
src/lib/libcrypto/conf/conf_mod.c | 4 ++++
|
||||
src/usr.bin/openssl/apps.c | 4 ++++
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/src/lib/libcrypto/conf/conf_mod.c b/src/lib/libcrypto/conf/conf_mod.c
|
||||
index 9f252385e..f5271c89d 100644
|
||||
--- a/src/lib/libcrypto/conf/conf_mod.c
|
||||
+++ b/src/lib/libcrypto/conf/conf_mod.c
|
||||
@@ -545,8 +545,12 @@ CONF_get1_default_config_file(void)
|
||||
{
|
||||
char *file = NULL;
|
||||
|
||||
+#ifndef X509_CONF_FILE
|
||||
if (asprintf(&file, "%s/openssl.cnf",
|
||||
X509_get_default_cert_area()) == -1)
|
||||
+#else
|
||||
+ if (asprintf(&file, X509_CONF_FILE) == -1)
|
||||
+#endif
|
||||
return (NULL);
|
||||
return file;
|
||||
}
|
||||
diff --git a/src/usr.bin/openssl/apps.c b/src/usr.bin/openssl/apps.c
|
||||
index c9a2f34b2..313d6ecee 100644
|
||||
--- a/src/usr.bin/openssl/apps.c
|
||||
+++ b/src/usr.bin/openssl/apps.c
|
||||
@@ -1213,7 +1213,11 @@ make_config_name()
|
||||
const char *t = X509_get_default_cert_area();
|
||||
char *p;
|
||||
|
||||
+#ifndef X509_CONF_FILE
|
||||
if (asprintf(&p, "%s/openssl.cnf", t) == -1)
|
||||
+#else
|
||||
+ if (asprintf(&p, X509_CONF_FILE) == -1)
|
||||
+#endif
|
||||
return NULL;
|
||||
return p;
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
66
SUSE-extra-symver.patch
Normal file
66
SUSE-extra-symver.patch
Normal file
|
@ -0,0 +1,66 @@
|
|||
From f2969c659b4cbccbb3766f72926a9a829b17d561 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Engelhardt <jengelh@inai.de>
|
||||
Date: Mon, 4 Dec 2017 21:25:11 +0100
|
||||
Subject: [PATCH 8/8] SUSE extra symver
|
||||
|
||||
Add symbol versions into the library to be on par with openssl.
|
||||
---
|
||||
libressl/crypto/Makefile.am | 6 +++++-
|
||||
libressl/ssl/Makefile.am | 6 +++++-
|
||||
libressl/tls/Makefile.am | 6 +++++-
|
||||
3 files changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libressl/crypto/Makefile.am b/libressl/crypto/Makefile.am
|
||||
index f66bb73..fdb970b 100644
|
||||
--- a/libressl/crypto/Makefile.am
|
||||
+++ b/libressl/crypto/Makefile.am
|
||||
@@ -93,7 +93,11 @@ if HOST_WIN
|
||||
-mv crypto_portable.sym.tmp crypto_portable.sym
|
||||
endif
|
||||
|
||||
-libcrypto_la_LDFLAGS = -version-info @LIBCRYPTO_VERSION@ -no-undefined -export-symbols crypto_portable.sym
|
||||
+crypto2.sym: crypto_portable.sym
|
||||
+ (echo 'LIBRESSL { global: '; sed -e 's/\(.*\)/\1;/' <$<; echo 'local: *; };') >$@
|
||||
+
|
||||
+libcrypto_la_DEPENDENCIES = crypto2.sym libcompat.la
|
||||
+libcrypto_la_LDFLAGS = -version-info @LIBCRYPTO_VERSION@ -no-undefined -Wl,--version-script=crypto2.sym
|
||||
libcrypto_la_LIBADD = libcompat.la
|
||||
if !HAVE_EXPLICIT_BZERO
|
||||
libcrypto_la_LIBADD += libcompatnoopt.la
|
||||
diff --git a/libressl/ssl/Makefile.am b/libressl/ssl/Makefile.am
|
||||
index 02109f5..a92c86c 100644
|
||||
--- a/libressl/ssl/Makefile.am
|
||||
+++ b/libressl/ssl/Makefile.am
|
||||
@@ -6,7 +6,11 @@ EXTRA_DIST = VERSION
|
||||
EXTRA_DIST += CMakeLists.txt
|
||||
EXTRA_DIST += ssl.sym
|
||||
|
||||
-libssl_la_LDFLAGS = -version-info @LIBSSL_VERSION@ -no-undefined -export-symbols $(top_srcdir)/ssl/ssl.sym
|
||||
+ssl2.sym: ssl.sym
|
||||
+ (echo 'LIBRESSL { global: '; sed -e 's/\(.*\)/\1;/' <$<; echo 'local: *; };') >$@
|
||||
+
|
||||
+libssl_la_DEPENDENCIES = ssl2.sym
|
||||
+libssl_la_LDFLAGS = -version-info @LIBSSL_VERSION@ -no-undefined -Wl,--version-script=ssl2.sym
|
||||
libssl_la_LIBADD = $(abs_top_builddir)/crypto/libcrypto.la
|
||||
|
||||
libssl_la_SOURCES = bio_ssl.c
|
||||
diff --git a/libressl/tls/Makefile.am b/libressl/tls/Makefile.am
|
||||
index 40ba156..cc03b2d 100644
|
||||
--- a/libressl/tls/Makefile.am
|
||||
+++ b/libressl/tls/Makefile.am
|
||||
@@ -6,7 +6,11 @@ EXTRA_DIST = VERSION
|
||||
EXTRA_DIST += CMakeLists.txt
|
||||
EXTRA_DIST += tls.sym
|
||||
|
||||
-libtls_la_LDFLAGS = -version-info @LIBTLS_VERSION@ -no-undefined -export-symbols $(top_srcdir)/tls/tls.sym
|
||||
+tls2.sym: tls.sym
|
||||
+ (echo 'LIBRESSL { global: '; sed -e 's/\(.*\)/\1;/' <$<; echo 'local: *; };') >$@
|
||||
+
|
||||
+libtls_la_DEPENDENCIES = tls2.sym
|
||||
+libtls_la_LDFLAGS = -version-info @LIBTLS_VERSION@ -no-undefined -Wl,--version-script=tls2.sym
|
||||
libtls_la_LIBADD = $(abs_top_builddir)/ssl/libssl.la
|
||||
libtls_la_LIBADD += $(abs_top_builddir)/crypto/libcrypto.la
|
||||
libtls_la_LIBADD += $(PLATFORM_LDADD)
|
||||
--
|
||||
2.21.0
|
||||
|
7
libressl.rpmlintrc
Normal file
7
libressl.rpmlintrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
# I have put %define _use_internal_dependency_generator 0
|
||||
# Why does this error still occur?!
|
||||
addFilter("E: external-depfilter-with-internal-depgen")
|
||||
# /opt is used intentionally
|
||||
addFilter("E: dir-or-file-in-opt")
|
||||
# We add rpath to *.pc in %%install intentionally
|
||||
addFilter("E: rpath-in-buildconfig")
|
421
libressl.spec
Normal file
421
libressl.spec
Normal file
|
@ -0,0 +1,421 @@
|
|||
# Initial purpose of packaging LibreSSL was the need to have a handy
|
||||
# tool to work with GOST keys easily (LibreSSL has GOSTs out of the box).
|
||||
# netcat-openbsd is now also packaged here.
|
||||
# LibreSSL is a fork of OpenSSL and has same libraries, binaries
|
||||
# and fucntions names, that is why it cannot coexist with OpenSSL
|
||||
# easily and is packages to a separate prefix here.
|
||||
# Remember some directories before changing %%_prefix, o - original
|
||||
%define _oprefix /usr
|
||||
%define _obindir %{_oprefix}/bin
|
||||
%define _omandir %{_oprefix}/share/man
|
||||
%define _olibdir %{_oprefix}/%{_lib}
|
||||
%define _prefix /opt/libressl
|
||||
# No need to have /opt/libressl/lib64, use /opt/libressl/lib
|
||||
%define _libdir %{_prefix}/lib
|
||||
# Keep package docs in normal locations
|
||||
%define _defaultdocdir %{_oprefix}/share/doc
|
||||
# Disable /usr/share/spec-helper/relink_symlinks
|
||||
# to make sure that symlinks are not broken
|
||||
%define dont_relink 1
|
||||
# If man pages compression is not set up, skip it
|
||||
%{?!_compress:%define _compress /bin/true}
|
||||
%{?!_extension:%define _extension .xz}
|
||||
|
||||
# Fallback to the old external dependency generator
|
||||
# http://lists.rosalab.ru/pipermail/rosa-devel/2013-April/004702.html
|
||||
# http://lists.rosalab.ru/pipermail/rosa-devel/2013-April/004703.html
|
||||
# because there is no way to filter by filepath in the internal one
|
||||
# TODO: avoid using external dep. gen.
|
||||
%define _use_internal_dependency_generator 0
|
||||
# Those libraries in /opt are not available without RPATH or ld.so.conf
|
||||
%define _exclude_files_from_autoprov %{_libdir}
|
||||
# We rename e.g. libtls.pc to libressl-tls.pc, make sure that we do not
|
||||
# get odd provides and break the repository if forgot to rename something
|
||||
#define __noautoprov '.*openssl.*|pkgconfig\\(lib.*'
|
||||
%define _provides_exceptions '.*openssl.*|pkgconfig(lib.*'
|
||||
# libressl-devel must not require devel(libxxx)
|
||||
# because it has those devels inside himself
|
||||
%define _requires_exceptions 'devel(lib.*'
|
||||
# Ideas behind this dependency generation crap are the following:
|
||||
# - libressl-devel must provide pkgconfig(libressl*)
|
||||
# - libressl-devel must not provide pkgconfig(openssl),
|
||||
# pkgconfig(libtls), pkgconfig(libcrypto), pkgconfig(libssl)
|
||||
# to prevent conflicts with OpenSSL
|
||||
# - libressl must not depend from separate library packages with
|
||||
# libtls.so.*, libcrypto.so.*, libssl.so.*, instead it has
|
||||
# copies of those libraries in /opt/libressl/lib/ and has RPATH
|
||||
# - packages netcat-openbsd and ocspcheck are intended to be
|
||||
# installable without installing libressl package with a lot of
|
||||
# odd stuff; so libtls.so.*, libcrypto.so.* and libssl.so.* are
|
||||
# packaged into separate packages, RPATHs are removed and nc
|
||||
# and ocspcheck must depend from separate libs packages and will
|
||||
# use /usr/lib(64)/lib*.so.* instead of /opt/libressl/lib/*.so.*
|
||||
# - there are no per-library devel packages, only one libressl-devel.
|
||||
# // mikhailnov, 30.11.2019
|
||||
|
||||
%define libcrypto_sover 45
|
||||
%define libssl_sover 47
|
||||
%define libtls_sover 19
|
||||
%define libssl_pkg %mklibname ssl_libressl %{libssl_sover}
|
||||
%define libcrypto_pkg %mklibname crypto_libressl %{libcrypto_sover}
|
||||
%define libtls_pkg %mklibname tls_libressl %{libtls_sover}
|
||||
|
||||
Summary: LibreSSL utils and libs coexisting with OpenSSL
|
||||
Name: libressl
|
||||
Version: 3.0.2
|
||||
Release: 1
|
||||
# The code is distributed under ISC license except of original OpenSSL code
|
||||
License: ISC and BSD-like
|
||||
Group: System/Libraries
|
||||
Url: http://libressl.org
|
||||
Source0: http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-%{version}.tar.gz
|
||||
# TODO: add printing config location to `openssl version`
|
||||
Source1: 0001-Allow-custom-config-location.patch
|
||||
Source10: libressl.rpmlintrc
|
||||
# If both openssl and libressl libraries are loaded into one runtime,
|
||||
# versioning their symbols will or may allow them to coexist
|
||||
# (patch from ALT Linux)
|
||||
Patch2: SUSE-extra-symver.patch
|
||||
# From https://www.mitchr.me/SS/exampleCode/openssl.html
|
||||
Source20: test.c
|
||||
Source22: test2.c
|
||||
# From import/openssl, originates from Fedora
|
||||
Source25: test5.c
|
||||
# To get %%_openssldir and for %%check
|
||||
BuildRequires: openssl-devel
|
||||
# readelf <...> | <...>
|
||||
BuildRequires: binutils grep gawk
|
||||
BuildRequires: chrpath
|
||||
# This LibreSSL uses /etc/pki/tls from system OpenSSL
|
||||
# but most functions will work without its files
|
||||
Suggests: openssl
|
||||
# Prevent dependencies from lib*_libressl* subpackages for the main package
|
||||
# because it may freely use /opt/libressl/lib/*.so.*
|
||||
# but put "Autoreq: 1" in other subpackages which may be installed without
|
||||
# libressl main package being installed and will use /usr/lib(64)/.*so.*
|
||||
Autoreq: 0
|
||||
|
||||
%description
|
||||
LibreSSL utils and libs coexisting with OpenSSL.
|
||||
GOST is supported out of the box.
|
||||
|
||||
%files
|
||||
%doc ChangeLog COPYING
|
||||
# %%_bindir here is /opt/libressl/bin
|
||||
# %%_obindir is /usr/bin
|
||||
# %%_mandir is /opt/libressl/share/man
|
||||
# %%_omandir is /usr/share/man
|
||||
%{_bindir}/openssl
|
||||
%{_bindir}/libressl
|
||||
%{_obindir}/libressl
|
||||
%{_mandir}/man1/*
|
||||
%{_mandir}/man5/*
|
||||
%{_omandir}/*/*
|
||||
%{_libdir}/*.so.*
|
||||
%config(noreplace) %{_openssldir}/libressl.cnf
|
||||
%config(noreplace) %{_openssldir}/x509v3.cnf
|
||||
%exclude %{_omandir}/man3/*
|
||||
%exclude %{_omandir}/*/nc.*
|
||||
%exclude %{_omandir}/*/netcat.*
|
||||
%exclude %{_omandir}/*/ocspcheck.*
|
||||
%exclude %{_libdir}/*.so
|
||||
#-------------------------------------------------------------------------------------
|
||||
|
||||
%package -n %{libcrypto_pkg}
|
||||
Summary: libcrypto library from LibreSSL
|
||||
Autoreq: 1
|
||||
|
||||
%description -n %{libcrypto_pkg}
|
||||
libcrypto library from LibreSSL
|
||||
|
||||
%files -n %{libcrypto_pkg}
|
||||
%{_olibdir}/libcrypto.so.%{libcrypto_sover}*
|
||||
#-------------------------------------------------------------------------------------
|
||||
|
||||
%package -n %{libssl_pkg}
|
||||
Summary: libssl library from LibreSSL
|
||||
Autoreq: 1
|
||||
|
||||
%description -n %{libssl_pkg}
|
||||
libssl library from LibreSSL
|
||||
|
||||
%files -n %{libssl_pkg}
|
||||
%{_olibdir}/libssl.so.%{libssl_sover}*
|
||||
#-------------------------------------------------------------------------------------
|
||||
|
||||
%package -n %{libtls_pkg}
|
||||
Summary: libtls library from LibreSSL
|
||||
Autoreq: 1
|
||||
|
||||
%description -n %{libtls_pkg}
|
||||
libtls library from LibreSSL
|
||||
|
||||
%files -n %{libtls_pkg}
|
||||
%{_olibdir}/libtls.so.%{libtls_sover}*
|
||||
#-------------------------------------------------------------------------------------
|
||||
|
||||
%package devel
|
||||
Summary: LibreSSL devel package
|
||||
Requires: %{name} = %{EVRD}
|
||||
Autoreq: 1
|
||||
|
||||
%description devel
|
||||
LibreSSL devel package. Devel libraries are in %{_libdir},
|
||||
but the same runtime libraries exist in
|
||||
%{_libdir}
|
||||
and
|
||||
%{_olibdir}.
|
||||
After linking, binaries will load libs from %{_olibdir}.
|
||||
When using pkg-config, RPATH is set to %{_libdir},
|
||||
remove RPATH/RUNPATH manually if needed.
|
||||
|
||||
%files devel
|
||||
%doc ChangeLog COPYING
|
||||
%{_libdir}/*.so
|
||||
%{_olibdir}/pkgconfig/*.pc
|
||||
%{_includedir}
|
||||
%{_mandir}/man3/*
|
||||
%{_omandir}/man3/*
|
||||
#-------------------------------------------------------------------------------------
|
||||
|
||||
%package -n ocspcheck
|
||||
Summary: Utility to validate certificates
|
||||
Autoreq: 1
|
||||
|
||||
%description -n ocspcheck
|
||||
Utility to validate a certificate against its OCSP responder and
|
||||
save the reply for stapling
|
||||
|
||||
%files -n ocspcheck
|
||||
%doc ChangeLog COPYING
|
||||
%{_obindir}/ocspcheck
|
||||
%{_omandir}/man*/ocspcheck.*
|
||||
#-------------------------------------------------------------------------------------
|
||||
|
||||
%package -n netcat-openbsd
|
||||
Summary: Reads and writes data across network connections using TCP or UDP
|
||||
Conflicts: netcat < 1.0
|
||||
Conflicts: netcat-traditional
|
||||
Conflicts: netcat-gnu
|
||||
# netcat-openbsd 1.89 was imported from Mandriva in 2012 and now, in 2019, is replaced
|
||||
#Obsoletes: netcat-openbsd < 1.89.1
|
||||
Provides: netcat-tls = %{EVRD}
|
||||
Provides: netcat-libressl = %{EVRD}
|
||||
Provides: nc = %{EVRD}
|
||||
Autoreq: 1
|
||||
|
||||
%description -n netcat-openbsd
|
||||
The nc package contains Netcat (the program is actually nc), a simple
|
||||
utility for reading and writing data across network connections, using
|
||||
the TCP or UDP protocols. Netcat is intended to be a reliable back-end
|
||||
tool which can be used directly or easily driven by other programs and
|
||||
scripts. Netcat is also a feature-rich network debugging and
|
||||
exploration tool, since it can create many different connections and
|
||||
has many built-in capabilities.
|
||||
|
||||
You may want to install the netcat package if you are administering a
|
||||
network and you'd like to use its debugging and network exploration
|
||||
capabilities.
|
||||
|
||||
%files -n netcat-openbsd
|
||||
%doc ChangeLog COPYING
|
||||
%{_obindir}/nc
|
||||
%{_obindir}/netcat
|
||||
%{_omandir}/man*/nc.*
|
||||
%{_omandir}/man*/netcat.*
|
||||
#-------------------------------------------------------------------------------------
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch2 -p2
|
||||
# Patch is against gits https://github.com/libressl-portable/
|
||||
# Release tarball is packaged in a tricky way
|
||||
cat %{SOURCE1} | sed \
|
||||
-e 's,src/lib/libcrypto/,crypto/,g' \
|
||||
-e 's,src/usr.bin/openssl/,apps/openssl/,g' \
|
||||
> 1.patch
|
||||
patch -p1 < 1.patch
|
||||
|
||||
%build
|
||||
%setup_compile_flags
|
||||
%serverbuild
|
||||
# Use the same %%_openssl dir with OpenSSL, but separate the config
|
||||
# (note that we patch libressl, X509_CONF_FILE is not upstream)
|
||||
export CFLAGS="$CFLAGS -DX509_CONF_FILE='\"%{_openssldir}/libressl.cnf\"'"
|
||||
# TODO: why by default without this runpath is not set on libcrypto.so*,
|
||||
# but is set on libtls.so* and libssl.so*?
|
||||
export LDFLAGS="$LDFLAGS -Wl,-rpath=%{_libdir}"
|
||||
autoreconf -if #patch2
|
||||
# static libs are required for tests target in Makefile
|
||||
%configure2_5x \
|
||||
--enable-nc \
|
||||
--enable-static \
|
||||
--with-openssldir=%{_openssldir}
|
||||
%make
|
||||
|
||||
%install
|
||||
set +f # explicitly enable shell globbing
|
||||
|
||||
%makeinstall_std
|
||||
|
||||
# Some ideas about mans are from ALT Linux spec
|
||||
install -m 0644 apps/nc/nc.1 %{buildroot}%{_mandir}/man1/nc.1
|
||||
install -m 0644 apps/nc/nc.1 %{buildroot}%{_mandir}/man1/netcat.1
|
||||
mkdir -p %{buildroot}%{_mandir}/man8/
|
||||
install -m 0644 apps/ocspcheck/ocspcheck.8 %{buildroot}%{_mandir}/man8/ocspcheck.8
|
||||
for i in $(seq 1 8)
|
||||
do
|
||||
man_dir="%{buildroot}%{_mandir}/man${i}"
|
||||
if [ ! -d "$man_dir" ]; then continue; fi
|
||||
( cd "$man_dir"
|
||||
grep -Irl '/etc/ssl' . | xargs sed -i 's,/etc/ssl,%{_openssldir},g' || :
|
||||
if find . -name 'libressl_*' | grep -q '.' ; then
|
||||
echo 'Rewrite spec because upstream libressl_* manpages appeared!'
|
||||
exit 1
|
||||
fi
|
||||
# Make all man pages with potentially the same names as in OpenSSL
|
||||
# be avaialble in standard man directories, but prevent conflicts with OpenSSL
|
||||
for openssl_manpage in $(ls -1v | grep -vE '^LIBRESSL_|^netcat|^nc|^ocspcheck|^openssl\.') ; do
|
||||
openssl_LibreSSL_manpage="libressl_${openssl_manpage}"
|
||||
cp -v "$openssl_manpage" "$openssl_LibreSSL_manpage"
|
||||
done
|
||||
for openssl_manpage in $(ls -1v | grep '^openssl\.') ; do
|
||||
openssl_LibreSSL_manpage="$(echo "$openssl_manpage" | sed -e 's,openssl,libressl,g')"
|
||||
cp -v "$openssl_manpage" "$openssl_LibreSSL_manpage"
|
||||
done
|
||||
)
|
||||
done
|
||||
mkdir -p %{buildroot}%{_omandir}
|
||||
cp -rv %{buildroot}%{_mandir}/* %{buildroot}%{_omandir}/
|
||||
# We have put libressl_ prefixed mans to system man directory,
|
||||
# now delete them from /opt/libressl/share/man to leave
|
||||
# mans with original names in /opt/libressl/share/man
|
||||
rm -fv %{buildroot}%{_mandir}/*/libressl_*
|
||||
rm -fv %{buildroot}%{_omandir}/*/openssl.*
|
||||
# Fully delete other mans from /opt
|
||||
rm -fv %{buildroot}%{_mandir}/*/{nc,netcat,ocspcheck}*
|
||||
# Manually compress man pages because we use both
|
||||
# /usr/share/man and /opt/libressl/share/man,
|
||||
# /usr/lib/rpm/brp-compress will not compress both of them
|
||||
mkdir tmp
|
||||
pushd tmp
|
||||
sed -e 's,./usr/share/man/man*,%{buildroot}%{_mandir}/man* %{buildroot}%{_omandir}/man*,g' \
|
||||
%{_usrlibrpm}/brp-compress > ./brp-compress.sh
|
||||
chmod +x ./brp-compress.sh
|
||||
COMPRESS="%{_compress}" COMPRESS_EXT="%{_extension}" ./brp-compress.sh
|
||||
popd
|
||||
|
||||
mkdir -p %{buildroot}%{_obindir}
|
||||
mv -v %{buildroot}%{_bindir}/{nc,ocspcheck} %{buildroot}%{_obindir}/
|
||||
( cd %{buildroot}%{_bindir} ; ln -s openssl libressl )
|
||||
( cd %{buildroot}%{_obindir} ; ln -s %{_bindir}/openssl libressl )
|
||||
( cd %{buildroot}%{_obindir} ; ln -s nc netcat )
|
||||
( cd %{buildroot}%{_includedir} ; ln -s openssl libressl )
|
||||
# Remove static libs
|
||||
( cd %{buildroot}%{_libdir} ; rm -fv *.la *.a )
|
||||
|
||||
# Build scripts set RUNPATH, it is needed because /usr/bin/* are linked with
|
||||
# /opt/libressl/lib/*.so.*, make sure that RUNPATH exists
|
||||
for i in $(find %{buildroot}%{_bindir} %{buildroot}%{_libdir} -type f -executable) ; do
|
||||
rpath="$(readelf -a "$i" | grep '(RUNPATH)' | head -n 1 | awk '{print $NF}' | tr -d '[]')"
|
||||
if [ "$rpath" != '%{_libdir}' ]; then
|
||||
echo "Empty or incorrect RPATH on ${i}!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir -p %{buildroot}/%{_olibdir}/pkgconfig
|
||||
mv -v %{buildroot}/%{_libdir}/pkgconfig/*.pc %{buildroot}/%{_olibdir}/pkgconfig
|
||||
for i in share %{_lib}
|
||||
do
|
||||
pkgconfig_dir="%{buildroot}/%{_oprefix}/${i}/pkgconfig"
|
||||
if [ ! -d "$pkgconfig_dir" ]; then continue; fi
|
||||
( cd "$pkgconfig_dir"
|
||||
for f in *.pc
|
||||
do
|
||||
if [ "$f" != 'openssl.pc' ] && ! grep '^Name:' "$f" | grep -qi 'libressl\-'; then
|
||||
echo "Name in $f is not prefixed with LibreSSL-"
|
||||
exit 1
|
||||
fi
|
||||
# Restore ability to work with custom prefix
|
||||
# It is lost due to --exec_prefix=XXX in %%configure2_5x
|
||||
sed -i -r \
|
||||
-e 's,^exec_prefix=.+,exec_prefix=${prefix},' \
|
||||
-e 's,^libdir=.+,libdir=${exec_prefix}/lib,' \
|
||||
-e 's,^includedir=.+,includedir=${prefix}/include,' \
|
||||
"$f"
|
||||
# TODO: is rpath in *.pc really needed?
|
||||
if ! grep '^Libs:' "$f"
|
||||
then
|
||||
echo 'Libs: -Wl,-rpath=${libdir}' >> "$f"
|
||||
else
|
||||
# https://unix.stackexchange.com/a/328656
|
||||
sed -i -e '/^Libs:/s/$/ -Wl,-rpath=${libdir}/' "$f"
|
||||
grep '^Libs:' "$f" | grep -q rpath || exit 1
|
||||
fi
|
||||
mv -v "$f" "libressl-${f}"
|
||||
# Requires: libxx -> Requires: libressl-libxx
|
||||
sed -i \
|
||||
-e 's/libcrypto/libressl-libcrypto/g' \
|
||||
-e 's/libtls/libressl-liblts/g' \
|
||||
-e 's/libssl/libressl-libssl/g' \
|
||||
-e 's/libressl-libressl-/libressl-/g' \
|
||||
"libressl-${f}"
|
||||
if [ -f libressl-openssl.pc ]; then
|
||||
mv -v libressl-openssl.pc libressl.pc
|
||||
fi
|
||||
done
|
||||
)
|
||||
done
|
||||
|
||||
cp -v %{buildroot}/%{_libdir}/{libcrypto,libtls,libssl}.so.* %{buildroot}/%{_olibdir}/
|
||||
chrpath --delete %{buildroot}/%{_olibdir}/*.so.*
|
||||
chrpath --delete %{buildroot}/%{_obindir}/{nc,ocspcheck}
|
||||
|
||||
# Stuff from system OpenSSL will be used
|
||||
rm -fvr %{buildroot}/%{_openssldir}/{certs,cert.pem}
|
||||
mv -v %{buildroot}/%{_openssldir}/openssl.cnf %{buildroot}/%{_openssldir}/libressl.cnf
|
||||
|
||||
%check
|
||||
_pcf(){
|
||||
unset oflags nflags
|
||||
oflags="$(eval $@)"
|
||||
nflags="$(echo "$oflags" | sed -e 's,%{_prefix},%{buildroot}%{_prefix},g')"
|
||||
}
|
||||
rflags="-Wl,-rpath=%{buildroot}%{_libdir},-rpath=%{buildroot}%{_olibdir}"
|
||||
# These tests caught a lot of mistakes during first builds
|
||||
export PKG_CONFIG_PATH=%{buildroot}/%{_olibdir}/pkgconfig
|
||||
# (test 1) Check that openssldir is correct
|
||||
export LD_LIBRARY_PATH=%{buildroot}/%{_libdir}
|
||||
%{buildroot}/%{_bindir}/libressl version -d | awk '{print $NF}' | tr -d '""' | grep -q '^%{_openssldir}$'
|
||||
unset LD_LIBRARY_PATH
|
||||
# (test 2) Check that path to config file is correct
|
||||
# and also check that pkg-config libressl points to libressl, not openssl
|
||||
_pcf pkg-config --libs --cflags libressl
|
||||
%__cc -o test2 %{SOURCE22} $nflags $rflags
|
||||
ldd ./test2
|
||||
[ "$(./test2)" = "%{_openssldir}/libressl.cnf" ] || exit 1
|
||||
# Check that our pkgconfig hacks somehow work
|
||||
# (test 3) There is no /opt/libressl/ at build time
|
||||
_pcf pkg-config --libs --cflags libressl-libcrypto
|
||||
%__cc -o test3 %{SOURCE20} $nflags $rflags
|
||||
ldd ./test3
|
||||
ldd ./test3 | grep -E '%{_prefix}.*/libcrypto\.so\.%{libcrypto_sover}'
|
||||
./test3 | grep Hello
|
||||
# (test 4) Check that OpenSSL and LibreSSL devel parts coexist correctly
|
||||
# (build with libcrypto from OpenSSL)
|
||||
_pcf pkg-config --libs --cflags libcrypto
|
||||
%__cc -o test4 %{SOURCE20} $nflags $rflags
|
||||
ldd ./test4
|
||||
ldd ./test4 | grep -v 'libcrypto\.so\.%{libcrypto_sover}'
|
||||
ldd ./test4 | grep -v '%{_prefix}'
|
||||
./test4 | grep Hello
|
||||
# (test 5) Check that flags from all *.pc are valid
|
||||
# libtls is overlinking here, but check linking
|
||||
_pcf pkg-config --libs --cflags libressl libressl-libssl libressl-libtls libressl-libcrypto
|
||||
%__сс -o test5 %{SOURCE25} $nflags $rflags -lpthread -lz -ldl
|
||||
ldd ./test5
|
||||
ldd ./test3 | grep -E '%{_prefix}.*/libcrypto\.so\.%{libcrypto_sover}'
|
||||
ldd ./test3 | grep -E '%{_prefix}.*/libssl\.so\.%{libssl_sover}'
|
||||
ldd ./test3 | grep -E '%{_prefix}.*/libtls\.so\.%{libtls_sover}'
|
||||
./test5 --threads 2
|
32
test.c
Normal file
32
test.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
@file bio_hello.c
|
||||
@author Mitch Richling <https://www.mitchr.me/>
|
||||
@Copyright Copyright 2008 by Mitch Richling. All rights reserved.
|
||||
@brief Simple OpenSSL I/O example program.@EOL
|
||||
@Keywords hello world openssl bio
|
||||
@Std C99
|
||||
|
||||
This code has no error checking so that the basic
|
||||
concepts are more visible.
|
||||
|
||||
https://www.mitchr.me/SS/exampleCode/openssl.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
int main(int argc, char *argv[]);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
BIO *bio_stdout;
|
||||
|
||||
bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
|
||||
BIO_printf(bio_stdout, "Hello\n");
|
||||
|
||||
BIO_free_all(bio_stdout);
|
||||
|
||||
return 0;
|
||||
}
|
6
test2.c
Normal file
6
test2.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
// by mikhailnov
|
||||
#include <openssl/conf.h>
|
||||
int main(){
|
||||
char *f = NULL;
|
||||
printf("%s", CONF_get1_default_config_file());
|
||||
}
|
400
test5.c
Normal file
400
test5.c
Normal file
|
@ -0,0 +1,400 @@
|
|||
/* Test program to verify that RSA signing is thread-safe in OpenSSL. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
/* Just assume we want to do engine stuff if we're using 0.9.6b or
|
||||
* higher. This assumption is only valid for versions bundled with RHL. */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090602fL
|
||||
#include <openssl/engine.h>
|
||||
#define USE_ENGINE
|
||||
#endif
|
||||
|
||||
#define MAX_THREAD_COUNT 10000
|
||||
#define ITERATION_COUNT 10
|
||||
#define MAIN_COUNT 100
|
||||
|
||||
/* OpenSSL requires us to provide thread ID and locking primitives. */
|
||||
pthread_mutex_t *mutex_locks = NULL;
|
||||
static unsigned long
|
||||
thread_id_cb(void)
|
||||
{
|
||||
return (unsigned long) pthread_self();
|
||||
}
|
||||
static void
|
||||
lock_cb(int mode, int n, const char *file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK) {
|
||||
pthread_mutex_lock(&mutex_locks[n]);
|
||||
} else {
|
||||
pthread_mutex_unlock(&mutex_locks[n]);
|
||||
}
|
||||
}
|
||||
|
||||
struct thread_args {
|
||||
RSA *rsa;
|
||||
int digest_type;
|
||||
unsigned char *digest;
|
||||
unsigned int digest_len;
|
||||
unsigned char *signature;
|
||||
unsigned int signature_len;
|
||||
pthread_t main_thread;
|
||||
};
|
||||
|
||||
static int print = 0;
|
||||
|
||||
pthread_mutex_t sign_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int locked_sign = 0;
|
||||
static void SIGN_LOCK() {if (locked_sign) pthread_mutex_lock(&sign_lock);}
|
||||
static void SIGN_UNLOCK() {if (locked_sign) pthread_mutex_unlock(&sign_lock);}
|
||||
|
||||
pthread_mutex_t verify_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int locked_verify = 0;
|
||||
static void VERIFY_LOCK() {if (locked_verify) pthread_mutex_lock(&verify_lock);}
|
||||
static void VERIFY_UNLOCK() {if (locked_verify) pthread_mutex_unlock(&verify_lock);}
|
||||
|
||||
pthread_mutex_t failure_count_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
long failure_count = 0;
|
||||
static void
|
||||
failure()
|
||||
{
|
||||
pthread_mutex_lock(&failure_count_lock);
|
||||
failure_count++;
|
||||
pthread_mutex_unlock(&failure_count_lock);
|
||||
}
|
||||
|
||||
static void *
|
||||
thread_main(void *argp)
|
||||
{
|
||||
struct thread_args *args = argp;
|
||||
unsigned char *signature;
|
||||
unsigned int signature_len, signature_alloc_len;
|
||||
int ret, i;
|
||||
|
||||
signature_alloc_len = args->signature_len;
|
||||
if (RSA_size(args->rsa) > signature_alloc_len) {
|
||||
signature_alloc_len = RSA_size(args->rsa);
|
||||
}
|
||||
signature = malloc(signature_alloc_len);
|
||||
if (signature == NULL) {
|
||||
fprintf(stderr, "Skipping checks in thread %lu -- %s.\n",
|
||||
(unsigned long) pthread_self(), strerror(errno));
|
||||
pthread_exit(0);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < ITERATION_COUNT; i++) {
|
||||
signature_len = signature_alloc_len;
|
||||
SIGN_LOCK();
|
||||
ret = RSA_check_key(args->rsa);
|
||||
ERR_print_errors_fp(stdout);
|
||||
if (ret != 1) {
|
||||
failure();
|
||||
break;
|
||||
}
|
||||
ret = RSA_sign(args->digest_type,
|
||||
args->digest,
|
||||
args->digest_len,
|
||||
signature, &signature_len,
|
||||
args->rsa);
|
||||
SIGN_UNLOCK();
|
||||
ERR_print_errors_fp(stdout);
|
||||
if (ret != 1) {
|
||||
failure();
|
||||
break;
|
||||
}
|
||||
|
||||
VERIFY_LOCK();
|
||||
ret = RSA_verify(args->digest_type,
|
||||
args->digest,
|
||||
args->digest_len,
|
||||
signature, signature_len,
|
||||
args->rsa);
|
||||
VERIFY_UNLOCK();
|
||||
if (ret != 1) {
|
||||
fprintf(stderr,
|
||||
"Signature from thread %lu(%d) fails "
|
||||
"verification (passed in thread #%lu)!\n",
|
||||
(long) pthread_self(), i,
|
||||
(long) args->main_thread);
|
||||
ERR_print_errors_fp(stdout);
|
||||
failure();
|
||||
continue;
|
||||
}
|
||||
if (print) {
|
||||
fprintf(stderr, ">%d\n", i);
|
||||
}
|
||||
}
|
||||
free(signature);
|
||||
|
||||
pthread_exit(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
xmemdup(unsigned char *s, size_t len)
|
||||
{
|
||||
unsigned char *r;
|
||||
r = malloc(len);
|
||||
if (r == NULL) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
ERR_print_errors_fp(stdout);
|
||||
assert(r != NULL);
|
||||
}
|
||||
memcpy(r, s, len);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
RSA *rsa;
|
||||
MD5_CTX md5;
|
||||
int fd, i;
|
||||
pthread_t threads[MAX_THREAD_COUNT];
|
||||
int thread_count = 1000;
|
||||
unsigned char *message, *digest;
|
||||
unsigned int message_len, digest_len;
|
||||
unsigned char *correct_signature;
|
||||
unsigned int correct_siglen, ret;
|
||||
struct thread_args master_args, *args;
|
||||
int sync = 0, seed = 0;
|
||||
int again = 1;
|
||||
#ifdef USE_ENGINE
|
||||
char *engine = NULL;
|
||||
ENGINE *e = NULL;
|
||||
#endif
|
||||
|
||||
pthread_mutex_init(&failure_count_lock, NULL);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--seed") == 0) {
|
||||
printf("Seeding PRNG.\n");
|
||||
seed++;
|
||||
} else
|
||||
if (strcmp(argv[i], "--sync") == 0) {
|
||||
printf("Running synchronized.\n");
|
||||
sync++;
|
||||
} else
|
||||
if ((strcmp(argv[i], "--threads") == 0) && (i < argc - 1)) {
|
||||
i++;
|
||||
thread_count = atol(argv[i]);
|
||||
if (thread_count > MAX_THREAD_COUNT) {
|
||||
thread_count = MAX_THREAD_COUNT;
|
||||
}
|
||||
printf("Starting %d threads.\n", thread_count);
|
||||
sync++;
|
||||
} else
|
||||
if (strcmp(argv[i], "--sign") == 0) {
|
||||
printf("Locking signing.\n");
|
||||
locked_sign++;
|
||||
} else
|
||||
if (strcmp(argv[i], "--verify") == 0) {
|
||||
printf("Locking verifies.\n");
|
||||
locked_verify++;
|
||||
} else
|
||||
if (strcmp(argv[i], "--print") == 0) {
|
||||
printf("Tracing.\n");
|
||||
print++;
|
||||
#ifdef USE_ENGINE
|
||||
} else
|
||||
if ((strcmp(argv[i], "--engine") == 0) && (i < argc - 1)) {
|
||||
printf("Using engine \"%s\".\n", argv[i + 1]);
|
||||
engine = argv[i + 1];
|
||||
i++;
|
||||
#endif
|
||||
} else {
|
||||
printf("Bad argument: %s\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get some random data to sign. */
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "Error opening /dev/urandom: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
if (print) {
|
||||
fprintf(stderr, "Reading random data.\n");
|
||||
}
|
||||
message = malloc(message_len = 9371);
|
||||
read(fd, message, message_len);
|
||||
close(fd);
|
||||
|
||||
/* Initialize the SSL library and set up thread-safe locking. */
|
||||
ERR_load_crypto_strings();
|
||||
SSL_library_init();
|
||||
mutex_locks = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
|
||||
for (i = 0; i < CRYPTO_num_locks(); i++) {
|
||||
pthread_mutex_init(&mutex_locks[i], NULL);
|
||||
}
|
||||
CRYPTO_set_id_callback(thread_id_cb);
|
||||
CRYPTO_set_locking_callback(lock_cb);
|
||||
ERR_print_errors_fp(stdout);
|
||||
|
||||
/* Seed the PRNG if we were asked to do so. */
|
||||
if (seed) {
|
||||
if (print) {
|
||||
fprintf(stderr, "Seeding PRNG.\n");
|
||||
}
|
||||
RAND_add(message, message_len, message_len);
|
||||
ERR_print_errors_fp(stdout);
|
||||
}
|
||||
|
||||
/* Turn on a hardware crypto device if asked to do so. */
|
||||
#ifdef USE_ENGINE
|
||||
if (engine) {
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090700fL
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
if (print) {
|
||||
fprintf(stderr, "Initializing \"%s\" engine.\n",
|
||||
engine);
|
||||
}
|
||||
e = ENGINE_by_id(engine);
|
||||
ERR_print_errors_fp(stdout);
|
||||
if (e) {
|
||||
i = ENGINE_init(e);
|
||||
ERR_print_errors_fp(stdout);
|
||||
i = ENGINE_set_default_RSA(e);
|
||||
ERR_print_errors_fp(stdout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compute the digest for the signature. */
|
||||
if (print) {
|
||||
fprintf(stderr, "Computing digest.\n");
|
||||
}
|
||||
digest = malloc(digest_len = MD5_DIGEST_LENGTH);
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, message, message_len);
|
||||
MD5_Final(digest, &md5);
|
||||
|
||||
/* Generate a signing key. */
|
||||
if (print) {
|
||||
fprintf(stderr, "Generating key.\n");
|
||||
}
|
||||
rsa = RSA_generate_key(4096, 3, NULL, NULL);
|
||||
ERR_print_errors_fp(stdout);
|
||||
if (rsa == NULL) {
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/* Sign the data. */
|
||||
correct_siglen = RSA_size(rsa);
|
||||
correct_signature = malloc(correct_siglen);
|
||||
for (i = 0; i < MAIN_COUNT; i++) {
|
||||
if (print) {
|
||||
fprintf(stderr, "Signing data (%d).\n", i);
|
||||
}
|
||||
ret = RSA_check_key(rsa);
|
||||
ERR_print_errors_fp(stdout);
|
||||
if (ret != 1) {
|
||||
failure();
|
||||
}
|
||||
correct_siglen = RSA_size(rsa);
|
||||
ret = RSA_sign(NID_md5, digest, digest_len,
|
||||
correct_signature, &correct_siglen,
|
||||
rsa);
|
||||
ERR_print_errors_fp(stdout);
|
||||
if (ret != 1) {
|
||||
_exit(2);
|
||||
}
|
||||
if (print) {
|
||||
fprintf(stderr, "Verifying data (%d).\n", i);
|
||||
}
|
||||
ret = RSA_verify(NID_md5, digest, digest_len,
|
||||
correct_signature, correct_siglen,
|
||||
rsa);
|
||||
if (ret != 1) {
|
||||
_exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Collect up the inforamtion which other threads will need for
|
||||
* comparing their signature results with ours. */
|
||||
master_args.rsa = rsa;
|
||||
master_args.digest_type = NID_md5;
|
||||
master_args.digest = digest;
|
||||
master_args.digest_len = digest_len;
|
||||
master_args.signature = correct_signature;
|
||||
master_args.signature_len = correct_siglen;
|
||||
master_args.main_thread = pthread_self();
|
||||
|
||||
fprintf(stdout, "Performing %d signatures in each of %d threads "
|
||||
"(%d, %d).\n", ITERATION_COUNT, thread_count,
|
||||
digest_len, correct_siglen);
|
||||
fflush(NULL);
|
||||
|
||||
/* Start up all of the threads. */
|
||||
for (i = 0; i < thread_count; i++) {
|
||||
args = malloc(sizeof(struct thread_args));
|
||||
args->rsa = RSAPrivateKey_dup(master_args.rsa);
|
||||
args->digest_type = master_args.digest_type;
|
||||
args->digest_len = master_args.digest_len;
|
||||
args->digest = xmemdup(master_args.digest, args->digest_len);
|
||||
args->signature_len = master_args.signature_len;
|
||||
args->signature = xmemdup(master_args.signature,
|
||||
args->signature_len);
|
||||
args->main_thread = pthread_self();
|
||||
ret = pthread_create(&threads[i], NULL, thread_main, args);
|
||||
while ((ret != 0) && (errno == EAGAIN)) {
|
||||
ret = pthread_create(&threads[i], NULL,
|
||||
thread_main, &args);
|
||||
fprintf(stderr, "Thread limit hit at %d.\n", i);
|
||||
}
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Unable to create thread %d: %s.\n",
|
||||
i, strerror(errno));
|
||||
threads[i] = -1;
|
||||
} else {
|
||||
if (sync) {
|
||||
ret = pthread_join(threads[i], NULL);
|
||||
assert(ret == 0);
|
||||
}
|
||||
if (print) {
|
||||
fprintf(stderr, "%d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for all threads to complete. So long as we can find an
|
||||
* unjoined thread, keep joining threads. */
|
||||
do {
|
||||
again = 0;
|
||||
for (i = 0; i < thread_count; i++) {
|
||||
/* If we have an unterminated thread, join it. */
|
||||
if (threads[i] != -1) {
|
||||
again = 1;
|
||||
if (print) {
|
||||
fprintf(stderr, "Joining thread %d.\n",
|
||||
i);
|
||||
}
|
||||
pthread_join(threads[i], NULL);
|
||||
threads[i] = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (again == 1);
|
||||
|
||||
fprintf(stderr, "%ld failures\n", failure_count);
|
||||
|
||||
return (failure_count != 0);
|
||||
}
|
Loading…
Add table
Reference in a new issue