/* allocate */ tpool_t *tpool_create(unsigned int cnt, tfunc controller, tfunc handler) { tpool_t *tp = malloc(sizeof *tp); /* set it up */ if (tp) tpool_init(tp, cnt, controller, handler); return tp; }
int main(void) { int i; tpool_t test_pool; tpool_init(&test_pool, 8, 20); for ( i = 0; i < 5; i++) { tpool_add_work(test_pool, job, str[i]); } tpool_destroy(test_pool, 1); return 0; }
int main() { tpool_t *t; char buf[256], *ptr; int len, i = 0; # ifdef DEBUG log_open("stderr", "tp_test", -1); # endif t = tpool_init(NULL, 3, 2, 2); printf("Thread Pool[%d] initlized OK, try to write your message after >\n", getpid()); printf("Main thread: %p\n", pthread_self()); do { printf(">"); fflush(stdout); if (!fgets(buf, sizeof(buf) - 1, stdin)) { puts("Aborted!\n"); break; } if (buf[0] == '\r' || buf[0] == '\n') continue; len = strlen(buf); buf[len - 1] = '\0'; if (!strcasecmp(buf, "quit") || !strcasecmp(buf, "exit")) { puts("Quit!\n"); break; } else if (!strcasecmp(buf, "cancel")) { for (i = 0; i < t->max_total; i++) { int cc; if (!(t->threads[i].status & TPOOL_THREAD_ACTIVED)) continue; pthread_cancel(t->threads[i].tid); } continue; } else if (!strcasecmp(buf, "cancel2")) { tpool_cancel(t); tpool_destroy(t); exit(0); } else if (!strcasecmp(buf, "timeout")) { tpool_cancel_timeout(t, 5); continue; } else if (!strcasecmp(buf, "display")) { ptr = tpool_draw(t); puts(ptr); free(ptr); continue; } ptr = strdup(buf); printf("strdup(%p)\n", ptr); tpool_exec(t, test_task, test_cancel, ptr); } while (1); //tpool_cancel(t); tpool_destroy(t); exit(0); }
int main(int argc, char **argv) { int debug = 0, conftest = 0, nodaemon = 0; int i = 0; unsigned int clilen; struct sockaddr_in cliaddr; struct timeval start, end; char *cnfg = DEF_CNFG; char localhost[MAXNAMLEN + 1], path[MAXNAMLEN + 1]; FILE *pidfp; octet_t oct; ruleset_t *rs; /* * Who am I running as ? */ uname(&myname); /* * spocp_err = 0 ; */ memset(&srv, 0, sizeof(srv_t)); pthread_mutex_init(&(srv.mutex), NULL); pthread_mutex_init(&(srv.mlock), NULL); gethostname(localhost, MAXNAMLEN); #ifdef HAVE_GETDOMAINNAME getdomainname(path, MAXNAMLEN); #else { char *pos; if(pos = strstr(localhost, ".")) strncpy(path, pos+1, MAXNAMLEN); else strcpy(path, ""); } #endif if (0) printf("Domain: %s\n", path); srv.hostname = Strdup(localhost); /* * truncating input strings to reasonable length */ for (i = 0; i < argc; i++) if (strlen(argv[i]) > 512) argv[i][512] = '\0'; while ((i = getopt(argc, argv, "Dhrtf:d:")) != EOF) { switch (i) { case 'D': nodaemon = 1; break; case 'f': cnfg = Strdup(optarg); break; case 'd': debug = atoi(optarg); if (debug < 0) debug = 0; break; case 't': conftest = 1; break; case 'r': srv.readonly = 1; case 'h': default: fprintf(stderr, "Usage: %s [-t] ", argv[0]); fprintf(stderr, "[-f configfile] "); fprintf(stderr, "[-D] [-d debuglevel]\n"); exit(0); } } srv.root = ruleset_new(0); if (srv_init(&srv, cnfg) < 0) exit(1); if (srv.port && srv.uds) { fprintf(stderr, "Sorry are not allowed to listen on both a unix domain socket and a port\n"); exit(1); } if (srv.logfile) spocp_open_log(srv.logfile, debug); else if (debug) spocp_open_log(0, debug); if (srv.name){ localcontext = (char *) Calloc(strlen(srv.name) + strlen("//") + 1, sizeof(char)); /* Flawfinder: ignore */ sprintf(localcontext, "//%s", srv.name); } else { localcontext = (char *) Calloc(strlen(localhost) + strlen("//") + 1, sizeof(char)); /* Flawfinder: ignore */ sprintf(localcontext, "//%s", localhost); } /* * where I put the access rules for access to this server and its * rules */ snprintf(path, MAXNAMLEN, "%s/server", localcontext); oct_assign(&oct, path); if ((rs = ruleset_create(&oct, srv.root)) == 0) exit(1); rs->db = db_new(); /* * access rules for operations */ snprintf(path, MAXNAMLEN, "%s/operation", localcontext); oct_assign(&oct, path); if ((rs = ruleset_create(&oct, srv.root)) == 0) exit(1); rs->db = db_new(); LOG(SPOCP_INFO) { traceLog(LOG_INFO, "Local context: \"%s\"", localcontext); traceLog(LOG_INFO, "initializing backends"); if (srv.root->db) plugin_display(srv.plugin); } if (srv.plugin) { run_plugin_init(&srv); } if ( get_rules( &srv ) != SPOCP_SUCCESS ) exit(1); /*ruleset_tree( srv.root, 0);*/ /* If only testing configuration and rulefile this is as far as I go */ if (conftest) { traceLog(LOG_INFO,"Configuration was OK"); exit(0); } gettimeofday(&start, NULL); if (srv.port || srv.uds) { /* * stdin and stdout will not be used from here on, close to * save file descriptors */ fclose(stdin); fclose(stdout); #ifdef HAVE_SSL /* * ---------------------------------------------------------- */ /* * build our SSL context, whether it will ever be used or not */ /* * mutex'es for openSSL to use */ THREAD_setup(); if (srv.certificateFile && srv.privateKey && srv.caList) { traceLog(LOG_INFO,"Initializing the TLS/SSL environment"); if (!(srv.ctx = tls_init(&srv))) { return FALSE; } } /* * ---------------------------------------------------------- */ #endif #ifdef HAVE_SASL { int r = sasl_server_init(sasl_cb, "spocp"); if (r != SASL_OK) { traceLog( LOG_ERR, "Unable to initialized SASL library: %s", sasl_errstring(r, NULL, NULL)); return FALSE; } } #endif saci_init(); if( nodaemon == 0 ) { #ifdef HAVE_DAEMON if (daemon(1, 1) < 0) { fprintf(stderr, "couldn't go daemon\n"); exit(1); } #else daemon_init("spocp", 0); #endif } if (srv.pidfile) { /* * Write the PID file. */ pidfp = fopen(srv.pidfile, "w"); if (pidfp == (FILE *) 0) { fprintf(stderr, "Couldn't open pidfile \"%s\"\n", srv.pidfile); exit(1); } fprintf(pidfp, "%d\n", (int) getpid()); fclose(pidfp); } if (srv.port) { LOG(SPOCP_INFO) traceLog( LOG_INFO, "Asked to listen on port %d", srv.port); if ((srv.listen_fd = spocp_stream_socket(srv.port)) < 0) exit(1); srv.id = (char *) Malloc(16); sprintf(srv.id, "spocp-%d", srv.port); srv.type = AF_INET; } else { LOG(SPOCP_INFO) traceLog(LOG_INFO,"Asked to listen on unix domain socket"); if ((srv.listen_fd = spocp_unix_domain_socket(srv.uds)) < 0) exit(1); srv.id = (char *) Malloc(7 + strlen(srv.uds)); /* Flawfinder: ignore */ sprintf(srv.id, "spocp-%s", srv.uds); srv.type = AF_UNIX; } xsignal(SIGCHLD, sig_chld); xsignal(SIGPIPE, sig_pipe); xsignal(SIGINT, sig_int); xsignal(SIGTERM, sig_term); xsignal(SIGUSR1, sig_usr1); clilen = sizeof(cliaddr); DEBUG(SPOCP_DSRV) traceLog(LOG_DEBUG,"Creating threads"); /* * returns the pool the threads are picking work from */ srv.work = tpool_init(srv.threads, 64, 1); spocp_srv_run(&srv); } else { conn_t *conn; saci_init(); DEBUG(SPOCP_DSRV) traceLog(LOG_DEBUG,"---->"); LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading STDIN"); /* * If I want to use this I have to do init_server() first * conn = spocp_open_connection( STDIN_FILENO, &srv ) ; */ /* * this is much simpler */ conn = conn_new(); conn_setup(conn, &srv, STDIN_FILENO, "localhost", "127.0.0.1"); LOG(SPOCP_INFO) traceLog(LOG_INFO,"Running server"); spocp_server((void *) conn); gettimeofday(&end, NULL); print_elapsed("query time:", start, end); conn_free( conn ); } srv_free( &srv ); if (cnfg != DEF_CNFG) Free( cnfg ); exit(0); }
int main(int argc, char *argv[]) { tpool_t *pool; logmy=log_open("test.log", 0); pool=tpool_init(10,20,1); socket_branch(); char Construction[2]; while(1) { printf("Please Input Construction number On Server:\t"); scanf("%s", Construction); printf("%s\n", Construction); switch (Construction[1]) { case 9: tpool_destroy(pool,1); log_close(logmy); pthread_exit(NULL); exit (EXIT_SUCCESS); case 8: exit (EXIT_FAILURE); case 6: break; default: break; } struct sockaddr_in client_addr; int client_addr_length =sizeof(client_addr); int new_server_socket_fd =accept(server_socket_fd,(struct sockaddr*)&client_addr, &client_addr_length); if(new_server_socket_fd < 0) { perror("Server Accept Failed:"); break; } else { printf("Accept Client Socket Address\n"); char peeraddrstr[60]; char peerip[18]; time_t timep; time(&timep); int len = sizeof(client_addr); if(!getpeername(new_server_socket_fd, (struct sockaddr *)&client_addr, &len)) { sprintf(peeraddrstr, "time: %s\npeer address: %s:%d\n\n",ctime(&timep) , inet_ntop(AF_INET, &client_addr.sin_addr, peerip, sizeof(peerip)), ntohs(client_addr.sin_port)); printf("%s\n", peeraddrstr); } tpool_add_work(pool,thread,peeraddrstr); } } sleep(5); tpool_destroy(pool,1); log_close(logmy); pthread_exit(NULL); }
int main (int argc, char **argv) { int opt = 0; /* Option Identifier */ int optindex = 0; /* Option Index */ bool isProfiling = false; /* Are we profiling the cache? */ bool isPriming = false; /* Are we priming the cache? */ long numCPUs = 0; /* The number of online CPUs */ struct dirent *dp = NULL; /* Directory Entry Pointer */ DIR *dfd = NULL; /* Directory Stream */ double loadAverages[3] = { 0.00 }; /* System Load Averages */ PGconn *pgh = NULL; /* Postgres Connection Handle */ bool isPWDRequired = false; /* Is Postgres Password Reqd? */ struct option long_options[] = /* Options for getopt() */ { {"connect-string", required_argument, NULL, 'c'}, {"profile", no_argument, NULL, 'p'}, {"prime", no_argument, NULL, 'w'}, {"data-dir", required_argument, NULL, 'D'}, {"postgres-only", no_argument, NULL, 'o'}, {"sqlite-db", required_argument, NULL, 's'}, {"help", no_argument, NULL, 'h'}, {"debug", no_argument, NULL, 'd'}, {NULL, 0, NULL, 0} }; /* Go for the glory! */ fprintf(stderr, "\n%s: Release %s - %s\n", PACKAGE_NAME, PACKAGE_VERSION, APP_RELEASE); fprintf(stderr, "\n%s\n\n", APP_COPYRIGHT); fflush(stdout); /* Process command-line options */ while ((opt = getopt_long(argc, argv, "c:s:D:awhdp", long_options, &optindex)) != -1) { switch (opt) { case 'h': usage(); exit(EXIT_SUCCESS); break; case 'p': if (isPriming == false) isProfiling = true; else { fprintf(stderr, "Profiling and warming are mutually exlusive!\n"); exit(EXIT_FAILURE); } break; case 'w': if (isProfiling == false) isPriming = true; else { fprintf(stderr, "Profiling and warming are mutually exlusive!\n"); exit(EXIT_FAILURE); } break; case 'd': is_debug = true; break; case 's': dbFileName = xstrdup(optarg); break; case 'c': pgConnectString = xstrdup(optarg); break; case 'D': pgDataDir = optarg; break; default: usage(); exit(EXIT_FAILURE); } } /* Make sure user requested profile OR prime */ if (isProfiling == false && isPriming == false) { fprintf(stderr, "Expected either -p or -w\n"); usage(); exit(EXIT_FAILURE); } /* Make sure the database name is set */ /* Get the PG log file name from the end of the command line */ if (optind < (argc - 1)) { fprintf(stderr, "too many command-line arguments (first is \"%s\")\n", argv[optind + 1]); usage(); exit(EXIT_FAILURE); } /* Perform a Postgres connection test & get password (if required) */ do { isPWDRequired = false; pgh = PQsetdbLogin(NULL, NULL, NULL, NULL, pgConnectString == NULL ? "postgres" : pgConnectString, NULL, pgPassword); if (PQstatus(pgh) == CONNECTION_BAD) { if (PQconnectionNeedsPassword(pgh) && pgPassword == NULL) { printf("\nTesting Postgres Connection\n"); PQfinish(pgh); pgPassword = simple_prompt("Password: "******"%s", "Connection Test Failed\n"); ERROR_PRINT("SQLERRMC: %s\n", PQerrorMessage(pgh)); PQfinish(pgh); exit(EXIT_FAILURE); } } } while (isPWDRequired); PQfinish(pgh); /* Get the number of available CPUs */ numCPUs = sysconf(_SC_NPROCESSORS_ONLN); if (numCPUs < 1) numCPUs = 1; /* * Choose the number of CPUs to use in the thread pool based on load * average. It only makes sense to do this if we have more than one CPU * to play with. */ if ((numCPUs > 1) && (getloadavg(loadAverages, 3) == 3)) { long idleCPUs = 0; /* The number of idle CPUs */ /* Show what we got */ printf("load averages.... %3.2f %3.2f %3.2f\n", loadAverages[0], loadAverages[1], loadAverages[2]); /* * We're going to base the number of usable CPUs by subtracting * the sum of 1 (to account for OS and I/O overhead) plus the 1 minute * load average from the number of available CPUs. */ idleCPUs = numCPUs - (1 + (int)(loadAverages[0] + 0.5)); /* Assign # of available CPUs with some sanity checking */ if (idleCPUs < numCPUs) numCPUs = idleCPUs; if (numCPUs < 1) numCPUs = 1; } /* Inform user of # of CPUs that will be used */ printf("usable CPUs...... %d\n", numCPUs); /* If we have more than one CPU, multi-thread our operations */ if (numCPUs > 1) { /* Initialize the thread pool */ thp = tpool_init(numCPUs, 1024, true); } if (isProfiling) BuildCacheProfile(); else /* isPriming */ PrimeCache(); /* If we have more than one CPU, multi-thread our operations */ if (POINTER_IS_VALID(thp)) { /* Destroy the thread pool */ tpool_destroy(thp, 1); } /* Cleanup */ free(dbFileName); return EXIT_SUCCESS; } /* main() */
/************************************************************* ** MAIN ** Reads the config file. Binds to a port. Launches the ** worker and other threads. Listens for requests. */ int main(int argc, char **argv) { char * conf = NULL; int nthreads; int c, ret; char** ary; char* prog; u_int numfds = 0; int xerror; int bg_flag = TRUE; int only_check_config; char ebuf[BUFSIZ]; char nbuf[64]; u_char * gifimage = NULL; u_char * favicon = NULL; int gifimagelen = 0; int faviconlen = 0; TPOOL_CTX * tpool_ctx = NULL; DEBUGS * dp; LISTEN_CTX *gctx = NULL; LISTEN_CTX *dctx = NULL; LISTEN_CTX *jctx = NULL; pthread_t gif_tid; pthread_t data_tid; pthread_t upload_tid; #if HAVE_RESOURCE_H || HAVE_SYS_RESOURCE_H struct rlimit rl; #endif time_t servertimeout; prog = basename(argv[0]); if (prog == NULL) prog = argv[0]; only_check_config = FALSE; servertimeout = 20; while ((c = getopt(argc, argv, "C:d:c:f")) != -1) { switch (c) { case 'f': bg_flag = FALSE; break; case 'C': only_check_config = TRUE; /*FALLTHROUGH*/ case 'c': conf = optarg; break; case 'd': /* * Debugging turned of if in background */ if (bg_flag == TRUE) break; for (dp = DebugNames; dp->name != NULL; dp++) { if (strncasecmp(dp->name, optarg, strlen(optarg)) == 0) { setdebug(dp->flag); if (dp->flag == BUG_THREADS || dp->flag == BUG_ALL) tpool_debug_set(TRUE); break; } } if (dp->name != NULL) break; printf("Unknown debug flag: %s, select from:\n", optarg); for (dp = DebugNames; dp->name != NULL; dp++) printf("\t%s\n", dp->name); return 0; case '?': default: usage: printf("Usage: %s " "[-c /path/onepixd.conf " "or " "-C /path/onepixd.conf] " "-d what " "[-f]\n", prog); return 0; } } if (argc != optind) goto usage; if (conf == NULL || strlen(conf) == 0) { (void) fprintf(stderr, "Required Parameter \"-c configfile\" missing.\n"); goto usage; } ret = config_read_file(conf); if (ret != 0) return 0; /* * All errors are logged, so we need to set up * logging before checking the config file. */ ary = config_lookup(CONF_LOG_FACILITY); if (ary == NULL) ret = log_init(DEFAULT_LOG_FACILITY, prog); else ret = log_init(ary[0], prog); if (ret != 0) return 0; ret = config_validate(); if (ret != 0) return 0; if (ret == 0 && only_check_config == TRUE) (void) printf("%s: FILE IS OKAY TO USE\n", conf); if (only_check_config == TRUE) return 0; ary = config_lookup(CONF_HOME_DIR); if (ary != NULL) { if (chdir(ary[0]) != 0) { xerror = errno; (void) snprintf(ebuf, sizeof ebuf, "Attempt to chdir(\"%s\"): %s", ary[0], strerror(xerror)); log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf); goto shutdown_server; } } if (util_bg(bg_flag) != 0) { (void) snprintf(ebuf, sizeof ebuf, "fork(): %s\n", strerror(errno)); log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf); goto shutdown_server; } #if HAVE_RESOURCE_H || HAVE_SYS_RESOURCE_H #ifdef RLIMIT_AS rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_AS, &rl); /* max size virtual memory */ #endif #ifdef RLIMIT_CPU rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_CPU, &rl); /* unlimited CPU usage */ #endif #ifdef RLIMIT_DATA rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_DATA, &rl); /* unlimited memory */ #endif #ifdef RLIMIT_FSIZE rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_FSIZE, &rl); /* unlimited file sizes */ #endif #ifdef RLIMIT_STACK rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_STACK, &rl); /* unlimited stack */ #endif #ifdef RLIMIT_CORE rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_CORE, &rl); /* allow core dumps */ #endif #ifdef RLIMIT_NOFILE rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_NOFILE, &rl); /* maximum file descriptors */ (void) getrlimit(RLIMIT_NOFILE, &rl); numfds = (rl.rlim_cur); #endif #endif /* HAVE_RESOURCE_H */ ary = config_lookup(CONF_BECOME_USER); if (ary != NULL) { /* * Note that setrunasuser() logs its own errors */ if (setrunasuser(ary[0]) != 0) goto shutdown_server; } ary = config_lookup(CONF_NUMTHREADS); if (ary == NULL) nthreads = DEFAULT_THREADS; else { nthreads = strtoul(ary[0], NULL, 10); if (nthreads <= 0) { (void) fprintf(stderr, "Configuration item \"%s\" illegal value: %d.\n", CONF_NUMTHREADS, nthreads); return 0; } } if (numfds == 0 || numfds > (nthreads * 3)) numfds = nthreads * 3; (void) io_init(numfds); gifimage = gif_get1x1gif(&gifimagelen); if (gifimage == NULL) { (void) snprintf(ebuf, sizeof ebuf, "Load gif image: %s\n", strerror(errno)); log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf); goto shutdown_server; } favicon = gif_getfavicon_ico(&faviconlen); /* * Prepare to launch the thread to listen for inbound * gif requests. */ gctx = str_alloc(sizeof(LISTEN_CTX), 1, __FILE__, __LINE__); if (gctx == NULL) { (void) snprintf(ebuf, sizeof ebuf, "alloc(): %s\n", strerror(errno)); log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf); goto shutdown_server; } gctx->type = LISTEN_TYPE_GIF; /* gif image only, no favicon */ gctx->gifimage = gifimage; gctx->gifimagelen = gifimagelen; gctx->favicon = NULL; gctx->faviconlen = 0; ary = config_lookup(CONF_GIF_PORT); if (ary == NULL) (void) strlcpy(gctx->port, "80", sizeof gctx->port); else (void) strlcpy(gctx->port, ary[0], sizeof gctx->port); ary = config_lookup(CONF_GIF_INTERFACE); if (ary == NULL) (void) strlcpy(gctx->interface, "INADDR_ANY", sizeof gctx->interface); else (void) strlcpy(gctx->interface, ary[0], sizeof gctx->interface); /* * Everything from here down must be thread safe. */ tpool_ctx = tpool_init(nthreads, ebuf, sizeof ebuf); if (tpool_ctx == NULL) goto shutdown_server; gctx->tpool_ctx = tpool_ctx; /* * The GIF server may have to bind to a privaliged port, such * as port 80, so we launch it and expect it to change the * user id after its bind. */ ret = pthread_create(&gif_tid, NULL, thread_listener, (void *)gctx); if (ret != 0) { } /* * Prepare to launch the thread to listen for inbound * data requests. */ dctx = str_alloc(sizeof(LISTEN_CTX), 1, __FILE__, __LINE__); if (dctx == NULL) { (void) snprintf(ebuf, sizeof ebuf, "alloc(): %s\n", strerror(errno)); log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf); goto shutdown_server; } dctx->type = LISTEN_TYPE_DATA; /* a favicon only, no gif */ dctx->gifimage = NULL; dctx->favicon = favicon; dctx->gifimagelen = 0; dctx->faviconlen = faviconlen; ary = config_lookup(CONF_DATA_PORT); if (ary == NULL) (void) strlcpy(dctx->port, "8100", sizeof dctx->port); else (void) strlcpy(dctx->port, ary[0], sizeof dctx->port); ary = config_lookup(CONF_DATA_INTERFACE); if (ary == NULL) (void) strlcpy(dctx->interface, "INADDR_ANY", sizeof dctx->interface); else (void) strlcpy(dctx->interface, ary[0], sizeof dctx->interface); dctx->tpool_ctx = tpool_ctx; ret = pthread_create(&data_tid, NULL, thread_listener, (void *)dctx); if (ret != 0) { } /* * Prepare to launch the thread to listen for uploads of more. */ (void) verify_threads_locking_init(); jctx = str_alloc(sizeof(LISTEN_CTX), 1, __FILE__, __LINE__); if (jctx == NULL) { (void) snprintf(ebuf, sizeof ebuf, "alloc(): %s\n", strerror(errno)); log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf); goto shutdown_server; } jctx->type = LISTEN_TYPE_UPLOAD; /* a favicon only, no gif */ jctx->gifimage = NULL; jctx->favicon = favicon; jctx->gifimagelen = 0; jctx->faviconlen = faviconlen; ary = config_lookup(CONF_UPLOAD_PORT); if (ary == NULL) (void) strlcpy(jctx->port, "8101", sizeof jctx->port); else (void) strlcpy(jctx->port, ary[0], sizeof jctx->port); ary = config_lookup(CONF_UPLOAD_INTERFACE); if (ary == NULL) (void) strlcpy(jctx->interface, "INADDR_ANY", sizeof jctx->interface); else (void) strlcpy(jctx->interface, ary[0], sizeof jctx->interface); jctx->tpool_ctx = tpool_ctx; ret = pthread_create(&upload_tid, NULL, thread_listener, (void *)jctx); if (ret != 0) { } ary = config_lookup(CONF_PIDFILE); if (ary != NULL) { /* * Note that write_pid_file() logs its own errors */ if (write_pid_file(ary[0]) != 0) goto shutdown_server; } (void) strlcpy(ebuf, "Startup: version=", sizeof ebuf); (void) strlcat(ebuf, VERSION, sizeof ebuf); (void) strlcat(ebuf, ", gif_interface=", sizeof ebuf); (void) strlcat(ebuf, gctx->interface, sizeof ebuf); (void) strlcat(ebuf, ", gif_port=", sizeof ebuf); (void) strlcat(ebuf, gctx->port, sizeof ebuf); (void) strlcat(ebuf, ", data_interface=", sizeof ebuf); (void) strlcat(ebuf, dctx->interface, sizeof ebuf); (void) strlcat(ebuf, ", data_port=", sizeof ebuf); (void) strlcat(ebuf, dctx->port, sizeof ebuf); (void) strlcat(ebuf, ", threads=", sizeof ebuf); (void) str_ultoa(nthreads, nbuf, sizeof nbuf); (void) strlcat(ebuf, nbuf, sizeof ebuf); log_emit(LOG_INFO, NULL, __FILE__, __LINE__, ebuf); Global_Die = FALSE; (void) signal(SIGINT, catch_sig); (void) signal(SIGQUIT, catch_sig); (void) signal(SIGKILL, catch_sig); (void) signal(SIGTERM, catch_sig); (void) signal(SIGPIPE, SIG_IGN); if (Global_Die == TRUE) goto shutdown_server; (void) file_prune_garbage(&Global_Die); shutdown_server: Global_Die = TRUE; (void) pthread_join(data_tid, NULL); (void) pthread_join(gif_tid, NULL); (void) pthread_join(upload_tid, NULL); (void) verify_threads_locking_shutdown(); if (tpool_ctx != NULL) tpool_ctx = tpool_shutdown(tpool_ctx, ebuf, sizeof ebuf); if (gctx != NULL) gctx = str_free(gctx, __FILE__, __LINE__); if (dctx != NULL) dctx = str_free(dctx, __FILE__, __LINE__); if (jctx != NULL) jctx = str_free(jctx, __FILE__, __LINE__); if (gifimage != NULL) gifimage = str_free(gifimage, __FILE__, __LINE__); if (favicon != NULL) favicon = str_free(favicon, __FILE__, __LINE__); ary = config_lookup(CONF_PIDFILE); if (ary != NULL) (void) unlink(ary[0]); io_shutdown(); config_shutdown(); (void) strlcpy(ebuf, "Shutdown: version=", sizeof ebuf); (void) strlcat(ebuf, VERSION, sizeof ebuf); log_emit(LOG_INFO, NULL, __FILE__, __LINE__, ebuf); /* * This str_shutdown must always be last. */ str_shutdown(); return 0; }