From 3f935d5bf975b26836da2fac5cd6e3df67a5e184 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 1 Apr 2003 18:10:25 +0000 Subject: [PATCH] Various error-handling fixes, mostly in Unix PuTTY but one (failure to save a session) crosses over into the platform-independent side. git-svn-id: svn://svn.tartarus.org/sgt/putty@3041 cda61777-01e9-0310-a592-d414129be87e --- config.c | 8 +++++++- mac/macstore.c | 8 +++++--- putty.h | 2 +- settings.c | 8 +++++--- storage.h | 4 +++- unix/gtkdlg.c | 19 +++++-------------- unix/pterm.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++------------ unix/ptermm.c | 11 +++++++++++ unix/unix.h | 3 +++ unix/uxstore.c | 24 +++++++++++++++++------- winstore.c | 11 +++++++++-- 11 files changed, 112 insertions(+), 44 deletions(-) diff --git a/config.c b/config.c index 99a65ee1..7204a6c3 100644 --- a/config.c +++ b/config.c @@ -305,7 +305,13 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, savedsession[0] = '\0'; } } - save_settings(savedsession, !isdef, cfg); + { + char *errmsg = save_settings(savedsession, !isdef, cfg); + if (errmsg) { + dlg_error_msg(dlg, errmsg); + sfree(errmsg); + } + } get_sesslist(ssd->sesslist, FALSE); get_sesslist(ssd->sesslist, TRUE); dlg_refresh(ssd->editbox, dlg); diff --git a/mac/macstore.c b/mac/macstore.c index 5425efa3..548b7ac2 100644 --- a/mac/macstore.c +++ b/mac/macstore.c @@ -1,4 +1,4 @@ -/* $Id: macstore.c,v 1.18 2003/03/29 23:07:55 ben Exp $ */ +/* $Id: macstore.c,v 1.19 2003/04/01 18:10:25 simon Exp $ */ /* * macstore.c: Macintosh-specific impementation of the interface @@ -116,13 +116,15 @@ struct write_settings { FSSpec dstfile; }; -void *open_settings_w(char const *sessionname) { +void *open_settings_w(char const *sessionname, char **errmsg) { short sessVRefNum; long sessDirID; OSErr error; Str255 psessionname; FSSpec dstfile; - + + *errmsg = NULL; + error = get_session_dir(kCreateFolder, &sessVRefNum, &sessDirID); if (error != noErr) return NULL; diff --git a/putty.h b/putty.h index 68e722e3..0717f96b 100644 --- a/putty.h +++ b/putty.h @@ -546,7 +546,7 @@ void random_destroy_seed(void); /* * Exports from settings.c. */ -void save_settings(char *section, int do_host, Config * cfg); +char *save_settings(char *section, int do_host, Config * cfg); void save_open_settings(void *sesskey, int do_host, Config *cfg); void load_settings(char *section, int do_host, Config * cfg); void load_open_settings(void *sesskey, int do_host, Config *cfg); diff --git a/settings.c b/settings.c index f633d313..1de8e51a 100644 --- a/settings.c +++ b/settings.c @@ -141,15 +141,17 @@ static void wprefs(void *sesskey, char *name, write_setting_s(sesskey, name, buf); } -void save_settings(char *section, int do_host, Config * cfg) +char *save_settings(char *section, int do_host, Config * cfg) { void *sesskey; + char *errmsg; - sesskey = open_settings_w(section); + sesskey = open_settings_w(section, &errmsg); if (!sesskey) - return; + return errmsg; save_open_settings(sesskey, do_host, cfg); close_settings_w(sesskey); + return NULL; } void save_open_settings(void *sesskey, int do_host, Config *cfg) diff --git a/storage.h b/storage.h index 560ad600..704f2311 100644 --- a/storage.h +++ b/storage.h @@ -25,8 +25,10 @@ * A given key will be written at most once while saving a session. * Keys may be up to 255 characters long. String values have no length * limit. + * + * Any returned error message must be freed after use. */ -void *open_settings_w(const char *sessionname); +void *open_settings_w(const char *sessionname, char **errmsg); void write_setting_s(void *handle, const char *key, const char *value); void write_setting_i(void *handle, const char *key, int value); void write_setting_filename(void *handle, const char *key, Filename value); diff --git a/unix/gtkdlg.c b/unix/gtkdlg.c index 6f906df1..a454d8bb 100644 --- a/unix/gtkdlg.c +++ b/unix/gtkdlg.c @@ -2337,30 +2337,21 @@ void old_keyfile_warning(void) */ } -void fatalbox(char *p, ...) +void fatal_message_box(void *window, char *msg) { - va_list ap; - char *msg; - va_start(ap, p); - msg = dupvprintf(p, ap); - va_end(ap); - messagebox(NULL, "PuTTY Fatal Error", msg, + messagebox(window, "PuTTY Fatal Error", msg, string_width("REASONABLY LONG LINE OF TEXT FOR BASIC SANITY"), "OK", 'o', 1, 1, NULL); - sfree(msg); - cleanup_exit(1); } -void connection_fatal(void *frontend, char *p, ...) + +void fatalbox(char *p, ...) { va_list ap; char *msg; va_start(ap, p); msg = dupvprintf(p, ap); va_end(ap); - messagebox(GTK_WIDGET(get_window(frontend)), - "PuTTY Fatal Error", msg, - string_width("REASONABLY LONG LINE OF TEXT FOR BASIC SANITY"), - "OK", 'o', 1, 1, NULL); + fatal_message_box(NULL, msg); sfree(msg); cleanup_exit(1); } diff --git a/unix/pterm.c b/unix/pterm.c index 0ac3e305..00ce217e 100644 --- a/unix/pterm.c +++ b/unix/pterm.c @@ -86,6 +86,23 @@ char *x_get_default(const char *key) return XGetDefault(GDK_DISPLAY(), app_name, key); } +void connection_fatal(void *frontend, char *p, ...) +{ + Terminal *term = (Terminal *)frontend; + struct gui_data *inst = (struct gui_data *)term->frontend; + + va_list ap; + char *msg; + va_start(ap, p); + msg = dupvprintf(p, ap); + va_end(ap); + inst->exited = TRUE; + fatal_message_box(inst->window, msg); + sfree(msg); + if (inst->cfg.close_on_exit == FORCE_ON) + cleanup_exit(1); +} + /* * Default settings that are specific to pterm. */ @@ -1018,7 +1035,8 @@ gint timer_func(gpointer data) struct gui_data *inst = (struct gui_data *)data; int exitcode; - if ((exitcode = inst->back->exitcode(inst->backhandle)) >= 0) { + if (!inst->exited && + (exitcode = inst->back->exitcode(inst->backhandle)) >= 0) { inst->exited = TRUE; if (inst->cfg.close_on_exit == FORCE_ON || (inst->cfg.close_on_exit == AUTO && exitcode == 0)) @@ -1032,10 +1050,17 @@ gint timer_func(gpointer data) void fd_input_func(gpointer data, gint sourcefd, GdkInputCondition condition) { - select_result(sourcefd, - (condition == GDK_INPUT_READ ? 1 : - condition == GDK_INPUT_WRITE ? 2 : - condition == GDK_INPUT_EXCEPTION ? 4 : -1)); + /* + * We must process exceptional notifications before ordinary + * readability ones, or we may go straight past the urgent + * marker. + */ + if (condition & GDK_INPUT_EXCEPTION) + select_result(sourcefd, 4); + if (condition & GDK_INPUT_READ) + select_result(sourcefd, 1); + if (condition & GDK_INPUT_WRITE) + select_result(sourcefd, 2); } void destroy(GtkWidget *widget, gpointer data) @@ -2437,13 +2462,24 @@ int pt_main(int argc, char **argv) uxsel_init(); + term_size(inst->term, inst->cfg.height, inst->cfg.width, inst->cfg.savelines); + inst->back = select_backend(&inst->cfg); { - char *realhost; - - inst->back->init((void *)inst->term, &inst->backhandle, &inst->cfg, - inst->cfg.host, inst->cfg.port, &realhost, - inst->cfg.tcp_nodelay); + char *realhost, *error; + + error = inst->back->init((void *)inst->term, &inst->backhandle, + &inst->cfg, inst->cfg.host, inst->cfg.port, + &realhost, inst->cfg.tcp_nodelay); + + if (error) { + char *msg = dupprintf("Unable to open connection to %s:\n%s", + inst->cfg.host, error); + inst->exited = TRUE; + fatal_message_box(inst->window, msg); + sfree(msg); + return 0; + } if (inst->cfg.wintitle[0]) set_title(inst, inst->cfg.wintitle); @@ -2457,8 +2493,6 @@ int pt_main(int argc, char **argv) term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle); - term_size(inst->term, inst->cfg.height, inst->cfg.width, inst->cfg.savelines); - inst->ldisc = ldisc_create(&inst->cfg, inst->term, inst->back, inst->backhandle, inst); ldisc_send(inst->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */ diff --git a/unix/ptermm.c b/unix/ptermm.c index 9a27f23c..128f3102 100644 --- a/unix/ptermm.c +++ b/unix/ptermm.c @@ -3,6 +3,7 @@ */ #include +#include #include "putty.h" @@ -16,6 +17,16 @@ int cfgbox(Config *cfg) return 1; /* no-op in pterm */ } +void fatal_message_box(void *window, char *msg) +{ + /* also a no-op in pterm */ +} + +void cleanup_exit(int code) +{ + exit(code); +} + int process_nonoption_arg(char *arg, Config *cfg) { return 0; /* pterm doesn't have any. */ diff --git a/unix/unix.h b/unix/unix.h index a5dbca90..8c4b5fd9 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -58,6 +58,9 @@ long get_windowid(void *frontend); /* Things gtkdlg.c needs from pterm.c */ void *get_window(void *frontend); /* void * to avoid depending on gtk.h */ +/* Things pterm.c needs from gtkdlg.c */ +void fatal_message_box(void *window, char *msg); + /* Things pterm.c needs from {ptermm,uxputty}.c */ char *make_default_wintitle(char *hostname); int process_nonoption_arg(char *arg, Config *cfg); diff --git a/unix/uxstore.c b/unix/uxstore.c index b049c285..b04d557c 100644 --- a/unix/uxstore.c +++ b/unix/uxstore.c @@ -5,7 +5,9 @@ #include #include +#include #include +#include #include #include #include @@ -132,24 +134,32 @@ static char *fgetline(FILE *fp) * file somewhere or other. */ -void *open_settings_w(const char *sessionname) +void *open_settings_w(const char *sessionname, char **errmsg) { char filename[FILENAME_MAX]; FILE *fp; + *errmsg = NULL; + /* - * Start by making sure the sessions subdir exists. Ignore the - * error return from mkdir since it's perfectly likely to be - * `already exists', and any other error will trip us up later - * on so there's no real need to catch it now. + * Start by making sure the .putty directory and its sessions + * subdir actually exist. Ignore error returns from mkdir since + * they're perfectly likely to be `already exists', and any + * other error will trip us up later on so there's no real need + * to catch it now. */ + make_filename(filename, INDEX_DIR, sessionname); + mkdir(filename, 0700); make_filename(filename, INDEX_SESSIONDIR, sessionname); mkdir(filename, 0700); make_filename(filename, INDEX_SESSION, sessionname); fp = fopen(filename, "w"); - if (!fp) - return NULL; /* can't open */ + if (!fp) { + *errmsg = dupprintf("Unable to create %s: %s", + filename, strerror(errno)); + return NULL; /* can't open */ + } return fp; } diff --git a/winstore.c b/winstore.c index 90d262fe..b6f98f5d 100644 --- a/winstore.c +++ b/winstore.c @@ -61,12 +61,14 @@ static void unmungestr(const char *in, char *out, int outlen) return; } -void *open_settings_w(const char *sessionname) +void *open_settings_w(const char *sessionname, char **errmsg) { HKEY subkey1, sesskey; int ret; char *p; + *errmsg = NULL; + if (!sessionname || !*sessionname) sessionname = "Default Settings"; @@ -76,13 +78,18 @@ void *open_settings_w(const char *sessionname) ret = RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1); if (ret != ERROR_SUCCESS) { sfree(p); + *errmsg = dupprintf("Unable to create registry key\n" + "HKEY_CURRENT_USER%s", puttystr); return NULL; } ret = RegCreateKey(subkey1, p, &sesskey); sfree(p); RegCloseKey(subkey1); - if (ret != ERROR_SUCCESS) + if (ret != ERROR_SUCCESS) { + *errmsg = dupprintf("Unable to create registry key\n" + "HKEY_CURRENT_USER%s\\%s", puttystr, p); return NULL; + } return (void *) sesskey; } -- 2.11.0