/* Return a dynamically allocated socket address structure according to the value returned by either getpeername() or getsockname() (according to POSIX, applications should not assume a particular length for `sockaddr_un.sun_path') */ static struct sockaddr *get_peer_sock_name(LPFN_GETPEERNAME socket_func, int fd) { socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK; socklen_t actual_socknamelen = socknamelen; struct sockaddr *sockname = malloc(socknamelen); if (sockname == NULL) return NULL; /* Both getpeername() and getsockname() truncates sockname if there is not enough space and set the required length in actual_socknamelen */ if (socket_func(fd, sockname, &actual_socknamelen) == -1) goto sock_or_realloc_error; if (actual_socknamelen > socknamelen) { struct sockaddr *new_sockname = NULL; socknamelen = actual_socknamelen; if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL) goto sock_or_realloc_error; sockname = new_sockname; if (socket_func(fd, sockname, &actual_socknamelen) == -1 || actual_socknamelen > socknamelen) goto sock_or_realloc_error; } return sockname; sock_or_realloc_error: free(sockname); return NULL; }
int create_lisfd(void) { int lisfd = -1; /* socket */ lisfd = socket_func(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* set address listen reuse */ int opt = 1; setsockopt_func(lisfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); /* bind */ struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(8000); inet_pton_func(AF_INET, "127.0.0.1", &saddr.sin_addr); bind_func(lisfd, (struct sockaddr *)&saddr, sizeof(saddr)); /* listen */ listen(lisfd, 10); return lisfd; }