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 }