gboolean setStatsFileFromIOC(GIOChannel *ioc, GIOCondition condition, gpointer n) { gchar *buf = NULL; GError *error = NULL; gsize bytes; gboolean r = TRUE; GIOStatus iostatus = G_IO_STATUS_NORMAL; if(!n) return(FALSE); if (condition & (G_IO_HUP | G_IO_PRI | G_IO_IN)) { buf = (gchar *) g_malloc0 (g_io_channel_get_buffer_size (ioc) + 1); r = FALSE; while(iostatus == G_IO_STATUS_NORMAL && ((HostNode *) n)->fpstat) { iostatus = g_io_channel_read_chars (ioc, buf, g_io_channel_get_buffer_size (ioc), &bytes, NULL); if(iostatus == G_IO_STATUS_ERROR || iostatus == G_IO_STATUS_AGAIN) break; if(*buf == 0) condition = G_IO_HUP; if(fwrite(buf, sizeof(gchar), bytes, ((HostNode *) n)->fpstat) != bytes) break; r = TRUE; } if(r == TRUE) fflush(((HostNode *) n)->fpstat); g_free(buf); } if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { g_io_channel_unref (ioc); if(g_io_channel_shutdown (ioc, TRUE, &error) == G_IO_STATUS_ERROR) { g_warning("%s", error->message); g_clear_error (&error); } r = FALSE; } return(r); }
static void test_small_writes (void) { GIOChannel *io; GIOStatus status = G_IO_STATUS_NORMAL; guint cnt; gchar tmp; GError *error = NULL; io = g_io_channel_new_file ("iochannel-test-outfile", "w", &error); gcut_assert_error (error); g_io_channel_set_encoding (io, NULL, NULL); g_io_channel_set_buffer_size (io, 1022); cnt = 2 * g_io_channel_get_buffer_size (io); tmp = 0; while (cnt) { status = g_io_channel_write_chars (io, &tmp, 1, NULL, NULL); if (status == G_IO_STATUS_ERROR) break; if (status == G_IO_STATUS_NORMAL) cnt--; } cut_assert_equal_int (G_IO_STATUS_NORMAL, status); g_io_channel_unref (io); }
static void test_small_writes (void) { GIOChannel *io; GIOStatus status; guint cnt; gchar tmp; GError *error = NULL; io = g_io_channel_new_file ("iochannel-test-outfile", "w", &error); if (error) { g_warning ("Unable to open file %s: %s", "iochannel-test-outfile", error->message); g_clear_error (&error); exit (1); } g_io_channel_set_encoding (io, NULL, NULL); g_io_channel_set_buffer_size (io, 1022); cnt = 2 * g_io_channel_get_buffer_size (io); tmp = 0; while (cnt) { status = g_io_channel_write_chars (io, &tmp, 1, NULL, NULL); if (status == G_IO_STATUS_ERROR) break; if (status == G_IO_STATUS_NORMAL) cnt--; } g_assert (status == G_IO_STATUS_NORMAL); g_io_channel_unref (io); }
static VALUE rg_buffer_size(VALUE self) { return UINT2NUM(g_io_channel_get_buffer_size(_SELF(self))); }
int main( int argc, char *argv[]) { glob_t gbuf; int grc, i; GString *cmd; GError *err = NULL; GMainLoop *loop; GPtrArray *child_args = NULL; /* parse options */ parse_options(&argc, &argv); /* set up logging */ if (!logc_setup(&err)) { air_opterr("%s", err->message); } if (fd_nextdir == NULL) { air_opterr("The --nextdir switch is required"); } child_args = g_ptr_array_sized_new(64); for (i=1; i < argc; i++) { /* Double dash indicates end of filedaemon's arguments */ if (!strncmp(argv[i], "--", strlen(argv[i])) ) continue; g_ptr_array_add(child_args, g_strdup(argv[i])); } g_ptr_array_add(child_args, NULL); if (child_args->len > 1) { if (fd_faildir == NULL) { air_opterr("The --faildir switch is required"); } } cmd = g_string_new(""); loop = g_main_loop_new(NULL, FALSE); /* We need an input glob */ if (!fd_inspec) { air_opterr("Input glob must be specified"); } /* If an output destination is provided, make sure it's a directory */ if (fd_outspec && !g_file_test(fd_outspec, G_FILE_TEST_IS_DIR )) { air_opterr("Output is not a directory"); } /* Options check out; daemonize */ if (!fd_nodaemon) { if (!daemonize()) { goto end; } } while (1) { /* Evaluate glob expression */ grc = glob(fd_inspec, 0, NULL, &gbuf); if (grc == GLOB_NOSPACE) { g_error("Out of memory: glob allocation failure"); } #ifdef GLOB_NOMATCH /* HaX0riffic! Simulate behavior without NOMATCH where we have it. */ else if (grc == GLOB_NOMATCH) { gbuf.gl_pathc = 0; gbuf.gl_pathv = NULL; } #endif /* Iterate over glob paths, enqueueing. */ for (i = 0; i < gbuf.gl_pathc; i++) { char **child_envp = {NULL}; GError *child_err = NULL; GString *filename_in = NULL; GString *filename_out = NULL; GString *filename_lock = NULL; GIOChannel *file_in = NULL; GIOChannel *file_out = NULL; GIOChannel *child_stdin = NULL; gint child_stdin_fd = -1; GIOChannel *child_stdout = NULL; gint child_stdout_fd = -1; GPid child_pid; int len; fd_read_data_t read_data; fd_write_data_t write_data; filename_in = g_string_new(gbuf.gl_pathv[i]); /* Skip non-regular files */ if (!g_file_test(filename_in->str, G_FILE_TEST_IS_REGULAR) ) { g_string_free(filename_in, TRUE); continue; } /* Skip lockfiles */ if (!strcmp(".lock", filename_in->str + strlen(filename_in->str) - 5)) { g_string_free(filename_in, TRUE); continue; } /* Generate lock path */ if (!filename_lock) filename_lock = g_string_new(""); g_string_printf(filename_lock, "%s.lock", filename_in->str); /* Skip files locked at queue time */ if (g_file_test(filename_lock->str, G_FILE_TEST_IS_REGULAR)) { g_debug("file %s is locked", filename_in->str); g_string_free(filename_in, TRUE); g_string_free(filename_lock, TRUE); continue; } if (child_args->len == 1) { /* Do move or delete */ GString *destpath = g_string_new(""); char *dbase = NULL; /* Calculate move destination path */ dbase = g_path_get_basename(filename_in->str); g_string_printf(destpath, "%s/%s", fd_nextdir, dbase); if (dbase) free(dbase); /* Do link */ g_message("moving %s -> %s", filename_in->str, fd_nextdir); if (link(filename_in->str, destpath->str) < 0) g_critical( "error moving input file to destination directory: %s", strerror(errno)); /* Do delete */ if (unlink(filename_in->str) < 0) { g_critical("error deleting input file"); } g_string_free(destpath, TRUE); g_string_free(filename_in, TRUE); g_string_free(filename_lock, TRUE); continue; } if (fd_lock) { fd_lock_file(filename_in->str); } file_in = g_io_channel_new_file(filename_in->str, "r", &err); if (file_in == NULL) { g_critical("Cannot open input file!"); } g_io_channel_set_encoding(file_in, NULL, &err); if (err) { g_critical("error setting input encoding!"); } g_io_channel_set_buffer_size(file_in, fd_bufsize); filename_out = g_string_new(""); if (fd_outspec == NULL) { g_string_printf(filename_out, "%s", gbuf.gl_pathv[i]); } else { g_string_printf(filename_out, "%s/%s", fd_outspec, gbuf.gl_pathv[i]); } len = filename_out->len; if (g_strrstr(filename_out->str, ".")) { while (len-- > 0 && !g_str_has_suffix(filename_out->str, ".") ) { g_string_set_size(filename_out, filename_out->len - 1); } g_string_set_size(filename_out, filename_out->len - 1); } if (fd_outext) { g_string_append_printf(filename_out, ".%s", fd_outext); } else { g_string_append(filename_out, ".out"); } g_message("%d: %s -> %s", i, filename_in->str, filename_out->str); file_out = g_io_channel_new_file(filename_out->str, "w", &err); if (file_out == NULL) { g_error("Cannot open output file!"); } g_io_channel_set_encoding(file_out, NULL, &err); if (err) { g_error("error setting output encoding!"); } g_io_channel_set_buffer_size(file_out, fd_bufsize); if (!g_spawn_async_with_pipes(".", (gchar **) child_args->pdata, child_envp, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &child_pid, &child_stdin_fd, &child_stdout_fd, NULL, &child_err)) { g_error("error spawning process: %s", (child_err && child_err->message ? child_err-> message : "unknown error")); } g_debug("spawned process %d", i); /* Watch for process exit status */ g_child_watch_add(child_pid, on_child_exit, filename_in->str); child_stdin = g_io_channel_unix_new(child_stdin_fd); if (child_stdin == NULL) { g_error("Cannot open child stdin!"); } g_io_channel_set_encoding(child_stdin, NULL, &err); if (err) { g_error("error setting child stdin encoding!"); } g_io_channel_set_buffer_size(child_stdin, fd_bufsize); child_stdout = g_io_channel_unix_new(child_stdout_fd); if (child_stdout == NULL) { g_error("Cannot open child stdout!"); } g_io_channel_set_encoding(child_stdout, NULL, &err); if (err) { g_error("error setting child stdout encoding!"); } g_io_channel_set_buffer_size(child_stdout, fd_bufsize); write_data.infile = file_in; write_data.buf = g_malloc(g_io_channel_get_buffer_size(file_in)); if (write_data.buf == NULL) { g_error("error allocating file_in buffer"); } if (!g_io_add_watch(child_stdin, G_IO_OUT | G_IO_PRI | G_IO_HUP | G_IO_ERR, write_to_child, &write_data)) g_error("Cannot add watch on GIOChannel!"); read_data.outfile = file_out; read_data.loop = loop; read_data.buf = g_malloc(g_io_channel_get_buffer_size(file_out)); if (write_data.buf == NULL) { g_error("error allocating file_in buffer"); } if (!g_io_add_watch(child_stdout, G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_ERR, read_from_child, &read_data)) g_error("Cannot add watch on GIOChannel!"); g_main_loop_run(loop); if (fd_lock) { fd_unlock_file(filename_in->str); } if (read_data.buf) { g_free(read_data.buf); } if (write_data.buf) { g_free(write_data.buf); } g_string_free(filename_in, TRUE); g_string_free(filename_out, TRUE); g_string_free(filename_lock, TRUE); } sleep(fd_poll_delay); } end: return 0; }