Mercurial > hg > xemacs-beta
comparison src/fileio.c @ 404:2f8bb876ab1d r21-2-32
Import from CVS: tag r21-2-32
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:16:07 +0200 |
parents | a86b2b5e0111 |
children | de805c49cfc1 |
comparison
equal
deleted
inserted
replaced
403:9f011ab08d48 | 404:2f8bb876ab1d |
---|---|
633 arbitrary limit broke generation of Gnus Incoming* files. | 633 arbitrary limit broke generation of Gnus Incoming* files. |
634 | 634 |
635 This implementation is better than what one usually finds in libc. | 635 This implementation is better than what one usually finds in libc. |
636 --hniksic */ | 636 --hniksic */ |
637 | 637 |
638 static unsigned int temp_name_rand; | |
639 | |
638 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* | 640 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* |
639 Generate temporary file name starting with PREFIX. | 641 Generate a temporary file name starting with PREFIX. |
640 The Emacs process number forms part of the result, so there is no | 642 The Emacs process number forms part of the result, so there is no |
641 danger of generating a name being used by another process. | 643 danger of generating a name being used by another process. |
642 | 644 |
643 In addition, this function makes an attempt to choose a name that | 645 In addition, this function makes an attempt to choose a name that |
644 does not specify an existing file. To make this work, PREFIX should | 646 does not specify an existing file. To make this work, PREFIX should |
645 be an absolute file name. | 647 be an absolute file name. |
646 */ | 648 */ |
647 (prefix)) | 649 (prefix)) |
648 { | 650 { |
649 static char tbl[64] = { | 651 static const char tbl[64] = |
652 { | |
650 'A','B','C','D','E','F','G','H', | 653 'A','B','C','D','E','F','G','H', |
651 'I','J','K','L','M','N','O','P', | 654 'I','J','K','L','M','N','O','P', |
652 'Q','R','S','T','U','V','W','X', | 655 'Q','R','S','T','U','V','W','X', |
653 'Y','Z','a','b','c','d','e','f', | 656 'Y','Z','a','b','c','d','e','f', |
654 'g','h','i','j','k','l','m','n', | 657 'g','h','i','j','k','l','m','n', |
655 'o','p','q','r','s','t','u','v', | 658 'o','p','q','r','s','t','u','v', |
656 'w','x','y','z','0','1','2','3', | 659 'w','x','y','z','0','1','2','3', |
657 '4','5','6','7','8','9','-','_' }; | 660 '4','5','6','7','8','9','-','_' |
658 static unsigned count, count_initialized_p; | 661 }; |
659 | 662 |
660 Lisp_Object val; | 663 Lisp_Object val; |
661 Bytecount len; | 664 Bytecount len; |
662 Bufbyte *p, *data; | 665 Bufbyte *p, *data; |
663 unsigned pid; | |
664 | 666 |
665 CHECK_STRING (prefix); | 667 CHECK_STRING (prefix); |
666 | 668 |
667 /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's | 669 /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's |
668 a bad idea because: | 670 a bad idea because: |
684 memcpy (data, XSTRING_DATA (prefix), len); | 686 memcpy (data, XSTRING_DATA (prefix), len); |
685 p = data + len; | 687 p = data + len; |
686 | 688 |
687 /* VAL is created by adding 6 characters to PREFIX. The first three | 689 /* VAL is created by adding 6 characters to PREFIX. The first three |
688 are the PID of this process, in base 64, and the second three are | 690 are the PID of this process, in base 64, and the second three are |
689 incremented if the file already exists. This ensures 262144 | 691 a pseudo-random number seeded from process startup time. This |
690 unique file names per PID per PREFIX. */ | 692 ensures 262144 unique file names per PID per PREFIX per machine. */ |
691 | 693 |
692 pid = (unsigned)getpid (); | 694 { |
693 *p++ = tbl[pid & 63], pid >>= 6; | 695 unsigned int pid = (unsigned int) getpid (); |
694 *p++ = tbl[pid & 63], pid >>= 6; | 696 *p++ = tbl[(pid >> 0) & 63]; |
695 *p++ = tbl[pid & 63], pid >>= 6; | 697 *p++ = tbl[(pid >> 6) & 63]; |
698 *p++ = tbl[(pid >> 12) & 63]; | |
699 } | |
696 | 700 |
697 /* Here we try to minimize useless stat'ing when this function is | 701 /* Here we try to minimize useless stat'ing when this function is |
698 invoked many times successively with the same PREFIX. We achieve | 702 invoked many times successively with the same PREFIX. We achieve |
699 this by initializing count to a random value, and incrementing it | 703 this by using a very pseudo-random number generator to generate |
700 afterwards. */ | 704 file names unique to this process, with a very long cycle. */ |
701 if (!count_initialized_p) | |
702 { | |
703 count = (unsigned)time (NULL); | |
704 /* Dumping temacs with a non-zero count_initialized_p wouldn't | |
705 make much sense. */ | |
706 if (NILP (Frunning_temacs_p ())) | |
707 count_initialized_p = 1; | |
708 } | |
709 | 705 |
710 while (1) | 706 while (1) |
711 { | 707 { |
712 struct stat ignored; | 708 struct stat ignored; |
713 unsigned num = count; | 709 |
714 | 710 p[0] = tbl[(temp_name_rand >> 0) & 63]; |
715 p[0] = tbl[num & 63], num >>= 6; | 711 p[1] = tbl[(temp_name_rand >> 6) & 63]; |
716 p[1] = tbl[num & 63], num >>= 6; | 712 p[2] = tbl[(temp_name_rand >> 12) & 63]; |
717 p[2] = tbl[num & 63], num >>= 6; | |
718 | 713 |
719 /* Poor man's congruential RN generator. Replace with ++count | 714 /* Poor man's congruential RN generator. Replace with ++count |
720 for debugging. */ | 715 for debugging. */ |
721 count += 25229; | 716 temp_name_rand += 25229; |
722 count %= 225307; | 717 temp_name_rand %= 225307; |
723 | 718 |
724 QUIT; | 719 QUIT; |
725 | 720 |
726 if (stat ((const char *) data, &ignored) < 0) | 721 if (stat ((const char *) data, &ignored) < 0) |
727 { | 722 { |
1844 | 1839 |
1845 if (XSTRING_LENGTH (dirname_) > (Bytecount) (sizeof (dir) - 1)) | 1840 if (XSTRING_LENGTH (dirname_) > (Bytecount) (sizeof (dir) - 1)) |
1846 { | 1841 { |
1847 return Fsignal (Qfile_error, | 1842 return Fsignal (Qfile_error, |
1848 list3 (build_translated_string ("Creating directory"), | 1843 list3 (build_translated_string ("Creating directory"), |
1849 build_translated_string ("pathame too long"), | 1844 build_translated_string ("pathname too long"), |
1850 dirname_)); | 1845 dirname_)); |
1851 } | 1846 } |
1852 strncpy (dir, (char *) XSTRING_DATA (dirname_), | 1847 strncpy (dir, (char *) XSTRING_DATA (dirname_), |
1853 XSTRING_LENGTH (dirname_) + 1); | 1848 XSTRING_LENGTH (dirname_) + 1); |
1854 | 1849 |
2073 | 2068 |
2074 UNGCPRO; | 2069 UNGCPRO; |
2075 return Qnil; | 2070 return Qnil; |
2076 } | 2071 } |
2077 | 2072 |
2078 #ifdef S_IFLNK | |
2079 DEFUN ("make-symbolic-link", Fmake_symbolic_link, 2, 3, | 2073 DEFUN ("make-symbolic-link", Fmake_symbolic_link, 2, 3, |
2080 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np", /* | 2074 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np", /* |
2081 Make a symbolic link to FILENAME, named LINKNAME. Both args strings. | 2075 Make a symbolic link to FILENAME, named LINKNAME. Both args strings. |
2082 Signals a `file-already-exists' error if a file LINKNAME already exists | 2076 Signals a `file-already-exists' error if a file LINKNAME already exists |
2083 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil. | 2077 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil. |
2085 This happens for interactive use with M-x. | 2079 This happens for interactive use with M-x. |
2086 */ | 2080 */ |
2087 (filename, linkname, ok_if_already_exists)) | 2081 (filename, linkname, ok_if_already_exists)) |
2088 { | 2082 { |
2089 /* This function can GC. GC checked 1997.06.04. */ | 2083 /* This function can GC. GC checked 1997.06.04. */ |
2084 /* XEmacs change: run handlers even if local machine doesn't have symlinks */ | |
2090 Lisp_Object handler; | 2085 Lisp_Object handler; |
2091 struct gcpro gcpro1, gcpro2; | 2086 struct gcpro gcpro1, gcpro2; |
2092 | 2087 |
2093 GCPRO2 (filename, linkname); | 2088 GCPRO2 (filename, linkname); |
2094 CHECK_STRING (filename); | 2089 CHECK_STRING (filename); |
2112 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link); | 2107 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link); |
2113 if (!NILP (handler)) | 2108 if (!NILP (handler)) |
2114 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename, | 2109 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename, |
2115 linkname, ok_if_already_exists)); | 2110 linkname, ok_if_already_exists)); |
2116 | 2111 |
2112 #ifdef S_IFLNK | |
2117 if (NILP (ok_if_already_exists) | 2113 if (NILP (ok_if_already_exists) |
2118 || INTP (ok_if_already_exists)) | 2114 || INTP (ok_if_already_exists)) |
2119 barf_or_query_if_file_exists (linkname, "make it a link", | 2115 barf_or_query_if_file_exists (linkname, "make it a link", |
2120 INTP (ok_if_already_exists), 0); | 2116 INTP (ok_if_already_exists), 0); |
2121 | 2117 |
2124 (char *) XSTRING_DATA (linkname))) | 2120 (char *) XSTRING_DATA (linkname))) |
2125 { | 2121 { |
2126 report_file_error ("Making symbolic link", | 2122 report_file_error ("Making symbolic link", |
2127 list2 (filename, linkname)); | 2123 list2 (filename, linkname)); |
2128 } | 2124 } |
2125 #endif /* S_IFLNK */ | |
2126 | |
2129 UNGCPRO; | 2127 UNGCPRO; |
2130 return Qnil; | 2128 return Qnil; |
2131 } | 2129 } |
2132 #endif /* S_IFLNK */ | |
2133 | 2130 |
2134 #ifdef HPUX_NET | 2131 #ifdef HPUX_NET |
2135 | 2132 |
2136 DEFUN ("sysnetunam", Fsysnetunam, 2, 2, 0, /* | 2133 DEFUN ("sysnetunam", Fsysnetunam, 2, 2, 0, /* |
2137 Open a network connection to PATH using LOGIN as the login string. | 2134 Open a network connection to PATH using LOGIN as the login string. |
2349 Otherwise returns nil. | 2346 Otherwise returns nil. |
2350 */ | 2347 */ |
2351 (filename)) | 2348 (filename)) |
2352 { | 2349 { |
2353 /* This function can GC. GC checked 1997.04.10. */ | 2350 /* This function can GC. GC checked 1997.04.10. */ |
2351 /* XEmacs change: run handlers even if local machine doesn't have symlinks */ | |
2354 #ifdef S_IFLNK | 2352 #ifdef S_IFLNK |
2355 char *buf; | 2353 char *buf; |
2356 int bufsize; | 2354 int bufsize; |
2357 int valsize; | 2355 int valsize; |
2358 Lisp_Object val; | 2356 Lisp_Object val; |
2357 #endif | |
2359 Lisp_Object handler; | 2358 Lisp_Object handler; |
2360 struct gcpro gcpro1; | 2359 struct gcpro gcpro1; |
2361 | 2360 |
2362 CHECK_STRING (filename); | 2361 CHECK_STRING (filename); |
2363 filename = Fexpand_file_name (filename, Qnil); | 2362 filename = Fexpand_file_name (filename, Qnil); |
2368 handler = Ffind_file_name_handler (filename, Qfile_symlink_p); | 2367 handler = Ffind_file_name_handler (filename, Qfile_symlink_p); |
2369 UNGCPRO; | 2368 UNGCPRO; |
2370 if (!NILP (handler)) | 2369 if (!NILP (handler)) |
2371 return call2 (handler, Qfile_symlink_p, filename); | 2370 return call2 (handler, Qfile_symlink_p, filename); |
2372 | 2371 |
2372 #ifdef S_IFLNK | |
2373 bufsize = 100; | 2373 bufsize = 100; |
2374 while (1) | 2374 while (1) |
2375 { | 2375 { |
2376 buf = xnew_array_and_zero (char, bufsize); | 2376 buf = xnew_array_and_zero (char, bufsize); |
2377 valsize = readlink ((char *) XSTRING_DATA (filename), | 2377 valsize = readlink ((char *) XSTRING_DATA (filename), |
4183 DEFSUBR (Fmake_directory_internal); | 4183 DEFSUBR (Fmake_directory_internal); |
4184 DEFSUBR (Fdelete_directory); | 4184 DEFSUBR (Fdelete_directory); |
4185 DEFSUBR (Fdelete_file); | 4185 DEFSUBR (Fdelete_file); |
4186 DEFSUBR (Frename_file); | 4186 DEFSUBR (Frename_file); |
4187 DEFSUBR (Fadd_name_to_file); | 4187 DEFSUBR (Fadd_name_to_file); |
4188 #ifdef S_IFLNK | |
4189 DEFSUBR (Fmake_symbolic_link); | 4188 DEFSUBR (Fmake_symbolic_link); |
4190 #endif /* S_IFLNK */ | |
4191 #ifdef HPUX_NET | 4189 #ifdef HPUX_NET |
4192 DEFSUBR (Fsysnetunam); | 4190 DEFSUBR (Fsysnetunam); |
4193 #endif /* HPUX_NET */ | 4191 #endif /* HPUX_NET */ |
4194 DEFSUBR (Ffile_name_absolute_p); | 4192 DEFSUBR (Ffile_name_absolute_p); |
4195 DEFSUBR (Ffile_exists_p); | 4193 DEFSUBR (Ffile_exists_p); |
4314 what the normal separator is. | 4312 what the normal separator is. |
4315 */ ); | 4313 */ ); |
4316 #ifdef WINDOWSNT | 4314 #ifdef WINDOWSNT |
4317 Vdirectory_sep_char = make_char ('\\'); | 4315 Vdirectory_sep_char = make_char ('\\'); |
4318 #else | 4316 #else |
4319 Vdirectory_sep_char = make_char ('/'); | 4317 Vdirectory_sep_char = make_char ('/'); |
4320 #endif | 4318 #endif |
4321 } | 4319 |
4320 reinit_vars_of_fileio (); | |
4321 } | |
4322 | |
4323 void | |
4324 reinit_vars_of_fileio (void) | |
4325 { | |
4326 /* We want temp_name_rand to be initialized to a value likely to be | |
4327 unique to the process, not to the executable. The danger is that | |
4328 two different XEmacs processes using the same binary on different | |
4329 machines creating temp files in the same directory will be | |
4330 unlucky enough to have the same pid. If we randomize using | |
4331 process startup time, then in practice they will be unlikely to | |
4332 collide. We use the microseconds field so that scripts that start | |
4333 simultaneous XEmacs processes on multiple machines will have less | |
4334 chance of collision. */ | |
4335 { | |
4336 EMACS_TIME thyme; | |
4337 | |
4338 EMACS_GET_TIME (thyme); | |
4339 temp_name_rand = (unsigned int) (EMACS_SECS (thyme) ^ EMACS_USECS (thyme)); | |
4340 } | |
4341 } |