PolyVert * pl_remove_vertex(Polygon * pl, const PolyVert * const vx) { assert(pl); assert(vx); uint i; for (i=0; i < pl->last; i++){ if (pl->points + i == vx) return pl_remove(pl, i); } return NULL; }
int main(int argc, char** args) { int argchar; char* progname = args[0]; int sock; struct sockaddr_in addr; int port = 6789; unsigned int opt; pl* clients; int flags; while ((argchar = getopt (argc, args, OPTIONS)) != -1) { switch (argchar) { case 'p': port = atoi(optarg); break; case 'f': solvedfnpattern = optarg; break; case 'h': default: printHelp(progname); exit(-1); } } sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { fprintf(stderr, "Error: couldn't create socket: %s\n", strerror(errno)); exit(-1); } opt = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) { fprintf(stderr, "Warning: failed to setsockopt() to reuse address.\n"); } flags = fcntl(sock, F_GETFL, 0); if (flags == -1) { fprintf(stderr, "Warning: failed to get socket flags: %s\n", strerror(errno)); } else { flags |= O_NONBLOCK; if (fcntl(sock, F_SETFL, flags) == -1) { fprintf(stderr, "Warning: failed to set socket flags: %s\n", strerror(errno)); } } memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); // gcc with strict-aliasing warn about this cast but according to "the internet" // it's okay because we're not dereferencing the cast pointer. if (bind(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in))) { fprintf(stderr, "Error: couldn't bind socket: %s\n", strerror(errno)); exit(-1); } if (listen(sock, 1000)) { fprintf(stderr, "Error: failed to listen() on socket: %s\n", strerror(errno)); exit(-1); } printf("Listening on port %i.\n", port); fflush(stdout); signal(SIGINT, sighandler); clients = pl_new(32); // wait for a connection or i/o... while (1) { struct sockaddr_in clientaddr; socklen_t addrsz = sizeof(clientaddr); FILE* fid; fd_set rset; struct timeval timeout; int res; int maxval = 0; int i; timeout.tv_sec = 1; timeout.tv_usec = 0; FD_ZERO(&rset); maxval = sock; for (i=0; i<pl_size(clients); i++) { int val; fid = pl_get(clients, i); val = fileno(fid); FD_SET(val, &rset); if (val > maxval) maxval = val; } assert(maxval<FD_SETSIZE); FD_SET(sock, &rset); res = select(maxval+1, &rset, NULL, NULL, &timeout); if (res == -1) { if (errno != EINTR) { fprintf(stderr, "Error: select(): %s\n", strerror(errno)); exit(-1); } } if (bailout) break; if (!res) continue; for (i=0; i<pl_size(clients); i++) { fid = pl_get(clients, i); if (FD_ISSET(fileno(fid), &rset)) { if (handle_request(fid)) { fprintf(stderr, "Error from fileno %i\n", fileno(fid)); pl_remove(clients, i); i--; continue; } } } if (FD_ISSET(sock, &rset)) { // See comment about strict aliasing above. Should be okay, despite gcc warning. int s = accept(sock, (struct sockaddr*)&clientaddr, &addrsz); if (s == -1) { fprintf(stderr, "Error: failed to accept() on socket: %s\n", strerror(errno)); continue; } if (addrsz != sizeof(clientaddr)) { fprintf(stderr, "Error: client address has size %i, not %i.\n", addrsz, (uint)sizeof(clientaddr)); continue; } printf("Connection from %s.\n", inet_ntoa(clientaddr.sin_addr)); fflush(stdout); fid = fdopen(s, "a+b"); pl_append(clients, fid); } } printf("Closing socket...\n"); if (close(sock)) { fprintf(stderr, "Error: failed to close socket: %s\n", strerror(errno)); } return 0; }
static void pl_remove_test(void) { printsln((Any)__func__); List ac, ex; Any s; ac = sl_of_string("1, 2, 3, 4, 5, 6"); s = pl_get(ac, 0); s_free(s); pl_remove(ac, 0); ex = sl_of_string("2, 3, 4, 5, 6"); sl_check_expect(ac, ex); pl_free(ac); pl_free(ex); ac = sl_of_string("1, 2, 3, 4, 5, 6"); s = pl_get(ac, 5); s_free(s); pl_remove(ac, 5); ex = sl_of_string("1, 2, 3, 4, 5"); sl_check_expect(ac, ex); pl_free(ac); pl_free(ex); ac = sl_of_string("1, 2, 3, 4, 5, 6"); s = pl_get(ac, 3); s_free(s); pl_remove(ac, 3); ex = sl_of_string("1, 2, 3, 5, 6"); sl_check_expect(ac, ex); pl_free(ac); pl_free(ex); ac = sl_of_string("1"); pl_remove(ac, -1); ex = sl_of_string("1"); sl_check_expect(ac, ex); pl_free(ac); pl_free(ex); ac = sl_of_string("1"); pl_remove(ac, 1); ex = sl_of_string("1"); sl_check_expect(ac, ex); pl_free(ac); pl_free(ex); ac = sl_of_string("1"); s = pl_get(ac, 0); s_free(s); pl_remove(ac, 0); ex = pl_create(); sl_check_expect(ac, ex); pl_free(ac); l_free(ex); ac = sl_of_string(""); s = pl_get(ac, 0); s_free(s); pl_remove(ac, 0); ex = pl_create(); sl_check_expect(ac, ex); l_free(ac); l_free(ex); }