diff options
| author | Richard M. Stallman | 1998-04-20 18:13:03 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-04-20 18:13:03 +0000 |
| commit | 3ce839e4606d820e9d9f94ee6742d4ad3818a38b (patch) | |
| tree | 4c2162e528fd4710d9edd43b78591eaf3efd6e84 /src | |
| parent | 5feeeae29d2f59c9e33e65030b1f62ffd8c243bc (diff) | |
| download | emacs-3ce839e4606d820e9d9f94ee6742d4ad3818a38b.tar.gz emacs-3ce839e4606d820e9d9f94ee6742d4ad3818a38b.zip | |
(Fmake_temp_name): Complete rewrite.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 105 |
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 | ||
| 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", | ||
| 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 | ||
| 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\ |