The socket close enumerations are being directly passed to shutdown().
This is not correct because they do not directly map.
Use the size_read and size_write already provided in the socket file.
This allows for the length to be exclusively a write (better practice).
Provide f_signal_wait() and f_signal_wait_until() functions that handle sigwaitinfo() and sigtimedwait() respectively.
Use uint8_t rather than unsigned short.
The fact that there is still a short in use here makes it clear that I have not even glanced at this file in a long long time.
}
signal->id = 0;
+
return F_none;
}
#endif // _di_f_signal_close_
}
signal->id = result;
+
return F_none;
}
#endif // _di_f_signal_open_
}
#endif // _di_f_signal_set_has_
+#ifndef _di_f_signal_wait_
+ f_status_t f_signal_wait(const sigset_t *set, siginfo_t *information) {
+
+ if (sigwaitinfo(set, information) < 0) {
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_signal_wait_
+
+#ifndef _di_f_signal_wait_until_
+ f_status_t f_signal_wait_until(const sigset_t *set, const struct timespec *timeout, siginfo_t *information) {
+
+ if (sigtimedwait(set, information, timeout) < 0) {
+ if (errno == EAGAIN) return F_time_out;
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_signal_wait_until_
+
#ifdef __cplusplus
} // extern "C"
#endif
* F_input_output (with error bit) if an I/O error occurred.
* F_interrupt (with error bit) when program received an interrupt signal, halting operation.
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see close()
* F_file_descriptor_max (with error bit) if max file descriptors is reached.
* F_memory_not (with error bit) if out of memory.
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see signalfd()
* F_parameter (with error bit) if a parameter is invalid.
* F_input_output (with error bit) on I/O error.
* F_file_type_directory (with error bit) if file descriptor represents a directory.
+ *
* F_failure (with error bit) for any other error.
*
* @see poll()
* F_parameter (with error bit) if a parameter is invalid.
* F_prohibited (with error bit) if not allowed to send signals to the given process.
* F_found_not (with error bit) if the given process was not found.
+ *
* F_failure (with error bit) for any other error.
*
* @see kill()
* F_none on success but no signal found.
*
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see sigaddset()
* F_none on success but no signal found.
*
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see sigdelset()
* F_none on success but no signal found.
*
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see sigemptyset()
* F_none on success but no signal found.
*
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see sigfillset()
* F_none on success but no signal found.
*
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see sigprocmask()
* F_parameter (with error bit) if a parameter is invalid.
* F_resource_not (with error bit) if the max signals is reached.
* F_supported_not (with error bit) if this action is not supported by the current OS.
+ *
* F_failure (with error bit) for any other error.
*
* @see sigqueue()
* F_false if signal is not found.
*
* F_parameter (with error bit) if a parameter is invalid.
+ *
* F_failure (with error bit) for any other error.
*
* @see sigismember()
extern f_status_t f_signal_set_has(const int signal, const sigset_t *set);
#endif // _di_f_signal_set_has_
+/**
+ * Wait until any signal in a set of signals is received.
+ *
+ * @param set
+ * The set of signals to wait for.
+ * @param information
+ * (optional) The resulting signal information.
+ * Set to NULL to not use.
+ *
+ * @return
+ * F_none if signal is found.
+ *
+ * F_interrupt (with error bit) if interrupted by a signal other than one specified in the signal set.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * F_failure (with error bit) for any other error.
+ *
+ * @see sigwaitinfo()
+ */
+#ifndef _di_f_signal_wait_
+ extern f_status_t f_signal_wait(const sigset_t *set, siginfo_t *information);
+#endif // _di_f_signal_wait_
+
+/**
+ * Wait until any signal in a set of signals is received until the given time out is reached.
+ *
+ * @param set
+ * The set of signals to wait for.
+ * @param timeout
+ * The amount of time to wait.
+ * @param information
+ * (optional) The resulting signal information.
+ * Set to NULL to not use.
+ *
+ * @return
+ * F_none if signal is found before time out.
+ * F_time_out if no signal is find by the time out.
+ *
+ * F_interrupt (with error bit) if interrupted by a signal other than one specified in the signal set.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * F_failure (with error bit) for any other error.
+ *
+ * @see sigtimedwait()
+ */
+#ifndef _di_f_signal_wait_until_
+ extern f_status_t f_signal_wait_until(const sigset_t *set, const struct timespec *timeout, siginfo_t *information);
+#endif // _di_f_signal_wait_until_
+
#ifdef __cplusplus
} // extern "C"
#endif
* f_socket_close_*:
* - fast: Fast Socket close, as in close().
* - read: Read close, as in shutdown(, SHUT_RD).
- * - write: Write close, as in shutdown(, SHUT_WR).
* - read_write: Read/Write close, as in shutdown(, SHUT_RDWR).
+ * - write: Write close, as in shutdown(, SHUT_WR).
*/
#ifndef _di_f_socket_closes_
enum {
#endif // _di_f_socket_create_pair_
#ifndef _di_f_socket_disconnect_
- f_status_t f_socket_disconnect(f_socket_t * const socket, const unsigned short action) {
+ f_status_t f_socket_disconnect(f_socket_t * const socket, const uint8_t action) {
#ifndef _di_level_0_parameter_checking_
if (!socket) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
if (action == f_socket_close_fast_e) {
result = close(socket->id);
}
- else if (action == f_socket_close_read_e || action == f_socket_close_write_e || action == f_socket_close_read_write_e) {
- result = shutdown(socket->id, action);
+ else if (action == f_socket_close_read_e) {
+ result = shutdown(socket->id, SHUT_RD);
+ }
+ else if (action == f_socket_close_write_e) {
+ result = shutdown(socket->id, SHUT_WR);
+ }
+ else if (action == f_socket_close_read_write_e) {
+ result = shutdown(socket->id, SHUT_RDWR);
}
else {
return F_status_set_error(F_supported_not);
if (!length) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- const ssize_t result = recvfrom(socket->id, buffer, *length, flags, socket->address, &socket->length);
+ const ssize_t result = recvfrom(socket->id, buffer, socket->size_read, flags, socket->address, &socket->length);
if (result < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (!length) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- const ssize_t result = sendto(socket->id, buffer, *length, flags, socket->address, socket->length);
+ const ssize_t result = sendto(socket->id, buffer, socket->size_write, flags, socket->address, socket->length);
if (result < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
* @see shutdown()
*/
#ifndef _di_f_socket_disconnect_
- extern f_status_t f_socket_disconnect(f_socket_t * const socket, const unsigned short action);
+ extern f_status_t f_socket_disconnect(f_socket_t * const socket, const uint8_t action);
#endif // _di_f_socket_disconnect_
/**
* @param socket
* The socket structure.
* The socket.id must represent a valid socket file descriptor.
+ * The socket.size_read is used to represent the buffer size in buffer and must not be larger than the actual size of the buffer.
* @param flags
* Read flags.
* @param buffer
* @param socket
* The socket structure.
* The socket.id must represent a valid socket file descriptor.
+ * The socket.size_write is used to represent the buffer size in buffer and must not be larger than the actual size of the buffer.
* @param flags
* Read flags.
* @param buffer