The f_signal_pause() just calls pause() and returns F_none.
The return value of pause() is meaningless if I am understanding the man pages correctly.
It should always return -1 and then sets errno despite this not being an actual error.
extern "C" {
#endif
+#ifndef _di_f_signal_action_
+ f_status_t f_signal_action(const f_signal_t signal, const struct sigaction * const action, struct sigaction *previous) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!action && !previous) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (sigaction(signal.id, action, previous) == -1) {
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_signal_action_
+
#ifndef _di_f_signal_close_
f_status_t f_signal_close(f_signal_t * const signal) {
#ifndef _di_level_0_parameter_checking_
}
#endif // _di_f_signal_open_
+#ifndef _di_f_signal_pause_
+ f_status_t f_signal_pause(void) {
+
+ pause();
+
+ return F_none;
+ }
+#endif // _di_f_signal_pause_
+
#ifndef _di_f_signal_queue_
f_status_t f_signal_queue(const pid_t id, const int signal, const union sigval value) {
}
#endif // _di_f_signal_set_has_
+#ifndef _di_f_signal_suspend_
+ f_status_t f_signal_suspend(const sigset_t * const mask) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!mask) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ const int result = sigsuspend(mask);
+
+ if (result == -1) {
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_signal_suspend_
+
#ifndef _di_f_signal_wait_
f_status_t f_signal_wait(const sigset_t * const set, siginfo_t * const information) {
#endif
/**
+ * Get or set the signal action handlers.
+ *
+ * @param signal
+ * The signal settings.
+ * @param action
+ * (optional) The signal action to use.
+ * Set to NULL to not use.
+ * Both action and previous may not be NULL.
+ * @param previous
+ * (optional) The previous signal action.
+ * Set to NULL to not use.
+ *
+ * @return
+ * F_none on success but no signal found.
+ *
+ * F_buffer (with error bit) if the buffer is invalid (action or previous point to invalid memory).
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * F_failure (with error bit) for any other error.
+ *
+ * @see sigaction()
+ */
+#ifndef _di_f_signal_action_
+ extern f_status_t f_signal_action(const f_signal_t signal, const struct sigaction * const action, struct sigaction *previous);
+#endif // _di_f_signal_action_
+
+/**
* Close an open signal descriptor.
*
* The signal.id is set to 0 on success.
* @return
* F_none on success.
* F_data_not on success, but no descriptor was provided to close.
+ *
* F_descriptor (with error bit) if id is an invalid descriptor.
* F_filesystem_quota_block (with error bit) if file system's disk blocks or inodes are exhausted.
* F_input_output (with error bit) if an I/O error occurred.
#endif // _di_f_signal_open_
/**
+ * Pause the current process until a signal is received.
+ *
+ * @return
+ * The received signal.
+ *
+ * @see pause()
+ */
+#ifndef _di_f_signal_pause_
+ extern f_status_t f_signal_pause(void);
+#endif // _di_f_signal_pause_
+
+/**
* Send the signal and value to the given process.
*
* @param id
#endif // _di_f_signal_set_has_
/**
+ * Suspend the current process until one of the provided signals is received.
+ *
+ * @param mask
+ * The signal mask.
+ *
+ * @return
+ * F_none on success but no signal found.
+ *
+ * F_buffer (with error bit) if the mask is pointing to invalid memory.
+ * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
+ *
+ * F_failure (with error bit) for any other error.
+ *
+ * @see sigsuspend()
+ */
+#ifndef _di_f_signal_suspend_
+ extern f_status_t f_signal_suspend(const sigset_t * const mask);
+#endif // _di_f_signal_suspend_
+
+/**
* Wait until any signal in a set of signals is received.
*
* @param set
# Inject mocks.
flags -Wl,--wrap=close
flags -Wl,--wrap=kill
+flags -Wl,--wrap=pause
flags -Wl,--wrap=poll
flags -Wl,--wrap=read
+flags -Wl,--wrap=sigaction
flags -Wl,--wrap=sigaddset
flags -Wl,--wrap=sigdelset
flags -Wl,--wrap=sigemptyset
flags -Wl,--wrap=signalfd
flags -Wl,--wrap=sigprocmask
flags -Wl,--wrap=sigqueue
+flags -Wl,--wrap=sigsuspend
flags -Wl,--wrap=sigtimedwait
flags -Wl,--wrap=sigwaitinfo
build_libraries -lc -lcmocka
build_libraries-individual -lf_memory -lf_string -lf_signal
-build_sources_program test-signal-close.c test-signal-mask.c test-signal-open.c test-signal-queue.c test-signal-read.c test-signal-send.c test-signal-set_add.c test-signal-set_delete.c test-signal-set_empty.c test-signal-set_fill.c test-signal-set_has.c test-signal-wait.c test-signal-wait_until.c
+build_sources_program test-signal-action.c test-signal-close.c test-signal-mask.c test-signal-open.c test-signal-pause.c test-signal-queue.c test-signal-read.c test-signal-send.c test-signal-set_add.c test-signal-set_delete.c test-signal-set_empty.c test-signal-set_fill.c test-signal-set_has.c test-signal-suspend.c test-signal-wait.c test-signal-wait_until.c
build_sources_program test-signal.c
build_script no
extern "C" {
#endif
+int __wrap_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return -1;
+ }
+
+ return 0;
+}
+
int __wrap_close(int fd) {
const bool failure = mock_type(bool);
return 0;
}
+int __wrap_pause(void) {
+
+ return -1;
+}
+
int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
const bool failure = mock_type(bool);
return 0;
}
+int __wrap_sigsuspend(const sigset_t *mask) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return -1;
+ }
+
+ return 0;
+}
+
int __wrap_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) {
const bool failure = mock_type(bool);
const static int mock_errno_generic = 32767;
+extern int __wrap_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
extern int __wrap_close(int fd);
extern int __wrap_kill(pid_t pid, int sig);
+extern int __wrap_pause(void);
extern int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout);
extern ssize_t __wrap_read(int fd, void *buf, size_t count);
extern int __wrap_sigaddset(sigset_t *set, int signum);
extern int __wrap_signalfd(int fd, const sigset_t *mask, int flags);
extern int __wrap_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
extern int __wrap_sigqueue(pid_t pid, int sig, const union sigval value);
+extern int __wrap_sigsuspend(const sigset_t *mask);
extern int __wrap_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout);
extern int __wrap_sigwaitinfo(const sigset_t *set, siginfo_t *info);
--- /dev/null
+#include "test-signal.h"
+#include "test-signal-action.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_action__fails(void **state) {
+
+ f_signal_t signal = f_signal_t_initialize;
+
+ struct sigaction action;
+ struct sigaction previous;
+
+ memset(&action, 0, sizeof(struct sigaction));
+ memset(&previous, 0, sizeof(struct sigaction));
+
+ {
+ int errnos[] = {
+ EFAULT,
+ EINVAL,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_buffer,
+ F_parameter,
+ F_failure,
+ };
+
+ for (int i = 0; i < 3; ++i) {
+
+ will_return(__wrap_sigaction, true);
+ will_return(__wrap_sigaction, errnos[i]);
+
+ const f_status_t status = f_signal_action(signal, &action, 0);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+
+ for (int i = 0; i < 3; ++i) {
+
+ will_return(__wrap_sigaction, true);
+ will_return(__wrap_sigaction, errnos[i]);
+
+ const f_status_t status = f_signal_action(signal, 0, &previous);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+
+ for (int i = 0; i < 3; ++i) {
+
+ will_return(__wrap_sigaction, true);
+ will_return(__wrap_sigaction, errnos[i]);
+
+ const f_status_t status = f_signal_action(signal, &action, &previous);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+ }
+}
+
+void test__f_signal_action__parameter_checking(void **state) {
+
+ f_signal_t signal = f_signal_t_initialize;
+
+ {
+ const f_status_t status = f_signal_action(signal, 0, 0);
+
+ assert_int_equal(status, F_status_set_error(F_parameter));
+ }
+}
+
+void test__f_signal_action__works(void **state) {
+
+ f_signal_t signal = f_signal_t_initialize;
+
+ struct sigaction action;
+ struct sigaction previous;
+
+ memset(&action, 0, sizeof(struct sigaction));
+ memset(&previous, 0, sizeof(struct sigaction));
+
+ {
+ will_return(__wrap_sigaction, false);
+
+ const f_status_t status = f_signal_action(signal, &action, 0);
+
+ assert_int_equal(status, F_none);
+ }
+
+ {
+ will_return(__wrap_sigaction, false);
+
+ const f_status_t status = f_signal_action(signal, 0, &previous);
+
+ assert_int_equal(status, F_none);
+ }
+
+ {
+ will_return(__wrap_sigaction, false);
+
+ const f_status_t status = f_signal_action(signal, &action, &previous);
+
+ assert_int_equal(status, F_none);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.6
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_action_h
+#define _TEST__F_signal_action_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_action()
+ */
+extern void test__f_signal_action__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_action()
+ */
+extern void test__f_signal_action__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_action()
+ */
+extern void test__f_signal_action__works(void **state);
+
+#endif // _TEST__F_signal_action_h
--- /dev/null
+#include "test-signal.h"
+#include "test-signal-pause.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_pause__works(void **state) {
+
+ {
+ const f_status_t status = f_signal_pause();
+
+ assert_int_equal(status, F_none);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.6
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_pause_h
+#define _TEST__F_signal_pause_h
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_pause()
+ */
+extern void test__f_signal_pause__works(void **state);
+
+#endif // _TEST__F_signal_pause_h
--- /dev/null
+#include "test-signal.h"
+#include "test-signal-suspend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_suspend__fails(void **state) {
+
+ sigset_t set;
+
+ memset(&set, 0, sizeof(sigset_t));
+
+ {
+ int errnos[] = {
+ EFAULT,
+ EINTR,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_buffer,
+ F_interrupt,
+ F_failure,
+ };
+
+ for (int i = 0; i < 3; ++i) {
+
+ will_return(__wrap_sigsuspend, true);
+ will_return(__wrap_sigsuspend, errnos[i]);
+
+ const f_status_t status = f_signal_suspend(&set);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+ }
+}
+
+void test__f_signal_suspend__parameter_checking(void **state) {
+
+ {
+ const f_status_t status = f_signal_suspend(0);
+
+ assert_int_equal(status, F_status_set_error(F_parameter));
+ }
+}
+
+void test__f_signal_suspend__works(void **state) {
+
+ {
+ sigset_t set;
+
+ memset(&set, 0, sizeof(sigset_t));
+
+ will_return(__wrap_sigsuspend, false);
+
+ const f_status_t status = f_signal_suspend(&set);
+
+ assert_int_equal(status, F_none);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.6
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_suspend_h
+#define _TEST__F_signal_suspend_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_suspend()
+ */
+extern void test__f_signal_suspend__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_suspend()
+ */
+extern void test__f_signal_suspend__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_suspend()
+ */
+extern void test__f_signal_suspend__works(void **state);
+
+#endif // _TEST__F_signal_suspend_h
int main(void) {
const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test__f_signal_action__fails),
+ cmocka_unit_test(test__f_signal_action__works),
+
cmocka_unit_test(test__f_signal_close__fails),
cmocka_unit_test(test__f_signal_close__works),
cmocka_unit_test(test__f_signal_open__fails),
cmocka_unit_test(test__f_signal_open__works),
+ cmocka_unit_test(test__f_signal_pause__works),
+
cmocka_unit_test(test__f_signal_queue__fails),
cmocka_unit_test(test__f_signal_queue__works),
cmocka_unit_test(test__f_signal_set_has__fails),
cmocka_unit_test(test__f_signal_set_has__works),
+ cmocka_unit_test(test__f_signal_suspend__fails),
+ cmocka_unit_test(test__f_signal_suspend__works),
+
cmocka_unit_test(test__f_signal_wait__fails),
cmocka_unit_test(test__f_signal_wait__works),
cmocka_unit_test(test__f_signal_wait_until__works),
#ifndef _di_level_0_parameter_checking_
+ cmocka_unit_test(test__f_signal_action__parameter_checking),
cmocka_unit_test(test__f_signal_close__parameter_checking),
cmocka_unit_test(test__f_signal_mask__parameter_checking),
cmocka_unit_test(test__f_signal_open__parameter_checking),
+ // f_signal_pause() doesn't use parameter checking.
// f_signal_queue() doesn't use parameter checking.
cmocka_unit_test(test__f_signal_read__parameter_checking),
// f_signal_send() doesn't use parameter checking.
cmocka_unit_test(test__f_signal_set_empty__parameter_checking),
cmocka_unit_test(test__f_signal_set_fill__parameter_checking),
cmocka_unit_test(test__f_signal_set_has__parameter_checking),
+ cmocka_unit_test(test__f_signal_suspend__parameter_checking),
// f_signal_wait() doesn't use parameter checking.
// f_signal_wait_until() doesn't use parameter checking.
#endif // _di_level_0_parameter_checking_
#include "mock-signal.h"
// Test includes.
+#include "test-signal-action.h"
#include "test-signal-close.h"
#include "test-signal-mask.h"
#include "test-signal-open.h"
+#include "test-signal-pause.h"
#include "test-signal-queue.h"
#include "test-signal-read.h"
#include "test-signal-send.h"
#include "test-signal-set_empty.h"
#include "test-signal-set_fill.h"
#include "test-signal-set_has.h"
+#include "test-signal-suspend.h"
#include "test-signal-wait.h"
#include "test-signal-wait_until.h"