diff options
-rw-r--r-- | src/rharchive.c | 10 | ||||
-rw-r--r-- | src/writer.c | 80 | ||||
-rw-r--r-- | src/writer.h | 2 |
3 files changed, 75 insertions, 17 deletions
diff --git a/src/rharchive.c b/src/rharchive.c index dda75f4..fc5f442 100644 --- a/src/rharchive.c +++ b/src/rharchive.c @@ -124,16 +124,18 @@ int main_loop(options_t* opt) gst_element_set_state(pipeline, GST_STATE_PLAYING); signal_start(loop); - writer_start(&writer); - g_main_loop_run(loop); - signal_stop(); + ret = writer_start(&writer); + if(!ret) { + g_main_loop_run(loop); + signal_stop(); + } log_printf(NOTICE, "Stopping pipeline"); gst_element_set_state (pipeline, GST_STATE_NULL); writer_stop(&writer); gst_object_unref(GST_OBJECT(pipeline)); - return 0; + return ret; } int main(int argc, char* argv[]) diff --git a/src/writer.c b/src/writer.c index 633a34e..db20ec0 100644 --- a/src/writer.c +++ b/src/writer.c @@ -31,6 +31,8 @@ #include <sys/stat.h> #include <fcntl.h> +#include <errno.h> +#include <string.h> #include <time.h> #include "writer.h" @@ -38,7 +40,7 @@ #include "datatypes.h" #include "log.h" -static void init_time_boundaries(writer_t* writer) +static int init_time_boundaries(writer_t* writer) { if(!writer) return; @@ -51,9 +53,13 @@ static void init_time_boundaries(writer_t* writer) log_printf(INFO, "it's now: %02d:%02d:%02d on %d.%d.%d", bd_time.tm_hour, bd_time.tm_min, bd_time.tm_sec, bd_time.tm_mday, bd_time.tm_mon+1, bd_time.tm_year+1900); - strftime(writer->current_.name_, sizeof(writer->current_.name_), writer->name_format_, &bd_time); - log_printf(INFO, "current filename is: %s(.?)", writer->current_.name_); - + char name[256]; + strftime(name, sizeof(name), writer->name_format_, &bd_time); + asprintf(&(writer->current_.path_), "%s/%s", writer->output_dir_, name); + if(!writer->current_.path_) { + return -2; + } + log_printf(INFO, "current filename is: %s(.?)", writer->current_.path_); bd_time.tm_sec = 0; bd_time.tm_min = 0; @@ -65,11 +71,18 @@ static void init_time_boundaries(writer_t* writer) log_printf(INFO, "next boundary is at: %02d:%02d:%02d on %d.%d.%d", bd_time.tm_hour, bd_time.tm_min, bd_time.tm_sec, bd_time.tm_mday, bd_time.tm_mon+1, bd_time.tm_year+1900); - strftime(writer->next_.name_, sizeof(writer->next_.name_), writer->name_format_, &bd_time); - log_printf(INFO, "next filename will be: %s(.?)", writer->next_.name_); + strftime(name, sizeof(name), writer->name_format_, &bd_time); + asprintf(&(writer->next_.path_), "%s/%s", writer->output_dir_, name); + if(!writer->next_.path_) { + free(writer->current_.path_); + return -2; + } + log_printf(INFO, "next filename will be: %s(.?)", writer->next_.path_); struct timespec b = { T, 0 }; writer->next_boundary_ = b; + + return 0; } int writer_init(writer_t* writer, const char* name_format, const char* output_dir, int interval, int offset) @@ -91,14 +104,45 @@ int writer_init(writer_t* writer, const char* name_format, const char* output_di writer->output_dir_ = output_dir; writer->interval_ = interval * GST_MSECOND; writer->offset_ = offset * GST_MSECOND; - init_time_boundaries(writer); - - return 0; + writer->current_.path_ = NULL; + writer->next_.path_ = NULL; + writer->clock_id_ = 0; // TODO: NULL vs. 0 + writer->thread_ = 0; // TODO: NULL vs. 0 + return init_time_boundaries(writer); } static int open_file(file_t* file) { - + char* orig_path = file->path_; + int cnt = 0; + do { + file->fd_ = open(file->path_, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP); // make mode configurable + if(file->fd_ < 0) { + if(errno != EEXIST) { + // TODO: thread safe strerror + log_printf(ERROR, "can't open file '%s': %s", file->path_, strerror(errno)); + if(orig_path != file->path_) + free(orig_path); + return -1; + } + cnt++; + char* tmp; + asprintf(&tmp, "%s.%d", orig_path, cnt); + if(!tmp) { + if(orig_path != file->path_) + free(orig_path); + return -2; + } + + if(file->path_ != orig_path) + free(file->path_); + file->path_ = tmp; + } + } + while(file->fd_ < 0); + + if(orig_path != file->path_) + free(orig_path); } static gpointer writer_thread_func(gpointer data) @@ -123,13 +167,18 @@ static gpointer writer_thread_func(gpointer data) } log_printf(NOTICE, "writer thread stopped"); + // TODO: stop pipeline!! return NULL; } int writer_start(writer_t* writer) { if(!writer) - return; + return -1; + + int ret = open_file(&(writer->current_)); + if(ret) + return ret; writer->clock_id_ = gst_clock_new_periodic_id(writer->clock_, 0, writer->interval_); writer->thread_ = g_thread_create(writer_thread_func, writer, TRUE, NULL); @@ -137,6 +186,8 @@ int writer_start(writer_t* writer) log_printf(ERROR, "writer thread could not be started"); return -1; } + + return 0; } void writer_stop(writer_t* writer) @@ -144,7 +195,12 @@ void writer_stop(writer_t* writer) if(!writer) return; - gst_clock_id_unschedule(writer->clock_id_); + if(writer->current_.path_) free(writer->current_.path_); + if(writer->next_.path_) free(writer->next_.path_); + + if(writer->clock_id_) { + gst_clock_id_unschedule(writer->clock_id_); + } if(writer->thread_) { log_printf(NOTICE, "waiting for writer thread to stop"); g_thread_join(writer->thread_); diff --git a/src/writer.h b/src/writer.h index 4619d95..f39b659 100644 --- a/src/writer.h +++ b/src/writer.h @@ -33,7 +33,7 @@ struct file_struct { int fd_; - char name_[100]; + char* path_; }; typedef struct file_struct file_t; |