Mercurial > hg > xemacs-beta
comparison 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 |
comparison
equal
deleted
inserted
replaced
275:a68ae4439f57 | 276:6330739388db |
---|---|
109 | 109 |
110 int disable_auto_save_when_buffer_shrinks; | 110 int disable_auto_save_when_buffer_shrinks; |
111 | 111 |
112 Lisp_Object Qfile_name_handler_alist; | 112 Lisp_Object Qfile_name_handler_alist; |
113 | 113 |
114 /* Syncing with FSF 19.34.6 note: although labelled as NT-specific, these | |
115 two lisp variables are compiled in even when not defined(DOS_NT). | |
116 Need to check if we should bracket them between #ifdef's. | |
117 --marcpa */ | |
118 /* On NT, specifies the directory separator character, used (eg.) when | |
119 expanding file names. This can be bound to / or \. | |
120 | |
121 This needs to be initialized statically, because file name functions | |
122 are called during initialization. */ | |
123 Lisp_Object Vdirectory_sep_char; | 114 Lisp_Object Vdirectory_sep_char; |
124 | 115 |
125 /* These variables describe handlers that have "already" had a chance | 116 /* These variables describe handlers that have "already" had a chance |
126 to handle the current operation. | 117 to handle the current operation. |
127 | 118 |
531 | 522 |
532 | 523 |
533 static char * | 524 static char * |
534 file_name_as_directory (char *out, char *in) | 525 file_name_as_directory (char *out, char *in) |
535 { | 526 { |
536 int size = strlen (in) - 1; | 527 int size = strlen (in); |
537 | 528 |
538 strcpy (out, in); | 529 if (size == 0) |
539 | 530 { |
540 /* For Unix syntax, Append a slash if necessary */ | 531 out[0] = '.'; |
541 if (!IS_ANY_SEP (out[size])) | 532 out[1] = DIRECTORY_SEP; |
542 { | 533 out[2] = '\0'; |
543 out[size + 1] = DIRECTORY_SEP; | 534 } |
544 out[size + 2] = '\0'; | 535 else |
536 { | |
537 strcpy (out, in); | |
538 /* Append a slash if necessary */ | |
539 if (!IS_ANY_SEP (out[size-1])) | |
540 { | |
541 out[size] = DIRECTORY_SEP; | |
542 out[size + 1] = '\0'; | |
543 } | |
545 } | 544 } |
546 #ifdef WINDOWSNT | 545 #ifdef WINDOWSNT |
547 CORRECT_DIR_SEPS (out); | 546 CORRECT_DIR_SEPS (out); |
548 #endif | 547 #endif |
549 return out; | 548 return out; |
553 Return a string representing file FILENAME interpreted as a directory. | 552 Return a string representing file FILENAME interpreted as a directory. |
554 This operation exists because a directory is also a file, but its name as | 553 This operation exists because a directory is also a file, but its name as |
555 a directory is different from its name as a file. | 554 a directory is different from its name as a file. |
556 The result can be used as the value of `default-directory' | 555 The result can be used as the value of `default-directory' |
557 or passed as second argument to `expand-file-name'. | 556 or passed as second argument to `expand-file-name'. |
558 For a Unix-syntax file name, just appends a slash. | 557 For a Unix-syntax file name, just appends a slash, |
558 except for (file-name-as-directory \"\") => \"./\". | |
559 */ | 559 */ |
560 (file)) | 560 (file)) |
561 { | 561 { |
562 /* This function can GC. GC checked 1997.04.06. */ | 562 /* This function can GC. GC checked 1997.04.06. */ |
563 char *buf; | 563 char *buf; |
642 return build_string (buf); | 642 return build_string (buf); |
643 } | 643 } |
644 | 644 |
645 /* Fmake_temp_name used to be a simple wrapper around mktemp(), but it | 645 /* Fmake_temp_name used to be a simple wrapper around mktemp(), but it |
646 proved too broken for our purposes (it supported only 26 or 62 | 646 proved too broken for our purposes (it supported only 26 or 62 |
647 unique names under some implementations). For instance, the stupid | 647 unique names under some implementations). For example, this |
648 limit broke Gnus Incoming* files generation. | 648 arbitrary limit broke generation of Gnus Incoming* files. |
649 | 649 |
650 NB, this implementation is better than what one usually finds in | 650 This implementation is better than what one usually finds in libc. |
651 libc. --hniksic */ | 651 --hniksic */ |
652 | |
653 #define MTN_RANDOM(x) ((int) (random () % x)) | |
654 #define MTN_INC(var, limit) (var = ((var == (limit) - 1) ? 0 : (var + 1))) | |
655 #define MTN_LOOP(var, limit, keep) \ | |
656 for (keep = var = MTN_RANDOM (limit), MTN_INC (var, limit); \ | |
657 var != keep; \ | |
658 MTN_INC (var, limit)) | |
659 | 652 |
660 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* | 653 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* |
661 Generate temporary file name starting with PREFIX. | 654 Generate temporary file name starting with PREFIX. |
662 The Emacs process number forms part of the result, so there is no | 655 The Emacs process number forms part of the result, so there is no |
663 danger of generating a name being used by another process. | 656 danger of generating a name being used by another process. |
675 'Q','R','S','T','U','V','W','X', | 668 'Q','R','S','T','U','V','W','X', |
676 'Y','Z','a','b','c','d','e','f', | 669 'Y','Z','a','b','c','d','e','f', |
677 'g','h','i','j','k','l','m','n', | 670 'g','h','i','j','k','l','m','n', |
678 'o','p','q','r','s','t','u','v', | 671 'o','p','q','r','s','t','u','v', |
679 'w','x','y','z','0','1','2','3', | 672 'w','x','y','z','0','1','2','3', |
680 '4','5','6','7','8','9','-','_' | 673 '4','5','6','7','8','9','-','_' }; |
681 }; | 674 static unsigned count, count_initialized_p; |
675 | |
682 Lisp_Object val; | 676 Lisp_Object val; |
683 Bytecount len; | 677 Bytecount len; |
684 int pid; | |
685 int i, j, k, keep1, keep2, keep3; | |
686 Bufbyte *p, *data; | 678 Bufbyte *p, *data; |
679 unsigned pid; | |
687 | 680 |
688 CHECK_STRING (prefix); | 681 CHECK_STRING (prefix); |
689 | 682 |
690 /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's | 683 /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's |
691 a bad idea because: | 684 a bad idea because: |
696 | 689 |
697 2) It breaks under many unforeseeable circumstances, such as with | 690 2) It breaks under many unforeseeable circumstances, such as with |
698 the code that uses (make-temp-name "") instead of | 691 the code that uses (make-temp-name "") instead of |
699 (make-temp-name "./"). | 692 (make-temp-name "./"). |
700 | 693 |
701 3) It might yield unexpected results in the presence of EFS and | 694 3) It might yield unexpected (to stat(2)) results in the presence |
702 file name handlers. */ | 695 of EFS and file name handlers. */ |
703 | 696 |
704 len = XSTRING_LENGTH (prefix); | 697 len = XSTRING_LENGTH (prefix); |
705 val = make_uninit_string (len + 6); | 698 val = make_uninit_string (len + 6); |
706 data = XSTRING_DATA (val); | 699 data = XSTRING_DATA (val); |
707 memcpy (data, XSTRING_DATA (prefix), len); | 700 memcpy (data, XSTRING_DATA (prefix), len); |
710 /* `val' is created by adding 6 characters to PREFIX. The first | 703 /* `val' is created by adding 6 characters to PREFIX. The first |
711 three are the PID of this process, in base 64, and the second | 704 three are the PID of this process, in base 64, and the second |
712 three are incremented if the file already exists. This ensures | 705 three are incremented if the file already exists. This ensures |
713 262144 unique file names per PID per PREFIX. */ | 706 262144 unique file names per PID per PREFIX. */ |
714 | 707 |
715 pid = (int)getpid (); | 708 pid = (unsigned)getpid (); |
716 *p++ = tbl[pid & 63], pid >>= 6; | 709 *p++ = tbl[pid & 63], pid >>= 6; |
717 *p++ = tbl[pid & 63], pid >>= 6; | 710 *p++ = tbl[pid & 63], pid >>= 6; |
718 *p++ = tbl[pid & 63], pid >>= 6; | 711 *p++ = tbl[pid & 63], pid >>= 6; |
719 | 712 |
720 /* Here we employ some trickery to minimize useless stat'ing when | 713 /* Here we try to minimize useless stat'ing when this function is |
721 this function is invoked many times successively with the same | 714 invoked many times successively with the same PREFIX. We achieve |
722 PREFIX. Instead of looping from 0 to 63, each of the variables | 715 this by initializing count to a random value, and incrementing it |
723 is assigned a random number less than 64, and is incremented up | 716 afterwards. */ |
724 to 63 and back to zero, until the initial value is reached again. | 717 if (!count_initialized_p) |
725 | 718 { |
726 In other words, MTN_LOOP (i, 64, keep1) is equivalent to | 719 count = (unsigned)time (NULL); |
727 for (i = 0; i < 64; i++) with the difference that the beginning | 720 count_initialized_p = 1; |
728 value needn't be 0 -- all that matters is that i is guaranteed to | 721 } |
729 loop through all the values in the [0, 64) range. */ | 722 |
730 MTN_LOOP (i, 64, keep1) | 723 while (1) |
731 { | 724 { |
732 p[0] = tbl[i]; | 725 struct stat ignored; |
733 MTN_LOOP (j, 64, keep2) | 726 unsigned num = count++; |
727 | |
728 p[0] = tbl[num & 63], num >>= 6; | |
729 p[1] = tbl[num & 63], num >>= 6; | |
730 p[2] = tbl[num & 63], num >>= 6; | |
731 | |
732 if (stat ((const char *) data, &ignored) < 0) | |
734 { | 733 { |
735 p[1] = tbl[j]; | 734 /* We want to return only if errno is ENOENT. */ |
736 MTN_LOOP (k, 64, keep3) | 735 if (errno == ENOENT) |
737 { | 736 return val; |
738 struct stat ignored; | 737 else |
739 p[2] = tbl[k]; | 738 /* The error here is dubious, but there is little else we |
740 if (stat (data, &ignored) < 0) | 739 can do. The alternatives are to return nil, which is |
741 { | 740 as bad as (and in many cases worse than) throwing the |
742 /* We want to return only if errno is ENOENT. */ | 741 error, or to ignore the error, which will likely result |
743 if (errno == ENOENT) | 742 in looping through 262144 stat's, which is not only |
744 return val; | 743 dog-slow, but also useless since it will fallback to |
745 else | 744 the errow below, anyway. */ |
746 /* The error here is dubious, but there is little | 745 report_file_error ("Cannot create temporary name for prefix", |
747 else we can do. The alternatives are to return | 746 list1 (prefix)); |
748 nil, which is as bad as (and in many cases | 747 /* not reached */ |
749 worse than) throwing the error, or to ignore | |
750 the error, which will likely result in looping | |
751 through 262144 stat's, which is not only SLOW, | |
752 but also useless since it will fallback to the | |
753 errow below, anyway. */ | |
754 report_file_error | |
755 ("Cannot create temporary name for prefix", | |
756 list1 (prefix)); | |
757 /* not reached */ | |
758 } | |
759 } | |
760 } | 748 } |
761 } | 749 } |
762 signal_simple_error ("Cannot create temporary name for prefix", prefix); | 750 signal_simple_error ("Cannot create temporary name for prefix", prefix); |
763 RETURN_NOT_REACHED (Qnil); | 751 RETURN_NOT_REACHED (Qnil); |
764 } | 752 } |
1147 if (newdir) | 1135 if (newdir) |
1148 { | 1136 { |
1149 /* Get rid of any slash at the end of newdir, unless newdir is | 1137 /* Get rid of any slash at the end of newdir, unless newdir is |
1150 just // (an incomplete UNC name). */ | 1138 just // (an incomplete UNC name). */ |
1151 length = strlen ((char *) newdir); | 1139 length = strlen ((char *) newdir); |
1152 if (length > 0 && IS_DIRECTORY_SEP (newdir[length - 1]) | 1140 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) |
1153 #ifdef WINDOWSNT | 1141 #ifdef WINDOWSNT |
1154 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) | 1142 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) |
1155 #endif | 1143 #endif |
1156 ) | 1144 ) |
1157 { | 1145 { |
3331 | 3319 |
3332 (This has supposedly been fixed in Sunos 4, | 3320 (This has supposedly been fixed in Sunos 4, |
3333 but who knows about all the other machines with NFS?) */ | 3321 but who knows about all the other machines with NFS?) */ |
3334 /* On VMS and APOLLO, must do the stat after the close | 3322 /* On VMS and APOLLO, must do the stat after the close |
3335 since closing changes the modtime. */ | 3323 since closing changes the modtime. */ |
3336 #if 0 /* !defined (VMS) && !defined (APOLLO) */ | 3324 #if 1 /* !defined (VMS) && !defined (APOLLO) */ |
3337 fstat (desc, &st); | 3325 fstat (desc, &st); |
3338 #endif | 3326 #endif |
3339 | 3327 |
3340 /* NFS can report a write failure now. */ | 3328 /* NFS can report a write failure now. */ |
3341 if (close (desc) < 0) | 3329 if (close (desc) < 0) |
3350 XCAR (desc_locative) = Qnil; | 3338 XCAR (desc_locative) = Qnil; |
3351 unbind_to (speccount, Qnil); | 3339 unbind_to (speccount, Qnil); |
3352 } | 3340 } |
3353 | 3341 |
3354 | 3342 |
3355 #if 1 /* defined (VMS) || defined (APOLLO) */ | 3343 #if 0 /* defined (VMS) || defined (APOLLO) */ |
3356 stat ((char *) XSTRING_DATA (fn), &st); | 3344 stat ((char *) XSTRING_DATA (fn), &st); |
3357 #endif | 3345 #endif |
3358 | 3346 |
3359 #ifdef CLASH_DETECTION | 3347 #ifdef CLASH_DETECTION |
3360 if (!auto_saving) | 3348 if (!auto_saving) |
4311 The value should be either ?/ or ?\\ (any other value is treated as ?\\). | 4299 The value should be either ?/ or ?\\ (any other value is treated as ?\\). |
4312 This variable affects the built-in functions only on Windows, | 4300 This variable affects the built-in functions only on Windows, |
4313 on other platforms, it is initialized so that Lisp code can find out | 4301 on other platforms, it is initialized so that Lisp code can find out |
4314 what the normal separator is. | 4302 what the normal separator is. |
4315 */ ); | 4303 */ ); |
4316 Vdirectory_sep_char = make_char('/'); | 4304 Vdirectory_sep_char = make_char(DIRECTORY_SEP); |
4317 } | 4305 } |