Skip to content

Commit

Permalink
add ansi c support (goatshriek#328)
Browse files Browse the repository at this point in the history
Library compilation and functionality was not portable enough to support
builds in ANSI C only environments, where some functions such as gmtime_r
and getaddrinfo are not provided. This change updates the configuration
and build to support these environments, and improves documentation in the
affected areas of functionality to more clearly convey caveats and
limitations.

This fixes goatshriek#325, which can be referenced for more details.
  • Loading branch information
goatshriek authored Jan 16, 2023
1 parent e59efc4 commit c5926ff
Show file tree
Hide file tree
Showing 59 changed files with 1,188 additions and 349 deletions.
1 change: 1 addition & 0 deletions .github/workflows/analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
scripts/check_l10n.rb "include/private/config/locale/*-??.h"
- name: Build Documentation
run: |
sudo apt-get update
sudo apt-get install doxygen
cmake .
make docs
Expand Down
98 changes: 98 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,59 @@ jobs:
- name: Build Documentation
run: |
make docs
linux-debug-ansi:
name: "linux, debug, ansi"
runs-on: "ubuntu-latest"
env:
CFLAGS: "-D_ANSI_SOURCE -pedantic -Wall -std=c99"
steps:
- name: Install Prereqs
run: |
sudo apt-get update
sudo apt-get install doxygen libsystemd-dev valgrind
- uses: actions/checkout@v3
- name: Configure
run: |
cmake -DCOVERAGE=ON -DCMAKE_BUILD_TYPE=Debug .
- name: Build
run: |
make all
- name: Test
run: |
make check
if grep "DEPRECATED" Testing/Temporary/LastTest.log; then exit 1; fi
- name: Privileged Tests
run: |
sudo ./function-test-tcp4
sudo ./function-test-tcp4_leak
sudo ./function-test-tcp6
sudo ./function-test-tcp6_leak
sudo ./function-test-udp4
sudo ./function-test-udp4_leak
sudo ./function-test-udp6
sudo ./function-test-udp6_leak
- name: Codecov Upload
uses: codecov/codecov-action@v3
with:
fail_ci_if_error: true
gcov: true
- name: Thread Safety Tests
run: |
make check-thread-safety
sudo ./thread-safety-test-network
- name: Run Examples
run: |
make examples
- name: Valgrind Tests
run: |
(for f in $(ls function-test-*); do valgrind --error-exitcode=1 --leak-check=yes --suppressions=tools/valgrind/journald.supp ./$f || exit 1; done)
(for f in $(ls example-*); do valgrind --error-exitcode=1 --leak-check=yes --suppressions=tools/valgrind/journald.supp ./$f || exit 1; done)
- name: Install
run: |
sudo make install
- name: Build Documentation
run: |
make docs
linux-release:
name: "linux, release"
runs-on: "ubuntu-latest"
Expand Down Expand Up @@ -145,6 +198,50 @@ jobs:
run: |
gcc docs/examples/basic/basic_example.c -lstumpless -o basic_example
./basic_example
linux-release-ansi:
name: "linux, release, ansi"
runs-on: "ubuntu-latest"
env:
CFLAGS: "-D_ANSI_SOURCE -pedantic -Wall -std=c99"
steps:
- uses: actions/checkout@v3
- name: Configure
run: |
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr .
- name: Build
run: |
make all
- name: Test
run: |
make check
if grep "DEPRECATED" Testing/Temporary/LastTest.log; then exit 1; fi
- name: Privileged Tests
run: |
sudo ./function-test-tcp4
sudo ./function-test-tcp4_leak
sudo ./function-test-tcp6
sudo ./function-test-tcp6_leak
sudo ./function-test-udp4
sudo ./function-test-udp4_leak
sudo ./function-test-udp6
sudo ./function-test-udp6_leak
- name: Thread Safety Tests
run: |
make check-thread-safety
sudo ./thread-safety-test-network
- name: Run Examples
run: |
make examples
- name: Run Benchmarks
run: |
make bench
- name: Install
run: |
sudo make install
- name: Test Install
run: |
gcc docs/examples/basic/basic_example.c -lstumpless -o basic_example
./basic_example
linux-all-disabled-debug:
name: "linux, all features disabled, debug"
runs-on: "ubuntu-latest"
Expand Down Expand Up @@ -237,6 +334,7 @@ jobs:
bundle install
- name: Install Packages
run: |
sudo apt-get update
sudo apt-get install doxygen
- name: Configure
run: |
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Stumpless Logging Library
license: Apache-2.0
repository-code: "https://github.com/goatshriek/stumpless"
version: 2.2.0
date-released: 2023-01-15
date-released: 2023-01-16
keywords:
- journald
- logging
Expand Down
21 changes: 17 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,12 @@ check_include_files(windows.h HAVE_WINDOWS_H)
check_include_files(winsock2.h HAVE_WINSOCK2_H)

check_symbol_exists(fopen_s stdio.h HAVE_FOPEN_S)
check_symbol_exists(getaddrinfo netdb.h HAVE_GETADDRINFO)
check_symbol_exists(gethostname unistd.h HAVE_UNISTD_GETHOSTNAME)
check_symbol_exists(gethostbyname netdb.h HAVE_GETHOSTBYNAME)
check_symbol_exists(gethostbyname2 netdb.h HAVE_GETHOSTBYNAME2)
check_symbol_exists(getpagesize unistd.h HAVE_UNISTD_GETPAGESIZE)
check_symbol_exists(gmtime time.h HAVE_GMTIME)
check_symbol_exists(gmtime_r time.h HAVE_GMTIME_R)
check_symbol_exists(_SC_PAGESIZE unistd.h HAVE_UNISTD_SC_PAGESIZE)
check_symbol_exists(sprintf_s stdio.h HAVE_SPRINTF_S)
Expand Down Expand Up @@ -266,10 +270,6 @@ if(HAVE_FOPEN_S)
list(APPEND STUMPLESS_SOURCES src/config/have_fopen_s.c)
endif(HAVE_FOPEN_S)

if(HAVE_GMTIME_R)
list(APPEND STUMPLESS_SOURCES src/config/have_gmtime_r.c)
endif(HAVE_GMTIME_R)

if(HAVE_PTHREAD_H)
list(APPEND STUMPLESS_SOURCES src/config/have_pthread.c)
endif()
Expand Down Expand Up @@ -305,6 +305,12 @@ if(HAVE_WINDOWS_H AND HAVE_SPRINTF_S)
list(APPEND STUMPLESS_SOURCES src/config/windows_get_now_supported.c)
endif()

if(HAVE_GMTIME_R)
list(APPEND STUMPLESS_SOURCES src/config/have_gmtime_r.c)
elseif(NOT SUPPORT_WINDOWS_GET_NOW AND HAVE_GMTIME)
list(APPEND STUMPLESS_SOURCES src/config/have_gmtime.c)
endif()

if(HAVE_UNISTD_GETHOSTNAME)
list(APPEND STUMPLESS_SOURCES src/config/have_unistd_gethostname.c)
elseif(NOT HAVE_WINSOCK2_H)
Expand Down Expand Up @@ -450,6 +456,13 @@ else()
if(HAVE_SYS_SOCKET_H)
list(APPEND STUMPLESS_SOURCES src/config/have_sys_socket.c)
set(HAVE_WINSOCK2_H FALSE)

if(HAVE_GETADDRINFO)
list(APPEND STUMPLESS_SOURCES src/config/have_getaddrinfo.c)
elseif(HAVE_GETHOSTBYNAME2 OR HAVE_GETHOSTBYNAME)
set(SUPPORT_GETHOSTBYNAME TRUE)
list(APPEND STUMPLESS_SOURCES src/config/gethostbyname_supported.c)
endif()
elseif(HAVE_WINSOCK2_H)
list(APPEND STUMPLESS_SOURCES src/config/have_winsock2.c)
find_library(WINSOCK2 NAMES Ws2_32)
Expand Down
3 changes: 2 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ fixes, check out the
[roadmap](https://github.com/goatshriek/stumpless/blob/master/docs/roadmap.md).


## [2.2.0] - 2022-11-26
## [2.2.0] - 2023-01-16
### Fixed
- Deadlock potential in `stumpless_set_entry_hostname` and
`stumpless_set_entry_procid` when validation fails.
- Builds in ANSI C environments.


## [2.1.0] - 2022-11-13
Expand Down
7 changes: 6 additions & 1 deletion include/private/config.h.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0 */

/*
* Copyright 2018-2022 Joel E. Anderson
* Copyright 2018-2023 Joel E. Anderson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,6 +31,10 @@

/* symbol checks */
#cmakedefine HAVE_FOPEN_S 1
#cmakedefine HAVE_GETADDRINFO 1
#cmakedefine HAVE_GETHOSTBYNAME 1
#cmakedefine HAVE_GETHOSTBYNAME2 1
#cmakedefine HAVE_GMTIME 1
#cmakedefine HAVE_GMTIME_R 1
#cmakedefine HAVE_UNISTD_SC_PAGESIZE 1
#cmakedefine HAVE_UNISTD_GETHOSTNAME 1
Expand All @@ -42,6 +46,7 @@

/* function support checks */
#cmakedefine SUPPORT_ABSTRACT_SOCKET_NAMES 1
#cmakedefine SUPPORT_GETHOSTBYNAME 1
#cmakedefine SUPPORT_UNISTD_SYSCONF_GETPAGESIZE 1
#cmakedefine SUPPORT_WINDOWS_GET_NOW 1

Expand Down
73 changes: 73 additions & 0 deletions include/private/config/gethostbyname_supported.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: Apache-2.0 */

/*
* Copyright 2023 Joel E. Anderson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @file
* Functionality to perform name resolution for a given host and connecting
* to it, based on `gethostbyname` functions.
*/

#ifndef __STUMPLESS_PRIVATE_CONFIG_GETHOSTBYNAME_SUPPORTED_H
# define __STUMPLESS_PRIVATE_CONFIG_GETHOSTBYNAME_SUPPORTED_H

/**
* Resolves the provided hostname, and attempts to connect to the resulting
* address on a newly-created socket.
*
* If gethostbyname2 is available, it will be used for the name resolution. If
* not, then gethostbyname is used instead.
*
* If gethostbyname[2] cannot resolve the name, then inet_pton is tried. If both
* of these fail to return an address, then this function returns -1 and raises
* an error that the name could not be resolved.
*
* **Thread Safety: MT-Safe race:destination race:port env locale**
* This function is thread safe, with some caveats. The destination and port
* must not be changed during execution. gethostbyname and inet_pton also uses
* env and locale variables, which may cause issues for some usages.
*
* **Async Signal Safety: AS-Unsafe**
* This function is not safe to call from signal handlers due to the use of
* static pointers returned by gethostbyname.
*
* **Async Cancel Safety: AC-Unsafe**
* This function is not safe to call from threads that may be asynchronously
* cancelled, due to the use of a lock that could be left locked as well as
* memory management functions.
*
* @since release v2.2.0
*
* @param destination The hostname or address to connect to.
*
* @param port The port to connect to on the given host.
*
* @param domain The socket domain to use for the connection.
*
* @param type The type of socket to create.
*
* @param protocol The protocol to use for the connection.
*
* @return The connected socket, or -1 if an error is encountered.
*/
int
gethostbyname_int_connect( const char *destination,
const char *port,
int domain,
int type,
int protocol );

#endif /* __STUMPLESS_PRIVATE_CONFIG_GETHOSTBYNAME_SUPPORTED_H */
64 changes: 64 additions & 0 deletions include/private/config/have_getaddrinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: Apache-2.0 */

/*
* Copyright 2023 Joel E. Anderson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @file
* Functionality to perform name resolution for a given host and connecting
* to it, based on getaddrinfo.
*/

#ifndef __STUMPLESS_PRIVATE_CONFIG_HAVE_GETADDRINFO_H
# define __STUMPLESS_PRIVATE_CONFIG_HAVE_GETADDRINFO_H

/**
* Resolves the provided hostname, and attempts to connect to the resulting
* address on a newly-created socket.
*
* **Thread Safety: MT-Safe race:destination race:port env locale**
* This function is thread safe, with some caveats. The destination and port
* must not be changed during execution. getaddrinfo also uses env and locale
* variables, which may cause issues for some usages.
*
* **Async Signal Safety: AS-Safe**
* This function is safe to call from signal handlers.
*
* **Async Cancel Safety: AC-Unsafe**
* This function is not safe to call from threads that may be asynchronously
* cancelled, as socket handles may not be cleaned up in this case.
*
* @since release v2.2.0
*
* @param destination The hostname or address to connect to.
*
* @param port The port to connect to on the given host.
*
* @param domain The socket domain to use for the connection.
*
* @param type The type of socket to create.
*
* @param protocol The protocol to use for the connection.
*
* @return The connected socket, or -1 if an error is encountered.
*/
int
getaddrinfo_int_connect( const char *destination,
const char *port,
int domain,
int type,
int protocol );

#endif /* __STUMPLESS_PRIVATE_CONFIG_HAVE_GETADDRINFO_H */
Loading

0 comments on commit c5926ff

Please sign in to comment.