X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/8acbc68eb105f230393b6ab379022923c449ac44..76936a96e8256ec096612dc6dc9c75b880b868a8:/src/babel.c?ds=sidebyside diff --git a/src/babel.c b/src/babel.c index 27bc918d..e362ef2c 100644 --- a/src/babel.c +++ b/src/babel.c @@ -96,7 +96,7 @@ gboolean a_babel_convert( VikTrwLayer *vt, const char *babelargs, BabelStatusFun a_gpx_write_file(vt, f); fclose(f); f = NULL; - ret = a_babel_convert_from ( vt, bargs, cb, name_src, user_data ); + ret = a_babel_convert_from ( vt, bargs, name_src, cb, user_data ); g_remove(name_src); g_free(name_src); } @@ -105,68 +105,27 @@ gboolean a_babel_convert( VikTrwLayer *vt, const char *babelargs, BabelStatusFun return ret; } -#ifdef WINDOWS -static gboolean babel_general_convert( BabelStatusFunc cb, gchar **args, gpointer user_data ) +/** + * Perform any cleanup actions once GPSBabel has completed running + */ +static void babel_watch ( GPid pid, + gint status, + gpointer user_data ) { - gboolean ret; - FILE *f; - gchar *cmd; - gchar **args2; - - STARTUPINFO si; - PROCESS_INFORMATION pi; - - ZeroMemory( &si, sizeof(si) ); - ZeroMemory( &pi, sizeof(pi) ); - si.cb = sizeof(si); - si.dwFlags = STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; - - cmd = g_strjoinv( " ", args); - args2 = g_strsplit(cmd, "\\", 0); - g_free(cmd); - cmd = g_strjoinv( "\\\\", args2); - g_free(args2); - args2 = g_strsplit(cmd, "/", 0); - g_free(cmd); - cmd = g_strjoinv( "\\\\", args2); - - if( !CreateProcess( - NULL, // No module name (use command line). - (LPTSTR)cmd, // Command line. - NULL, // Process handle not inheritable. - NULL, // Thread handle not inheritable. - FALSE, // Set handle inheritance to FALSE. - 0, // No creation flags. - NULL, // Use parent's environment block. - NULL, // Use parent's starting directory. - &si, // Pointer to STARTUPINFO structure. - &pi ) // Pointer to PROCESS_INFORMATION structure. - ){ - g_error ( "CreateProcess failed" ); - ret = FALSE; - } - else { - WaitForSingleObject(pi.hProcess, INFINITE); - WaitForSingleObject(pi.hThread, INFINITE); - - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - - if ( cb ) - cb(BABEL_DONE, NULL, user_data); - - ret = TRUE; - } - - g_strfreev( args2 ); - g_free( cmd ); - - return ret; + g_spawn_close_pid ( pid ); } -/* Windows */ -#else -/* Posix */ + +/** + * babel_general_convert: + * @args: The command line arguments passed to GPSBabel + * @cb: callback that is run for each line of GPSBabel output and at completion of the run + * callback may be NULL + * @user_data: passed along to cb + * + * The function to actually invoke the GPSBabel external command + * + * Returns: %TRUE on successful invocation of GPSBabel command + */ static gboolean babel_general_convert( BabelStatusFunc cb, gchar **args, gpointer user_data ) { gboolean ret = FALSE; @@ -174,7 +133,7 @@ static gboolean babel_general_convert( BabelStatusFunc cb, gchar **args, gpointe GError *error = NULL; gint babel_stdout; - if (!g_spawn_async_with_pipes (NULL, args, NULL, 0, NULL, NULL, &pid, NULL, &babel_stdout, NULL, &error)) { + if (!g_spawn_async_with_pipes (NULL, args, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL, &babel_stdout, NULL, &error)) { g_error("Async command failed: %s", error->message); g_error_free(error); ret = FALSE; @@ -193,15 +152,14 @@ static gboolean babel_general_convert( BabelStatusFunc cb, gchar **args, gpointe cb(BABEL_DONE, NULL, user_data); fclose(diag); diag = NULL; - waitpid(pid, NULL, 0); - g_spawn_close_pid(pid); + + g_child_watch_add ( pid, (GChildWatchFunc) babel_watch, NULL ); ret = TRUE; } return ret; } -#endif /* Posix */ /** * babel_general_convert_from: @@ -234,10 +192,9 @@ static gboolean babel_general_convert_from( VikTrwLayer *vt, BabelStatusFunc cb, f = g_fopen(name_dst, "r"); if (f) { - a_gpx_read_file ( vt, f ); + ret = a_gpx_read_file ( vt, f ); fclose(f); f = NULL; - ret = TRUE; } } @@ -257,7 +214,7 @@ static gboolean babel_general_convert_from( VikTrwLayer *vt, BabelStatusFunc cb, * * Returns: %TRUE on success */ -gboolean a_babel_convert_from( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, const char *from, gpointer user_data ) +gboolean a_babel_convert_from( VikTrwLayer *vt, const char *babelargs, const char *from, BabelStatusFunc cb, gpointer user_data ) { int i,j; int fd_dst; @@ -292,7 +249,7 @@ gboolean a_babel_convert_from( VikTrwLayer *vt, const char *babelargs, BabelStat g_strfreev(sub_args); } else - g_error("gpsbabel not found in PATH"); + g_critical("gpsbabel not found in PATH"); g_remove(name_dst); g_free(name_dst); } @@ -362,7 +319,7 @@ gboolean a_babel_convert_from_url ( VikTrwLayer *vt, const char *url, const char fetch_ret = a_http_download_get_url(url, "", name_src, &options, NULL); if (fetch_ret == 0) - ret = a_babel_convert_from( vt, babelargs, NULL, name_src, NULL); + ret = a_babel_convert_from( vt, babelargs, name_src, NULL, NULL); g_remove(name_src); g_free(babelargs); @@ -375,14 +332,14 @@ gboolean a_babel_convert_from_url ( VikTrwLayer *vt, const char *url, const char static gboolean babel_general_convert_to( VikTrwLayer *vt, BabelStatusFunc cb, gchar **args, const gchar *name_src, gpointer user_data ) { if (!a_file_export(vt, name_src, FILE_TYPE_GPX, NULL)) { - g_error("Error exporting to %s", name_src); + g_critical("Error exporting to %s", name_src); return FALSE; } return babel_general_convert (cb, args, user_data); } -gboolean a_babel_convert_to( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, const char *to, gpointer user_data ) +gboolean a_babel_convert_to( VikTrwLayer *vt, const char *babelargs, const char *to, BabelStatusFunc cb, gpointer user_data ) { int i,j; int fd_src; @@ -416,7 +373,7 @@ gboolean a_babel_convert_to( VikTrwLayer *vt, const char *babelargs, BabelStatus g_strfreev(sub_args); } else - g_error("gpsbabel not found in PATH"); + g_critical("gpsbabel not found in PATH"); g_remove(name_src); g_free(name_src); } @@ -452,7 +409,7 @@ static void load_feature_parse_line (gchar *line) BabelDevice *device = g_malloc ( sizeof (BabelDevice) ); set_mode (device->mode, tokens[1]); device->name = g_strdup (tokens[2]); - device->label = g_strdup (tokens[4]); + device->label = g_strndup (tokens[4], 50); // Limit really long label text a_babel_device_list = g_list_append (a_babel_device_list, device); g_debug ("New gpsbabel device: %s", device->name); } else { @@ -502,7 +459,7 @@ static gboolean load_feature () ret = babel_general_convert (load_feature_cb, args, NULL); } else - g_error("gpsbabel not found in PATH"); + g_critical("gpsbabel not found in PATH"); return ret; } @@ -512,7 +469,7 @@ void a_babel_init () /* TODO allow to set gpsbabel path via command line */ gpsbabel_loc = g_find_program_in_path( "gpsbabel" ); if ( !gpsbabel_loc ) - g_error( "gpsbabel not found in PATH" ); + g_critical( "gpsbabel not found in PATH" ); unbuffer_loc = g_find_program_in_path( "unbuffer" ); if ( !unbuffer_loc ) g_warning( "unbuffer not found in PATH" ); @@ -524,4 +481,28 @@ void a_babel_uninit () { g_free ( gpsbabel_loc ); g_free ( unbuffer_loc ); + + if ( a_babel_file_list ) { + GList *gl; + for (gl = a_babel_file_list; gl != NULL; gl = g_list_next(gl)) { + BabelFile *file = gl->data; + g_free ( file->name ); + g_free ( file->ext ); + g_free ( file->label ); + g_free ( gl->data ); + } + g_list_free ( a_babel_file_list ); + } + + if ( a_babel_device_list ) { + GList *gl; + for (gl = a_babel_device_list; gl != NULL; gl = g_list_next(gl)) { + BabelDevice *device = gl->data; + g_free ( device->name ); + g_free ( device->label ); + g_free ( gl->data ); + } + g_list_free ( a_babel_device_list ); + } + }