[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


From: Eli Zaretskii
Subject: Re: $USERPROFILE for $HOME on W32
Date: Sat, 27 Nov 2004 13:36:20 +0200

> Cc: address@hidden
> From: Stefan Monnier <address@hidden>
> Date: Fri, 26 Nov 2004 17:03:51 -0500
> > On the same system as the one where it was dumped and when invoked by
> > the same user, it will stay /u/monnier/.
> Not necessarily.  My HOME dir might get moved at some point.

Yes, but that's hardly a common situation, let alone something you
expect to be done behind your back.

> No: *you* lost me here.  Of course HOME typically never changes during
> a session.  But you were talking about "before dumping" and "after dumping",
> which is a whole other kettle of fish.

I was thinking about an Emacs developer who debugs temacs and/or
dumped emacs on the same machine and under the same user name.  Having
HOME with different values in each case is an unexpected subtlety in
such a situation.

> > i.e. some of the init_* functions.  In the case in point, we need to
> > set HOME very early, because the C part of the session initialization
> > needs to see the same value of HOME as the Lisp code and all the rest
> > of the session will.
> Why would it matter?

It _could_ matter; I didn't check that the current sources actually
reference $HOME in the initialization code.  But they most certainly
could, and I think we need to come up with a method of setting $HOME
that has the least probability of introducing a bug if the
initialization code ever references the value of HOME.  Setting its
value as close as possible to the first line of `main' comes closer to
achieving this goal than doing it as part of top-level.

> Anyway, feel free to provide an alternative patch.

Below.  It's also untested (I don't have a working Windows development
environment to try it), so caveat emptor.

If the patch is accepted, there are a few issues with this patch that
I think need to be discussed:

 . Use of R_OK to probe .emacs usability.  The code as written does
   what Stefan's Lisp implementation did, but I'm not sure it is
   correct to settle for .emacs being readable.  Shouldn't we check if
   it is writable?  Suppose that C:/.emacs exists, but is from another
   user of the same system, for example.

 . Use of W_OK to probe whether a directory is usable.  On Windows,
   the read-only bit of a directory does not prevent a user from
   creating files in that directory.  So it might be enough to check
   for D_OK alone.

 . The exact environment variables to check.  I think I saw HOMEDRIVE
   and HOMEPATH spelled on Windows XP as HomeDrive and HomePath.  If
   the Windows' version of `getenv' is case-sensitive, the code below
   should try both spellings.

--- emacs/src/w32.c~    2004-10-23 23:04:50.000000000 +0200
+++ emacs/src/w32.c     2004-11-27 13:35:14.000000000 +0200
@@ -371,8 +371,8 @@ getloadavg (double loadavg[], int nelem)
 static char the_passwd_name[PASSWD_FIELD_SIZE];
 static char the_passwd_passwd[PASSWD_FIELD_SIZE];
 static char the_passwd_gecos[PASSWD_FIELD_SIZE];
-static char the_passwd_dir[PASSWD_FIELD_SIZE];
-static char the_passwd_shell[PASSWD_FIELD_SIZE];
+static char the_passwd_dir[MAX_PATH];
+static char the_passwd_shell[MAX_PATH];
 static struct passwd the_passwd =
@@ -896,6 +896,7 @@ w32_get_resource (key, lpdwtype)
 char *get_emacs_configuration (void);
 extern Lisp_Object Vsystem_configuration;
+int sys_access (const char *, int);
 init_environment (char ** argv)
@@ -1033,6 +1034,39 @@ init_environment (char ** argv)
+    /* Compute the default value for HOME.  Maintain compatibility
+       with previous setup of defaulting to C:/ if there's already a
+       usable .emacs in there.  */
+    if (sys_access ("C:/.emacs", R_OK) != 0
+       && sys_access ("C:/_emacs", R_OK) != 0)
+      {
+       char *userprofile = getenv ("USERPROFILE");
+       char *homepath = getenv ("HOMEPATH");
+       char *homedrive = getenv ("HOMEDRIVE");
+       for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
+         {
+           if (strcmp (env_vars[i].name, "HOME") == 0)
+             break;
+         }
+       /* Default to %USERPROFILE% if set and accessible, otherwise
+          to %HOMEDRIVE%/%HOMEPATH%.  The former is set on W2K, XP,
+          and later systems, the latter on Windows NT; Windows 9X
+          doesn't set either.  */
+       if (userprofile && sys_access (userprofile, D_OK | W_OK) == 0)
+         env_vars[i].def_value = strdup (userprofile);
+       else if (homedrive && homepath)
+         {
+           char homedir[MAX_PATH];
+           strcat (strcpy (homedir, homedrive), homepath);
+           if (sys_access (homedir, D_OK | W_OK) == 0)
+             env_vars[i].def_value = strdup (homedir);
+         }
+      }
+    /* Now handle the entire list of env_vars[].  */
     for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
        if (!getenv (env_vars[i].name))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]