#include #include #include #include #include "icmp.h" #include "internal/icmp_internal.h" /* Helper: check if we have CAP_NET_RAW capability */ static int has_net_raw_capability(void) { icmp_handle_t *h = icmp_create(); if (NULL != h) { icmp_destroy(h); return 1; } return 0; } /* Test 1: icmp_destroy() with NULL handle does not crash */ Test(handle, destroy_null_handle) { icmp_destroy(NULL); cr_assert(1, "Should not crash with NULL handle"); } /* Test 2: icmp_destroy() closes the file descriptor */ Test(handle, destroy_closes_fd) { if (0 == has_net_raw_capability()) { cr_skip("Test requires CAP_NET_RAW or root privileges"); } icmp_handle_t *h = icmp_create(); cr_assert_not_null(h); int fd = icmp_get_fd(h); cr_assert_geq(fd, 0); /* Destroy handle */ icmp_destroy(h); /* Verify FD is closed (fcntl should fail with EBADF) */ int flags = fcntl(fd, F_GETFL, 0); cr_assert_eq(flags, -1, "FD should be closed after destroy"); } Test(handle, destroy_with_invalid_fd) { struct icmp_handle *h = malloc(sizeof(struct icmp_handle)); cr_assert_not_null(h); h->fd = -1; h->last_error = ICMP_OK; h->error_msg[0] = '\0'; /* Should not crash even with invalid FD (close will fail but OK) */ icmp_destroy((icmp_handle_t *)h); cr_assert(1, "Should handle invalid FD gracefully"); }