aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1998-04-20 18:13:03 +0000
committerRichard M. Stallman1998-04-20 18:13:03 +0000
commit3ce839e4606d820e9d9f94ee6742d4ad3818a38b (patch)
tree4c2162e528fd4710d9edd43b78591eaf3efd6e84 /src
parent5feeeae29d2f59c9e33e65030b1f62ffd8c243bc (diff)
downloademacs-3ce839e4606d820e9d9f94ee6742d4ad3818a38b.tar.gz
emacs-3ce839e4606d820e9d9f94ee6742d4ad3818a38b.zip
(Fmake_temp_name): Complete rewrite.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c105
1 files changed, 90 insertions, 15 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 25f4ea6185a..0e6eb79f6bb 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -790,33 +790,108 @@ it returns a file name such as \"[X]Y.DIR.1\".")
790 return build_string (buf); 790 return build_string (buf);
791} 791}
792 792
793static char make_temp_name_tbl[64] =
794{
795 'A','B','C','D','E','F','G','H',
796 'I','J','K','L','M','N','O','P',
797 'Q','R','S','T','U','V','W','X',
798 'Y','Z','a','b','c','d','e','f',
799 'g','h','i','j','k','l','m','n',
800 'o','p','q','r','s','t','u','v',
801 'w','x','y','z','0','1','2','3',
802 '4','5','6','7','8','9','-','_'
803};
804static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
805
793DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0, 806DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
794 "Generate temporary file name (string) starting with PREFIX (a string).\n\ 807 "Generate temporary file name (string) starting with PREFIX (a string).\n\
795The Emacs process number forms part of the result,\n\ 808The Emacs process number forms part of the result,\n\
796so there is no danger of generating a name being used by another process.\n\ 809so there is no danger of generating a name being used by another process.\n\
810\n\
797In addition, this function makes an attempt to choose a name\n\ 811In addition, this function makes an attempt to choose a name\n\
798which has no existing file.") 812which has no existing file. To make this work,\n\
813PREFIX should be an absolute file name.")
799 (prefix) 814 (prefix)
800 Lisp_Object prefix; 815 Lisp_Object prefix;
801{ 816{
802 char *temp;
803 Lisp_Object val; 817 Lisp_Object val;
804#ifdef MSDOS 818 int len;
805 /* Don't use too many characters of the restricted 8+3 DOS 819 int pid;
806 filename space. */ 820 unsigned char *p, *data;
807 val = concat2 (prefix, build_string ("a.XXX")); 821 char pidbuf[20];
822 int pidlen;
823
824 CHECK_STRING (prefix, 0);
825
826 /* VAL is created by adding 6 characters to PREFIX. The first
827 three are the PID of this process, in base 64, and the second
828 three are incremented if the file already exists. This ensures
829 262144 unique file names per PID per PREFIX. */
830
831 pid = (int) getpid ();
832
833#ifdef HAVE_LONG_FILE_NAMES
834 sprintf (pidbuf, "%d", pid);
835 pidlen = strlen (pidbuf);
808#else 836#else
809 val = concat2 (prefix, build_string ("XXXXXX")); 837 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
810#endif 838 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
811 temp = mktemp (XSTRING (val)->data); 839 pidbuf[2] = make_temp_name_tbl[pid & 63], pid >>= 6;
812 if (! temp) 840 pidlen = 3;
813 error ("No temporary file names based on %s are available",
814 XSTRING (prefix)->data);
815#ifdef DOS_NT
816 CORRECT_DIR_SEPS (XSTRING (val)->data);
817#endif 841#endif
818 return val; 842
843 len = XSTRING (prefix)->size;
844 val = make_uninit_string (len + 3 + pidlen);
845 data = XSTRING (val)->data;
846 bcopy(XSTRING (prefix)->data, data, len);
847 p = data + len;
848
849 bcopy (pidbuf, p, pidlen);
850 p += pidlen;
851
852 /* Here we try to minimize useless stat'ing when this function is
853 invoked many times successively with the same PREFIX. We achieve
854 this by initializing count to a random value, and incrementing it
855 afterwards. */
856 if (!make_temp_name_count_initialized_p)
857 {
858 make_temp_name_count = (unsigned) time (NULL);
859 make_temp_name_count_initialized_p = 1;
860 }
861
862 while (1)
863 {
864 struct stat ignored;
865 unsigned num = make_temp_name_count++;
866
867 p[0] = make_temp_name_tbl[num & 63], num >>= 6;
868 p[1] = make_temp_name_tbl[num & 63], num >>= 6;
869 p[2] = make_temp_name_tbl[num & 63], num >>= 6;
870
871 if (stat (data, &ignored) < 0)
872 {
873 /* We want to return only if errno is ENOENT. */
874 if (errno == ENOENT)
875 return val;
876 else
877 /* The error here is dubious, but there is little else we
878 can do. The alternatives are to return nil, which is
879 as bad as (and in many cases worse than) throwing the
880 error, or to ignore the error, which will likely result
881 in looping through 262144 stat's, which is not only
882 SLOW, but also useless since it will fallback to the
883 errow below, anyway. */
884 report_file_error ("Cannot create temporary name for prefix `%s'",
885 Fcons (prefix, Qnil));
886 /* not reached */
887 }
888 }
889
890 error ("Cannot create temporary name for prefix `%s'",
891 XSTRING (prefix)->data);
892 return Qnil;
819} 893}
894
820 895
821DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, 896DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
822 "Convert filename NAME to absolute, and canonicalize it.\n\ 897 "Convert filename NAME to absolute, and canonicalize it.\n\