Mercurial > hg > xemacs-beta
comparison src/fileio.c @ 274:ca9a9ec9c1c1 r21-0b35
Import from CVS: tag r21-0b35
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:29:42 +0200 |
parents | c5d627a313b1 |
children | 6330739388db |
comparison
equal
deleted
inserted
replaced
273:411aac7253ef | 274:ca9a9ec9c1c1 |
---|---|
639 return call2_check_string (handler, Qdirectory_file_name, directory); | 639 return call2_check_string (handler, Qdirectory_file_name, directory); |
640 buf = (char *) alloca (XSTRING_LENGTH (directory) + 20); | 640 buf = (char *) alloca (XSTRING_LENGTH (directory) + 20); |
641 directory_file_name ((char *) XSTRING_DATA (directory), buf); | 641 directory_file_name ((char *) XSTRING_DATA (directory), buf); |
642 return build_string (buf); | 642 return build_string (buf); |
643 } | 643 } |
644 | |
645 /* Fmake_temp_name used to be a simple wrapper around mktemp(), but it | |
646 proved too broken for our purposes (it supported only 26 or 62 | |
647 unique names under some implementations). For instance, the stupid | |
648 limit broke Gnus Incoming* files generation. | |
649 | |
650 NB, this implementation is better than what one usually finds in | |
651 libc. --hniksic */ | |
652 | |
653 #define MTN_RANDOM(x) ((int) (random () % x)) | |
654 #define MTN_INC(var, limit) (var = ((var == (limit) - 1) ? 0 : (var + 1))) | |
655 #define MTN_LOOP(var, limit, keep) \ | |
656 for (keep = var = MTN_RANDOM (limit), MTN_INC (var, limit); \ | |
657 var != keep; \ | |
658 MTN_INC (var, limit)) | |
644 | 659 |
645 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* | 660 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* |
646 Generate temporary file name (string) starting with PREFIX (a string). | 661 Generate temporary file name starting with PREFIX. |
647 The Emacs process number forms part of the result, | 662 The Emacs process number forms part of the result, so there is no |
648 so there is no danger of generating a name being used by another process. | 663 danger of generating a name being used by another process. |
664 | |
665 In its current implementation, this function guarantees 262144 unique | |
666 names per process per PREFIX (this is 54872 on case-insensitive | |
667 filesystems. However, if you want it to operate safely, PREFIX should | |
668 have been passed through `expand-file-name'. | |
649 */ | 669 */ |
650 (prefix)) | 670 (prefix)) |
651 { | 671 { |
652 CONST char suffix[] = "XXXXXX"; | 672 static char tbl[64] = { |
653 Bufbyte *data; | 673 'A','B','C','D','E','F','G','H', |
674 'I','J','K','L','M','N','O','P', | |
675 'Q','R','S','T','U','V','W','X', | |
676 'Y','Z','a','b','c','d','e','f', | |
677 'g','h','i','j','k','l','m','n', | |
678 'o','p','q','r','s','t','u','v', | |
679 'w','x','y','z','0','1','2','3', | |
680 '4','5','6','7','8','9','-','_' | |
681 }; | |
682 Lisp_Object val; | |
654 Bytecount len; | 683 Bytecount len; |
655 Lisp_Object val; | 684 int pid; |
685 int i, j, k, keep1, keep2, keep3; | |
686 Bufbyte *p, *data; | |
656 | 687 |
657 CHECK_STRING (prefix); | 688 CHECK_STRING (prefix); |
689 | |
690 /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's | |
691 a bad idea because: | |
692 | |
693 1) It might change the prefix, so the resulting string might not | |
694 begin with PREFIX. This violates the principle of least | |
695 surprise. | |
696 | |
697 2) It breaks under many unforeseeable circumstances, such as with | |
698 the code that uses (make-temp-name "") instead of | |
699 (make-temp-name "./"). | |
700 | |
701 3) It might yield unexpected results in the presence of EFS and | |
702 file name handlers. */ | |
703 | |
658 len = XSTRING_LENGTH (prefix); | 704 len = XSTRING_LENGTH (prefix); |
659 val = make_uninit_string (len + countof (suffix) - 1); | 705 val = make_uninit_string (len + 6); |
660 data = XSTRING_DATA (val); | 706 data = XSTRING_DATA (val); |
661 memcpy (data, XSTRING_DATA (prefix), len); | 707 memcpy (data, XSTRING_DATA (prefix), len); |
662 memcpy (data + len, suffix, countof (suffix)); | 708 p = data + len; |
663 /* !!#### does mktemp() Mule-encapsulate? */ | 709 |
664 mktemp ((char *) data); | 710 /* `val' is created by adding 6 characters to PREFIX. The first |
665 | 711 three are the PID of this process, in base 64, and the second |
666 #ifdef WINDOWSNT | 712 three are incremented if the file already exists. This ensures |
667 CORRECT_DIR_SEPS (XSTRING_DATA (val)); | 713 262144 unique file names per PID per PREFIX. */ |
668 #endif /* WINDOWSNT */ | 714 |
669 return val; | 715 pid = (int)getpid (); |
716 *p++ = tbl[pid & 63], pid >>= 6; | |
717 *p++ = tbl[pid & 63], pid >>= 6; | |
718 *p++ = tbl[pid & 63], pid >>= 6; | |
719 | |
720 /* Here we employ some trickery to minimize useless stat'ing when | |
721 this function is invoked many times successively with the same | |
722 PREFIX. Instead of looping from 0 to 63, each of the variables | |
723 is assigned a random number less than 64, and is incremented up | |
724 to 63 and back to zero, until the initial value is reached again. | |
725 | |
726 In other words, MTN_LOOP (i, 64, keep1) is equivalent to | |
727 for (i = 0; i < 64; i++) with the difference that the beginning | |
728 value needn't be 0 -- all that matters is that i is guaranteed to | |
729 loop through all the values in the [0, 64) range. */ | |
730 MTN_LOOP (i, 64, keep1) | |
731 { | |
732 p[0] = tbl[i]; | |
733 MTN_LOOP (j, 64, keep2) | |
734 { | |
735 p[1] = tbl[j]; | |
736 MTN_LOOP (k, 64, keep3) | |
737 { | |
738 struct stat ignored; | |
739 p[2] = tbl[k]; | |
740 if (stat (data, &ignored) < 0) | |
741 { | |
742 /* We want to return only if errno is ENOENT. */ | |
743 if (errno == ENOENT) | |
744 return val; | |
745 else | |
746 /* The error here is dubious, but there is little | |
747 else we can do. The alternatives are to return | |
748 nil, which is as bad as (and in many cases | |
749 worse than) throwing the error, or to ignore | |
750 the error, which will likely result in looping | |
751 through 262144 stat's, which is not only SLOW, | |
752 but also useless since it will fallback to the | |
753 errow below, anyway. */ | |
754 report_file_error | |
755 ("Cannot create temporary name for prefix", | |
756 list1 (prefix)); | |
757 /* not reached */ | |
758 } | |
759 } | |
760 } | |
761 } | |
762 signal_simple_error ("Cannot create temporary name for prefix", prefix); | |
763 RETURN_NOT_REACHED (Qnil); | |
670 } | 764 } |
671 | 765 |
672 DEFUN ("expand-file-name", Fexpand_file_name, 1, 2, 0, /* | 766 DEFUN ("expand-file-name", Fexpand_file_name, 1, 2, 0, /* |
673 Convert filename NAME to absolute, and canonicalize it. | 767 Convert filename NAME to absolute, and canonicalize it. |
674 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative | 768 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative |
2551 | 2645 |
2552 /* Stack sizes > 2**16 is a good way to elicit compiler bugs */ | 2646 /* Stack sizes > 2**16 is a good way to elicit compiler bugs */ |
2553 /* #define READ_BUF_SIZE (2 << 16) */ | 2647 /* #define READ_BUF_SIZE (2 << 16) */ |
2554 #define READ_BUF_SIZE (1 << 15) | 2648 #define READ_BUF_SIZE (1 << 15) |
2555 | 2649 |
2556 DEFUN ("insert-file-contents-internal", | 2650 DEFUN ("insert-file-contents-internal", Finsert_file_contents_internal, 1, 7, 0, /* |
2557 Finsert_file_contents_internal, 1, 7, 0, /* | |
2558 Insert contents of file FILENAME after point; no coding-system frobbing. | 2651 Insert contents of file FILENAME after point; no coding-system frobbing. |
2559 This function is identical to `insert-file-contents' except for the | 2652 This function is identical to `insert-file-contents' except for the |
2560 handling of the CODESYS and USED-CODESYS arguments under | 2653 handling of the CODESYS and USED-CODESYS arguments under |
2561 XEmacs/Mule. (When Mule support is not present, both functions are | 2654 XEmacs/Mule. (When Mule support is not present, both functions are |
2562 identical and ignore the CODESYS and USED-CODESYS arguments.) | 2655 identical and ignore the CODESYS and USED-CODESYS arguments.) |
2568 if CODESYS specifies automatic encoding detection or end-of-line detection. | 2661 if CODESYS specifies automatic encoding detection or end-of-line detection. |
2569 | 2662 |
2570 Currently BEG and END refer to byte positions (as opposed to character | 2663 Currently BEG and END refer to byte positions (as opposed to character |
2571 positions), even in Mule. (Fixing this is very difficult.) | 2664 positions), even in Mule. (Fixing this is very difficult.) |
2572 */ | 2665 */ |
2573 (filename, visit, beg, end, replace, codesys, used_codesys)) | 2666 (filename, visit, beg, end, replace, codesys, used_codesys)) |
2574 { | 2667 { |
2575 /* This function can call lisp */ | 2668 /* This function can call lisp */ |
2576 /* #### dmoore - this function hasn't been checked for gc recently */ | 2669 /* #### dmoore - this function hasn't been checked for gc recently */ |
2577 struct stat st; | 2670 struct stat st; |
2578 int fd; | 2671 int fd; |
2834 /* Make sure point-max won't overflow after this insertion. */ | 2927 /* Make sure point-max won't overflow after this insertion. */ |
2835 if (total != XINT (make_int (total))) | 2928 if (total != XINT (make_int (total))) |
2836 error ("Maximum buffer size exceeded"); | 2929 error ("Maximum buffer size exceeded"); |
2837 } | 2930 } |
2838 else | 2931 else |
2839 /* For a special file, all we can do is guess. */ | 2932 /* For a special file, all we can do is guess. The value of -1 |
2840 total = READ_BUF_SIZE; | 2933 will make the stream functions read as much as possible. */ |
2934 total = -1; | |
2841 | 2935 |
2842 if (XINT (beg) != 0 | 2936 if (XINT (beg) != 0 |
2843 #ifdef FSFMACS_SPEEDY_INSERT | 2937 #ifdef FSFMACS_SPEEDY_INSERT |
2844 /* why was this here? asked jwz. The reason is that the replace-mode | 2938 /* why was this here? asked jwz. The reason is that the replace-mode |
2845 connivings above will normally put the file pointer other than | 2939 connivings above will normally put the file pointer other than |
2863 #ifdef FILE_CODING | 2957 #ifdef FILE_CODING |
2864 stream = make_decoding_input_stream | 2958 stream = make_decoding_input_stream |
2865 (XLSTREAM (stream), Fget_coding_system (codesys)); | 2959 (XLSTREAM (stream), Fget_coding_system (codesys)); |
2866 Lstream_set_character_mode (XLSTREAM (stream)); | 2960 Lstream_set_character_mode (XLSTREAM (stream)); |
2867 Lstream_set_buffering (XLSTREAM (stream), LSTREAM_BLOCKN_BUFFERED, 65536); | 2961 Lstream_set_buffering (XLSTREAM (stream), LSTREAM_BLOCKN_BUFFERED, 65536); |
2868 #endif /* MULE */ | 2962 #endif /* FILE_CODING */ |
2869 | 2963 |
2870 record_unwind_protect (close_stream_unwind, stream); | 2964 record_unwind_protect (close_stream_unwind, stream); |
2871 | 2965 |
2872 /* No need to limit the amount of stuff we attempt to read. (It would | 2966 /* No need to limit the amount of stuff we attempt to read. (It would |
2873 be incorrect, anyway, when Mule is enabled.) Instead, the limiting | 2967 be incorrect, anyway, when Mule is enabled.) Instead, the limiting |
2899 if (!NILP (used_codesys)) | 2993 if (!NILP (used_codesys)) |
2900 { | 2994 { |
2901 Fset (used_codesys, | 2995 Fset (used_codesys, |
2902 XCODING_SYSTEM_NAME (decoding_stream_coding_system (XLSTREAM (stream)))); | 2996 XCODING_SYSTEM_NAME (decoding_stream_coding_system (XLSTREAM (stream)))); |
2903 } | 2997 } |
2904 #endif /* MULE */ | 2998 #endif /* FILE_CODING */ |
2905 NUNGCPRO; | 2999 NUNGCPRO; |
2906 } | 3000 } |
2907 | 3001 |
2908 /* Close the file/stream */ | 3002 /* Close the file/stream */ |
2909 unbind_to (speccount, Qnil); | 3003 unbind_to (speccount, Qnil); |
3050 to protect the current_buffer from being destroyed, but the | 3144 to protect the current_buffer from being destroyed, but the |
3051 multiple return points make this a pain in the butt. */ | 3145 multiple return points make this a pain in the butt. */ |
3052 | 3146 |
3053 #ifdef FILE_CODING | 3147 #ifdef FILE_CODING |
3054 codesys = Fget_coding_system (codesys); | 3148 codesys = Fget_coding_system (codesys); |
3055 #endif /* MULE */ | 3149 #endif /* FILE_CODING */ |
3056 | 3150 |
3057 if (current_buffer->base_buffer && ! NILP (visit)) | 3151 if (current_buffer->base_buffer && ! NILP (visit)) |
3058 error ("Cannot do file visiting in an indirect buffer"); | 3152 error ("Cannot do file visiting in an indirect buffer"); |
3059 | 3153 |
3060 if (!NILP (start) && !STRINGP (start)) | 3154 if (!NILP (start) && !STRINGP (start)) |
3191 #ifdef FILE_CODING | 3285 #ifdef FILE_CODING |
3192 outstream = | 3286 outstream = |
3193 make_encoding_output_stream (XLSTREAM (outstream), codesys); | 3287 make_encoding_output_stream (XLSTREAM (outstream), codesys); |
3194 Lstream_set_buffering (XLSTREAM (outstream), | 3288 Lstream_set_buffering (XLSTREAM (outstream), |
3195 LSTREAM_BLOCKN_BUFFERED, 65536); | 3289 LSTREAM_BLOCKN_BUFFERED, 65536); |
3196 #endif /* MULE */ | 3290 #endif /* FILE_CODING */ |
3197 if (STRINGP (start)) | 3291 if (STRINGP (start)) |
3198 { | 3292 { |
3199 instream = make_lisp_string_input_stream (start, 0, -1); | 3293 instream = make_lisp_string_input_stream (start, 0, -1); |
3200 start1 = 0; | 3294 start1 = 0; |
3201 } | 3295 } |