void read_map(boardp b){ /* The bot reads the map from stdin on each turn, with the width and height on the first line, and the map on the following height x width lines, like this : 5 4 // 5 columns by 4 rows ##### // row 0, column 0 to 4 #1 2# // 1 is "me", 2 is "them" # # // # is wall ##### */ char buffer[MAX_BOARD_WIDTH+2]; int width, height, status, i; read_line(buffer, " 'width height' input line could not be read"); status = sscanf(buffer, "%d %d", &width, &height); if (status != 2){ _fatal_error(" 'width height' not found as expected"); } if (b->width == -1){ /* 1st time: initialize board map */ b->map = malloc(width * height + 1); b->width = width; b->height = height; b->map[0] = 0; /* set to zero length string */ } if (width != b->width || height != b->height){ _fatal_error("inconsistent width or height"); } for (i=0; i<height; i++){ read_line(buffer, "could not read board row"); memcpy(b->map + i*width, buffer, width); } b->map[width * height] = 0; /* make map null terminated */ b->_me.row = b->_them.row = -1; /* clear cached values */ }
cell find(boardp b, char what){ int i; cell c; if (b->width < 0){ _fatal_error("find() called on board without map"); } for (i=0; i< b->width * b->height; i++){ if (b->map[i] == what){ c.row = i / b->width; c.col = i % b->width; return c; } } _fatal_error("find() failed"); }
static int _setup_sockets(void) { ice_config_t *config; int i = 0; int ret = 0; int successful = 0; char pbuf[1024]; config = config_get_config_unlocked(); for(i = 0; i < MAX_LISTEN_SOCKETS; i++) { if(config->listeners[i].port <= 0) break; global.serversock[i] = sock_get_server_socket( config->listeners[i].port, config->listeners[i].bind_address); if (global.serversock[i] == SOCK_ERROR) { memset(pbuf, '\000', sizeof(pbuf)); snprintf(pbuf, sizeof(pbuf)-1, "Could not create listener socket on port %d", config->listeners[i].port); _fatal_error(pbuf); return 0; } else { ret = 1; successful++; } } global.server_sockets = successful; return ret; }
/* bind the socket and start listening */ static int _server_proc_init(void) { ice_config_t *config; if (!_setup_sockets()) return 0; if (!_start_listening()) { _fatal_error("Failed trying to listen on server socket"); return 0; } config = config_get_config_unlocked(); /* recreate the pid file */ if (config->pidfile) { FILE *f; pidfile = strdup (config->pidfile); if (pidfile && (f = fopen (config->pidfile, "w")) != NULL) { fprintf (f, "%d\n", (int)getpid()); fclose (f); } } return 1; }
void hlt_thread_queue_delete(hlt_thread_queue* queue) { if ( PTHREAD_SPIN_DESTROY(&queue->lock) != 0 ) _fatal_error("cannot destroy lock"); for ( int w = 0; w < queue->writers; w++ ) { batch* b = queue->writer_batches[w]; while ( b ) { batch* next = b->next; hlt_free(b); b = next; } } batch* b = queue->reader_head; while ( b ) { batch* next = b->next; hlt_free(b); b = next; } b = queue->lock_pending_head; while ( b ) { batch* next = b->next; hlt_free(b); b = next; } hlt_free(queue->reader_stats); hlt_free(queue->writer_batches); hlt_free(queue->writer_num_written); hlt_free(queue->writer_stats); hlt_free(queue->lock_writers_terminated); hlt_free(queue); }
void* _allocate_bytes(size_t num) { void* mem = malloc(num); if (mem == NULL) _fatal_error("Out of memory!"); // TODO: remove this? assert(((value_t)mem & POINTER_MASK) == 0); return mem; }
inline static void _release_lock(hlt_thread_queue* queue, int i, int reader, int thread) { if ( PTHREAD_SPIN_UNLOCK(&queue->lock) != 0 ) _fatal_error("cannot release lock"); // fprintf(stderr, "released %p %d %d\n", queue, reader, thread); hlt_pthread_setcancelstate(i, NULL); }
void read_line(char* buffer, char* error_message){ /* copy a line from stdin to buffer */ char* status; size_t length; buffer[0] = 0; /* initialize to length 0 */ status = fgets(buffer, MAX_BOARD_WIDTH+1, stdin); length = strlen(buffer); if (status == NULL || length == 0 || length > MAX_BOARD_WIDTH){ _fatal_error(error_message); } }
hlt_thread_queue* hlt_thread_queue_new(int writers, int batch_size, int max_batches) { hlt_thread_queue *queue = (hlt_thread_queue *) hlt_malloc(sizeof(hlt_thread_queue)); if ( ! queue ) _fatal_error("out of memory"); queue->writers = writers; queue->batch_size = batch_size; queue->max_batches = max_batches; queue->reader_head = 0; queue->reader_pos = 0; queue->reader_num_read = 0; queue->reader_num_terminated = 0; queue->reader_stats = (hlt_thread_queue_stats*) hlt_malloc(sizeof(hlt_thread_queue_stats)); memset(queue->reader_stats, 0, sizeof(hlt_thread_queue_stats)); queue->writer_batches = (batch**) hlt_malloc(sizeof(batch*) * writers); queue->writer_num_written = (uint64_t*) hlt_malloc(sizeof(uint64_t) * writers); queue->writer_stats = (hlt_thread_queue_stats*) hlt_malloc(sizeof(hlt_thread_queue_stats) * writers); queue->lock_num_pending = 0; queue->lock_pending_head = 0; queue->lock_pending_tail = 0; queue->lock_block = 0; queue->lock_writers_terminated = (int*) hlt_malloc(sizeof(int) * writers); memset(queue->writer_stats, 0, sizeof(hlt_thread_queue_stats) * writers); for ( int i = 0; i < writers; ++i ) { queue->writer_batches[i] = 0; queue->writer_num_written[i] = 0; queue->lock_writers_terminated[i] = 0; } queue->need_flush = 0; if ( PTHREAD_SPIN_INIT(&queue->lock) != 0 ) _fatal_error("cannot init lock"); return queue; }
/* bind the socket and start listening */ static int _server_proc_init(void) { if (!_setup_sockets()) return 0; if (!_start_listening()) { _fatal_error("Failed trying to listen on server socket"); return 0; } return 1; }
// Note: When using _acquire/_release, it is important that there's no // cancelation point between the two calls as otherwise a lock main remain // acquired after a thread has already terminated. inline static void _acquire_lock(hlt_thread_queue* queue, int* i, int reader, int thread) { hlt_pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, i); // stderr, "trying acquired %p %d %d\n", queue, reader, thread); if ( PTHREAD_SPIN_LOCK(&queue->lock) != 0 ) _fatal_error("cannot acquire lock"); // fprintf(stderr, "acquired %p %d %d\n", queue, reader, thread); }
void init_map(boardp b, int width, int height){ if (width < 0 || height < 0){ _fatal_error("illegal width or height in init_map()"); } if (b->width != -1){ /* map allocated ? */ free(b->map); } b->map = malloc(width * height + 1); b->width = width; b->height = height; b->map[0] = 0; /* map initilized to zero length string */ }
value_t _apply_closure(value_t a, ...) { ASSERT_CLOSURE(a); closure_t closure = VALUE_TO_CLOSURE(a); va_list var_args; va_start(var_args, a); value_t op[32]; size_t i = 0, j = 0; for (; i < closure.arity; i++) { op[i] = va_arg(var_args, value_t); } va_end(var_args); for (; closure.env != NULL && closure.env[j] != 0; j++, i++) { op[i] = closure.env[j]; } value_t result; #define OP_0 #define OP_1 op[0] #define OP_2 OP_1 , op[1] #define OP_3 OP_2 , op[2] #define OP_4 OP_3 , op[3] #define OP_5 OP_4 , op[4] #define OP_6 OP_5 , op[5] #define OP_7 OP_6 , op[6] #define OP_8 OP_7 , op[7] #define OP(n) OP_##n #define CASE(n) case n: result = closure.func( OP(n) ); break; switch (closure.arity + j) { CASE(0); CASE(1); CASE(2); CASE(3); CASE(4); CASE(5); CASE(6); CASE(7); CASE(8); default: _fatal_error("Can't apply that many arguments to a function"); result = 0; } return result; }
static int _start_logging(void) { char fn_error[FILENAME_MAX]; char fn_access[FILENAME_MAX]; char pbuf[1024]; ice_config_t *config = config_get_config_unlocked(); if(strcmp(config->error_log, "-")) { snprintf(fn_error, FILENAME_MAX, "%s%s%s", config->log_dir, PATH_SEPARATOR, config->error_log); errorlog = log_open(fn_error); } else { errorlog = log_open_file(stderr); } if(strcmp(config->access_log, "-")) { snprintf(fn_access, FILENAME_MAX, "%s%s%s", config->log_dir, PATH_SEPARATOR, config->access_log); accesslog = log_open(fn_access); } else { accesslog = log_open_file(stderr); } log_set_level(errorlog, config->loglevel); log_set_level(accesslog, 4); if (errorlog < 0) { _fatal_error("FATAL: could not open error logging"); } if (accesslog < 0) { memset(pbuf, '\000', sizeof(pbuf)); snprintf(pbuf, sizeof(pbuf)-1, "FATAL: could not open access logging"); _fatal_error(pbuf); } if (errorlog >= 0 && accesslog >= 0) return 1; return 0; }
void hlt_thread_queue_write(hlt_thread_queue* queue, int writer, void *elem) { if ( queue->lock_writers_terminated[writer] ) // Ignore when we have already terminated. We can read this without // locking as we're the only thread ever going to write to it. return; do { batch* b = queue->writer_batches[writer]; // If we don't have a batch, get us one. if ( ! b ) { b = (batch*) hlt_malloc(sizeof(batch) * queue->batch_size * sizeof(void*)); if ( ! b ) _fatal_error("out of memory"); b->write_pos = 0; b->next = 0; queue->writer_batches[writer] = b; } // If there isn't enough space in our batch, flush. if ( b->write_pos >= queue->batch_size ) hlt_thread_queue_flush(queue, writer); } while ( ! queue->writer_batches[writer] ); // Write the element. batch* b = queue->writer_batches[writer]; assert(b && b->write_pos < queue->batch_size); b->elems[b->write_pos++] = elem; ++queue->writer_num_written[writer]; ++queue->writer_stats[writer].elems; hlt_thread_queue_writer_update(queue, writer); }
int main(int argc, char **argv) { int res, ret; char filename[512]; char pbuf[1024]; kitsune_do_automigrate(); /**DSU data */ if (!kitsune_is_updating()) { /**DSU control */ /* parse the '-c icecast.xml' option ** only, so that we can read a configfile */ res = _parse_config_opts(argc, argv, filename, 512); if (res == 1) { /* startup all the modules */ _initialize_subsystems(); /* parse the config file */ config_get_config(); ret = config_initial_parse_file(filename); config_release_config(); if (ret < 0) { memset(pbuf, '\000', sizeof(pbuf)); snprintf(pbuf, sizeof(pbuf)-1, "FATAL: error parsing config file (%s)", filename); _fatal_error(pbuf); switch (ret) { case CONFIG_EINSANE: _fatal_error("filename was null or blank"); break; case CONFIG_ENOROOT: _fatal_error("no root element found"); break; case CONFIG_EBADROOT: _fatal_error("root element is not <icecast>"); break; default: _fatal_error("XML config parsing error"); break; } _shutdown_subsystems(); return 1; } } else if (res == -1) { _print_usage(); return 1; } /* override config file options with commandline options */ config_parse_cmdline(argc, argv); /* Bind socket, before we change userid */ if(!_server_proc_init()) { _fatal_error("Server startup failed. Exiting"); _shutdown_subsystems(); return 1; } _ch_root_uid_setup(); /* Change user id and root if requested/possible */ stats_initialize(); /* We have to do this later on because of threading */ fserve_initialize(); /* This too */ #ifdef CHUID /* We'll only have getuid() if we also have setuid(), it's reasonable to * assume */ if(!getuid()) /* Running as root! Don't allow this */ { fprintf(stderr, "ERROR: You should not run icecast2 as root\n"); fprintf(stderr, "Use the changeowner directive in the config file\n"); _shutdown_subsystems(); return 1; } #endif /* setup default signal handlers */ sighandler_initialize(); if (!_start_logging()) { _fatal_error("FATAL: Could not start logging"); _shutdown_subsystems(); return 1; } INFO0 (ICECAST_VERSION_STRING " server started"); /* REM 3D Graphics */ /* let her rip */ global.running = ICE_RUNNING; /* Startup yp thread */ yp_initialize(); /* Do this after logging init */ slave_initialize(); auth_initialise (); } else { /**DSU control 2 */ /* setup default signal handlers */ sighandler_initialize(); } /* END EKIDEN INIT BLOCK */ _server_proc(); INFO0("Shutting down"); _shutdown_subsystems(); if (pidfile) { remove (pidfile); free (pidfile); } return 0; }
int server_init (int argc, char *argv[]) { int ret; char filename[512]; char pbuf[1024]; switch (_parse_config_opts (argc, argv, filename, 512)) { case -1: _print_usage(); return -1; default: /* parse the config file */ config_get_config(); ret = config_initial_parse_file(filename); config_release_config(); if (ret < 0) { snprintf (pbuf, sizeof(pbuf), "FATAL: error parsing config file (%s)", filename); _fatal_error (pbuf); switch (ret) { case CONFIG_EINSANE: _fatal_error("filename was null or blank"); break; case CONFIG_ENOROOT: _fatal_error("no root element found"); break; case CONFIG_EBADROOT: _fatal_error("root element is not <icecast>"); break; default: _fatal_error("XML config parsing error"); break; } return -1; } } /* override config file options with commandline options */ config_parse_cmdline(argc, argv); /* Bind socket, before we change userid */ if (_server_proc_init() == 0) { _fatal_error("Server startup failed. Exiting"); return -1; } fserve_initialize(); #ifdef CHUID /* We'll only have getuid() if we also have setuid(), it's reasonable to * assume */ if (getuid() == 0) /* Running as root! Don't allow this */ { fprintf (stderr, "ERROR: You should not run icecast2 as root\n"); fprintf (stderr, "Use the changeowner directive in the config file\n"); return -1; } #endif /* setup default signal handlers */ sighandler_initialize(); if (start_logging (config_get_config_unlocked()) < 0) { _fatal_error("FATAL: Could not start logging"); return -1; } return 0; }
static int _start_logging(void) { char fn_error[FILENAME_MAX]; char fn_access[FILENAME_MAX]; char fn_playlist[FILENAME_MAX]; char buf[1024]; int log_to_stderr; ice_config_t *config = config_get_config_unlocked(); if(strcmp(config->error_log, "-")) { snprintf(fn_error, FILENAME_MAX, "%s%s%s", config->log_dir, PATH_SEPARATOR, config->error_log); errorlog = log_open(fn_error); log_to_stderr = 0; } else { errorlog = log_open_file(stderr); log_to_stderr = 1; } if (errorlog < 0) { buf[sizeof(buf)-1] = 0; snprintf(buf, sizeof(buf)-1, "FATAL: could not open error logging (%s): %s", log_to_stderr?"standard error":fn_error, strerror(errno)); _fatal_error(buf); } log_set_level(errorlog, config->loglevel); if(strcmp(config->access_log, "-")) { snprintf(fn_access, FILENAME_MAX, "%s%s%s", config->log_dir, PATH_SEPARATOR, config->access_log); accesslog = log_open(fn_access); log_to_stderr = 0; } else { accesslog = log_open_file(stderr); log_to_stderr = 1; } if (accesslog < 0) { buf[sizeof(buf)-1] = 0; snprintf(buf, sizeof(buf)-1, "FATAL: could not open access logging (%s): %s", log_to_stderr?"standard error":fn_access, strerror(errno)); _fatal_error(buf); } if(config->playlist_log) { snprintf(fn_playlist, FILENAME_MAX, "%s%s%s", config->log_dir, PATH_SEPARATOR, config->playlist_log); playlistlog = log_open(fn_playlist); if (playlistlog < 0) { buf[sizeof(buf)-1] = 0; snprintf(buf, sizeof(buf)-1, "FATAL: could not open playlist logging (%s): %s", log_to_stderr?"standard error":fn_playlist, strerror(errno)); _fatal_error(buf); } log_to_stderr = 0; } else { playlistlog = -1; } log_set_level(errorlog, config->loglevel); log_set_level(accesslog, 4); log_set_level(playlistlog, 4); if (errorlog >= 0 && accesslog >= 0) return 1; return 0; }
int main(int argc, char **argv) { int res, ret; ice_config_t *config; char *pidfile = NULL; char filename[512]; char pbuf[1024]; /* parse the '-c icecast.xml' option ** only, so that we can read a configfile */ res = _parse_config_file(argc, argv, filename, 512); if (res == 1) { /* startup all the modules */ _initialize_subsystems(); /* parse the config file */ config_get_config(); ret = config_initial_parse_file(filename); config_release_config(); if (ret < 0) { memset(pbuf, '\000', sizeof(pbuf)); snprintf(pbuf, sizeof(pbuf)-1, "FATAL: error parsing config file (%s)", filename); _fatal_error(pbuf); switch (ret) { case CONFIG_EINSANE: _fatal_error("filename was null of blank"); break; case CONFIG_ENOROOT: _fatal_error("no root element found"); break; case CONFIG_EBADROOT: _fatal_error("root element is not <icecast>"); break; default: _fatal_error("XML config parsing error"); break; } _shutdown_subsystems(); return 1; } } else if (res == -1) { _print_usage(); return 1; } /* override config file options with commandline options */ config_parse_cmdline(argc, argv); /* Bind socket, before we change userid */ if(!_server_proc_init()) { _fatal_error("Server startup failed. Exiting"); _shutdown_subsystems(); return 1; } _ch_root_uid_setup(); /* Change user id and root if requested/possible */ stats_initialize(); /* We have to do this later on because of threading */ fserve_initialize(); /* This too */ #ifdef CHUID /* We'll only have getuid() if we also have setuid(), it's reasonable to * assume */ if(!getuid()) /* Running as root! Don't allow this */ { fprintf(stderr, "WARNING: You should not run icecast2 as root\n"); fprintf(stderr, "Use the changeowner directive in the config file\n"); _shutdown_subsystems(); return 1; } #endif /* setup default signal handlers */ sighandler_initialize(); if (!_start_logging()) { _fatal_error("FATAL: Could not start logging"); _shutdown_subsystems(); return 1; } config = config_get_config_unlocked(); /* recreate the pid file */ if (config->pidfile) { FILE *f; pidfile = strdup (config->pidfile); if (pidfile && (f = fopen (config->pidfile, "w")) != NULL) { fprintf (f, "%d\n", getpid()); fclose (f); } } /* Do this after logging init */ slave_initialize(); INFO0("icecast server started"); /* REM 3D Graphics */ /* let her rip */ global.running = ICE_RUNNING; #ifdef USE_YP /* Startup yp thread */ yp_initialize(); #endif _server_proc(); INFO0("Shutting down"); _shutdown_subsystems(); if (pidfile) { remove (pidfile); free (pidfile); } return 0; }