]> Kevux Git Server - fll/commitdiff
Bugfix: The socket id is not the same descriptor for reading.
authorKevin Day <kevin@kevux.org>
Sat, 5 Aug 2023 15:40:14 +0000 (10:40 -0500)
committerKevin Day <kevin@kevux.org>
Sat, 5 Aug 2023 15:45:58 +0000 (10:45 -0500)
When binding and listening on some socket id, the accept call on that socket creates a new descriptor.
That descriptor is not the same as the original socket id.

Add a new id_data to the socket structure to represent the data transfer file descriptor that is created via the accept() call.
Add a new f_file_close_id() to close the file by the id in case the f_file_t is not available or in use.

13 files changed:
level_0/f_file/c/file.c
level_0/f_file/c/file.h
level_0/f_file/c/private-file.c
level_0/f_file/c/private-file.h
level_0/f_file/data/build/settings-tests
level_0/f_file/tests/unit/c/test-file-close_id.c [new file with mode: 0644]
level_0/f_file/tests/unit/c/test-file-close_id.h [new file with mode: 0644]
level_0/f_file/tests/unit/c/test-file.c
level_0/f_file/tests/unit/c/test-file.h
level_0/f_socket/c/socket.c
level_0/f_socket/c/socket.h
level_0/f_socket/c/socket/common.h
level_0/f_socket/tests/unit/c/test-socket-accept.c

index 4434051627652af2aac046012be4b020092dea3b..b6e8f760a91dfc1d1646424777b1cc7f35e5c36c 100644 (file)
@@ -128,10 +128,22 @@ extern "C" {
 
     if (file->id == -1) return F_file_descriptor_not;
 
-    return private_f_file_close(file);
+    return private_f_file_close(&file->id);
   }
 #endif // _di_f_file_close_
 
+#ifndef _di_f_file_close_id_
+  f_status_t f_file_close_id(int * const id) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!id) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (*id == -1) return F_file_descriptor_not;
+
+    return private_f_file_close(id);
+  }
+#endif // _di_f_file_close_id_
+
 #ifndef _di_f_file_copy_
   f_status_t f_file_copy(const f_string_static_t source, const f_string_static_t destination, const f_mode_t mode, const f_number_unsigned_t size_block, const uint8_t flag) {
 
index 250e2fe1b407f03ccd3f02cf4e6e004f6a28e71f..730061ad76bbfd70094aeff73ed0f05f0231aea7 100644 (file)
@@ -203,6 +203,32 @@ extern "C" {
 #endif // _di_f_file_close_
 
 /**
+ * Close an open file directly by the file descriptor.
+ *
+ * Will not flush before closing.
+ *
+ * @param id
+ *   The file descriptor.
+ *
+ * @return
+ *   F_none on success.
+ *   F_file_descriptor_not if id is -1.
+ *
+ *   F_file_close (with error bit) if fclose() failed for any other reason.
+ *   F_file_descriptor (with error bit) if file descriptor is invalid.
+ *   F_file_synchronize (with error bit) on flush failure.
+ *   F_filesystem_quota_block (with error bit) if file system's disk blocks or inodes are exhausted.
+ *   F_input_output (with error bit) on I/O error.
+ *   F_interrupt (with error bit) when program received an interrupt signal, halting operation.
+ *   F_space_not (with error bit) if file system is out of space (or file system quota is reached).
+ *
+ * @see fclose()
+ */
+#ifndef _di_f_file_close_id_
+  extern f_status_t f_file_close_id(int * const id);
+#endif // _di_f_file_close_id_
+
+/**
  * Copy a file.
  *
  * The paths must not contain NULL except for the terminating NULL.
@@ -2108,7 +2134,7 @@ extern "C" {
 #endif // _di_f_file_size_at_
 
 /**
- * Read size of a file relative to the path represented by the file descriptor id.
+ * Read size of a file relative to the path represented by the file descriptor.
  *
  * @param file
  *   The file.
@@ -2171,7 +2197,7 @@ extern "C" {
 #endif // _di_f_file_stat_
 
 /**
- * Read statistics of a file relative to the path represented by the file descriptor id.
+ * Read statistics of a file relative to the path represented by the file descriptor.
  *
  * @param directory
  *   The parent directory, via an open directory file descriptor, in which path is relative to.
@@ -2205,7 +2231,7 @@ extern "C" {
 #endif // _di_f_file_stat_at_
 
 /**
- * Read statistics of a file using a file descriptor id.
+ * Read statistics of a file using a file descriptor.
  *
  * @param file
  *   The file.
index ea3a9ade459d54b47b23a8e5f101166f380830ad..e69ccaf8aa6e18ab4f655c4b2d7339e929b36ee1 100644 (file)
@@ -6,13 +6,13 @@ extern "C" {
 #endif
 
 #if !defined(_di_f_file_clone_) || !defined(_di_f_file_close_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_create_) || !defined(_di_f_file_create_at_) || !defined(_di_f_file_stream_close_)
-  f_status_t private_f_file_close(f_file_t * const file) {
+  f_status_t private_f_file_close(int * const id) {
 
-    if (close(file->id) < 0) {
+    if (close(*id) < 0) {
 
       // According to man pages, retrying close() after another close on error is invalid on Linux because Linux releases the descriptor before stages that cause failures.
       if (errno != EBADF && errno != EINTR) {
-        file->id = -1;
+        *id = -1;
       }
 
       if (errno == EBADF) return F_status_set_error(F_file_descriptor);
@@ -24,7 +24,7 @@ extern "C" {
       return F_status_set_error(F_file_close);
     }
 
-    file->id = -1;
+    *id = -1;
 
     return F_none;
   }
@@ -46,7 +46,7 @@ extern "C" {
 
     if (F_status_is_error(status)) {
       private_f_file_flush(file_source);
-      private_f_file_close(&file_source);
+      private_f_file_close(&file_source.id);
 
       return status;
     }
@@ -65,8 +65,8 @@ extern "C" {
         private_f_file_flush(file_destination);
         private_f_file_flush(file_source);
 
-        private_f_file_close(&file_destination);
-        private_f_file_close(&file_source);
+        private_f_file_close(&file_destination.id);
+        private_f_file_close(&file_source.id);
 
         return F_status_set_error(F_file_write);
       }
@@ -75,8 +75,8 @@ extern "C" {
     private_f_file_flush(file_destination);
     private_f_file_flush(file_source);
 
-    private_f_file_close(&file_destination);
-    private_f_file_close(&file_source);
+    private_f_file_close(&file_destination.id);
+    private_f_file_close(&file_source.id);
 
     if (size_read < 0) return F_status_set_error(F_file_read);
 
@@ -100,7 +100,7 @@ extern "C" {
     if (F_status_is_error_not(status) && file.id != -1) {
       private_f_file_flush(file);
 
-      status = private_f_file_close(&file);
+      status = private_f_file_close(&file.id);
     }
 
     if (F_status_is_error(status)) return status;
@@ -125,7 +125,7 @@ extern "C" {
     if (F_status_is_error_not(status) && file_internal.id != -1) {
       private_f_file_flush(file_internal);
 
-      status = private_f_file_close(&file_internal);
+      status = private_f_file_close(&file_internal.id);
     }
 
     if (F_status_is_error(status)) return status;
index 26f96987e35b1eeb380ae08707f9d54057d46780..cb4df82c555b5c4e7690f03f5ce899af0b11b806 100644 (file)
@@ -20,8 +20,8 @@ extern "C" {
  *
  * Intended to be shared to each of the different implementation variations.
  *
- * @param file
- *   The file to close.
+ * @param id
+ *   The file descriptor to close.
  *   The file descriptor gets set to -1.
  *
  * @return
@@ -47,7 +47,7 @@ extern "C" {
  * @see f_file_stream_close()
  */
 #if !defined(_di_f_file_clone_) || !defined(_di_f_file_close_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_create_) || !defined(_di_f_file_create_at_) || !defined(_di_f_file_stream_close_)
-  extern f_status_t private_f_file_close(f_file_t * const file) F_attribute_visibility_internal_d;
+  extern f_status_t private_f_file_close(int * const id) F_attribute_visibility_internal_d;
 #endif // !defined(_di_f_file_clone_) || !defined(_di_f_file_close_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_create_) || !defined(_di_f_file_create_at_) || !defined(_di_f_file_stream_close_)
 
 /**
index d93bd70ed683cfb4c6d4c62d300071a1e7197429..c7d7c1338dae595271d8e1ee91d47286915100dc 100644 (file)
@@ -25,7 +25,7 @@ build_language c
 build_libraries -lc -lcmocka
 build_libraries-individual -lf_memory -lf_string -lf_file
 
-build_sources_program test-file-access.c test-file-access_at.c test-file-clone.c test-file-close.c test-file-copy.c test-file-create.c test-file-create_at.c test-file-create_device.c test-file-create_device_at.c test-file-create_fifo.c test-file-create_fifo_at.c test-file-create_node.c test-file-create_node_at.c test-file-descriptor.c test-file-exists.c test-file-exists_at.c test-file-flush.c test-file-group_read.c test-file-is.c test-file-is_at.c test-file-is_stat.c test-file-link.c test-file-link_at.c test-file-link_hard.c test-file-link_hard_at.c test-file-link_read.c test-file-link_read_at.c test-file-manipulate.c test-file-mode_determine.c test-file-mode_from_string.c test-file-mode_read.c test-file-mode_read_at.c test-file-mode_set.c test-file-mode_set_at.c test-file-mode_to_mode.c test-file-name_base.c test-file-name_directory.c test-file-open.c test-file-open_at.c test-file-owner_read.c test-file-read.c test-file-read_block.c test-file-read_until.c test-file-remove.c test-file-remove_at.c test-file-rename.c test-file-rename_at.c test-file-role_change.c test-file-role_change_at.c test-file-poll.c test-file-seek.c test-file-select.c test-file-select_signal.c test-file-size.c test-file-size_at.c test-file-size_by_id.c test-file-stat.c test-file-stat_at.c test-file-stat_by_id.c test-file-stream_close.c test-file-stream_open_descriptor.c test-file-stream_open.c test-file-stream_read.c test-file-stream_read_block.c test-file-stream_read_until.c test-file-stream_reopen.c test-file-stream_write.c test-file-stream_write_block.c test-file-stream_write_until.c test-file-stream_write_range.c test-file-touch.c test-file-touch_at.c test-file-type.c test-file-type_at.c test-file-umask_get.c test-file-umask_set.c test-file-write.c test-file-write_block.c test-file-write_until.c test-file-write_range.c
+build_sources_program test-file-access.c test-file-access_at.c test-file-clone.c test-file-close.c test-file-close_id.c test-file-copy.c test-file-create.c test-file-create_at.c test-file-create_device.c test-file-create_device_at.c test-file-create_fifo.c test-file-create_fifo_at.c test-file-create_node.c test-file-create_node_at.c test-file-descriptor.c test-file-exists.c test-file-exists_at.c test-file-flush.c test-file-group_read.c test-file-is.c test-file-is_at.c test-file-is_stat.c test-file-link.c test-file-link_at.c test-file-link_hard.c test-file-link_hard_at.c test-file-link_read.c test-file-link_read_at.c test-file-manipulate.c test-file-mode_determine.c test-file-mode_from_string.c test-file-mode_read.c test-file-mode_read_at.c test-file-mode_set.c test-file-mode_set_at.c test-file-mode_to_mode.c test-file-name_base.c test-file-name_directory.c test-file-open.c test-file-open_at.c test-file-owner_read.c test-file-read.c test-file-read_block.c test-file-read_until.c test-file-remove.c test-file-remove_at.c test-file-rename.c test-file-rename_at.c test-file-role_change.c test-file-role_change_at.c test-file-poll.c test-file-seek.c test-file-select.c test-file-select_signal.c test-file-size.c test-file-size_at.c test-file-size_by_id.c test-file-stat.c test-file-stat_at.c test-file-stat_by_id.c test-file-stream_close.c test-file-stream_open_descriptor.c test-file-stream_open.c test-file-stream_read.c test-file-stream_read_block.c test-file-stream_read_until.c test-file-stream_reopen.c test-file-stream_write.c test-file-stream_write_block.c test-file-stream_write_until.c test-file-stream_write_range.c test-file-touch.c test-file-touch_at.c test-file-type.c test-file-type_at.c test-file-umask_get.c test-file-umask_set.c test-file-write.c test-file-write_block.c test-file-write_until.c test-file-write_range.c
 build_sources_program test-file.c
 
 build_script no
diff --git a/level_0/f_file/tests/unit/c/test-file-close_id.c b/level_0/f_file/tests/unit/c/test-file-close_id.c
new file mode 100644 (file)
index 0000000..96b46b5
--- /dev/null
@@ -0,0 +1,88 @@
+#include "test-file.h"
+#include "test-file-close.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_file_close_id__fails(void **state) {
+
+  {
+    int errnos[] = {
+      EBADF,
+      EINTR,
+      EIO,
+      ENOSPC,
+      EDQUOT,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_file_descriptor,
+      F_interrupt,
+      F_input_output,
+      F_space_not,
+      F_filesystem_quota_block,
+      F_file_close,
+    };
+
+    for (int i = 0; i < 6; ++i) {
+
+      int id = F_type_descriptor_output_d;
+
+      will_return(__wrap_close, true);
+      will_return(__wrap_close, errnos[i]);
+
+      const f_status_t status = f_file_close_id(&id);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+
+      if (errnos[i] == EBADF || errnos[i] == EINTR) {
+        assert_int_equal(id, F_type_descriptor_output_d);
+      }
+      else {
+        assert_int_equal(id, -1);
+      }
+    } // for
+  }
+}
+
+void test__f_file_close_id__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_file_close_id(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_file_close_id__returns_file_descriptor_not(void **state) {
+
+  int id = -1;
+
+  {
+    const f_status_t status = f_file_close_id(&id);
+
+    assert_int_equal(status, F_file_descriptor_not);
+  }
+}
+
+void test__f_file_close_id__works(void **state) {
+
+  int id = F_type_descriptor_output_d;
+
+  {
+
+    will_return(__wrap_close, false);
+    will_return(__wrap_close, 0);
+
+    const f_status_t status = f_file_close_id(&id);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(id, -1);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_file/tests/unit/c/test-file-close_id.h b/level_0/f_file/tests/unit/c/test-file-close_id.h
new file mode 100644 (file)
index 0000000..88527cc
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: File
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the file project.
+ */
+#ifndef _TEST__F_file_close_id_h
+#define _TEST__F_file_close_id_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_file_close_id()
+ */
+extern void test__f_file_close_id__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_file_close_id()
+ */
+extern void test__f_file_close_id__parameter_checking(void **state);
+
+/**
+ * Test that function works but the descriptor is not valid.
+ *
+ * @see f_file_close_id()
+ */
+extern void test__f_file_close_id__returns_file_descriptor_not(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_file_close_id()
+ */
+extern void test__f_file_close_id__works(void **state);
+
+#endif // _TEST__F_file_close_id_h
index ed8c3bdcba2e4851ed2c06d4e8cdcef62f8bb1e2..5be450757d22f74d7e85b8ca4130fabd2c9df624 100644 (file)
@@ -40,6 +40,10 @@ int main(void) {
     cmocka_unit_test(test__f_file_close__returns_file_descriptor_not),
     cmocka_unit_test(test__f_file_close__works),
 
+    cmocka_unit_test(test__f_file_close_id__fails),
+    cmocka_unit_test(test__f_file_close_id__returns_file_descriptor_not),
+    cmocka_unit_test(test__f_file_close_id__works),
+
     cmocka_unit_test(test__f_file_copy__fails_during_read_write),
     cmocka_unit_test(test__f_file_copy__fails_for_block),
     cmocka_unit_test(test__f_file_copy__fails_for_character),
@@ -390,6 +394,7 @@ int main(void) {
       // f_file_access_at() doesn't use parameter checking.
       // f_file_clone() doesn't use parameter checking.
       cmocka_unit_test(test__f_file_close__parameter_checking),
+      cmocka_unit_test(test__f_file_close_id__parameter_checking),
       // f_file_copy() doesn't use parameter checking.
       // f_file_create() doesn't use parameter checking.
       // f_file_create_at() doesn't use parameter checking.
index c7abc55110d9bad94ad56df1e003d95ea4cfd3f1..9d21bb76556a3d4597583a9ce8357278ce6b1452 100644 (file)
@@ -30,6 +30,7 @@
 #include "test-file-access_at.h"
 #include "test-file-clone.h"
 #include "test-file-close.h"
+#include "test-file-close_id.h"
 #include "test-file-copy.h"
 #include "test-file-create.h"
 #include "test-file-create_at.h"
index 1d9ece3c54f9267ce10e7ec823f28b5e533b5d0c..cad16116bc795ba7ce0d2d85292f297ea782f6ee 100644 (file)
@@ -5,12 +5,12 @@ extern "C" {
 #endif
 
 #ifndef _di_f_socket_accept_
-  f_status_t f_socket_accept(f_socket_t * const socket, const int id) {
+  f_status_t f_socket_accept(f_socket_t * const socket) {
     #ifndef _di_level_0_parameter_checking_
       if (!socket) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int result = accept(id, (struct sockaddr *) &socket->address, &socket->length);
+    const int result = accept(socket->id, (struct sockaddr *) &socket->address, &socket->length);
 
     if (result == -1) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
@@ -40,7 +40,7 @@ extern "C" {
       return F_status_set_error(F_failure);
     }
 
-    socket->id = result;
+    socket->id_data = result;
 
     return F_none;
   }
@@ -431,7 +431,7 @@ extern "C" {
       if (!buffer) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const ssize_t result = recvfrom(socket->id, buffer, socket->size_read, flags, (struct sockaddr *) &socket->address, &socket->length);
+    const ssize_t result = recvfrom(socket->id_data, buffer, socket->size_read, flags, (struct sockaddr *) &socket->address, &socket->length);
 
     if (result < 0) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
@@ -470,7 +470,7 @@ extern "C" {
       if (!header) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const ssize_t result = recvmsg(socket->id, header, flags);
+    const ssize_t result = recvmsg(socket->id_data, header, flags);
 
     if (result < 0) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
@@ -509,7 +509,7 @@ extern "C" {
       if (!buffer) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const ssize_t result = recv(socket->id, buffer, socket->size_read, flags);
+    const ssize_t result = recv(socket->id_data, buffer, socket->size_read, flags);
 
     if (result < 0) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
@@ -548,7 +548,7 @@ extern "C" {
       if (!buffer) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const ssize_t result = sendto(socket->id, buffer, socket->size_write, flags, (struct sockaddr *) &socket->address, socket->length);
+    const ssize_t result = sendto(socket->id_data, buffer, socket->size_write, flags, (struct sockaddr *) &socket->address, socket->length);
 
     if (result < 0) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
@@ -590,7 +590,7 @@ extern "C" {
       if (!header) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const ssize_t result = sendmsg(socket->id, header, flags);
+    const ssize_t result = sendmsg(socket->id_data, header, flags);
 
     if (result < 0) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
@@ -632,7 +632,7 @@ extern "C" {
       if (!buffer) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const ssize_t result = send(socket->id, buffer, socket->size_write, flags);
+    const ssize_t result = send(socket->id_data, buffer, socket->size_write, flags);
 
     if (result < 0) {
       if (errno == EACCES) return F_status_set_error(F_access_denied);
index 323a8e2db2c7ac3231cf70dfd2508a1c55c23b3e..cd079621170e0b35273faffe624045d4012c36b8 100644 (file)
@@ -61,9 +61,8 @@ extern "C" {
  * @param socket
  *   The client socket structure.
  *   The structure should be memset as appropriate before calling this.
- *   The properties of the structure, namely socket.id, socket.address, and socket.length, are updated upon a successful return.
- * @param id
- *   The socket file descriptor representing an actively listening socket to retrieve from.
+ *   The socket.id is the socket file descriptor used to establish the data file descriptor socket.id_data.
+ *   The socket.id_data, socket.address, and socket.length are updated upon a successful return.
  *
  * @return
  *   F_none on success.
@@ -97,7 +96,7 @@ extern "C" {
  * @see accept()
  */
 #ifndef _di_f_socket_accept_
-  extern f_status_t f_socket_accept(f_socket_t * const socket, const int id);
+  extern f_status_t f_socket_accept(f_socket_t * const socket);
 #endif // _di_f_socket_accept_
 
 /**
@@ -557,9 +556,11 @@ extern "C" {
  *
  * This is the recommneded way to read UDP streams.
  *
+ * This uses the socket.id_data and not the socket.id for processing the data.
+ *
  * @param socket
  *   The socket structure.
- *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.id_data must represent a valid 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.
@@ -602,9 +603,11 @@ extern "C" {
 /**
  * Read a message from a socket.
  *
+ * This uses the socket.id_data and not the socket.id for processing the data.
+ *
  * @param socket
  *   The socket structure.
- *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.id_data must represent a valid file descriptor.
  * @param flags
  *   Read flags.
  * @param header
@@ -647,9 +650,11 @@ extern "C" {
  *
  * This is the recommneded way to read TCP streams.
  *
+ * This uses the socket.id_data and not the socket.id for processing the data.
+ *
  * @param socket
  *   The socket structure.
- *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.id_data must represent a valid 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.
@@ -694,9 +699,11 @@ extern "C" {
  *
  * This is the recommneded way to write UDP streams.
  *
+ * This uses the socket.id_data and not the socket.id for processing the data.
+ *
  * @param socket
  *   The socket structure.
- *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.id_data 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.
@@ -743,9 +750,11 @@ extern "C" {
 /**
  * Send a message to a socket.
  *
+ * This uses the socket.id_data and not the socket.id for processing the data.
+ *
  * @param socket
  *   The socket structure.
- *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.id_data must represent a valid file descriptor.
  * @param flags
  *   Read flags.
  * @param header
@@ -792,9 +801,11 @@ extern "C" {
  *
  * This is the recommneded way to write TCP streams.
  *
+ * This uses the socket.id_data and not the socket.id for processing the data.
+ *
  * @param socket
  *   The socket structure.
- *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.id_data 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.
index b6b931120ce47a0f980960a68cabd0a94bc5e29f..e718df37c18714a511a801dbf466aa5a794c0237 100644 (file)
@@ -734,7 +734,8 @@ extern "C" {
  * Commonly used socket related properties, loosely based off of f_file_t.
  *
  * Properties:
- *   - id:       File descriptor, with a value of -1 represents a closed file.
+ *   - id:       Socket file descriptor, used for binding and listening.
+ *   - id_data:  Data file descriptor, used for reading and writing data from or to the socket.
  *   - domain:   The socket domain (protocol family, such as f_socket_protocol_family_local_e).
  *   - protocol: The socket protocol (such as f_socket_protocol_tcp_e).
  *   - type:     The socket type (address family, such as f_socket_address_family_local_e).
@@ -752,6 +753,7 @@ extern "C" {
 #ifndef _di_f_socket_t_
   typedef struct {
     int id;
+    int id_data;
     int domain;
     int protocol;
     int type;
@@ -765,10 +767,11 @@ extern "C" {
     f_string_static_t name;
   } f_socket_t;
 
-  #define f_socket_t_initialize { -1, 0, 0, 0, F_socket_default_read_size_d, F_socket_default_write_size_d, f_socket_address_t_initialize, 0, f_string_static_t_initialize }
+  #define f_socket_t_initialize { -1, -1, 0, 0, 0, F_socket_default_read_size_d, F_socket_default_write_size_d, f_socket_address_t_initialize, 0, f_string_static_t_initialize }
 
   #define macro_f_socket_t_initialize_1(address, length) { \
     -1, \
+    -1, \
     0, \
     0, \
     0, \
@@ -781,6 +784,7 @@ extern "C" {
 
   #define macro_f_socket_t_initialize_2(address, length, name) { \
     -1, \
+    -1, \
     0, \
     0, \
     0, \
@@ -793,6 +797,7 @@ extern "C" {
 
   #define macro_f_socket_t_initialize_3(id, domain, protocol, type, address, length, name) { \
     id, \
+    -1, \
     domain, \
     protocol, \
     type, \
@@ -805,6 +810,20 @@ extern "C" {
 
   #define macro_f_socket_t_initialize_4(id, domain, protocol, type, size_read, size_write, address, length, name) { \
     id, \
+    -1, \
+    domain, \
+    protocol, \
+    type, \
+    size_read, \
+    size_write, \
+    address, \
+    length, \
+    name \
+  }
+
+  #define macro_f_socket_t_initialize_5(id, id_data, domain, protocol, type, size_read, size_write, address, length, name) { \
+    id, \
+    id_data, \
     domain, \
     protocol, \
     type, \
@@ -817,6 +836,7 @@ extern "C" {
 
   #define macro_f_socket_t_clear(file) \
     file.id = -1; \
+    file.id_data = -1; \
     file.domain = 0; \
     file.protocol = 0; \
     file.type = 0; \
@@ -827,6 +847,7 @@ extern "C" {
 
   #define macro_f_socket_t_reset(file) \
     file.id = -1; \
+    file.id_data = -1; \
     file.domain = 0; \
     file.protocol = 0; \
     file.type = 0; \
index e4ec32423e026e0731590048cd115cb32db4f8e9..6e2d3feb9520cf65e9ae6f2cb8d48d387db2a561 100644 (file)
@@ -70,7 +70,7 @@ void test__f_socket_accept__fails(void **state) {
     will_return(__wrap_accept, true);
     will_return(__wrap_accept, errnos[i]);
 
-    const f_status_t status = f_socket_accept(&socket, 0);
+    const f_status_t status = f_socket_accept(&socket);
 
     assert_int_equal(status, F_status_set_error(statuss[i]));
   } // for
@@ -79,7 +79,7 @@ void test__f_socket_accept__fails(void **state) {
 void test__f_socket_accept__parameter_checking(void **state) {
 
   {
-    const f_status_t status = f_socket_accept(0, 0);
+    const f_status_t status = f_socket_accept(0);
 
     assert_int_equal(status, F_status_set_error(F_parameter));
   }
@@ -89,16 +89,19 @@ void test__f_socket_accept__works(void **state) {
 
   f_socket_t socket = f_socket_t_initialize;
 
+  socket.id = 1;
+
   {
-    const int id = 1;
+    const int id = 2;
 
     will_return(__wrap_accept, false);
     will_return(__wrap_accept, id);
 
-    const f_status_t status = f_socket_accept(&socket, 0);
+    const f_status_t status = f_socket_accept(&socket);
 
     assert_int_equal(status, F_none);
-    assert_int_equal(socket.id, id);
+    assert_int_equal(socket.id_data, id);
+    assert_int_not_equal(socket.id, id);
   }
 }