diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 94b4ca6cf7fb5a4209fd7d9c05a2485c1dc8089e..d1b26ee21038494ee34afed17c822afc05851848 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -170,8 +170,8 @@ void Get_Options(int argc, char *argv[])
 
 #if !defined(HAVE_NO_PARSER)
   // Parse session and option files
-  ParseFile(CTX.session_filename_fullpath, 1);
-  ParseFile(CTX.options_filename_fullpath, 1);
+  ParseFile((CTX.home_dir + CTX.session_filename).c_str(), true);
+  ParseFile((CTX.home_dir + CTX.options_filename).c_str(), true);
 #endif
 
   // Get command line options
@@ -280,7 +280,7 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "option")) {
         i++;
         if(argv[i] != NULL)
-          ParseFile(argv[i++], 1);
+          ParseFile(argv[i++], true);
         else
 	  Msg::Fatal("Missing file name");
       }
@@ -668,8 +668,10 @@ void Get_Options(int argc, char *argv[])
 
   }
 
-  if(CTX.files.empty())
-    GModel::current()->setFileName(CTX.default_filename_fullpath);
+  if(CTX.files.empty()){
+    std::string base = (getenv("PWD") ? "" : CTX.home_dir);
+    GModel::current()->setFileName((base + CTX.default_filename).c_str());
+  }
   else
     GModel::current()->setFileName(CTX.files[0]);
 
diff --git a/Common/Context.h b/Common/Context.h
index 61ff290b8e6ed40bb6771eb054d2a46dc192e214..ca55ac1a2e0faed91efde725d70d894238179e70 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -21,15 +21,10 @@ class Context_T {
   const char *bgm_filename; // background mesh
   const char *output_filename; // output file specified with command line option '-o'
   const char *default_filename;
-  char default_filename_fullpath[256]; // the name of the default file
   const char *tmp_filename;
-  char tmp_filename_fullpath[256]; // the name of the temp file
   const char *session_filename;
-  char session_filename_fullpath[256]; // the name of the session configuration file
   const char *options_filename;
-  char options_filename_fullpath[256]; // the name of the option configuration file
   const char *error_filename;
-  char error_filename_fullpath[256]; // the name of the error file
   char statreport[256]; // mesh stat output file
   int create_append_statreport; // do nothing 0 create 1 append 2 
   int session_save, options_save; // save session/option file on exit
@@ -39,7 +34,7 @@ class Context_T {
   int num_windows, num_tiles; // number of graphical windows/tiles to create
   const char *editor; // text editor command (with included '%s')
   const char *web_browser; // web browser command (with included '%s')
-  char home_dir[256]; // the home directory
+  std::string home_dir; // the home directory
   const char *gui_theme; // FLTK GUI theme
   int tooltips; // show tootips in GUI?
   int position[2]; // position of the menu window on the screen
diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index 06dbf3c84b23b46e51d68bfa124642708e3c80a4..42e364a96f21379f24247ef00109c141e6d4ce3d 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -23,11 +23,11 @@
 
 extern Context_T CTX;
 
-int GuessFileFormatFromFileName(const char *name)
+int GuessFileFormatFromFileName(std::string fileName)
 {
   int len;
   char ext[256];
-
+  const char *name = fileName.c_str();
   for(len = strlen(name) - 1; len >= 0; len--) {
     if(name[len] == '.') {
       strcpy(ext, &name[len]);
@@ -133,7 +133,7 @@ void CreateOutputFile(const char *filename, int format)
   switch (format) {
 
   case FORMAT_AUTO:
-    CreateOutputFile(name.c_str(), GuessFileFormatFromFileName(name.c_str()));
+    CreateOutputFile(name.c_str(), GuessFileFormatFromFileName(name));
     printEndMessage = false;
     break;
     
diff --git a/Common/CreateFile.h b/Common/CreateFile.h
index 10cf9331f90b6eba922a7cb455528f9cfc3157b6..0c2e8dd354130e4de87b04eb65aaa490c6c8c760 100644
--- a/Common/CreateFile.h
+++ b/Common/CreateFile.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-int GuessFileFormatFromFileName(const char *name);
+int GuessFileFormatFromFileName(std::string fileName);
 std::string GetDefaultFileName(int format);
 void CreateOutputFile(const char *name, int format);
 
diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index 10e021fc08aedb270af64c8aa8e8b7914abaf1db..b5a871779dab33a8510fa8ae59f28174a06605fa 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -76,7 +76,7 @@ void Msg::Init(int argc, char **argv)
 void Msg::Exit(int level)
 {
   // delete the temp file
-  if(!_commRank) UnlinkFile(CTX.tmp_filename_fullpath);
+  if(!_commRank) UnlinkFile((CTX.home_dir + CTX.tmp_filename).c_str());
 
   // exit directly on abnormal program termination (level != 0). We
   // used to call abort() to flush open streams, but on modern OSes
@@ -95,10 +95,12 @@ void Msg::Exit(int level)
   if(GUI::available() && !_commRank) {
     if(CTX.session_save) {
       GUI::instance()->storeCurrentWindowsInfo();
-      Print_Options(0, GMSH_SESSIONRC, 0, 0, CTX.session_filename_fullpath);
+      Print_Options(0, GMSH_SESSIONRC, 0, 0, 
+                    (CTX.home_dir + CTX.session_filename).c_str());
     }
     if(CTX.options_save)
-      Print_Options(0, GMSH_OPTIONSRC, 1, 0, CTX.options_filename_fullpath);
+      Print_Options(0, GMSH_OPTIONSRC, 1, 0, 
+                    (CTX.home_dir + CTX.options_filename).c_str());
   }
 #endif
 
@@ -126,10 +128,10 @@ void Msg::Fatal(const char *fmt, ...)
     std::string tmp = std::string("@C1@.") + "Fatal   : " + str;
     GUI::instance()->messages->add(tmp.c_str());
     GUI::instance()->messages->show();
-    GUI::instance()->messages->save(CTX.error_filename_fullpath);
+    GUI::instance()->messages->save((CTX.home_dir + CTX.error_filename).c_str());
     fl_alert("A fatal error has occurred which will force Gmsh to abort.\n"
              "The error messages have been saved in the following file:\n\n%s",
-             CTX.error_filename_fullpath);
+             (CTX.home_dir + CTX.error_filename).c_str());
   }
 #endif
 
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index a3ee18d173e3c9ff99e31803437f8db62e682374..8cdf17e7cc4ce55e8127a7a7fa3e533c85970a17 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -196,11 +196,11 @@ void ParseString(std::string str)
 {
   if(str.empty()) return;
   FILE *fp;
-  if((fp = fopen(CTX.tmp_filename_fullpath, "w"))) {
+  if((fp = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "w"))) {
     fprintf(fp, str.c_str());
     fprintf(fp, "\n");
     fclose(fp);
-    ParseFile(CTX.tmp_filename_fullpath, 1);
+    ParseFile((CTX.home_dir + CTX.tmp_filename).c_str(), true);
     GModel::current()->importGEOInternals();
   }
 }
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 3903239b256de3651d58092bc3a05a1e95477995..0d34ec2ca098e51fac71b06469161f844fe40f3c 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -452,22 +452,22 @@ void Init_Options(int num)
   // Home directory
   const char *tmp;
   if((tmp = gmsh_getenv("GMSH_HOME")))
-    strcpy(CTX.home_dir, tmp);
+    CTX.home_dir = tmp;
   else if((tmp = gmsh_getenv("HOME")))
-    strcpy(CTX.home_dir, tmp);
+    CTX.home_dir = tmp;
   else if((tmp = gmsh_getenv("TMP")))
-    strcpy(CTX.home_dir, tmp);
+    CTX.home_dir = tmp;
   else if((tmp = gmsh_getenv("TEMP")))
-    strcpy(CTX.home_dir, tmp);
+    CTX.home_dir = tmp;
   else
-    strcpy(CTX.home_dir, "");
+    CTX.home_dir = "";
   
   // By defaults, no stat report
   CTX.create_append_statreport = 0;
 
-  int len = strlen(CTX.home_dir);
-  if(len && CTX.home_dir[len-1] != '/')
-    strcat(CTX.home_dir, "/");
+  int len = CTX.home_dir.size();
+  if(len && CTX.home_dir[len - 1] != '/')
+    CTX.home_dir += "/";
 
   Init_Options_Safe(num);
 
@@ -1010,11 +1010,8 @@ const char *opt_general_filename(OPT_ARGS_STR)
 
 const char *opt_general_default_filename(OPT_ARGS_STR)
 {
-  if(action & GMSH_SET){
+  if(action & GMSH_SET)
     CTX.default_filename = val;
-    strcpy(CTX.default_filename_fullpath, getenv("PWD") ? "" : CTX.home_dir);
-    strcat(CTX.default_filename_fullpath, CTX.default_filename);
-  }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->options->general.input[0]->value(CTX.default_filename);
@@ -1024,41 +1021,29 @@ const char *opt_general_default_filename(OPT_ARGS_STR)
 
 const char *opt_general_tmp_filename(OPT_ARGS_STR)
 {
-  if(action & GMSH_SET){
+  if(action & GMSH_SET)
     CTX.tmp_filename = val;
-    strcpy(CTX.tmp_filename_fullpath, CTX.home_dir);
-    strcat(CTX.tmp_filename_fullpath, CTX.tmp_filename);
-  }
   return CTX.tmp_filename;
 }
 
 const char *opt_general_error_filename(OPT_ARGS_STR)
 {
-  if(action & GMSH_SET){
+  if(action & GMSH_SET)
     CTX.error_filename = val;
-    strcpy(CTX.error_filename_fullpath, CTX.home_dir);
-    strcat(CTX.error_filename_fullpath, CTX.error_filename);
-  }
   return CTX.error_filename;
 }
 
 const char *opt_general_session_filename(OPT_ARGS_STR)
 {
-  if(action & GMSH_SET) {
+  if(action & GMSH_SET)
     CTX.session_filename = val;
-    strcpy(CTX.session_filename_fullpath, CTX.home_dir);
-    strcat(CTX.session_filename_fullpath, CTX.session_filename);
-  }
   return CTX.session_filename;
 }
 
 const char *opt_general_options_filename(OPT_ARGS_STR)
 {
-  if(action & GMSH_SET) {
+  if(action & GMSH_SET)
     CTX.options_filename = val;
-    strcpy(CTX.options_filename_fullpath, CTX.home_dir);
-    strcat(CTX.options_filename_fullpath, CTX.options_filename);
-  }
   return CTX.options_filename;
 }
 
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index 2bfe6b7f1e04348f05238c03d1f2d76dce0d9019..74f649ea7db241300049f20a04bf6d5dd6a0a46a 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
   Msg::Info("Build date     : %s", Get_GmshBuildDate());
   Msg::Info("Build host     : %s", Get_GmshBuildHost());
   Msg::Info("Packager       : %s", Get_GmshPackager());
-  Msg::Info("Home directory : %s", CTX.home_dir);
+  Msg::Info("Home directory : %s", CTX.home_dir.c_str());
   Msg::Info("Launch date    : %s", Msg::GetLaunchDate().c_str());
   Msg::Info("Command line   : %s", Msg::GetCommandLine().c_str());
   Msg::Info("-------------------------------------------------------");
diff --git a/Fltk/Solvers.cpp b/Fltk/Solvers.cpp
index 41fc4db848dbcb61e2288b581b65232a98b07957..ef892f13b82c693846fb506c967cba8283345d5c 100644
--- a/Fltk/Solvers.cpp
+++ b/Fltk/Solvers.cpp
@@ -101,9 +101,9 @@ int Solver(int num, const char *args)
     // Unix socket
     char tmp[1024];
     if(num >= 0)
-      sprintf(tmp, "%s%s-%d", CTX.home_dir, CTX.solver.socket_name, num);
+      sprintf(tmp, "%s%s-%d", CTX.home_dir.c_str(), CTX.solver.socket_name, num);
     else
-      sprintf(tmp, "%s%s", CTX.home_dir, CTX.solver.socket_name);
+      sprintf(tmp, "%s%s", CTX.home_dir.c_str(), CTX.solver.socket_name);
     sockname = FixWindowsPath(tmp);
   }
   else{
diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp
index 556d7a0ae4999eebfa9aae8358c93c875bd72cc7..39192d827d5d43e82213c9c4e5df5b1f1906f30d 100644
--- a/Fltk/fileDialogs.cpp
+++ b/Fltk/fileDialogs.cpp
@@ -77,7 +77,7 @@ int file_chooser(int multi, int create, const char *message,
   Fl_File_Chooser::show_label = "Format:";
   Fl_File_Chooser::all_files_label = "All files (*)";
   if(!fc) {
-    fc = new fileChooser(getenv("PWD") ? "." : CTX.home_dir, thefilter, 
+    fc = new fileChooser(getenv("PWD") ? "." : CTX.home_dir.c_str(), thefilter, 
                          Fl_File_Chooser::SINGLE, message);
     fc->position(CTX.file_chooser_position[0], CTX.file_chooser_position[1]);
   }
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index ed7c59a22800b1a811dce6aa7012f43a557e4c5b..3007fac27d61630b9c2a352c27723fd1cb2a34c8 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -142,16 +142,19 @@ static void options_browser_cb(Fl_Widget *w, void *data)
 
 void options_save_cb(Fl_Widget *w, void *data)
 {
-  Msg::StatusBar(2, true, "Writing '%s'", CTX.options_filename_fullpath);
-  Print_Options(0, GMSH_OPTIONSRC, 1, 1, CTX.options_filename_fullpath);
-  Msg::StatusBar(2, true, "Wrote '%s'", CTX.options_filename_fullpath);
+  Msg::StatusBar(2, true, "Writing '%s'",
+                 (CTX.home_dir + CTX.options_filename).c_str());
+  Print_Options(0, GMSH_OPTIONSRC, 1, 1, 
+                (CTX.home_dir + CTX.options_filename).c_str());
+  Msg::StatusBar(2, true, "Wrote '%s'",
+                 (CTX.home_dir + CTX.options_filename).c_str());
 }
 
 static void options_restore_defaults_cb(Fl_Widget *w, void *data)
 {
   // not sure if we have to remove the file...
-  UnlinkFile(CTX.session_filename_fullpath);
-  UnlinkFile(CTX.options_filename_fullpath);
+  UnlinkFile((CTX.home_dir + CTX.session_filename).c_str());
+  UnlinkFile((CTX.home_dir + CTX.options_filename).c_str());
   ReInit_Options(0);
   Init_Options_GUI(0);
   if(GUI::instance()->menu->module->value() == 3) // hack to refresh the buttons
@@ -247,7 +250,8 @@ static void general_options_ok_cb(Fl_Widget *w, void *data)
   double sessionrc = opt_general_session_save(0, GMSH_GET, 0);
   opt_general_session_save(0, GMSH_SET, o->general.butt[8]->value());
   if(sessionrc && !opt_general_session_save(0, GMSH_GET, 0))
-    Print_Options(0, GMSH_SESSIONRC, 1, 1, CTX.session_filename_fullpath);
+    Print_Options(0, GMSH_SESSIONRC, 1, 1, 
+                  (CTX.home_dir + CTX.session_filename).c_str());
   opt_general_options_save(0, GMSH_SET, o->general.butt[9]->value());
   opt_general_expert_mode(0, GMSH_SET, o->general.butt[10]->value());
   opt_general_tooltips(0, GMSH_SET, o->general.butt[13]->value());
diff --git a/Geo/GModelIO_Geo.cpp b/Geo/GModelIO_Geo.cpp
index 4a93498ec0945a9788b34425c21bb34e713fbd87..43c126bdbe695db3ffd3b950927c662711c789b1 100644
--- a/Geo/GModelIO_Geo.cpp
+++ b/Geo/GModelIO_Geo.cpp
@@ -34,7 +34,7 @@ void GModel::_deleteGEOInternals()
 
 int GModel::readGEO(const std::string &name)
 {
-  ParseFile(name.c_str(), 1);
+  ParseFile(name.c_str(), true);
   return importGEOInternals();
 }
 
diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
index e736d0edd8cdf7f5667072816ee88fd214a8320a..df5238db03ef30b49acc6efafa4e62996b78d1ce 100644
--- a/Geo/GeoStringInterface.cpp
+++ b/Geo/GeoStringInterface.cpp
@@ -27,15 +27,16 @@ double evaluate_scalarfunction(std::string var, double val, std::string funct)
   return 0.;
 #else
   FILE *tempf = gmsh_yyin;
-  if(!(gmsh_yyin = fopen(CTX.tmp_filename_fullpath, "w"))) {
-    Msg::Error("Unable to open temporary file '%s'", CTX.tmp_filename_fullpath);
+  if(!(gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "w"))) {
+    Msg::Error("Unable to open temporary file '%s'", 
+               (CTX.home_dir + CTX.tmp_filename).c_str());
     return 0.;
   }
   // pose "variable = function" and evaluate function
   fprintf(gmsh_yyin, "%s = %.16g ;\n", var.c_str(), val);
   fprintf(gmsh_yyin, "ValeurTemporaire__ = %s ;\n", funct.c_str());
   fclose(gmsh_yyin);
-  gmsh_yyin = fopen(CTX.tmp_filename_fullpath, "r");
+  gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "r");
   while(!feof(gmsh_yyin)) {
     gmsh_yyparse();
   }
@@ -53,15 +54,16 @@ void add_infile(std::string text, std::string filename, bool deleted_something)
 #if defined(HAVE_NO_PARSER)
   Msg::Error("GEO file creation not available without Gmsh parser");
 #else
-  if(!(gmsh_yyin = fopen(CTX.tmp_filename_fullpath, "w"))) {
-    Msg::Error("Unable to open temporary file '%s'", CTX.tmp_filename_fullpath);
+  if(!(gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "w"))) {
+    Msg::Error("Unable to open temporary file '%s'", 
+               (CTX.home_dir + CTX.tmp_filename).c_str());
     return;
   }
 
   fprintf(gmsh_yyin, "%s\n", text.c_str());
   Msg::StatusBar(2, true, "%s", text.c_str());
   fclose(gmsh_yyin);
-  gmsh_yyin = fopen(CTX.tmp_filename_fullpath, "r");
+  gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "r");
   while(!feof(gmsh_yyin)) {
     gmsh_yyparse();
   }
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 9c305ebbc6b69e9d18c92d9a9cef4374d70209c0..c6060c3d0bf8ac0f356c3c71d6f991a14e594c4c 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -5622,7 +5622,7 @@ yyreduce:
 	// to modify FunctionManager to reopen the files instead of
 	// using the FILE pointer, but hey, I'm lazy...
 	Msg::StatusBar(2, true, "Reading '%s'", tmpstring);
-	ParseFile(tmpstring, 0, 1);
+	ParseFile(tmpstring, false, true);
 	SetBoundingBox();
 	Msg::StatusBar(2, true, "Read '%s'", tmpstring);
       }
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 56edaf16afbf9924fef500a68239816580eaba78..51d4ce32ef4f019fabaf74f226b08679dd4c3c0f 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1846,7 +1846,7 @@ Command :
 	// to modify FunctionManager to reopen the files instead of
 	// using the FILE pointer, but hey, I'm lazy...
 	Msg::StatusBar(2, true, "Reading '%s'", tmpstring);
-	ParseFile(tmpstring, 0, 1);
+	ParseFile(tmpstring, false, true);
 	SetBoundingBox();
 	Msg::StatusBar(2, true, "Read '%s'", tmpstring);
       }