#include #include #include #include #include #include #include /* for setting the registration file descripter blocking */ #include /* for ioctl() */ #include #include #include #include #include #define AST(a) do { if (!(a)) {printf("error %d\n", __LINE__); return (void *)1;} } while(0) #define MAST(a) do { if (!(a)) {printf("error %d\n", __LINE__); return 0;} } while(0) #define MAX_CONNECT_TRIES 3 static char *PORT_ADDR = "check_sockets_port"; static int open_port(const char *address); static int accept_a_connection(int register_socket, int *new_socket); static int connect_to(const char *host); static pthread_attr_t attr; static int FORKED=0; static int WAIT_ON_SELECT=1; static int NON_BLOCKING_ACCEPT=1; static int IOCTL=0; void *server(void *addr_buf) { int port_sock, cli_sock, len; port_sock = open_port(addr_buf); AST(port_sock >= 0); AST(accept_a_connection(port_sock, &cli_sock) == 0); AST(shutdown(cli_sock, SHUT_RDWR)==0); AST(close(cli_sock)==0); AST(close(port_sock)==0); AST(unlink(addr_buf)==0); return NULL; } void *client(void *addr_buf) { int serv_sock, len; serv_sock = connect_to(addr_buf); AST(serv_sock >= 0); AST(shutdown(serv_sock, SHUT_RDWR)==0); AST(close(serv_sock)==0); return NULL; } int main (int argc, char **argv) { int pid; pthread_t s_id, c_id; int s_ans, c_ans; if (argc > 1 && strlen(argv[1]) > 0) { if (strncmp(argv[1], "h", 2)==0) { printf("options: 'i' use ioctl instead of fcntl to set socket blocking\n"); return 0; } if (strncmp(argv[1], "i", 2)==0) IOCTL = 1; } if (FORKED) { printf("Forked\n"); pid = fork(); if (pid > 0) { /* parent */ server(PORT_ADDR); } else if (pid == 0) { /* child */ sleep(1); client(PORT_ADDR); } else { abort(); } } else { printf("Threaded\n"); MAST(pthread_attr_init(&attr)==0); MAST(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)==0); MAST(pthread_create(&s_id, &attr, &server, PORT_ADDR)==0); sleep(1); MAST(pthread_create(&c_id, &attr, &client, PORT_ADDR)==0); MAST(pthread_join(s_id, (void **)&s_ans)==0); MAST(pthread_join(c_id, (void **)&c_ans)==0); MAST(s_ans==0); MAST(c_ans==0); MAST(pthread_attr_destroy(&attr)==0); } printf("Success\n"); return 0; } /* create a new Unix domain socket and bind it to SERVER_HOST_ADDR */ static int open_port(const char *address) { struct sockaddr_un serv_addr = {0}; int sock; /* Open a new port. Try to get requested port. */ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("socket"); abort(); } serv_addr.sun_family = AF_UNIX; strcpy( serv_addr.sun_path, address); unlink( address ); if (bind(sock, (struct sockaddr *)&serv_addr, SUN_LEN(&serv_addr)) <0 ) { perror("bind"); abort(); } if (listen(sock, 5) < 0) { perror("listen"); abort(); } printf("Bound and listening to \"%s\" on fd %d\n", address, sock); fflush(stdout); return sock; } static void print_bits(int num, int len) { int i, out; for (i=0; i=0){ printf("Connected :)\n"); fflush(stdout); break; /* we got it :) */ } printf("Connection failed\n"); fflush(stdout); close(sock); sleep(1); /* Let the server come up. */ } return sock; }