+/* State structure for set port API Test Case #4 */
+static black_box_state_t test_case_set_port_04_state = {
+ .test_case_name = "test_case_set_port_04",
+};
+
+static bool try_bind(int portno) {
+ int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
+ assert_int_not_equal(socket_fd, -1);
+
+ struct sockaddr_in sin;
+ socklen_t len = sizeof(sin);
+ bzero(&sin, len);
+
+ assert_int_not_equal(getsockname(socket_fd, (struct sockaddr *)&sin, &len), -1);
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = htons(portno);
+
+ errno = 0;
+ int bind_status = bind(socket_fd, (struct sockaddr *)&sin, len);
+
+ // Exempt EADDRINUSE error only
+
+ if(bind_status) {
+ assert_int_equal(errno, EADDRINUSE);
+ }
+
+ assert_int_not_equal(close(socket_fd), -1);
+
+ return !bind_status;
+}
+
+static void wait_for_socket_free(int portno) {
+
+ // Wait upto 20 seconds and poll every second whether the port is freed or not
+
+ for(int i = 0; i < 20; i++) {
+ if(try_bind(portno)) {
+ return;
+ } else {
+ sleep(1);
+ }
+ }
+
+ fail();
+}
+
+static int get_free_port(void) {
+
+ // Get a free port
+
+ int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
+ assert_int_not_equal(socket_fd, -1);
+
+ struct sockaddr_in sin;
+ socklen_t len = sizeof(sin);
+ bzero(&sin, len);
+
+ assert_int_not_equal(getsockname(socket_fd, (struct sockaddr *)&sin, &len), -1);
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = 0;
+
+ assert_int_not_equal(bind(socket_fd, (struct sockaddr *)&sin, len), -1);
+
+ assert_int_not_equal(getsockname(socket_fd, (struct sockaddr *)&sin, &len), -1);
+
+ assert_int_not_equal(close(socket_fd), -1);
+
+ return (int) sin.sin_port;
+}