diff -r fae782ef63dd src/fileio.c
--- a/src/fileio.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/fileio.c	Fri Oct 01 13:37:31 2010 +0900
@@ -3063,7 +3063,7 @@
 
     buf.actime	= atime;
     buf.modtime	= mtime;
-    (void)utime((char *)fname, &buf);
+    (void)utime((char *)vim2sys(fname), &buf);
 # else
 #  if defined(HAVE_UTIMES)
     struct timeval  tvp[2];
@@ -3073,9 +3073,9 @@
     tvp[1].tv_sec   = mtime;
     tvp[1].tv_usec  = 0;
 #   ifdef NeXT
-    (void)utimes((char *)fname, tvp);
+    (void)utimes((char *)vim2sys(fname), tvp);
 #   else
-    (void)utimes((char *)fname, (const struct timeval *)&tvp);
+    (void)utimes((char *)vim2sys(fname), (const struct timeval *)&tvp);
 #   endif
 #  endif
 # endif
diff -r fae782ef63dd src/globals.h
--- a/src/globals.h	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/globals.h	Fri Oct 01 13:37:31 2010 +0900
@@ -813,6 +813,10 @@
 EXTERN vimconv_T input_conv;			/* type of input conversion */
 EXTERN vimconv_T output_conv;			/* type of output conversion */
 
+/* Variables that tell what conversion is used for read and write file names */
+EXTERN vimconv_T sys2vim_conv;		/* type of input conversion */
+EXTERN vimconv_T vim2sys_conv;		/* type of output conversion */
+
 /*
  * Function pointers, used to quickly get to the right function.  Each has
  * three possible values: latin_ (8-bit), utfc_ or utf_ (utf-8) and dbcs_
diff -r fae782ef63dd src/gui_at_fs.c
--- a/src/gui_at_fs.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/gui_at_fs.c	Fri Oct 01 13:37:31 2010 +0900
@@ -2149,7 +2149,7 @@
 		    (unsigned) (Alloc * sizeof(SFEntry)));
 	}
 	result[i].statDone = 0;
-	str = dp->d_name;
+	str = sys2vim(dp->d_name);
 	len = strlen(str);
 	result[i].real = XtMalloc((unsigned) (len + 2));
 	(void) strcat(strcpy(result[i].real, str), " ");
diff -r fae782ef63dd src/macros.h
--- a/src/macros.h	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/macros.h	Fri Oct 01 13:37:31 2010 +0900
@@ -160,23 +160,26 @@
  */
 #define vim_isbreak(c) (breakat_flags[(char_u)(c)])
 
+# define vim2sys(str)  (char*)string_convert_static(&vim2sys_conv, (str))
+# define sys2vim(str)  (char*)string_convert_static(&sys2vim_conv, (str))
+
 /*
  * On VMS file names are different and require a translation.
  * On the Mac open() has only two arguments.
  */
 #ifdef VMS
-# define mch_access(n, p)	access(vms_fixfilename(n), (p))
+# define mch_access(n, p)	access(vim2sys(vms_fixfilename(n)), (p))
 				/* see mch_open() comment */
-# define mch_fopen(n, p)	fopen(vms_fixfilename(n), (p))
-# define mch_fstat(n, p)	fstat(vms_fixfilename(n), (p))
+# define mch_fopen(n, p)	fopen(vim2sys(vms_fixfilename(n)), (p))
+# define mch_fstat(n, p)	fstat((n), (p))
 	/* VMS does not have lstat() */
-# define mch_stat(n, p)		stat(vms_fixfilename(n), (p))
+# define mch_stat(n, p)		stat(vim2sys(vms_fixfilename(n)), (p))
 #else
 # ifndef WIN32
-#   define mch_access(n, p)	access((n), (p))
+#   define mch_access(n, p)	access(vim2sys((n)), (p))
 # endif
 # if !(defined(FEAT_MBYTE) && defined(WIN3264))
-#  define mch_fopen(n, p)	fopen((n), (p))
+#  define mch_fopen(n, p)	fopen(vim2sys((n)), (p))
 # endif
 # define mch_fstat(n, p)	fstat((n), (p))
 # ifdef MSWIN	/* has it's own mch_stat() function */
@@ -185,22 +188,22 @@
 #  ifdef STAT_IGNORES_SLASH
     /* On Solaris stat() accepts "file/" as if it was "file".  Return -1 if
      * the name ends in "/" and it's not a directory. */
-#   define mch_stat(n, p)	(illegal_slash(n) ? -1 : stat((n), (p)))
+#   define mch_stat(n, p)	(illegal_slash(n) ? -1 : stat(vim2sys((n)), (p)))
 #  else
-#   define mch_stat(n, p)	stat((n), (p))
+#   define mch_stat(n, p)	stat(vim2sys((n)), (p))
 #  endif
 # endif
 #endif
 
 #ifdef HAVE_LSTAT
-# define mch_lstat(n, p)	lstat((n), (p))
+# define mch_lstat(n, p)	lstat(vim2sys((n)), (p))
 #else
 # define mch_lstat(n, p)	mch_stat((n), (p))
 #endif
 
 #ifdef MACOS_CLASSIC
 /* MacOS classic doesn't support perm but MacOS X does. */
-# define mch_open(n, m, p)	open((n), (m))
+# define mch_open(n, m, p)	open(vim2sys((n)), (m))
 #else
 # ifdef VMS
 /*
@@ -208,10 +211,10 @@
  * #  define mch_open(n, m, p) open(vms_fixfilename(n), (m), (p)), "rat=cr", "rfm=stmlf", "mrs=0")
  * but it is not recommended, because it can destroy indexes etc.
  */
-#  define mch_open(n, m, p)	open(vms_fixfilename(n), (m), (p))
+#  define mch_open(n, m, p)	open(vim2sys(vms_fixfilename(n)), (m), (p))
 # else
 #  if !(defined(FEAT_MBYTE) && defined(WIN3264))
-#   define mch_open(n, m, p)	open((n), (m), (p))
+#   define mch_open(n, m, p)	open(vim2sys((n)), (m), (p))
 #  endif
 # endif
 #endif
diff -r fae782ef63dd src/main.c
--- a/src/main.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/main.c	Fri Oct 01 13:37:31 2010 +0900
@@ -577,6 +577,10 @@
     }
 #endif
 
+#ifdef FEAT_MBYTE
+    fix_buflist_by_systemencoding();
+#endif
+
 #ifdef FEAT_DIFF
     /* Decide about window layout for diff mode after reading vimrc. */
     if (params.diff_mode && params.window_layout == 0)
diff -r fae782ef63dd src/mbyte.c
--- a/src/mbyte.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/mbyte.c	Fri Oct 01 13:37:31 2010 +0900
@@ -518,6 +518,8 @@
 	input_conv.vc_type = CONV_NONE;
 	input_conv.vc_factor = 1;
 	output_conv.vc_type = CONV_NONE;
+	sys2vim_conv.vc_type = CONV_NONE;
+	vim2sys_conv.vc_type = CONV_NONE;
 	return NULL;
     }
 
@@ -4207,6 +4209,10 @@
 	convert_setup(&input_conv, NULL, NULL);
     if (output_conv.vc_type == CONV_ICONV)
 	convert_setup(&output_conv, NULL, NULL);
+    if (sys2vim_conv.vc_type == CONV_ICONV)
+	convert_setup(&sys2vim_conv, NULL, NULL);
+    if (vim2sys_conv.vc_type == CONV_ICONV)
+	convert_setup(&vim2sys_conv, NULL, NULL);
 
     if (hIconvDLL != 0)
 	FreeLibrary(hIconvDLL);
@@ -6093,4 +6099,81 @@
 
     return retval;
 }
+
+/*
+ * Convert encoding according to "vcp".
+ * Returns a pointer to converted string on static memory when successful.
+ * When failure, it returns original "instring" pointer.
+ */
+    char_u *
+string_convert_static(vcp, instring)
+    vimconv_T	*vcp;
+    char_u 	*instring;
+{
+    static char		*buf = NULL;
+    static size_t	buflen = 0;
+    char		*fname;
+    size_t		len;
+
+    if (vcp == NULL || vcp->vc_type == CONV_NONE)
+	return instring;
+
+    len = strlen(instring);
+    fname = string_convert(vcp, instring, &len);
+    if (fname == NULL)
+	return instring;
+
+    if (len > buflen)
+    {
+	buflen = len + 128;
+	if (buf)
+	    buf = (char *)vim_realloc(buf, buflen);
+	else
+	    buf = (char *)alloc(buflen * sizeof(char));
+    }
+
+    vim_strncpy(buf, fname, len);
+    vim_free(fname);
+
+    return buf;
+}
+
+
+/*
+ * Convert filenames of all buffer for file from 'systemencoding' to 'encoding'
+ * Returns void
+ */
+    void
+fix_buflist_by_systemencoding()
+{
+    buf_T *buf;
+
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+    {
+	if (buf->b_flags & BF_DUMMY)
+	    continue;
+	
+	if (buf->b_ffname)
+	{
+	    char *tmp = string_convert(&sys2vim_conv, buf->b_ffname, NULL);
+	    if (tmp)
+	    {
+		vim_free(buf->b_ffname);
+		buf->b_ffname = tmp;
+	    }
+	}
+
+	if (buf->b_sfname) 
+	{
+	    char *tmp = string_convert(&sys2vim_conv, buf->b_sfname, NULL);
+	    if (tmp)
+	    {
+		vim_free(buf->b_sfname);
+		buf->b_sfname = tmp;
+		buf->b_fname = buf->b_sfname;
+	    }
+	}
+    }
+}
+
 #endif
diff -r fae782ef63dd src/misc1.c
--- a/src/misc1.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/misc1.c	Fri Oct 01 13:37:31 2010 +0900
@@ -9185,7 +9185,7 @@
 
     /* open the directory for scanning */
     *s = NUL;
-    dirp = opendir(*buf == NUL ? "." : (char *)buf);
+    dirp = opendir(*buf == NUL ? "." : (char *)vim2sys(buf));
 
     /* Find all matching entries */
     if (dirp != NULL)
@@ -9196,9 +9196,9 @@
 	    if (dp == NULL)
 		break;
 	    if ((dp->d_name[0] != '.' || starts_with_dot)
-		    && vim_regexec(&regmatch, (char_u *)dp->d_name, (colnr_T)0))
-	    {
-		STRCPY(s, dp->d_name);
+		    && vim_regexec(&regmatch, (char_u *)sys2vim(dp->d_name), (colnr_T)0))
+	    {
+		STRCPY(s, sys2vim(dp->d_name));
 		len = STRLEN(buf);
 
 		if (starstar && stardepth < 100)
diff -r fae782ef63dd src/misc2.c
--- a/src/misc2.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/misc2.c	Fri Oct 01 13:37:31 2010 +0900
@@ -3128,7 +3128,7 @@
 	tag_freematch();
 
 	if (cmd == NULL || *p_sxq == NUL)
-	    retval = mch_call_shell(cmd, opt);
+	    retval = mch_call_shell(vim2sys(cmd), opt);
 	else
 	{
 	    ncmd = alloc((unsigned)(STRLEN(cmd) + STRLEN(p_sxq) * 2 + 1));
@@ -3137,12 +3137,13 @@
 		STRCPY(ncmd, p_sxq);
 		STRCAT(ncmd, cmd);
 		STRCAT(ncmd, p_sxq);
-		retval = mch_call_shell(ncmd, opt);
+		retval = mch_call_shell(vim2sys(ncmd), opt);
 		vim_free(ncmd);
 	    }
 	    else
 		retval = -1;
 	}
+	vim_free(cmd);
 #ifdef FEAT_GUI
 	--hold_gui_events;
 #endif
diff -r fae782ef63dd src/option.c
--- a/src/option.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/option.c	Fri Oct 01 13:37:31 2010 +0900
@@ -305,6 +305,7 @@
 static int	p_et;
 #ifdef FEAT_MBYTE
 static char_u	*p_fenc;
+static char_u	*p_senc;
 #endif
 static char_u	*p_ff;
 static char_u	*p_fo;
@@ -2466,6 +2467,15 @@
 			    {(char_u *)0L, (char_u *)0L}
 #endif
 			    SCRIPTID_INIT},
+    {"systemencoding","senc", P_STRING|P_VI_DEF,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_senc, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    SCRIPTID_INIT},
     {"tabline",	    "tal",  P_STRING|P_VI_DEF|P_RALL,
 #ifdef FEAT_STL_OPT
 			    (char_u *)&p_tal, PV_NONE,
@@ -5832,7 +5842,7 @@
 
 #ifdef FEAT_MBYTE
     /* 'encoding' and 'fileencoding' */
-    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc)
+    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc || varp == &p_senc)
     {
 	if (gvarp == &p_fenc)
 	{
@@ -5897,6 +5907,14 @@
 		convert_setup(&output_conv, p_enc, p_tenc);
 	    }
 
+	    if (((varp == &p_enc && *p_senc != NUL) || varp == &p_senc))
+	    {
+		convert_setup(&sys2vim_conv, p_senc, p_enc);
+		sys2vim_conv.vc_fail = TRUE; /* for safety */
+		convert_setup(&vim2sys_conv, p_enc, p_senc);
+		vim2sys_conv.vc_fail = TRUE; /* for safety */
+	    }
+
 # if defined(WIN3264) && defined(FEAT_MBYTE)
 	    /* $HOME may have characters in active code page. */
 	    if (varp == &p_enc)
diff -r fae782ef63dd src/os_unix.c
--- a/src/os_unix.c	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/os_unix.c	Fri Oct 01 13:37:31 2010 +0900
@@ -330,9 +330,9 @@
 	verbose_leave();
     }
 # ifdef VMS
-    return chdir(vms_fixfilename(path));
+    return chdir(vim2sys(vms_fixfilename(path)));
 # else
-    return chdir(path);
+    return chdir(vim2sys(path));
 # endif
 }
 
@@ -2554,7 +2554,7 @@
     DIR		*dirp;
     struct dirent *dp;
 
-    if (lstat((char *)name, &st) >= 0)
+    if (mch_lstat((char *)name, &st) >= 0)
     {
 	/* Open the directory where the file is located. */
 	slash = vim_strrchr(name, '/');
@@ -2566,7 +2566,7 @@
 	else
 	{
 	    *slash = NUL;
-	    dirp = opendir((char *)name);
+	    dirp = opendir((char *)vim2sys(name));
 	    *slash = '/';
 	    tail = slash + 1;
 	}
@@ -2577,21 +2577,22 @@
 	    {
 		/* Only accept names that differ in case and are the same byte
 		 * length. TODO: accept different length name. */
-		if (STRICMP(tail, dp->d_name) == 0
-			&& STRLEN(tail) == STRLEN(dp->d_name))
+		char *dname = sys2vim(dp->d_name);
+		if (STRICMP(tail, dname) == 0
+			&& STRLEN(tail) == STRLEN(dname))
 		{
 		    char_u	newname[MAXPATHL + 1];
 		    struct stat st2;
 
 		    /* Verify the inode is equal. */
 		    vim_strncpy(newname, name, MAXPATHL);
-		    vim_strncpy(newname + (tail - name), (char_u *)dp->d_name,
+		    vim_strncpy(newname + (tail - name), (char_u *)dname,
 						    MAXPATHL - (tail - name));
-		    if (lstat((char *)newname, &st2) >= 0
+		    if (lstat((char *)vim2sys(newname), &st2) >= 0
 			    && st.st_ino == st2.st_ino
 			    && st.st_dev == st2.st_dev)
 		    {
-			STRCPY(tail, dp->d_name);
+			STRCPY(tail, sys2vim(dp->d_name));
 			break;
 		    }
 		}
@@ -2614,11 +2615,7 @@
     struct stat statb;
 
     /* Keep the #ifdef outside of stat(), it may be a macro. */
-#ifdef VMS
-    if (stat((char *)vms_fixfilename(name), &statb))
-#else
-    if (stat((char *)name, &statb))
-#endif
+    if (mch_stat((char *)name, &statb))
 	return -1;
 #ifdef __INTERIX
     /* The top bit makes the value negative, which means the file doesn't
@@ -2729,19 +2726,19 @@
 {
     vim_acl_T	ret = NULL;
 #ifdef HAVE_POSIX_ACL
-    ret = (vim_acl_T)acl_get_file((char *)fname, ACL_TYPE_ACCESS);
+    ret = (vim_acl_T)acl_get_file((char *)vim2sys(fname), ACL_TYPE_ACCESS);
 #else
 #ifdef HAVE_SOLARIS_ACL
     vim_acl_solaris_T   *aclent;
 
     aclent = malloc(sizeof(vim_acl_solaris_T));
-    if ((aclent->acl_cnt = acl((char *)fname, GETACLCNT, 0, NULL)) < 0)
+    if ((aclent->acl_cnt = acl((char *)vim2sys(fname), GETACLCNT, 0, NULL)) < 0)
     {
 	free(aclent);
 	return NULL;
     }
     aclent->acl_entry = malloc(aclent->acl_cnt * sizeof(aclent_t));
-    if (acl((char *)fname, GETACL, aclent->acl_cnt, aclent->acl_entry) < 0)
+    if (acl((char *)vim2sys(fname), GETACL, aclent->acl_cnt, aclent->acl_entry) < 0)
     {
 	free(aclent->acl_entry);
 	free(aclent);
@@ -2755,13 +2752,13 @@
 
     aclsize = sizeof(struct acl);
     aclent = malloc(aclsize);
-    if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
+    if (statacl((char *)vim2sys(fname), STX_NORMAL, aclent, aclsize) < 0)
     {
 	if (errno == ENOSPC)
 	{
 	    aclsize = aclent->acl_len;
 	    aclent = realloc(aclent, aclsize);
-	    if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
+	    if (statacl((char *)vim2sys(fname), STX_NORMAL, aclent, aclsize) < 0)
 	    {
 		free(aclent);
 		return NULL;
@@ -2791,14 +2788,14 @@
     if (aclent == NULL)
 	return;
 #ifdef HAVE_POSIX_ACL
-    acl_set_file((char *)fname, ACL_TYPE_ACCESS, (acl_t)aclent);
+    acl_set_file((char *)vim2sys(fname), ACL_TYPE_ACCESS, (acl_t)aclent);
 #else
 #ifdef HAVE_SOLARIS_ACL
-    acl((char *)fname, SETACL, ((vim_acl_solaris_T *)aclent)->acl_cnt,
+    acl((char *)vim2sys(fname), SETACL, ((vim_acl_solaris_T *)aclent)->acl_cnt,
 	    ((vim_acl_solaris_T *)aclent)->acl_entry);
 #else
 #ifdef HAVE_AIX_ACL
-    chacl((char *)fname, aclent, ((struct acl *)aclent)->acl_len);
+    chacl((char *)vim2sys(fname), aclent, ((struct acl *)aclent)->acl_len);
 #endif /* HAVE_AIX_ACL */
 #endif /* HAVE_SOLARIS_ACL */
 #endif /* HAVE_POSIX_ACL */
@@ -2848,7 +2845,7 @@
 
     if (*name == NUL)	    /* Some stat()s don't flag "" as an error. */
 	return FALSE;
-    if (stat((char *)name, &statb))
+    if (mch_stat((char *)name, &statb))
 	return FALSE;
 #ifdef _POSIX_SOURCE
     return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
@@ -2868,7 +2865,7 @@
 {
     struct stat	st;
 
-    if (stat((char *)name, &st))
+    if (mch_stat((char *)name, &st))
 	return 0;
     return S_ISREG(st.st_mode) && mch_access((char *)name, X_OK) == 0;
 }
@@ -2939,7 +2936,7 @@
 {
     struct stat	st;
 
-    if (stat((char *)name, &st))
+    if (mch_stat((char *)name, &st))
 	return NODE_NORMAL;
     if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
 	return NODE_NORMAL;
@@ -5959,7 +5956,6 @@
 }
 #endif	/* ifndef __EMX__ */
 
-#ifndef HAVE_RENAME
 /*
  * Scaled-down version of rename(), which is missing in Xenix.
  * This version can only move regular files and will fail if the
@@ -5969,17 +5965,36 @@
 mch_rename(src, dest)
     const char *src, *dest;
 {
-    struct stat	    st;
-
-    if (stat(dest, &st) >= 0)	    /* fail if destination exists */
-	return -1;
-    if (link(src, dest) != 0)	    /* link file to new name */
-	return -1;
-    if (mch_remove(src) == 0)	    /* delete link to old name */
-	return 0;
-    return -1;
+    char    *src_fname = NULL;
+    char    *dst_fname = NULL;
+    int	    ret = -1;
+#ifndef HAVE_RENAME
+    struct  stat    st;
+#endif /* !HAVE_RENAME */
+
+    src_fname = vim_strsave(vim2sys(src));
+    if (src_fname == NULL)
+	goto err;
+
+    dst_fname = vim_strsave(vim2sys(dest));
+    if (dst_fname == NULL)
+	goto err;
+
+#ifdef HAVE_RENAME
+    ret = rename(src_fname, dst_fname);
+#else /* HAVE_RENAME */
+    if (mch_stat(dest, &st) >= 0)	    /* fail if destination exists */
+	goto err;
+    if (link(src_fname, dst_fname) != 0)    /* link file to new name */
+	goto err;
+    if (mch_remove(src) == 0)		    /* delete link to old name */
+	ret = 0;
+#endif /* HAVE_RENAME */
+err:
+    vim_free(src_fname);
+    vim_free(dst_fname);
+    return ret;
 }
-#endif /* !HAVE_RENAME */
 
 #ifdef FEAT_MOUSE_GPM
 /*
diff -r fae782ef63dd src/os_unix.h
--- a/src/os_unix.h	Thu Sep 30 21:47:56 2010 +0200
+++ b/src/os_unix.h	Fri Oct 01 13:37:31 2010 +0900
@@ -94,16 +94,16 @@
 /* always use unlink() to remove files */
 #ifndef PROTO
 # ifdef VMS
-#  define mch_remove(x) delete((char *)(x))
-#  define vim_mkdir(x, y) mkdir((char *)(x), y)
+#  define mch_remove(x) delete((char *)vim2sys((x)))
+#  define vim_mkdir(x, y) mkdir((char *)vim2sys((x)), y)
 #  ifdef VAX
 #  else
-#   define mch_rmdir(x) rmdir((char *)(x))
+#   define mch_rmdir(x) rmdir((char *)vim2sys((x)))
 #  endif
 # else
-#  define vim_mkdir(x, y) mkdir((char *)(x), y)
-#  define mch_rmdir(x) rmdir((char *)(x))
-#  define mch_remove(x) unlink((char *)(x))
+#  define vim_mkdir(x, y) mkdir((char *)vim2sys((x)), y)
+#  define mch_rmdir(x) rmdir((char *)vim2sys((x)))
+#  define mch_remove(x) unlink((char *)vim2sys((x)))
 # endif
 #endif
 
@@ -477,11 +477,7 @@
 #endif
 
 #ifndef PROTO
-# ifdef HAVE_RENAME
-#  define mch_rename(src, dst) rename(src, dst)
-# else
 int mch_rename __ARGS((const char *src, const char *dest));
-# endif
 # ifndef VMS
 #  ifdef __MVS__
   /* on OS390 Unix getenv() doesn't return a pointer to persistent
