Mercurial > hg > xemacs-beta
diff src/fileio.c @ 276:6330739388db r21-0b36
Import from CVS: tag r21-0b36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:30:37 +0200 |
parents | ca9a9ec9c1c1 |
children | 90d73dddcdc4 |
line wrap: on
line diff
--- a/src/fileio.c Mon Aug 13 10:29:43 2007 +0200 +++ b/src/fileio.c Mon Aug 13 10:30:37 2007 +0200 @@ -111,15 +111,6 @@ Lisp_Object Qfile_name_handler_alist; -/* Syncing with FSF 19.34.6 note: although labelled as NT-specific, these - two lisp variables are compiled in even when not defined(DOS_NT). - Need to check if we should bracket them between #ifdef's. - --marcpa */ -/* On NT, specifies the directory separator character, used (eg.) when - expanding file names. This can be bound to / or \. - - This needs to be initialized statically, because file name functions - are called during initialization. */ Lisp_Object Vdirectory_sep_char; /* These variables describe handlers that have "already" had a chance @@ -533,15 +524,23 @@ static char * file_name_as_directory (char *out, char *in) { - int size = strlen (in) - 1; - - strcpy (out, in); - - /* For Unix syntax, Append a slash if necessary */ - if (!IS_ANY_SEP (out[size])) + int size = strlen (in); + + if (size == 0) { - out[size + 1] = DIRECTORY_SEP; - out[size + 2] = '\0'; + out[0] = '.'; + out[1] = DIRECTORY_SEP; + out[2] = '\0'; + } + else + { + strcpy (out, in); + /* Append a slash if necessary */ + if (!IS_ANY_SEP (out[size-1])) + { + out[size] = DIRECTORY_SEP; + out[size + 1] = '\0'; + } } #ifdef WINDOWSNT CORRECT_DIR_SEPS (out); @@ -555,7 +554,8 @@ a directory is different from its name as a file. The result can be used as the value of `default-directory' or passed as second argument to `expand-file-name'. -For a Unix-syntax file name, just appends a slash. +For a Unix-syntax file name, just appends a slash, +except for (file-name-as-directory \"\") => \"./\". */ (file)) { @@ -644,18 +644,11 @@ /* Fmake_temp_name used to be a simple wrapper around mktemp(), but it proved too broken for our purposes (it supported only 26 or 62 - unique names under some implementations). For instance, the stupid - limit broke Gnus Incoming* files generation. - - NB, this implementation is better than what one usually finds in - libc. --hniksic */ - -#define MTN_RANDOM(x) ((int) (random () % x)) -#define MTN_INC(var, limit) (var = ((var == (limit) - 1) ? 0 : (var + 1))) -#define MTN_LOOP(var, limit, keep) \ -for (keep = var = MTN_RANDOM (limit), MTN_INC (var, limit); \ - var != keep; \ - MTN_INC (var, limit)) + unique names under some implementations). For example, this + arbitrary limit broke generation of Gnus Incoming* files. + + This implementation is better than what one usually finds in libc. + --hniksic */ DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* Generate temporary file name starting with PREFIX. @@ -677,13 +670,13 @@ 'g','h','i','j','k','l','m','n', 'o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3', - '4','5','6','7','8','9','-','_' - }; + '4','5','6','7','8','9','-','_' }; + static unsigned count, count_initialized_p; + Lisp_Object val; Bytecount len; - int pid; - int i, j, k, keep1, keep2, keep3; Bufbyte *p, *data; + unsigned pid; CHECK_STRING (prefix); @@ -698,8 +691,8 @@ the code that uses (make-temp-name "") instead of (make-temp-name "./"). - 3) It might yield unexpected results in the presence of EFS and - file name handlers. */ + 3) It might yield unexpected (to stat(2)) results in the presence + of EFS and file name handlers. */ len = XSTRING_LENGTH (prefix); val = make_uninit_string (len + 6); @@ -712,51 +705,46 @@ three are incremented if the file already exists. This ensures 262144 unique file names per PID per PREFIX. */ - pid = (int)getpid (); + pid = (unsigned)getpid (); *p++ = tbl[pid & 63], pid >>= 6; *p++ = tbl[pid & 63], pid >>= 6; *p++ = tbl[pid & 63], pid >>= 6; - /* Here we employ some trickery to minimize useless stat'ing when - this function is invoked many times successively with the same - PREFIX. Instead of looping from 0 to 63, each of the variables - is assigned a random number less than 64, and is incremented up - to 63 and back to zero, until the initial value is reached again. - - In other words, MTN_LOOP (i, 64, keep1) is equivalent to - for (i = 0; i < 64; i++) with the difference that the beginning - value needn't be 0 -- all that matters is that i is guaranteed to - loop through all the values in the [0, 64) range. */ - MTN_LOOP (i, 64, keep1) + /* Here we try to minimize useless stat'ing when this function is + invoked many times successively with the same PREFIX. We achieve + this by initializing count to a random value, and incrementing it + afterwards. */ + if (!count_initialized_p) { - p[0] = tbl[i]; - MTN_LOOP (j, 64, keep2) + count = (unsigned)time (NULL); + count_initialized_p = 1; + } + + while (1) + { + struct stat ignored; + unsigned num = count++; + + p[0] = tbl[num & 63], num >>= 6; + p[1] = tbl[num & 63], num >>= 6; + p[2] = tbl[num & 63], num >>= 6; + + if (stat ((const char *) data, &ignored) < 0) { - p[1] = tbl[j]; - MTN_LOOP (k, 64, keep3) - { - struct stat ignored; - p[2] = tbl[k]; - if (stat (data, &ignored) < 0) - { - /* We want to return only if errno is ENOENT. */ - if (errno == ENOENT) - return val; - else - /* The error here is dubious, but there is little - else we can do. The alternatives are to return - nil, which is as bad as (and in many cases - worse than) throwing the error, or to ignore - the error, which will likely result in looping - through 262144 stat's, which is not only SLOW, - but also useless since it will fallback to the - errow below, anyway. */ - report_file_error - ("Cannot create temporary name for prefix", - list1 (prefix)); - /* not reached */ - } - } + /* We want to return only if errno is ENOENT. */ + if (errno == ENOENT) + return val; + else + /* The error here is dubious, but there is little else we + can do. The alternatives are to return nil, which is + as bad as (and in many cases worse than) throwing the + error, or to ignore the error, which will likely result + in looping through 262144 stat's, which is not only + dog-slow, but also useless since it will fallback to + the errow below, anyway. */ + report_file_error ("Cannot create temporary name for prefix", + list1 (prefix)); + /* not reached */ } } signal_simple_error ("Cannot create temporary name for prefix", prefix); @@ -1149,7 +1137,7 @@ /* Get rid of any slash at the end of newdir, unless newdir is just // (an incomplete UNC name). */ length = strlen ((char *) newdir); - if (length > 0 && IS_DIRECTORY_SEP (newdir[length - 1]) + if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) #ifdef WINDOWSNT && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) #endif @@ -3333,7 +3321,7 @@ but who knows about all the other machines with NFS?) */ /* On VMS and APOLLO, must do the stat after the close since closing changes the modtime. */ -#if 0 /* !defined (VMS) && !defined (APOLLO) */ +#if 1 /* !defined (VMS) && !defined (APOLLO) */ fstat (desc, &st); #endif @@ -3352,7 +3340,7 @@ } -#if 1 /* defined (VMS) || defined (APOLLO) */ +#if 0 /* defined (VMS) || defined (APOLLO) */ stat ((char *) XSTRING_DATA (fn), &st); #endif @@ -4313,5 +4301,5 @@ on other platforms, it is initialized so that Lisp code can find out what the normal separator is. */ ); - Vdirectory_sep_char = make_char('/'); + Vdirectory_sep_char = make_char(DIRECTORY_SEP); }