Various error-handling fixes, mostly in Unix PuTTY but one (failure
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 1 Apr 2003 18:10:25 +0000 (18:10 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 1 Apr 2003 18:10:25 +0000 (18:10 +0000)
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
mac/macstore.c
putty.h
settings.c
storage.h
unix/gtkdlg.c
unix/pterm.c
unix/ptermm.c
unix/unix.h
unix/uxstore.c
winstore.c

index 99a65ee..7204a6c 100644 (file)
--- 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);
index 5425efa..548b7ac 100644 (file)
@@ -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 68e722e..0717f96 100644 (file)
--- 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);
index f633d31..1de8e51 100644 (file)
@@ -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)
index 560ad60..704f231 100644 (file)
--- a/storage.h
+++ b/storage.h
  * 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);
index 6f906df..a454d8b 100644 (file)
@@ -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);
 }
index 0ac3e30..00ce217 100644 (file)
@@ -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 */
index 9a27f23..128f310 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 
 #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. */
index a5dbca9..8c4b5fd 100644 (file)
@@ -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);
index b049c28..b04d557 100644 (file)
@@ -5,7 +5,9 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <assert.h>
+#include <errno.h>
 #include <ctype.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -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;
 }
 
index 90d262f..b6f98f5 100644 (file)
@@ -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;
 }