comparison src/fileio.c @ 21684:89e327fdea93

(Fmake_temp_name): Complete rewrite.
author Richard M. Stallman <rms@gnu.org>
date Mon, 20 Apr 1998 18:13:03 +0000
parents 55865851fd69
children e02be2b47d18
comparison
equal deleted inserted replaced
21683:dfb671ba22f8 21684:89e327fdea93
788 #endif 788 #endif
789 directory_file_name (XSTRING (directory)->data, buf); 789 directory_file_name (XSTRING (directory)->data, buf);
790 return build_string (buf); 790 return build_string (buf);
791 } 791 }
792 792
793 static 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 };
804 static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
805
793 DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0, 806 DEFUN ("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\
795 The Emacs process number forms part of the result,\n\ 808 The Emacs process number forms part of the result,\n\
796 so there is no danger of generating a name being used by another process.\n\ 809 so there is no danger of generating a name being used by another process.\n\
810 \n\
797 In addition, this function makes an attempt to choose a name\n\ 811 In addition, this function makes an attempt to choose a name\n\
798 which has no existing file.") 812 which has no existing file. To make this work,\n\
813 PREFIX 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", 841 #endif
814 XSTRING (prefix)->data); 842
815 #ifdef DOS_NT 843 len = XSTRING (prefix)->size;
816 CORRECT_DIR_SEPS (XSTRING (val)->data); 844 val = make_uninit_string (len + 3 + pidlen);
817 #endif 845 data = XSTRING (val)->data;
818 return val; 846 bcopy(XSTRING (prefix)->data, data, len);
819 } 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;
893 }
894
820 895
821 DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, 896 DEFUN ("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\
823 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\ 898 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
824 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\ 899 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\