emacs-devel
[Top][All Lists]
Advanced

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

Re: init_buffer PWD fix


From: 宮下 尚:HIMI
Subject: Re: init_buffer PWD fix
Date: Tue, 23 Apr 2002 15:14:31 +0900
User-agent: T-gnus/6.15.4 (based on Oort Gnus v0.04) (revision 11) SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/21.1 (i386-msvc-nt5.1.2600) MULE/5.0 (SAKAKI) Meadow/1.99 Alpha1 (AWOFUCHI)

Primarily, I suggested this change to the ML, but I don't explain
the detail on that to Nagano-san.  Sorry.

Paul Eggert <address@hidden> writes:

>> From: Keiichiro Nagano (=?ISO-2022-JP?B?GyRCMUpMbjc9MGxPOhsoQg==?=) 
>> <address@hidden>
>> Date: Mon, 22 Apr 2002 05:15:17 +0900
>> 
>> init_buffer uses environmental variable PWD to identify current
>> working directory.  I think we should not use it on Windows.  On
>> Windows with Cygwin, PWD is unreliable and confusing
>
> PWD is unreliable on all platforms, but Emacs works around the problem
> with a similar method on all platforms by statting $PWD and ".", and
> using $PWD only if stat results agree.  What is the problem with
> this workaround on Windows?

Yes, the current Emacs implementation compares the result of stat("."), but
stat() of Windows could not strictly emulate the behavior especially on inode.
So if "PWD" environment variable is wrongly set, default_directory would be also
wrongly set.

But, in the first place, is this code necessary on all platform?
Even now, is it really efficient on almost all of the platforms?
I don't think we should stick to such hacked code for the simple
job to get the current directory.

FYI, I've tested the following code on Debian GNU/Linux (sid) to check
the efficiency.

----------------------------------------
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAXPATHLEN 2048

#ifndef DIRECTORY_SEP
#define DIRECTORY_SEP '/'
#endif
#ifndef IS_DIRECTORY_SEP
#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
#endif
#ifndef IS_DEVICE_SEP
#ifndef DEVICE_SEP
#define IS_DEVICE_SEP(_c_) 0
#else
#define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP)
#endif
#endif

char* getcwd_stat(char *buf)
{
  char *pwd;
  struct stat pwdstat, dotstat;

  if ((pwd = getenv ("PWD")) != 0
      && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
      && stat (pwd, &pwdstat) == 0
      && stat (".", &dotstat) == 0
      && dotstat.st_ino == pwdstat.st_ino
      && dotstat.st_dev == pwdstat.st_dev
      && strlen (pwd) < MAXPATHLEN)
    strcpy (buf, pwd);
  else
    return NULL;
  return buf;
}

char * getcwd_normal(char *buf)
{
  return getcwd (buf, MAXPATHLEN + 1);
}

int main(int argc, char **argv)
{
  char buf[MAXPATHLEN + 1];
  char *pwd;
  int i;

  if (argv[1][0] == 's')
    {
      for (i = 0;i < 1000000;i++)
        getcwd_stat(buf);
    }
  else
    {
      for (i = 0;i < 1000000;i++)
        getcwd_normal(buf);
    }

  return 1;
}

----------------------------------------
The result are 
[~:] time ./a.out s
./a.out s  1.22s user 2.68s system 100% cpu 3.883 total
[~:] time ./a.out n
./a.out n  0.29s user 0.92s system 100% cpu 1.200 total
----------------------------------------

Of course, this check only covers narrow situation.  It may depends on
the file system the current directly locates.  But at least, I could state
there exist situations that the hacked code is much slower than simple getcwd()
calling.

Therefore, I'd like to propose to remove this hacked optimization from 
init_buffer().

Do you have any comments?

  With regards,

from himi



reply via email to

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