/** * Start watching the list of watched directories */ void sxe_dirwatch_start(void) { SXEE61("sxe_dirwatch_start() // fd=%d", sxe_dirwatch_watcher.fd); ev_io_start(sxe_private_main_loop, &sxe_dirwatch_watcher); SXER60("return"); }
/** * Stop watching the list of watched directories */ void sxe_dirwatch_stop(void) { SXEE60("sxe_stat_stop()"); ev_io_stop(sxe_private_main_loop, &sxe_dirwatch_watcher); SXER60("return"); }
/** * Construct a watched directory and add it to the list of watched directories * * @param dirwatch Pointer to the directory watcher * @param directory Name of directory to watch * @param flags Add one or more of: SXE_DIRWATCH_CREATED, SXE_DIRWATCH_MODIFIED, SXE_DIRWATCH_DELETED * @param notify Function to be called when directory changes * @param user_data Data to pass to the notify callback * * @exception Aborts if the dirwatch cannot be added to inotify */ void sxe_dirwatch_add(SXE_DIRWATCH * dirwatch, const char * directory, unsigned flags, void(*notify)(EV_P_ const char * file, int revents,void * user_data), void * user_data) { char buffer[PATH_MAX]; char * cwd; int inotify_flags = IN_MASK_ADD | IN_ONLYDIR; SXEE65("(dirwatch=%p, directory=%s, flags=0x%x, notify=%p, user_data=%p)", dirwatch, directory, flags, notify, user_data); if (flags & SXE_DIRWATCH_CREATED) { inotify_flags |= IN_CREATE | IN_MOVED_TO; } if (flags & SXE_DIRWATCH_MODIFIED) { inotify_flags |= IN_MODIFY; } if (flags & SXE_DIRWATCH_DELETED) { inotify_flags |= IN_DELETE | IN_MOVED_FROM; } dirwatch->notify = notify; dirwatch->user_data = user_data; dirwatch->fd = inotify_add_watch(sxe_dirwatch_watcher.fd, directory, inotify_flags); SXEA13(dirwatch->fd != -1, "Error watching directory '%s' (pwd = '%s'): %s", directory, (cwd = getcwd(buffer, sizeof(buffer))), strerror(errno)); sxe_list_push(&sxe_dirwatch_list, dirwatch); SXEL62("added directory %s as watch id %d", directory, dirwatch->fd); SXER60("return"); }
SXE_RETURN sxe_spawn_init(void) { SXEE60("sxe_spawn_init()"); SXER60("return SXE_RETURN_OK"); return SXE_RETURN_OK; }
static void test_dirwatch_event(EV_P_ const char *chfile, int chflags, void * user_data) { SXE_UNUSED_PARAMETER(loop); SXEE63("test_dirwatch_event(chfile=%s, chflags=%08x, user_data=%p)", chfile, chflags, user_data); tap_ev_push(__func__, 3, "chfile", tap_dup(chfile, strlen(chfile)), "chflags", chflags, "user_data", user_data); SXER60("return"); }
static void sxe_dirwatch_event(EV_P_ ev_io * io, int revents) { char buffer[8192]; int length; unsigned offset; struct inotify_event * event; SXE_UNUSED_PARAMETER(revents); SXEE62("(fd=%d, revents=%08x)", io->fd, revents); SXEA11((length = read(io->fd, buffer, sizeof(buffer))) >= 0, "sxe_dirwatch_event: Failed to read events from inotify: %s", strerror(errno)); for (offset = 0; offset < (unsigned)length;) { SXE_LIST_WALKER walker; SXE_DIRWATCH * dirwatch; int flags = 0; SXEA12(length - offset >= sizeof(struct inotify_event), "Odd sized chunk left in buffer %u (expected inotify event of %u bytes)", length - offset, sizeof(struct inotify_event)); event = (struct inotify_event *)&buffer[offset]; offset += sizeof(struct inotify_event); SXEA12(length - offset >= event->len, "Chunk left in buffer %u (expected length %u)", length - offset, event->len); offset += event->len; SXEL63("dirwatch_event: fd=%d flags=%08x file=%s", event->wd, event->mask, event->name); sxe_list_walker_construct(&walker, &sxe_dirwatch_list); while ((dirwatch = (SXE_DIRWATCH *)sxe_list_walker_step(&walker)) != NULL) { if (dirwatch->fd == event->wd) { break; } } SXEA11(dirwatch, "No watched directory found with fd %d", event->wd); flags |= (event->mask & IN_CREATE) ? SXE_DIRWATCH_CREATED : 0; flags |= (event->mask & IN_MOVED_TO) ? SXE_DIRWATCH_CREATED : 0; flags |= (event->mask & IN_MODIFY) ? SXE_DIRWATCH_MODIFIED : 0; flags |= (event->mask & IN_DELETE) ? SXE_DIRWATCH_DELETED : 0; flags |= (event->mask & IN_MOVED_FROM) ? SXE_DIRWATCH_DELETED : 0; dirwatch->notify(EV_A_ event->name, flags, dirwatch->user_data); } SXER60("return"); }
static void sxe_load_connect_ramp_tcp(void) { unsigned int i; SXE_RETURN result; unsigned int connection_id; SXEE60("tcp_connect_ramp()"); for (i = 0; i < sxe_load_connect_ramp; i++) { connection_id = sxe_pool_set_oldest_element_state(sxe_load_connection_pool, SXE_LOAD_CONNECTION_STATE_FREE, SXE_LOAD_CONNECTION_STATE_AWAITING_CONNECT); if (connection_id == SXE_POOL_NO_INDEX) { SXEL60("All connections established"); goto SXE_EARLY_OUT; } /* loop until we can bind and connect successfully (port/ip chosen might already be inuse by the system) */ do { sxe_load_connection_pool[connection_id].connection = sxe_new_tcp(NULL, sxe_load_client_ip_as_text[sxe_load_client_ip_index], sxe_load_next_port, sxe_load_event_connect_tcp, sxe_load_event_read_client_tcp, sxe_load_event_close_tcp); result = sxe_connect(sxe_load_connection_pool[connection_id].connection, sxe_load_server_ip, sxe_load_server_port); sxe_load_client_ip_index++; if (sxe_load_client_ip_index == sxe_load_client_ip_count) { sxe_load_client_ip_index = 0; sxe_load_next_port--; if (sxe_load_next_port <= 1024) { sxe_load_next_port = 65535; } } if (result != SXE_RETURN_OK) { sxe_close(sxe_load_connection_pool[connection_id].connection); } } while (result != SXE_RETURN_OK); SXEL60("Starting new tcp connection"); /* save the pool index in the SXE extra data */ SXE_USER_DATA_AS_INT(sxe_load_connection_pool[connection_id].connection) = connection_id; sxe_load_connection_pool[connection_id].connecting_time = sxe_time_get(); sxe_load_connection_pool[connection_id].queries_completed = 0; } SXE_EARLY_OR_ERROR_OUT: SXER60("return"); }
/** * Initialize the dirwatch package * * @exceptions Aborts if already initialized or on failure to initialize inotify */ void sxe_dirwatch_init(void) { SXEE60("()"); if (sxe_dirwatch_inotify_fd != -1) { SXEL60("sxe_dirwatch_init: Already initialized"); goto SXE_EARLY_OUT; } SXEA11((sxe_dirwatch_inotify_fd = inotify_init()) != -1, "sxe_dirwatch_init: inotify_init() failed with %s", strerror(errno)); SXEL61("inotify_init() returned fd: %d", sxe_dirwatch_inotify_fd); SXE_LIST_CONSTRUCT(&sxe_dirwatch_list, 0, SXE_DIRWATCH, node); ev_io_init(&sxe_dirwatch_watcher, sxe_dirwatch_event, sxe_dirwatch_inotify_fd, EV_READ); SXE_EARLY_OUT: SXER60("return"); }
int main(void) { struct object self; struct object * this = &self; plan_tests(47); /* Test sxe_return_to_string() */ is_eq(sxe_return_to_string(SXE_RETURN_OK), "OK" , "sxe_return_to_string(SXE_RETURN_OK) eq \"OK\""); is_eq(sxe_return_to_string(SXE_RETURN_ERROR_INTERNAL), "ERROR_INTERNAL", "sxe_return_to_string(SXE_RETURN_ERROR_INTERNAL) eq \"ERROR_INTERNAL\""); is( sxe_return_to_string(~0U), NULL, "sxe_return_to_string(~0U) == NULL"); TEST_CASE_RETURN_TO_STRING(EXPIRED_VALUE); TEST_CASE_RETURN_TO_STRING(NO_UNUSED_ELEMENTS); TEST_CASE_RETURN_TO_STRING(IN_PROGRESS); TEST_CASE_RETURN_TO_STRING(UNCATEGORIZED); TEST_CASE_RETURN_TO_STRING(END_OF_FILE); TEST_CASE_RETURN_TO_STRING(WARN_ALREADY_INITIALIZED); TEST_CASE_RETURN_TO_STRING(WARN_WOULD_BLOCK); TEST_CASE_RETURN_TO_STRING(WARN_ALREADY_CLOSED); TEST_CASE_RETURN_TO_STRING(ERROR_NOT_INITIALIZED); TEST_CASE_RETURN_TO_STRING(ERROR_ALLOC); TEST_CASE_RETURN_TO_STRING(ERROR_NO_CONNECTION); TEST_CASE_RETURN_TO_STRING(ERROR_ALREADY_CONNECTED); TEST_CASE_RETURN_TO_STRING(ERROR_INVALID_URI); TEST_CASE_RETURN_TO_STRING(ERROR_BAD_MESSAGE); TEST_CASE_RETURN_TO_STRING(ERROR_ADDRESS_IN_USE); TEST_CASE_RETURN_TO_STRING(ERROR_INTERRUPTED); TEST_CASE_RETURN_TO_STRING(ERROR_COMMAND_NOT_RUN); TEST_CASE_RETURN_TO_STRING(ERROR_LOCK_NOT_TAKEN); TEST_CASE_RETURN_TO_STRING(ERROR_INCORRECT_STATE); TEST_CASE_RETURN_TO_STRING(ERROR_TIMED_OUT); TEST_CASE_RETURN_TO_STRING(ERROR_WRITE_FAILED); TEST_CASE_RETURN_TO_STRING(INVALID_VALUE); /* Just for coverage */ ok(signal(SIGABRT, test_abort_handler) != SIG_ERR, "Caught abort signal"); sxe_log_hook_line_out(NULL); /* for coverage */ sxe_log_hook_line_out(log_line); PUTENV("SXE_LOG_LEVEL=6"); /* Trigger processing of the level in the first call to the log */ SXEE60(entering); PUTENV("SXE_LOG_LEVEL=1"); /* This should be ignored. If it is not, the tests will fail */ this->id = 99; SXEL60I(logging); SXEA60(1, "Asserting true"); SXED60(dumpdata, 4); SXER60(exiting); SXEL60(verylong); SXEE61("really long entry message: %s", verylong); SXEL60(escape); SXEL60(hextrunc); SXED60(dumpdata, 0); /* Edge case */ SXEA80(1, "We should not get this, because level 8 is too low!"); is(sxe_log_decrease_level(SXE_LOG_LEVEL_ERROR), SXE_LOG_LEVEL_TRACE, "Level decreased to ERROR (2) from TRACE (6)"); is(sxe_log_set_level( SXE_LOG_LEVEL_INFORMATION), SXE_LOG_LEVEL_ERROR, "Level set to INFO, was ERROR"); is(sxe_log_decrease_level(SXE_LOG_LEVEL_TRACE), SXE_LOG_LEVEL_INFORMATION, "Level was INFO, TRACE is not a decrease"); #if defined(_WIN32) && defined(LOCAL_SXE_DEBUG) skip(3, "Can't test aborts in a Windows debug build, due to pop up Window stopping the build"); #else SXEA60(this != &self, "This is not self"); /* Abort - must be the last thing we do*/ fail("Did not catch an abort signal"); #endif } /* Oog! Close the brace opened in the SXEE61 macro above */