#include #include #include #include #include #include #include #define A4_SOCK "./apr_accept4_test_socket" int main() { pid_t pid; int fd; struct sockaddr_un loc, rem; socklen_t rem_sz; if ((pid = fork())) { int status; unlink(A4_SOCK); if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) goto cleanup_failure2; loc.sun_family = AF_UNIX; strncpy(loc.sun_path, A4_SOCK, sizeof(loc.sun_path) - 1); if (bind(fd, (struct sockaddr *) &loc, sizeof(struct sockaddr_un)) == -1) goto cleanup_failure; if (listen(fd, 5) == -1) goto cleanup_failure; rem_sz = sizeof(struct sockaddr_un); if (accept4(fd, (struct sockaddr *) &rem, &rem_sz, 0) == -1) { goto cleanup_failure; } else { close(fd); waitpid(pid, &status, 0); unlink(A4_SOCK); return 0; } cleanup_failure: close(fd); cleanup_failure2: kill(pid, SIGKILL); waitpid(pid, &status, 0); unlink(A4_SOCK); return 1; } else { if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) return 1; /* this will be bad: we'll hang */ loc.sun_family = AF_UNIX; strncpy(loc.sun_path, A4_SOCK, sizeof(loc.sun_path) - 1); while(connect(fd, (struct sockaddr *) &loc, sizeof(struct sockaddr_un)) == -1 && (errno==ENOENT || errno==ECONNREFUSED)) ; close(fd); return 0; } }