comparison src/fileio.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
22 /* Synched up with: Mule 2.0, FSF 19.30. */ 22 /* Synched up with: Mule 2.0, FSF 19.30. */
23 /* More syncing: FSF Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */ 23 /* More syncing: FSF Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
24 24
25 #include <config.h> 25 #include <config.h>
26 #include "lisp.h" 26 #include "lisp.h"
27 #include <limits.h>
28 27
29 #include "buffer.h" 28 #include "buffer.h"
30 #include "events.h" 29 #include "events.h"
31 #include "frame.h" 30 #include "frame.h"
32 #include "insdel.h" 31 #include "insdel.h"
52 #ifdef HPUX_PRE_8_0 51 #ifdef HPUX_PRE_8_0
53 #include <errnet.h> 52 #include <errnet.h>
54 #endif /* HPUX_PRE_8_0 */ 53 #endif /* HPUX_PRE_8_0 */
55 #endif /* HPUX */ 54 #endif /* HPUX */
56 55
57 #ifdef WINDOWSNT 56 #ifdef WIN32_NATIVE
58 #define NOMINMAX 1
59 #include <direct.h>
60 #include <fcntl.h>
61 #include <stdlib.h>
62 #endif /* not WINDOWSNT */
63
64 #ifdef WINDOWSNT
65 #define CORRECT_DIR_SEPS(s) \
66 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
67 else unixtodos_filename (s); \
68 } while (0)
69 #define IS_DRIVE(x) isalpha (x) 57 #define IS_DRIVE(x) isalpha (x)
70 /* Need to lower-case the drive letter, or else expanded 58 /* Need to lower-case the drive letter, or else expanded
71 filenames will sometimes compare inequal, because 59 filenames will sometimes compare inequal, because
72 `expand-file-name' doesn't always down-case the drive letter. */ 60 `expand-file-name' doesn't always down-case the drive letter. */
73 #define DRIVE_LETTER(x) tolower (x) 61 #define DRIVE_LETTER(x) tolower (x)
74 #endif /* WINDOWSNT */ 62 #endif /* WIN32_NATIVE */
75 63
76 int lisp_to_time (Lisp_Object, time_t *); 64 int lisp_to_time (Lisp_Object, time_t *);
77 Lisp_Object time_to_lisp (time_t); 65 Lisp_Object time_to_lisp (time_t);
78 66
79 /* Nonzero during writing of auto-save files */ 67 /* Nonzero during writing of auto-save files */
133 EXFUN (Frunning_temacs_p, 0); 121 EXFUN (Frunning_temacs_p, 0);
134 122
135 /* signal a file error when errno contains a meaningful value. */ 123 /* signal a file error when errno contains a meaningful value. */
136 124
137 DOESNT_RETURN 125 DOESNT_RETURN
138 report_file_error (CONST char *string, Lisp_Object data) 126 report_file_error (const char *string, Lisp_Object data)
139 { 127 {
140 /* #### dmoore - This uses current_buffer, better make sure no one 128 /* #### dmoore - This uses current_buffer, better make sure no one
141 has GC'd the current buffer. File handlers are giving me a headache 129 has GC'd the current buffer. File handlers are giving me a headache
142 maybe I'll just always protect current_buffer around all of those 130 maybe I'll just always protect current_buffer around all of those
143 calls. */ 131 calls. */
146 Fcons (build_translated_string (string), 134 Fcons (build_translated_string (string),
147 Fcons (lisp_strerror (errno), data))); 135 Fcons (lisp_strerror (errno), data)));
148 } 136 }
149 137
150 void 138 void
151 maybe_report_file_error (CONST char *string, Lisp_Object data, 139 maybe_report_file_error (const char *string, Lisp_Object data,
152 Lisp_Object class, Error_behavior errb) 140 Lisp_Object class, Error_behavior errb)
153 { 141 {
154 /* Optimization: */ 142 /* Optimization: */
155 if (ERRB_EQ (errb, ERROR_ME_NOT)) 143 if (ERRB_EQ (errb, ERROR_ME_NOT))
156 return; 144 return;
162 } 150 }
163 151
164 /* signal a file error when errno does not contain a meaningful value. */ 152 /* signal a file error when errno does not contain a meaningful value. */
165 153
166 DOESNT_RETURN 154 DOESNT_RETURN
167 signal_file_error (CONST char *string, Lisp_Object data) 155 signal_file_error (const char *string, Lisp_Object data)
168 { 156 {
169 signal_error (Qfile_error, 157 signal_error (Qfile_error,
170 list2 (build_translated_string (string), data)); 158 list2 (build_translated_string (string), data));
171 } 159 }
172 160
173 void 161 void
174 maybe_signal_file_error (CONST char *string, Lisp_Object data, 162 maybe_signal_file_error (const char *string, Lisp_Object data,
175 Lisp_Object class, Error_behavior errb) 163 Lisp_Object class, Error_behavior errb)
176 { 164 {
177 /* Optimization: */ 165 /* Optimization: */
178 if (ERRB_EQ (errb, ERROR_ME_NOT)) 166 if (ERRB_EQ (errb, ERROR_ME_NOT))
179 return; 167 return;
181 list2 (build_translated_string (string), data), 169 list2 (build_translated_string (string), data),
182 class, errb); 170 class, errb);
183 } 171 }
184 172
185 DOESNT_RETURN 173 DOESNT_RETURN
186 signal_double_file_error (CONST char *string1, CONST char *string2, 174 signal_double_file_error (const char *string1, const char *string2,
187 Lisp_Object data) 175 Lisp_Object data)
188 { 176 {
189 signal_error (Qfile_error, 177 signal_error (Qfile_error,
190 list3 (build_translated_string (string1), 178 list3 (build_translated_string (string1),
191 build_translated_string (string2), 179 build_translated_string (string2),
192 data)); 180 data));
193 } 181 }
194 182
195 void 183 void
196 maybe_signal_double_file_error (CONST char *string1, CONST char *string2, 184 maybe_signal_double_file_error (const char *string1, const char *string2,
197 Lisp_Object data, Lisp_Object class, 185 Lisp_Object data, Lisp_Object class,
198 Error_behavior errb) 186 Error_behavior errb)
199 { 187 {
200 /* Optimization: */ 188 /* Optimization: */
201 if (ERRB_EQ (errb, ERROR_ME_NOT)) 189 if (ERRB_EQ (errb, ERROR_ME_NOT))
206 data), 194 data),
207 class, errb); 195 class, errb);
208 } 196 }
209 197
210 DOESNT_RETURN 198 DOESNT_RETURN
211 signal_double_file_error_2 (CONST char *string1, CONST char *string2, 199 signal_double_file_error_2 (const char *string1, const char *string2,
212 Lisp_Object data1, Lisp_Object data2) 200 Lisp_Object data1, Lisp_Object data2)
213 { 201 {
214 signal_error (Qfile_error, 202 signal_error (Qfile_error,
215 list4 (build_translated_string (string1), 203 list4 (build_translated_string (string1),
216 build_translated_string (string2), 204 build_translated_string (string2),
217 data1, data2)); 205 data1, data2));
218 } 206 }
219 207
220 void 208 void
221 maybe_signal_double_file_error_2 (CONST char *string1, CONST char *string2, 209 maybe_signal_double_file_error_2 (const char *string1, const char *string2,
222 Lisp_Object data1, Lisp_Object data2, 210 Lisp_Object data1, Lisp_Object data2,
223 Lisp_Object class, Error_behavior errb) 211 Lisp_Object class, Error_behavior errb)
224 { 212 {
225 /* Optimization: */ 213 /* Optimization: */
226 if (ERRB_EQ (errb, ERROR_ME_NOT)) 214 if (ERRB_EQ (errb, ERROR_ME_NOT))
287 QUIT; 275 QUIT;
288 return sys_read_1 (fildes, buf, size, 1); 276 return sys_read_1 (fildes, buf, size, 1);
289 } 277 }
290 278
291 ssize_t 279 ssize_t
292 write_allowing_quit (int fildes, CONST void *buf, size_t size) 280 write_allowing_quit (int fildes, const void *buf, size_t size)
293 { 281 {
294 QUIT; 282 QUIT;
295 return sys_write_1 (fildes, buf, size, 1); 283 return sys_write_1 (fildes, buf, size, 1);
296 } 284 }
297 285
410 Otherwise return a directory spec. 398 Otherwise return a directory spec.
411 Given a Unix syntax file name, returns a string ending in slash. 399 Given a Unix syntax file name, returns a string ending in slash.
412 */ 400 */
413 (file)) 401 (file))
414 { 402 {
415 /* This function can GC. GC checked 1997.04.06. */ 403 /* This function can GC. GC checked 2000-07-28 ben */
416 Bufbyte *beg; 404 Bufbyte *beg;
417 Bufbyte *p; 405 Bufbyte *p;
418 Lisp_Object handler; 406 Lisp_Object handler;
419 407
420 CHECK_STRING (file); 408 CHECK_STRING (file);
430 #endif 418 #endif
431 beg = XSTRING_DATA (file); 419 beg = XSTRING_DATA (file);
432 p = beg + XSTRING_LENGTH (file); 420 p = beg + XSTRING_LENGTH (file);
433 421
434 while (p != beg && !IS_ANY_SEP (p[-1]) 422 while (p != beg && !IS_ANY_SEP (p[-1])
435 #ifdef WINDOWSNT 423 #ifdef WIN32_NATIVE
436 /* only recognize drive specifier at beginning */ 424 /* only recognize drive specifier at beginning */
437 && !(p[-1] == ':' && p == beg + 2) 425 && !(p[-1] == ':' && p == beg + 2)
438 #endif 426 #endif
439 ) p--; 427 ) p--;
440 428
441 if (p == beg) 429 if (p == beg)
442 return Qnil; 430 return Qnil;
443 #ifdef WINDOWSNT 431 #ifdef WIN32_NATIVE
444 /* Expansion of "c:" to drive and default directory. */ 432 /* Expansion of "c:" to drive and default directory. */
445 /* (NT does the right thing.) */ 433 /* (NT does the right thing.) */
446 if (p == beg + 2 && beg[1] == ':') 434 if (p == beg + 2 && beg[1] == ':')
447 { 435 {
448 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */ 436 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
449 Bufbyte *res = alloca (MAXPATHLEN + 1); 437 Bufbyte *res = (Bufbyte*) alloca (MAXPATHLEN + 1);
450 if (getdefdir (toupper (*beg) - 'A' + 1, res)) 438 if (_getdcwd (toupper (*beg) - 'A' + 1, (char *)res, MAXPATHLEN))
451 { 439 {
452 char *c=((char *) res) + strlen ((char *) res); 440 char *c=((char *) res) + strlen ((char *) res);
453 if (!IS_DIRECTORY_SEP (*c)) 441 if (!IS_DIRECTORY_SEP (*c))
454 { 442 {
455 *c++ = DIRECTORY_SEP; 443 *c++ = DIRECTORY_SEP;
457 } 445 }
458 beg = res; 446 beg = res;
459 p = beg + strlen ((char *) beg); 447 p = beg + strlen ((char *) beg);
460 } 448 }
461 } 449 }
462 #endif /* WINDOWSNT */ 450 #endif /* WIN32_NATIVE */
463 return make_string (beg, p - beg); 451 return make_string (beg, p - beg);
464 } 452 }
465 453
466 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, 1, 1, 0, /* 454 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, 1, 1, 0, /*
467 Return file name NAME sans its directory. 455 Return file name NAME sans its directory.
469 this is everything after the last slash, 457 this is everything after the last slash,
470 or the entire name if it contains no slash. 458 or the entire name if it contains no slash.
471 */ 459 */
472 (file)) 460 (file))
473 { 461 {
474 /* This function can GC. GC checked 1997.04.06. */ 462 /* This function can GC. GC checked 2000-07-28 ben */
475 Bufbyte *beg, *p, *end; 463 Bufbyte *beg, *p, *end;
476 Lisp_Object handler; 464 Lisp_Object handler;
477 465
478 CHECK_STRING (file); 466 CHECK_STRING (file);
479 467
485 473
486 beg = XSTRING_DATA (file); 474 beg = XSTRING_DATA (file);
487 end = p = beg + XSTRING_LENGTH (file); 475 end = p = beg + XSTRING_LENGTH (file);
488 476
489 while (p != beg && !IS_ANY_SEP (p[-1]) 477 while (p != beg && !IS_ANY_SEP (p[-1])
490 #ifdef WINDOWSNT 478 #ifdef WIN32_NATIVE
491 /* only recognize drive specifier at beginning */ 479 /* only recognize drive specifier at beginning */
492 && !(p[-1] == ':' && p == beg + 2) 480 && !(p[-1] == ':' && p == beg + 2)
493 #endif 481 #endif
494 ) p--; 482 ) p--;
495 483
505 The `call-process' and `start-process' functions use this function to 493 The `call-process' and `start-process' functions use this function to
506 get a current directory to run processes in. 494 get a current directory to run processes in.
507 */ 495 */
508 (filename)) 496 (filename))
509 { 497 {
510 /* This function can GC. GC checked 1997.04.06. */ 498 /* This function can GC. GC checked 2000-07-28 ben */
511 Lisp_Object handler; 499 Lisp_Object handler;
512 500
513 /* If the file name has special constructs in it, 501 /* If the file name has special constructs in it,
514 call the corresponding file handler. */ 502 call the corresponding file handler. */
515 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory); 503 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
522 510
523 511
524 static char * 512 static char *
525 file_name_as_directory (char *out, char *in) 513 file_name_as_directory (char *out, char *in)
526 { 514 {
515 /* This function cannot GC */
527 int size = strlen (in); 516 int size = strlen (in);
528 517
529 if (size == 0) 518 if (size == 0)
530 { 519 {
531 out[0] = '.'; 520 out[0] = '.';
554 For a Unix-syntax file name, just appends a slash, 543 For a Unix-syntax file name, just appends a slash,
555 except for (file-name-as-directory \"\") => \"./\". 544 except for (file-name-as-directory \"\") => \"./\".
556 */ 545 */
557 (file)) 546 (file))
558 { 547 {
559 /* This function can GC. GC checked 1997.04.06. */ 548 /* This function can GC. GC checked 2000-07-28 ben */
560 char *buf; 549 char *buf;
561 Lisp_Object handler; 550 Lisp_Object handler;
562 551
563 CHECK_STRING (file); 552 CHECK_STRING (file);
564 553
579 * 568 *
580 * Value is nonzero if the string output is different from the input. 569 * Value is nonzero if the string output is different from the input.
581 */ 570 */
582 571
583 static int 572 static int
584 directory_file_name (CONST char *src, char *dst) 573 directory_file_name (const char *src, char *dst)
585 { 574 {
575 /* This function cannot GC */
586 long slen = strlen (src); 576 long slen = strlen (src);
587 /* Process as Unix format: just remove any final slash. 577 /* Process as Unix format: just remove any final slash.
588 But leave "/" unchanged; do not change it to "". */ 578 But leave "/" unchanged; do not change it to "". */
589 strcpy (dst, src); 579 strcpy (dst, src);
590 if (slen > 1 580 if (slen > 1
591 && IS_DIRECTORY_SEP (dst[slen - 1]) 581 && IS_DIRECTORY_SEP (dst[slen - 1])
592 #ifdef WINDOWSNT 582 #ifdef WIN32_NATIVE
593 && !IS_ANY_SEP (dst[slen - 2]) 583 && !IS_ANY_SEP (dst[slen - 2])
594 #endif /* WINDOWSNT */ 584 #endif /* WIN32_NATIVE */
595 ) 585 )
596 dst[slen - 1] = 0; 586 dst[slen - 1] = 0;
597 return 1; 587 return 1;
598 } 588 }
599 589
604 a directory is different from its name as a file. 594 a directory is different from its name as a file.
605 In Unix-syntax, this function just removes the final slash. 595 In Unix-syntax, this function just removes the final slash.
606 */ 596 */
607 (directory)) 597 (directory))
608 { 598 {
609 /* This function can GC. GC checked 1997.04.06. */ 599 /* This function can GC. GC checked 2000-07-28 ben */
610 char *buf; 600 char *buf;
611 Lisp_Object handler; 601 Lisp_Object handler;
612 602
613 CHECK_STRING (directory); 603 CHECK_STRING (directory);
614 604
633 arbitrary limit broke generation of Gnus Incoming* files. 623 arbitrary limit broke generation of Gnus Incoming* files.
634 624
635 This implementation is better than what one usually finds in libc. 625 This implementation is better than what one usually finds in libc.
636 --hniksic */ 626 --hniksic */
637 627
628 static unsigned int temp_name_rand;
629
638 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* 630 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /*
639 Generate temporary file name starting with PREFIX. 631 Generate a temporary file name starting with PREFIX.
640 The Emacs process number forms part of the result, so there is no 632 The Emacs process number forms part of the result, so there is no
641 danger of generating a name being used by another process. 633 danger of generating a name being used by another process.
642 634
643 In addition, this function makes an attempt to choose a name that 635 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 636 does not specify an existing file. To make this work, PREFIX should
645 be an absolute file name. 637 be an absolute file name.
646 */ 638 */
647 (prefix)) 639 (prefix))
648 { 640 {
649 static char tbl[64] = { 641 static const char tbl[64] =
642 {
650 'A','B','C','D','E','F','G','H', 643 'A','B','C','D','E','F','G','H',
651 'I','J','K','L','M','N','O','P', 644 'I','J','K','L','M','N','O','P',
652 'Q','R','S','T','U','V','W','X', 645 'Q','R','S','T','U','V','W','X',
653 'Y','Z','a','b','c','d','e','f', 646 'Y','Z','a','b','c','d','e','f',
654 'g','h','i','j','k','l','m','n', 647 'g','h','i','j','k','l','m','n',
655 'o','p','q','r','s','t','u','v', 648 'o','p','q','r','s','t','u','v',
656 'w','x','y','z','0','1','2','3', 649 'w','x','y','z','0','1','2','3',
657 '4','5','6','7','8','9','-','_' }; 650 '4','5','6','7','8','9','-','_'
658 static unsigned count, count_initialized_p; 651 };
659 652
660 Lisp_Object val; 653 Lisp_Object val;
661 Bytecount len; 654 Bytecount len;
662 Bufbyte *p, *data; 655 Bufbyte *p, *data;
663 unsigned pid;
664 656
665 CHECK_STRING (prefix); 657 CHECK_STRING (prefix);
666 658
667 /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's 659 /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's
668 a bad idea because: 660 a bad idea because:
684 memcpy (data, XSTRING_DATA (prefix), len); 676 memcpy (data, XSTRING_DATA (prefix), len);
685 p = data + len; 677 p = data + len;
686 678
687 /* VAL is created by adding 6 characters to PREFIX. The first three 679 /* 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 680 are the PID of this process, in base 64, and the second three are
689 incremented if the file already exists. This ensures 262144 681 a pseudo-random number seeded from process startup time. This
690 unique file names per PID per PREFIX. */ 682 ensures 262144 unique file names per PID per PREFIX per machine. */
691 683
692 pid = (unsigned)getpid (); 684 {
693 *p++ = tbl[pid & 63], pid >>= 6; 685 unsigned int pid = (unsigned int) getpid ();
694 *p++ = tbl[pid & 63], pid >>= 6; 686 *p++ = tbl[(pid >> 0) & 63];
695 *p++ = tbl[pid & 63], pid >>= 6; 687 *p++ = tbl[(pid >> 6) & 63];
688 *p++ = tbl[(pid >> 12) & 63];
689 }
696 690
697 /* Here we try to minimize useless stat'ing when this function is 691 /* Here we try to minimize useless stat'ing when this function is
698 invoked many times successively with the same PREFIX. We achieve 692 invoked many times successively with the same PREFIX. We achieve
699 this by initializing count to a random value, and incrementing it 693 this by using a very pseudo-random number generator to generate
700 afterwards. */ 694 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 695
710 while (1) 696 while (1)
711 { 697 {
712 struct stat ignored; 698 struct stat ignored;
713 unsigned num = count; 699
714 700 p[0] = tbl[(temp_name_rand >> 0) & 63];
715 p[0] = tbl[num & 63], num >>= 6; 701 p[1] = tbl[(temp_name_rand >> 6) & 63];
716 p[1] = tbl[num & 63], num >>= 6; 702 p[2] = tbl[(temp_name_rand >> 12) & 63];
717 p[2] = tbl[num & 63], num >>= 6;
718 703
719 /* Poor man's congruential RN generator. Replace with ++count 704 /* Poor man's congruential RN generator. Replace with ++count
720 for debugging. */ 705 for debugging. */
721 count += 25229; 706 temp_name_rand += 25229;
722 count %= 225307; 707 temp_name_rand %= 225307;
723 708
724 QUIT; 709 QUIT;
725 710
726 if (stat ((CONST char *) data, &ignored) < 0) 711 if (xemacs_stat ((const char *) data, &ignored) < 0)
727 { 712 {
728 /* We want to return only if errno is ENOENT. */ 713 /* We want to return only if errno is ENOENT. */
729 if (errno == ENOENT) 714 if (errno == ENOENT)
730 return val; 715 return val;
731 716
755 An initial `~USER/' expands to USER's home directory. 740 An initial `~USER/' expands to USER's home directory.
756 See also the function `substitute-in-file-name'. 741 See also the function `substitute-in-file-name'.
757 */ 742 */
758 (name, default_directory)) 743 (name, default_directory))
759 { 744 {
760 /* This function can GC */ 745 /* This function can GC. GC-checked 2000-07-11 ben */
761 Bufbyte *nm; 746 Bufbyte *nm;
762 747
763 Bufbyte *newdir, *p, *o; 748 Bufbyte *newdir, *p, *o;
764 int tlen; 749 int tlen;
765 Bufbyte *target; 750 Bufbyte *target;
766 #ifdef WINDOWSNT 751 #ifdef WIN32_NATIVE
767 int drive = 0; 752 int drive = 0;
768 int collapse_newdir = 1; 753 int collapse_newdir = 1;
769 #else 754 #else
770 struct passwd *pw; 755 struct passwd *pw;
771 #endif /* WINDOWSNT */ 756 #endif /* WIN32_NATIVE */
772 int length; 757 int length;
773 Lisp_Object handler; 758 Lisp_Object handler;
774 #ifdef __CYGWIN32__ 759 #ifdef CYGWIN
775 char *user; 760 char *user;
776 #endif 761 #endif
762 struct gcpro gcpro1, gcpro2;
763
764 /* both of these get set below */
765 GCPRO2 (name, default_directory);
777 766
778 CHECK_STRING (name); 767 CHECK_STRING (name);
779 768
780 /* If the file name has special constructs in it, 769 /* If the file name has special constructs in it,
781 call the corresponding file handler. */ 770 call the corresponding file handler. */
782 handler = Ffind_file_name_handler (name, Qexpand_file_name); 771 handler = Ffind_file_name_handler (name, Qexpand_file_name);
783 if (!NILP (handler)) 772 if (!NILP (handler))
784 return call3_check_string (handler, Qexpand_file_name, name, 773 {
785 default_directory); 774 UNGCPRO;
775 return call3_check_string (handler, Qexpand_file_name, name,
776 default_directory);
777 }
786 778
787 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */ 779 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
788 if (NILP (default_directory)) 780 if (NILP (default_directory))
789 default_directory = current_buffer->directory; 781 default_directory = current_buffer->directory;
790 if (! STRINGP (default_directory)) 782 if (! STRINGP (default_directory))
792 784
793 if (!NILP (default_directory)) 785 if (!NILP (default_directory))
794 { 786 {
795 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name); 787 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
796 if (!NILP (handler)) 788 if (!NILP (handler))
797 return call3 (handler, Qexpand_file_name, name, default_directory); 789 {
790 UNGCPRO;
791 return call3 (handler, Qexpand_file_name, name, default_directory);
792 }
798 } 793 }
799 794
800 o = XSTRING_DATA (default_directory); 795 o = XSTRING_DATA (default_directory);
801 796
802 /* Make sure DEFAULT_DIRECTORY is properly expanded. 797 /* Make sure DEFAULT_DIRECTORY is properly expanded.
811 The EQ test avoids infinite recursion. */ 806 The EQ test avoids infinite recursion. */
812 if (! NILP (default_directory) && !EQ (default_directory, name) 807 if (! NILP (default_directory) && !EQ (default_directory, name)
813 /* Save time in some common cases - as long as default_directory 808 /* Save time in some common cases - as long as default_directory
814 is not relative, it can be canonicalized with name below (if it 809 is not relative, it can be canonicalized with name below (if it
815 is needed at all) without requiring it to be expanded now. */ 810 is needed at all) without requiring it to be expanded now. */
816 #ifdef WINDOWSNT 811 #ifdef WIN32_NATIVE
817 /* Detect MSDOS file names with drive specifiers. */ 812 /* Detect Windows file names with drive specifiers. */
818 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))) 813 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
819 /* Detect Windows file names in UNC format. */ 814 /* Detect Windows file names in UNC format. */
820 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1])) 815 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
821 816
822 #else /* not WINDOWSNT */ 817 #else /* not WIN32_NATIVE */
823 818
824 /* Detect Unix absolute file names (/... alone is not absolute on 819 /* Detect Unix absolute file names (/... alone is not absolute on
825 DOS or Windows). */ 820 Windows). */
826 && ! (IS_DIRECTORY_SEP (o[0])) 821 && ! (IS_DIRECTORY_SEP (o[0]))
827 #endif /* not WINDOWSNT */ 822 #endif /* not WIN32_NATIVE */
828 ) 823 )
829 { 824
830 struct gcpro gcpro1; 825 default_directory = Fexpand_file_name (default_directory, Qnil);
831
832 GCPRO1 (name);
833 default_directory = Fexpand_file_name (default_directory, Qnil);
834 UNGCPRO;
835 }
836 826
837 #ifdef FILE_SYSTEM_CASE 827 #ifdef FILE_SYSTEM_CASE
838 name = FILE_SYSTEM_CASE (name); 828 name = FILE_SYSTEM_CASE (name);
839 #endif 829 #endif
840 830
841 /* #### dmoore - this is ugly, clean this up. Looks like nm pointing 831 /* #### dmoore - this is ugly, clean this up. Looks like nm pointing
842 into name should be safe during all of this, though. */ 832 into name should be safe during all of this, though. */
843 nm = XSTRING_DATA (name); 833 nm = XSTRING_DATA (name);
844 834
845 #ifdef WINDOWSNT 835 #ifdef WIN32_NATIVE
846 /* We will force directory separators to be either all \ or /, so make 836 /* We will force directory separators to be either all \ or /, so make
847 a local copy to modify, even if there ends up being no change. */ 837 a local copy to modify, even if there ends up being no change. */
848 nm = strcpy (alloca (strlen (nm) + 1), nm); 838 nm = strcpy ((char *)alloca (strlen ((char *)nm) + 1), (char *)nm);
849 839
850 /* Find and remove drive specifier if present; this makes nm absolute 840 /* Find and remove drive specifier if present; this makes nm absolute
851 even if the rest of the name appears to be relative. */ 841 even if the rest of the name appears to be relative. */
852 { 842 {
853 Bufbyte *colon = strrchr (nm, ':'); 843 Bufbyte *colon = (Bufbyte *) strrchr ((char *)nm, ':');
854 844
855 if (colon) 845 if (colon)
856 /* Only recognize colon as part of drive specifier if there is a 846 /* Only recognize colon as part of drive specifier if there is a
857 single alphabetic character preceding the colon (and if the 847 single alphabetic character preceding the colon (and if the
858 character before the drive letter, if present, is a directory 848 character before the drive letter, if present, is a directory
878 /* If we see "c://somedir", we want to strip the first slash after the 868 /* If we see "c://somedir", we want to strip the first slash after the
879 colon when stripping the drive letter. Otherwise, this expands to 869 colon when stripping the drive letter. Otherwise, this expands to
880 "//somedir". */ 870 "//somedir". */
881 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) 871 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
882 nm++; 872 nm++;
883 #endif /* WINDOWSNT */ 873 #endif /* WIN32_NATIVE */
884 874
885 /* If nm is absolute, look for /./ or /../ sequences; if none are 875 /* If nm is absolute, look for /./ or /../ sequences; if none are
886 found, we can probably return right away. We will avoid allocating 876 found, we can probably return right away. We will avoid allocating
887 a new string if name is already fully expanded. */ 877 a new string if name is already fully expanded. */
888 if ( 878 if (
889 IS_DIRECTORY_SEP (nm[0]) 879 IS_DIRECTORY_SEP (nm[0])
890 #ifdef WINDOWSNT 880 #ifdef WIN32_NATIVE
891 && (drive || IS_DIRECTORY_SEP (nm[1])) 881 && (drive || IS_DIRECTORY_SEP (nm[1]))
892 #endif 882 #endif
893 ) 883 )
894 { 884 {
895 /* If it turns out that the filename we want to return is just a 885 /* If it turns out that the filename we want to return is just a
916 lose = 1; 906 lose = 1;
917 p++; 907 p++;
918 } 908 }
919 if (!lose) 909 if (!lose)
920 { 910 {
921 #ifdef WINDOWSNT 911 #ifdef WIN32_NATIVE
922 /* Make sure directories are all separated with / or \ as 912 /* Make sure directories are all separated with / or \ as
923 desired, but avoid allocation of a new string when not 913 desired, but avoid allocation of a new string when not
924 required. */ 914 required. */
925 CORRECT_DIR_SEPS (nm); 915 CORRECT_DIR_SEPS (nm);
926 if (IS_DIRECTORY_SEP (nm[1])) 916 if (IS_DIRECTORY_SEP (nm[1]))
933 { 923 {
934 name = make_string (nm - 2, p - nm + 2); 924 name = make_string (nm - 2, p - nm + 2);
935 XSTRING_DATA (name)[0] = DRIVE_LETTER (drive); 925 XSTRING_DATA (name)[0] = DRIVE_LETTER (drive);
936 XSTRING_DATA (name)[1] = ':'; 926 XSTRING_DATA (name)[1] = ':';
937 } 927 }
938 return name; 928 RETURN_UNGCPRO (name);
939 #else /* not WINDOWSNT */ 929 #else /* not WIN32_NATIVE */
940 if (nm == XSTRING_DATA (name)) 930 if (nm == XSTRING_DATA (name))
941 return name; 931 RETURN_UNGCPRO (name);
942 return build_string ((char *) nm); 932 RETURN_UNGCPRO (build_string ((char *) nm));
943 #endif /* not WINDOWSNT */ 933 #endif /* not WIN32_NATIVE */
944 } 934 }
945 } 935 }
946 936
947 /* At this point, nm might or might not be an absolute file name. We 937 /* At this point, nm might or might not be an absolute file name. We
948 need to expand ~ or ~user if present, otherwise prefix nm with 938 need to expand ~ or ~user if present, otherwise prefix nm with
975 TO_INTERNAL_FORMAT (C_STRING, newdir_external, 965 TO_INTERNAL_FORMAT (C_STRING, newdir_external,
976 C_STRING_ALLOCA, (* ((char **) &newdir)), 966 C_STRING_ALLOCA, (* ((char **) &newdir)),
977 Qfile_name); 967 Qfile_name);
978 968
979 nm++; 969 nm++;
980 #ifdef WINDOWSNT 970 #ifdef WIN32_NATIVE
981 collapse_newdir = 0; 971 collapse_newdir = 0;
982 #endif 972 #endif
983 } 973 }
984 else /* ~user/filename */ 974 else /* ~user/filename */
985 { 975 {
994 names the user who runs this instance of XEmacs. While 984 names the user who runs this instance of XEmacs. While
995 NT is single-user (for the moment) you still can have 985 NT is single-user (for the moment) you still can have
996 multiple user profiles users defined, each with its HOME. 986 multiple user profiles users defined, each with its HOME.
997 Therefore, the following should be reworked to handle 987 Therefore, the following should be reworked to handle
998 this case. */ 988 this case. */
999 #ifdef WINDOWSNT 989 #ifdef WIN32_NATIVE
1000 /* Now if the file given is "~foo/file" and HOME="c:/", then 990 /* Now if the file given is "~foo/file" and HOME="c:/", then
1001 we want the file to be named "c:/file" ("~foo" becomes 991 we want the file to be named "c:/file" ("~foo" becomes
1002 "c:/"). The variable o has "~foo", so we can use the 992 "c:/"). The variable o has "~foo", so we can use the
1003 length of that string to offset nm. August Hill, 31 Aug 993 length of that string to offset nm. August Hill, 31 Aug
1004 1998. */ 994 1998. */
1005 newdir = (Bufbyte *) get_home_directory(); 995 newdir = (Bufbyte *) get_home_directory();
1006 dostounix_filename (newdir); 996 dostounix_filename (newdir);
1007 nm += strlen(o) + 1; 997 nm += strlen(o) + 1;
1008 #else /* not WINDOWSNT */ 998 #else /* not WIN32_NATIVE */
1009 #ifdef __CYGWIN32__ 999 #ifdef CYGWIN
1010 if ((user = user_login_name (NULL)) != NULL) 1000 if ((user = user_login_name (NULL)) != NULL)
1011 { 1001 {
1012 /* Does the user login name match the ~name? */ 1002 /* Does the user login name match the ~name? */
1013 if (strcmp (user, (char *) o + 1) == 0) 1003 if (strcmp (user, (char *) o + 1) == 0)
1014 { 1004 {
1016 nm = p; 1006 nm = p;
1017 } 1007 }
1018 } 1008 }
1019 if (! newdir) 1009 if (! newdir)
1020 { 1010 {
1021 #endif /* __CYGWIN32__ */ 1011 #endif /* CYGWIN */
1022 /* Jamie reports that getpwnam() can get wedged by SIGIO/SIGALARM 1012 /* Jamie reports that getpwnam() can get wedged by SIGIO/SIGALARM
1023 occurring in it. (It can call select()). */ 1013 occurring in it. (It can call select()). */
1024 slow_down_interrupts (); 1014 slow_down_interrupts ();
1025 pw = (struct passwd *) getpwnam ((char *) o + 1); 1015 pw = (struct passwd *) getpwnam ((char *) o + 1);
1026 speed_up_interrupts (); 1016 speed_up_interrupts ();
1027 if (pw) 1017 if (pw)
1028 { 1018 {
1029 newdir = (Bufbyte *) pw -> pw_dir; 1019 newdir = (Bufbyte *) pw -> pw_dir;
1030 nm = p; 1020 nm = p;
1031 } 1021 }
1032 #ifdef __CYGWIN32__ 1022 #ifdef CYGWIN
1033 } 1023 }
1034 #endif 1024 #endif
1035 #endif /* not WINDOWSNT */ 1025 #endif /* not WIN32_NATIVE */
1036 1026
1037 /* If we don't find a user of that name, leave the name 1027 /* If we don't find a user of that name, leave the name
1038 unchanged; don't move nm forward to p. */ 1028 unchanged; don't move nm forward to p. */
1039 } 1029 }
1040 } 1030 }
1041 1031
1042 #ifdef WINDOWSNT 1032 #ifdef WIN32_NATIVE
1043 /* On DOS and Windows, nm is absolute if a drive name was specified; 1033 /* On DOS and Windows, nm is absolute if a drive name was specified;
1044 use the drive's current directory as the prefix if needed. */ 1034 use the drive's current directory as the prefix if needed. */
1045 if (!newdir && drive) 1035 if (!newdir && drive)
1046 { 1036 {
1047 /* Get default directory if needed to make nm absolute. */ 1037 /* Get default directory if needed to make nm absolute. */
1048 if (!IS_DIRECTORY_SEP (nm[0])) 1038 if (!IS_DIRECTORY_SEP (nm[0]))
1049 { 1039 {
1050 newdir = alloca (MAXPATHLEN + 1); 1040 newdir = alloca (MAXPATHLEN + 1);
1051 if (!getdefdir (toupper (drive) - 'A' + 1, newdir)) 1041 if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN))
1052 newdir = NULL; 1042 newdir = NULL;
1053 } 1043 }
1054 if (!newdir) 1044 if (!newdir)
1055 { 1045 {
1056 /* Either nm starts with /, or drive isn't mounted. */ 1046 /* Either nm starts with /, or drive isn't mounted. */
1059 newdir[1] = ':'; 1049 newdir[1] = ':';
1060 newdir[2] = '/'; 1050 newdir[2] = '/';
1061 newdir[3] = 0; 1051 newdir[3] = 0;
1062 } 1052 }
1063 } 1053 }
1064 #endif /* WINDOWSNT */ 1054 #endif /* WIN32_NATIVE */
1065 1055
1066 /* Finally, if no prefix has been specified and nm is not absolute, 1056 /* Finally, if no prefix has been specified and nm is not absolute,
1067 then it must be expanded relative to default_directory. */ 1057 then it must be expanded relative to default_directory. */
1068 1058
1069 if (1 1059 if (1
1070 #ifndef WINDOWSNT 1060 #ifndef WIN32_NATIVE
1071 /* /... alone is not absolute on DOS and Windows. */ 1061 /* /... alone is not absolute on DOS and Windows. */
1072 && !IS_DIRECTORY_SEP (nm[0]) 1062 && !IS_DIRECTORY_SEP (nm[0])
1073 #else 1063 #else
1074 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) 1064 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1075 #endif 1065 #endif
1076 && !newdir) 1066 && !newdir)
1077 { 1067 {
1078 newdir = XSTRING_DATA (default_directory); 1068 newdir = XSTRING_DATA (default_directory);
1079 } 1069 }
1080 1070
1081 #ifdef WINDOWSNT 1071 #ifdef WIN32_NATIVE
1082 if (newdir) 1072 if (newdir)
1083 { 1073 {
1084 /* First ensure newdir is an absolute name. */ 1074 /* First ensure newdir is an absolute name. */
1085 if ( 1075 if (
1086 /* Detect MSDOS file names with drive specifiers. */ 1076 /* Detect Windows file names with drive specifiers. */
1087 ! (IS_DRIVE (newdir[0]) 1077 ! (IS_DRIVE (newdir[0])
1088 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2])) 1078 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1089 /* Detect Windows file names in UNC format. */ 1079 /* Detect Windows file names in UNC format. */
1090 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])) 1080 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1091 /* Detect drive spec by itself */ 1081 /* Detect drive spec by itself */
1111 nm = tmp; 1101 nm = tmp;
1112 } 1102 }
1113 newdir = alloca (MAXPATHLEN + 1); 1103 newdir = alloca (MAXPATHLEN + 1);
1114 if (drive) 1104 if (drive)
1115 { 1105 {
1116 if (!getdefdir (toupper (drive) - 'A' + 1, newdir)) 1106 if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN))
1117 newdir = "/"; 1107 newdir = "/";
1118 } 1108 }
1119 else 1109 else
1120 getwd (newdir); 1110 getwd (newdir);
1121 } 1111 }
1142 } 1132 }
1143 else 1133 else
1144 newdir = ""; 1134 newdir = "";
1145 } 1135 }
1146 } 1136 }
1147 #endif /* WINDOWSNT */ 1137 #endif /* WIN32_NATIVE */
1148 1138
1149 if (newdir) 1139 if (newdir)
1150 { 1140 {
1151 /* Get rid of any slash at the end of newdir, unless newdir is 1141 /* Get rid of any slash at the end of newdir, unless newdir is
1152 just // (an incomplete UNC name). */ 1142 just // (an incomplete UNC name). */
1153 length = strlen ((char *) newdir); 1143 length = strlen ((char *) newdir);
1154 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) 1144 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
1155 #ifdef WINDOWSNT 1145 #ifdef WIN32_NATIVE
1156 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) 1146 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1157 #endif 1147 #endif
1158 ) 1148 )
1159 { 1149 {
1160 Bufbyte *temp = (Bufbyte *) alloca (length); 1150 Bufbyte *temp = (Bufbyte *) alloca (length);
1167 else 1157 else
1168 tlen = 0; 1158 tlen = 0;
1169 1159
1170 /* Now concatenate the directory and name to new space in the stack frame */ 1160 /* Now concatenate the directory and name to new space in the stack frame */
1171 tlen += strlen ((char *) nm) + 1; 1161 tlen += strlen ((char *) nm) + 1;
1172 #ifdef WINDOWSNT 1162 #ifdef WIN32_NATIVE
1173 /* Add reserved space for drive name. (The Microsoft x86 compiler 1163 /* Add reserved space for drive name. (The Microsoft x86 compiler
1174 produces incorrect code if the following two lines are combined.) */ 1164 produces incorrect code if the following two lines are combined.) */
1175 target = (Bufbyte *) alloca (tlen + 2); 1165 target = (Bufbyte *) alloca (tlen + 2);
1176 target += 2; 1166 target += 2;
1177 #else /* not WINDOWSNT */ 1167 #else /* not WIN32_NATIVE */
1178 target = (Bufbyte *) alloca (tlen); 1168 target = (Bufbyte *) alloca (tlen);
1179 #endif /* not WINDOWSNT */ 1169 #endif /* not WIN32_NATIVE */
1180 *target = 0; 1170 *target = 0;
1181 1171
1182 if (newdir) 1172 if (newdir)
1183 { 1173 {
1184 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) 1174 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1223 /* Keep initial / only if this is the whole name. */ 1213 /* Keep initial / only if this is the whole name. */
1224 if (o == target && IS_ANY_SEP (*o) && p[3] == 0) 1214 if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
1225 ++o; 1215 ++o;
1226 p += 3; 1216 p += 3;
1227 } 1217 }
1228 #ifdef WINDOWSNT 1218 #ifdef WIN32_NATIVE
1229 /* if drive is set, we're not dealing with an UNC, so 1219 /* if drive is set, we're not dealing with an UNC, so
1230 multiple dir-seps are redundant (and reportedly cause trouble 1220 multiple dir-seps are redundant (and reportedly cause trouble
1231 under win95) */ 1221 under win95) */
1232 else if (drive && IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])) 1222 else if (drive && IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]))
1233 ++p; 1223 ++p;
1236 { 1226 {
1237 *o++ = *p++; 1227 *o++ = *p++;
1238 } 1228 }
1239 } 1229 }
1240 1230
1241 #ifdef WINDOWSNT 1231 #ifdef WIN32_NATIVE
1242 /* At last, set drive name, except for network file name. */ 1232 /* At last, set drive name, except for network file name. */
1243 if (drive) 1233 if (drive)
1244 { 1234 {
1245 target -= 2; 1235 target -= 2;
1246 target[0] = DRIVE_LETTER (drive); 1236 target[0] = DRIVE_LETTER (drive);
1249 else 1239 else
1250 { 1240 {
1251 assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])); 1241 assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1]));
1252 } 1242 }
1253 CORRECT_DIR_SEPS (target); 1243 CORRECT_DIR_SEPS (target);
1254 #endif /* WINDOWSNT */ 1244 #endif /* WIN32_NATIVE */
1255 1245
1256 return make_string (target, o - target); 1246 RETURN_UNGCPRO (make_string (target, o - target));
1257 } 1247 }
1258
1259 #if 0 /* FSFmacs */
1260 /* another older version of expand-file-name; */
1261 #endif
1262 1248
1263 DEFUN ("file-truename", Ffile_truename, 1, 2, 0, /* 1249 DEFUN ("file-truename", Ffile_truename, 1, 2, 0, /*
1264 Return the canonical name of the given FILE. 1250 Return the canonical name of the given FILE.
1265 Second arg DEFAULT is directory to start with if FILE is relative 1251 Second arg DEFAULT is directory to start with if FILE is relative
1266 (does not start with slash); if DEFAULT is nil or missing, 1252 (does not start with slash); if DEFAULT is nil or missing,
1268 No component of the resulting pathname will be a symbolic link, as 1254 No component of the resulting pathname will be a symbolic link, as
1269 in the realpath() function. 1255 in the realpath() function.
1270 */ 1256 */
1271 (filename, default_)) 1257 (filename, default_))
1272 { 1258 {
1273 /* This function can GC. GC checked 1997.04.06. */ 1259 /* This function can GC. GC checked 2000-07-28 ben. */
1274 Lisp_Object expanded_name; 1260 Lisp_Object expanded_name;
1275 Lisp_Object handler;
1276 struct gcpro gcpro1; 1261 struct gcpro gcpro1;
1277 1262
1278 CHECK_STRING (filename); 1263 CHECK_STRING (filename);
1279 1264
1280 expanded_name = Fexpand_file_name (filename, default_); 1265 expanded_name = Fexpand_file_name (filename, default_);
1281 1266
1282 if (!STRINGP (expanded_name)) 1267 if (!STRINGP (expanded_name))
1283 return Qnil; 1268 return Qnil;
1284 1269
1285 GCPRO1 (expanded_name); 1270 GCPRO1 (expanded_name);
1286 handler = Ffind_file_name_handler (expanded_name, Qfile_truename); 1271
1287 UNGCPRO; 1272 {
1288 1273 Lisp_Object handler =
1289 if (!NILP (handler)) 1274 Ffind_file_name_handler (expanded_name, Qfile_truename);
1290 return call2_check_string (handler, Qfile_truename, expanded_name); 1275
1276 if (!NILP (handler))
1277 RETURN_UNGCPRO
1278 (call2_check_string (handler, Qfile_truename, expanded_name));
1279 }
1291 1280
1292 { 1281 {
1293 char resolved_path[MAXPATHLEN]; 1282 char resolved_path[MAXPATHLEN];
1294 Extbyte *path; 1283 Extbyte *path;
1295 Extbyte *p; 1284 Extbyte *p;
1299 ALLOCA, (path, elen), 1288 ALLOCA, (path, elen),
1300 Qfile_name); 1289 Qfile_name);
1301 p = path; 1290 p = path;
1302 if (elen > MAXPATHLEN) 1291 if (elen > MAXPATHLEN)
1303 goto toolong; 1292 goto toolong;
1304 1293
1305 /* Try doing it all at once. */ 1294 /* Try doing it all at once. */
1306 /* !! Does realpath() Mule-encapsulate? 1295 /* !! Does realpath() Mule-encapsulate?
1307 Answer: Nope! So we do it above */ 1296 Answer: Nope! So we do it above */
1308 if (!xrealpath ((char *) path, resolved_path)) 1297 if (!xrealpath ((char *) path, resolved_path))
1309 { 1298 {
1310 /* Didn't resolve it -- have to do it one component at a time. */ 1299 /* Didn't resolve it -- have to do it one component at a time. */
1311 /* "realpath" is a typically useless, stupid un*x piece of crap. 1300 /* "realpath" is a typically useless, stupid un*x piece of crap.
1312 It claims to return a useful value in the "error" case, but since 1301 It claims to return a useful value in the "error" case, but since
1313 there is no indication provided of how far along the pathname 1302 there is no indication provided of how far along the pathname
1314 the function went before erring, there is no way to use the 1303 the function went before erring, there is no way to use the
1315 partial result returned. What a piece of junk. */ 1304 partial result returned. What a piece of junk.
1305
1306 The above comment refers to historical versions of
1307 realpath(). The Unix98 specs state:
1308
1309 "On successful completion, realpath() returns a
1310 pointer to the resolved name. Otherwise, realpath()
1311 returns a null pointer and sets errno to indicate the
1312 error, and the contents of the buffer pointed to by
1313 resolved_name are undefined."
1314
1315 Since we depend on undocumented semantics of various system realpath()s,
1316 we just use our own version in realpath.c. */
1316 for (;;) 1317 for (;;)
1317 { 1318 {
1318 p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path)); 1319 p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path));
1319 if (p) 1320 if (p)
1320 *p = 0; 1321 *p = 0;
1321 1322
1322 /* memset (resolved_path, 0, sizeof (resolved_path)); */
1323 if (xrealpath ((char *) path, resolved_path)) 1323 if (xrealpath ((char *) path, resolved_path))
1324 { 1324 {
1325 if (p) 1325 if (p)
1326 *p = '/'; 1326 *p = '/';
1327 else 1327 else
1335 int rlen = strlen (resolved_path); 1335 int rlen = strlen (resolved_path);
1336 1336
1337 /* "On failure, it returns NULL, sets errno to indicate 1337 /* "On failure, it returns NULL, sets errno to indicate
1338 the error, and places in resolved_path the absolute pathname 1338 the error, and places in resolved_path the absolute pathname
1339 of the path component which could not be resolved." */ 1339 of the path component which could not be resolved." */
1340 if (p) 1340
1341 if (p)
1341 { 1342 {
1342 int plen = elen - (p - path); 1343 int plen = elen - (p - path);
1343 1344
1344 if (rlen > 1 && resolved_path[rlen - 1] == '/') 1345 if (rlen > 1 && resolved_path[rlen - 1] == '/')
1345 rlen = rlen - 1; 1346 rlen = rlen - 1;
1356 goto lose; 1357 goto lose;
1357 } 1358 }
1358 } 1359 }
1359 1360
1360 { 1361 {
1362 Lisp_Object resolved_name;
1361 int rlen = strlen (resolved_path); 1363 int rlen = strlen (resolved_path);
1362 if (elen > 0 && XSTRING_BYTE (expanded_name, elen - 1) == '/' 1364 if (elen > 0 && XSTRING_BYTE (expanded_name, elen - 1) == '/'
1363 && !(rlen > 0 && resolved_path[rlen - 1] == '/')) 1365 && !(rlen > 0 && resolved_path[rlen - 1] == '/'))
1364 { 1366 {
1365 if (rlen + 1 > countof (resolved_path)) 1367 if (rlen + 1 > countof (resolved_path))
1366 goto toolong; 1368 goto toolong;
1367 resolved_path[rlen] = '/'; 1369 resolved_path[rlen++] = '/';
1368 resolved_path[rlen + 1] = 0; 1370 resolved_path[rlen] = '\0';
1369 rlen = rlen + 1;
1370 } 1371 }
1371 return make_ext_string ((Bufbyte *) resolved_path, rlen, Qbinary); 1372 TO_INTERNAL_FORMAT (DATA, (resolved_path, rlen),
1373 LISP_STRING, resolved_name,
1374 Qfile_name);
1375 RETURN_UNGCPRO (resolved_name);
1372 } 1376 }
1373 1377
1374 toolong: 1378 toolong:
1375 errno = ENAMETOOLONG; 1379 errno = ENAMETOOLONG;
1376 goto lose; 1380 goto lose;
1377 lose: 1381 lose:
1378 report_file_error ("Finding truename", list1 (expanded_name)); 1382 report_file_error ("Finding truename", list1 (expanded_name));
1379 } 1383 }
1380 return Qnil; /* suppress compiler warning */ 1384 RETURN_UNGCPRO (Qnil);
1381 } 1385 }
1382 1386
1383 1387
1384 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 1, 1, 0, /* 1388 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 1, 1, 0, /*
1385 Substitute environment variables referred to in FILENAME. 1389 Substitute environment variables referred to in FILENAME.
1390 If `/~' appears, all of FILENAME through that `/' is discarded. 1394 If `/~' appears, all of FILENAME through that `/' is discarded.
1391 1395
1392 */ 1396 */
1393 (string)) 1397 (string))
1394 { 1398 {
1395 /* This function can GC. GC checked 1997.04.06. */ 1399 /* This function can GC. GC checked 2000-07-28 ben. */
1396 Bufbyte *nm; 1400 Bufbyte *nm;
1397 1401
1398 Bufbyte *s, *p, *o, *x, *endp; 1402 Bufbyte *s, *p, *o, *x, *endp;
1399 Bufbyte *target = 0; 1403 Bufbyte *target = 0;
1400 int total = 0; 1404 int total = 0;
1417 /* If /~ or // appears, discard everything through first slash. */ 1421 /* If /~ or // appears, discard everything through first slash. */
1418 1422
1419 for (p = nm; p != endp; p++) 1423 for (p = nm; p != endp; p++)
1420 { 1424 {
1421 if ((p[0] == '~' 1425 if ((p[0] == '~'
1422 #if defined (WINDOWSNT) || defined (__CYGWIN32__) 1426 #if defined (WIN32_NATIVE) || defined (CYGWIN)
1423 /* // at start of file name is meaningful in WindowsNT systems */ 1427 /* // at start of file name is meaningful in WindowsNT systems */
1424 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm) 1428 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1425 #else /* not (WINDOWSNT || __CYGWIN32__) */ 1429 #else /* not (WIN32_NATIVE || CYGWIN) */
1426 || IS_DIRECTORY_SEP (p[0]) 1430 || IS_DIRECTORY_SEP (p[0])
1427 #endif /* not (WINDOWSNT || __CYGWIN32__) */ 1431 #endif /* not (WIN32_NATIVE || CYGWIN) */
1428 ) 1432 )
1429 && p != nm 1433 && p != nm
1430 && (IS_DIRECTORY_SEP (p[-1]))) 1434 && (IS_DIRECTORY_SEP (p[-1])))
1431 { 1435 {
1432 nm = p; 1436 nm = p;
1433 substituted = 1; 1437 substituted = 1;
1434 } 1438 }
1435 #ifdef WINDOWSNT 1439 #ifdef WIN32_NATIVE
1436 /* see comment in expand-file-name about drive specifiers */ 1440 /* see comment in expand-file-name about drive specifiers */
1437 else if (IS_DRIVE (p[0]) && p[1] == ':' 1441 else if (IS_DRIVE (p[0]) && p[1] == ':'
1438 && p > nm && IS_DIRECTORY_SEP (p[-1])) 1442 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1439 { 1443 {
1440 nm = p; 1444 nm = p;
1441 substituted = 1; 1445 substituted = 1;
1442 } 1446 }
1443 #endif /* WINDOWSNT */ 1447 #endif /* WIN32_NATIVE */
1444 } 1448 }
1445 1449
1446 /* See if any variables are substituted into the string 1450 /* See if any variables are substituted into the string
1447 and find the total length of their values in `total' */ 1451 and find the total length of their values in `total' */
1448 1452
1478 1482
1479 /* Copy out the variable name */ 1483 /* Copy out the variable name */
1480 target = (Bufbyte *) alloca (s - o + 1); 1484 target = (Bufbyte *) alloca (s - o + 1);
1481 strncpy ((char *) target, (char *) o, s - o); 1485 strncpy ((char *) target, (char *) o, s - o);
1482 target[s - o] = 0; 1486 target[s - o] = 0;
1483 #ifdef WINDOWSNT 1487 #ifdef WIN32_NATIVE
1484 strupr (target); /* $home == $HOME etc. */ 1488 strupr (target); /* $home == $HOME etc. */
1485 #endif /* WINDOWSNT */ 1489 #endif /* WIN32_NATIVE */
1486 1490
1487 /* Get variable value */ 1491 /* Get variable value */
1488 o = (Bufbyte *) egetenv ((char *) target); 1492 o = (Bufbyte *) egetenv ((char *) target);
1489 if (!o) goto badvar; 1493 if (!o) goto badvar;
1490 total += strlen ((char *) o); 1494 total += strlen ((char *) o);
1529 1533
1530 /* Copy out the variable name */ 1534 /* Copy out the variable name */
1531 target = (Bufbyte *) alloca (s - o + 1); 1535 target = (Bufbyte *) alloca (s - o + 1);
1532 strncpy ((char *) target, (char *) o, s - o); 1536 strncpy ((char *) target, (char *) o, s - o);
1533 target[s - o] = 0; 1537 target[s - o] = 0;
1534 #ifdef WINDOWSNT 1538 #ifdef WIN32_NATIVE
1535 strupr (target); /* $home == $HOME etc. */ 1539 strupr (target); /* $home == $HOME etc. */
1536 #endif /* WINDOWSNT */ 1540 #endif /* WIN32_NATIVE */
1537 1541
1538 /* Get variable value */ 1542 /* Get variable value */
1539 o = (Bufbyte *) egetenv ((char *) target); 1543 o = (Bufbyte *) egetenv ((char *) target);
1540 if (!o) 1544 if (!o)
1541 goto badvar; 1545 goto badvar;
1548 1552
1549 /* If /~ or // appears, discard everything through first slash. */ 1553 /* If /~ or // appears, discard everything through first slash. */
1550 1554
1551 for (p = xnm; p != x; p++) 1555 for (p = xnm; p != x; p++)
1552 if ((p[0] == '~' 1556 if ((p[0] == '~'
1553 #if defined (WINDOWSNT) 1557 #if defined (WIN32_NATIVE)
1554 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm) 1558 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
1555 #else /* not WINDOWSNT */ 1559 #else /* not WIN32_NATIVE */
1556 || IS_DIRECTORY_SEP (p[0]) 1560 || IS_DIRECTORY_SEP (p[0])
1557 #endif /* not WINDOWSNT */ 1561 #endif /* not WIN32_NATIVE */
1558 ) 1562 )
1559 /* don't do p[-1] if that would go off the beginning --jwz */ 1563 /* don't do p[-1] if that would go off the beginning --jwz */
1560 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1])) 1564 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1]))
1561 xnm = p; 1565 xnm = p;
1562 #ifdef WINDOWSNT 1566 #ifdef WIN32_NATIVE
1563 else if (IS_DRIVE (p[0]) && p[1] == ':' 1567 else if (IS_DRIVE (p[0]) && p[1] == ':'
1564 && p > nm && IS_DIRECTORY_SEP (p[-1])) 1568 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1565 xnm = p; 1569 xnm = p;
1566 #endif 1570 #endif
1567 1571
1568 return make_string (xnm, x - xnm); 1572 return make_string (xnm, x - xnm);
1569 1573
1570 badsubst: 1574 badsubst:
1571 error ("Bad format environment-variable substitution"); 1575 syntax_error ("Bad format environment-variable substitution", string);
1572 missingclose: 1576 missingclose:
1573 error ("Missing \"}\" in environment-variable substitution"); 1577 syntax_error ("Missing \"}\" in environment-variable substitution",
1578 string);
1574 badvar: 1579 badvar:
1575 error ("Substituting nonexistent environment variable \"%s\"", 1580 syntax_error_2 ("Substituting nonexistent environment variable",
1576 target); 1581 string, build_string (target));
1577 1582
1578 /* NOTREACHED */ 1583 /* NOTREACHED */
1579 return Qnil; /* suppress compiler warning */ 1584 return Qnil; /* suppress compiler warning */
1580 } 1585 }
1581 1586
1583 (directory-file-name (expand-file-name FOO)). */ 1588 (directory-file-name (expand-file-name FOO)). */
1584 1589
1585 Lisp_Object 1590 Lisp_Object
1586 expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir) 1591 expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir)
1587 { 1592 {
1588 /* This function can call lisp */ 1593 /* This function can call Lisp. GC checked 2000-07-28 ben */
1589 Lisp_Object abspath; 1594 Lisp_Object abspath;
1590 struct gcpro gcpro1; 1595 struct gcpro gcpro1;
1591 1596
1592 abspath = Fexpand_file_name (filename, defdir); 1597 abspath = Fexpand_file_name (filename, defdir);
1593 GCPRO1 (abspath); 1598 GCPRO1 (abspath);
1609 to alter the file. 1614 to alter the file.
1610 *STATPTR is used to store the stat information if the file exists. 1615 *STATPTR is used to store the stat information if the file exists.
1611 If the file does not exist, STATPTR->st_mode is set to 0. */ 1616 If the file does not exist, STATPTR->st_mode is set to 0. */
1612 1617
1613 static void 1618 static void
1614 barf_or_query_if_file_exists (Lisp_Object absname, CONST char *querystring, 1619 barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
1615 int interactive, struct stat *statptr) 1620 int interactive, struct stat *statptr)
1616 { 1621 {
1617 /* This function can GC. GC checked 1997.04.06. */ 1622 /* This function can call Lisp. GC checked 2000-07-28 ben */
1618 struct stat statbuf; 1623 struct stat statbuf;
1619 1624
1620 /* stat is a good way to tell whether the file exists, 1625 /* stat is a good way to tell whether the file exists,
1621 regardless of what access permissions it has. */ 1626 regardless of what access permissions it has. */
1622 if (stat ((char *) XSTRING_DATA (absname), &statbuf) >= 0) 1627 if (xemacs_stat ((char *) XSTRING_DATA (absname), &statbuf) >= 0)
1623 { 1628 {
1624 Lisp_Object tem; 1629 Lisp_Object tem;
1625 1630
1626 if (interactive) 1631 if (interactive)
1627 { 1632 {
1628 Lisp_Object prompt; 1633 Lisp_Object prompt;
1629 struct gcpro gcpro1; 1634 struct gcpro gcpro1;
1630 1635
1631 prompt = emacs_doprnt_string_c 1636 prompt = emacs_doprnt_string_c
1632 ((CONST Bufbyte *) GETTEXT ("File %s already exists; %s anyway? "), 1637 ((const Bufbyte *) GETTEXT ("File %s already exists; %s anyway? "),
1633 Qnil, -1, XSTRING_DATA (absname), 1638 Qnil, -1, XSTRING_DATA (absname),
1634 GETTEXT (querystring)); 1639 GETTEXT (querystring));
1635 1640
1636 GCPRO1 (prompt); 1641 GCPRO1 (prompt);
1637 tem = call1 (Qyes_or_no_p, prompt); 1642 tem = call1 (Qyes_or_no_p, prompt);
1666 last-modified time as the old one. (This works on only some systems.) 1671 last-modified time as the old one. (This works on only some systems.)
1667 A prefix arg makes KEEP-TIME non-nil. 1672 A prefix arg makes KEEP-TIME non-nil.
1668 */ 1673 */
1669 (filename, newname, ok_if_already_exists, keep_time)) 1674 (filename, newname, ok_if_already_exists, keep_time))
1670 { 1675 {
1671 /* This function can GC. GC checked 1997.04.06. */ 1676 /* This function can call Lisp. GC checked 2000-07-28 ben */
1672 int ifd, ofd, n; 1677 int ifd, ofd, n;
1673 char buf[16 * 1024]; 1678 char buf[16 * 1024];
1674 struct stat st, out_st; 1679 struct stat st, out_st;
1675 Lisp_Object handler; 1680 Lisp_Object handler;
1676 int speccount = specpdl_depth (); 1681 int speccount = specpdl_depth ();
1708 1713
1709 args[0] = newname; 1714 args[0] = newname;
1710 args[1] = Qnil; args[2] = Qnil; 1715 args[1] = Qnil; args[2] = Qnil;
1711 NGCPRO1 (*args); 1716 NGCPRO1 (*args);
1712 ngcpro1.nvars = 3; 1717 ngcpro1.nvars = 3;
1713 if (XSTRING_BYTE (newname, XSTRING_LENGTH (newname) - 1) != '/') 1718 if (!IS_DIRECTORY_SEP (XSTRING_BYTE (newname,
1714 args[i++] = build_string ("/"); 1719 XSTRING_LENGTH (newname) - 1)))
1720
1721 args[i++] = Fchar_to_string (Vdirectory_sep_char);
1715 args[i++] = Ffile_name_nondirectory (filename); 1722 args[i++] = Ffile_name_nondirectory (filename);
1716 newname = Fconcat (i, args); 1723 newname = Fconcat (i, args);
1717 NUNGCPRO; 1724 NUNGCPRO;
1718 } 1725 }
1719 1726
1720 if (NILP (ok_if_already_exists) 1727 if (NILP (ok_if_already_exists)
1721 || INTP (ok_if_already_exists)) 1728 || INTP (ok_if_already_exists))
1722 barf_or_query_if_file_exists (newname, "copy to it", 1729 barf_or_query_if_file_exists (newname, "copy to it",
1723 INTP (ok_if_already_exists), &out_st); 1730 INTP (ok_if_already_exists), &out_st);
1724 else if (stat ((CONST char *) XSTRING_DATA (newname), &out_st) < 0) 1731 else if (xemacs_stat ((const char *) XSTRING_DATA (newname), &out_st) < 0)
1725 out_st.st_mode = 0; 1732 out_st.st_mode = 0;
1726 1733
1727 ifd = interruptible_open ((char *) XSTRING_DATA (filename), O_RDONLY | OPEN_BINARY, 0); 1734 ifd = interruptible_open ((char *) XSTRING_DATA (filename), O_RDONLY | OPEN_BINARY, 0);
1728 if (ifd < 0) 1735 if (ifd < 0)
1729 report_file_error ("Opening input file", list1 (filename)); 1736 report_file_error ("Opening input file", list1 (filename));
1732 1739
1733 /* We can only copy regular files and symbolic links. Other files are not 1740 /* We can only copy regular files and symbolic links. Other files are not
1734 copyable by us. */ 1741 copyable by us. */
1735 input_file_statable_p = (fstat (ifd, &st) >= 0); 1742 input_file_statable_p = (fstat (ifd, &st) >= 0);
1736 1743
1737 #ifndef WINDOWSNT 1744 #ifndef WIN32_NATIVE
1738 if (out_st.st_mode != 0 1745 if (out_st.st_mode != 0
1739 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) 1746 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
1740 { 1747 {
1741 errno = 0; 1748 errno = 0;
1742 report_file_error ("Input and output files are the same", 1749 report_file_error ("Input and output files are the same",
1782 /* Closing the output clobbers the file times on some systems. */ 1789 /* Closing the output clobbers the file times on some systems. */
1783 if (close (ofd) < 0) 1790 if (close (ofd) < 0)
1784 report_file_error ("I/O error", list1 (newname)); 1791 report_file_error ("I/O error", list1 (newname));
1785 1792
1786 if (input_file_statable_p) 1793 if (input_file_statable_p)
1787 {
1788 if (!NILP (keep_time))
1789 { 1794 {
1790 EMACS_TIME atime, mtime; 1795 if (!NILP (keep_time))
1791 EMACS_SET_SECS_USECS (atime, st.st_atime, 0); 1796 {
1792 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0); 1797 EMACS_TIME atime, mtime;
1793 if (set_file_times ((char *) XSTRING_DATA (newname), atime, 1798 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
1794 mtime)) 1799 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
1795 report_file_error ("I/O error", list1 (newname)); 1800 if (set_file_times ((char *) XSTRING_DATA (newname), atime,
1801 mtime))
1802 report_file_error ("I/O error", list1 (newname));
1803 }
1804 chmod ((const char *) XSTRING_DATA (newname),
1805 st.st_mode & 07777);
1796 } 1806 }
1797 chmod ((CONST char *) XSTRING_DATA (newname),
1798 st.st_mode & 07777);
1799 }
1800 1807
1801 /* We'll close it by hand */ 1808 /* We'll close it by hand */
1802 XCAR (ofd_locative) = Qnil; 1809 XCAR (ofd_locative) = Qnil;
1803 1810
1804 /* Close ifd */ 1811 /* Close ifd */
1830 1837
1831 if (XSTRING_LENGTH (dirname_) > (Bytecount) (sizeof (dir) - 1)) 1838 if (XSTRING_LENGTH (dirname_) > (Bytecount) (sizeof (dir) - 1))
1832 { 1839 {
1833 return Fsignal (Qfile_error, 1840 return Fsignal (Qfile_error,
1834 list3 (build_translated_string ("Creating directory"), 1841 list3 (build_translated_string ("Creating directory"),
1835 build_translated_string ("pathame too long"), 1842 build_translated_string ("pathname too long"),
1836 dirname_)); 1843 dirname_));
1837 } 1844 }
1838 strncpy (dir, (char *) XSTRING_DATA (dirname_), 1845 strncpy (dir, (char *) XSTRING_DATA (dirname_),
1839 XSTRING_LENGTH (dirname_) + 1); 1846 XSTRING_LENGTH (dirname_) + 1);
1840 1847
1872 1879
1873 return Qnil; 1880 return Qnil;
1874 } 1881 }
1875 1882
1876 DEFUN ("delete-file", Fdelete_file, 1, 1, "fDelete file: ", /* 1883 DEFUN ("delete-file", Fdelete_file, 1, 1, "fDelete file: ", /*
1877 Delete specified file. One argument, a file name string. 1884 Delete the file named FILENAME (a string).
1878 If file has multiple names, it continues to exist with the other names. 1885 If FILENAME has multiple names, it continues to exist with the other names.
1879 */ 1886 */
1880 (filename)) 1887 (filename))
1881 { 1888 {
1882 /* This function can GC. GC checked 1997.04.06. */ 1889 /* This function can GC. GC checked 1997.04.06. */
1883 Lisp_Object handler; 1890 Lisp_Object handler;
1970 || INTP (ok_if_already_exists)) 1977 || INTP (ok_if_already_exists))
1971 barf_or_query_if_file_exists (newname, "rename to it", 1978 barf_or_query_if_file_exists (newname, "rename to it",
1972 INTP (ok_if_already_exists), 0); 1979 INTP (ok_if_already_exists), 0);
1973 1980
1974 /* Syncing with FSF 19.34.6 note: FSF does not have conditional code for 1981 /* Syncing with FSF 19.34.6 note: FSF does not have conditional code for
1975 WINDOWSNT here; I've removed it. --marcpa */ 1982 WIN32_NATIVE here; I've removed it. --marcpa */
1976 1983
1977 /* FSFmacs only calls rename() here under BSD 4.1, and calls 1984 /* We have configure check for rename() and emulate using
1978 link() and unlink() otherwise, but that's bogus. Sometimes 1985 link()/unlink() if necessary. */
1979 rename() succeeds where link()/unlink() fail, and we have
1980 configure check for rename() and emulate using link()/unlink()
1981 if necessary. */
1982 if (0 > rename ((char *) XSTRING_DATA (filename), 1986 if (0 > rename ((char *) XSTRING_DATA (filename),
1983 (char *) XSTRING_DATA (newname))) 1987 (char *) XSTRING_DATA (newname)))
1984 { 1988 {
1985 if (errno == EXDEV) 1989 if (errno == EXDEV)
1986 { 1990 {
2041 /* Syncing with FSF 19.34.6 note: FSF does not report a file error 2045 /* Syncing with FSF 19.34.6 note: FSF does not report a file error
2042 on NT here. --marcpa */ 2046 on NT here. --marcpa */
2043 /* But FSF #defines link as sys_link which is supplied in nt.c. We can't do 2047 /* But FSF #defines link as sys_link which is supplied in nt.c. We can't do
2044 that because sysfile.h defines sys_link depending on ENCAPSULATE_LINK. 2048 that because sysfile.h defines sys_link depending on ENCAPSULATE_LINK.
2045 Reverted to previous behavior pending a working fix. (jhar) */ 2049 Reverted to previous behavior pending a working fix. (jhar) */
2046 #if defined(WINDOWSNT) 2050 #if defined(WIN32_NATIVE)
2047 /* Windows does not support this operation. */ 2051 /* Windows does not support this operation. */
2048 report_file_error ("Adding new name", Flist (2, &filename)); 2052 report_file_error ("Adding new name", Flist (2, &filename));
2049 #else /* not defined(WINDOWSNT) */ 2053 #else /* not defined(WIN32_NATIVE) */
2050 2054
2051 unlink ((char *) XSTRING_DATA (newname)); 2055 unlink ((char *) XSTRING_DATA (newname));
2052 if (0 > link ((char *) XSTRING_DATA (filename), 2056 if (0 > link ((char *) XSTRING_DATA (filename),
2053 (char *) XSTRING_DATA (newname))) 2057 (char *) XSTRING_DATA (newname)))
2054 { 2058 {
2055 report_file_error ("Adding new name", 2059 report_file_error ("Adding new name",
2056 list2 (filename, newname)); 2060 list2 (filename, newname));
2057 } 2061 }
2058 #endif /* defined(WINDOWSNT) */ 2062 #endif /* defined(WIN32_NATIVE) */
2059 2063
2060 UNGCPRO; 2064 UNGCPRO;
2061 return Qnil; 2065 return Qnil;
2062 } 2066 }
2063 2067
2064 #ifdef S_IFLNK
2065 DEFUN ("make-symbolic-link", Fmake_symbolic_link, 2, 3, 2068 DEFUN ("make-symbolic-link", Fmake_symbolic_link, 2, 3,
2066 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np", /* 2069 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np", /*
2067 Make a symbolic link to FILENAME, named LINKNAME. Both args strings. 2070 Make a symbolic link to FILENAME, named LINKNAME. Both args strings.
2068 Signals a `file-already-exists' error if a file LINKNAME already exists 2071 Signals a `file-already-exists' error if a file LINKNAME already exists
2069 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil. 2072 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2071 This happens for interactive use with M-x. 2074 This happens for interactive use with M-x.
2072 */ 2075 */
2073 (filename, linkname, ok_if_already_exists)) 2076 (filename, linkname, ok_if_already_exists))
2074 { 2077 {
2075 /* This function can GC. GC checked 1997.06.04. */ 2078 /* This function can GC. GC checked 1997.06.04. */
2079 /* XEmacs change: run handlers even if local machine doesn't have symlinks */
2076 Lisp_Object handler; 2080 Lisp_Object handler;
2077 struct gcpro gcpro1, gcpro2; 2081 struct gcpro gcpro1, gcpro2;
2078 2082
2079 GCPRO2 (filename, linkname); 2083 GCPRO2 (filename, linkname);
2080 CHECK_STRING (filename); 2084 CHECK_STRING (filename);
2098 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link); 2102 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2099 if (!NILP (handler)) 2103 if (!NILP (handler))
2100 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename, 2104 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2101 linkname, ok_if_already_exists)); 2105 linkname, ok_if_already_exists));
2102 2106
2107 #ifdef S_IFLNK
2103 if (NILP (ok_if_already_exists) 2108 if (NILP (ok_if_already_exists)
2104 || INTP (ok_if_already_exists)) 2109 || INTP (ok_if_already_exists))
2105 barf_or_query_if_file_exists (linkname, "make it a link", 2110 barf_or_query_if_file_exists (linkname, "make it a link",
2106 INTP (ok_if_already_exists), 0); 2111 INTP (ok_if_already_exists), 0);
2107 2112
2110 (char *) XSTRING_DATA (linkname))) 2115 (char *) XSTRING_DATA (linkname)))
2111 { 2116 {
2112 report_file_error ("Making symbolic link", 2117 report_file_error ("Making symbolic link",
2113 list2 (filename, linkname)); 2118 list2 (filename, linkname));
2114 } 2119 }
2120 #endif /* S_IFLNK */
2121
2115 UNGCPRO; 2122 UNGCPRO;
2116 return Qnil; 2123 return Qnil;
2117 } 2124 }
2118 #endif /* S_IFLNK */
2119 2125
2120 #ifdef HPUX_NET 2126 #ifdef HPUX_NET
2121 2127
2122 DEFUN ("sysnetunam", Fsysnetunam, 2, 2, 0, /* 2128 DEFUN ("sysnetunam", Fsysnetunam, 2, 2, 0, /*
2123 Open a network connection to PATH using LOGIN as the login string. 2129 Open a network connection to PATH using LOGIN as the login string.
2132 CHECK_STRING (login); 2138 CHECK_STRING (login);
2133 2139
2134 /* netunam, being a strange-o system call only used once, is not 2140 /* netunam, being a strange-o system call only used once, is not
2135 encapsulated. */ 2141 encapsulated. */
2136 2142
2137 TO_EXTERNAL_FORMAT (LISP_STRING, path, C_STRING_ALLOCA, path_ext, Qfile_name); 2143 LISP_STRING_TO_EXTERNAL (path, path_ext, Qfile_name);
2138 TO_EXTERNAL_FORMAT (LISP_STRING, login, C_STRING_ALLOCA, login_ext, Qnative); 2144 LISP_STRING_TO_EXTERNAL (login, login_ext, Qnative);
2139 2145
2140 netresult = netunam (path_ext, login_ext); 2146 netresult = netunam (path_ext, login_ext);
2141 2147
2142 return netresult == -1 ? Qnil : Qt; 2148 return netresult == -1 ? Qnil : Qt;
2143 } 2149 }
2153 Bufbyte *ptr; 2159 Bufbyte *ptr;
2154 2160
2155 CHECK_STRING (filename); 2161 CHECK_STRING (filename);
2156 ptr = XSTRING_DATA (filename); 2162 ptr = XSTRING_DATA (filename);
2157 return (IS_DIRECTORY_SEP (*ptr) || *ptr == '~' 2163 return (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2158 #ifdef WINDOWSNT 2164 #ifdef WIN32_NATIVE
2159 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2])) 2165 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2160 #endif 2166 #endif
2161 ) ? Qt : Qnil; 2167 ) ? Qt : Qnil;
2162 } 2168 }
2163 2169
2164 /* Return nonzero if file FILENAME exists and can be executed. */ 2170 /* Return nonzero if file FILENAME exists and can be executed. */
2165 2171
2166 static int 2172 static int
2167 check_executable (char *filename) 2173 check_executable (char *filename)
2168 { 2174 {
2169 #ifdef WINDOWSNT 2175 #ifdef WIN32_NATIVE
2170 struct stat st; 2176 struct stat st;
2171 if (stat (filename, &st) < 0) 2177 if (xemacs_stat (filename, &st) < 0)
2172 return 0; 2178 return 0;
2173 return ((st.st_mode & S_IEXEC) != 0); 2179 return ((st.st_mode & S_IEXEC) != 0);
2174 #else /* not WINDOWSNT */ 2180 #else /* not WIN32_NATIVE */
2175 #ifdef HAVE_EACCESS 2181 #ifdef HAVE_EACCESS
2176 return eaccess (filename, 1) >= 0; 2182 return eaccess (filename, X_OK) >= 0;
2177 #else 2183 #else
2178 /* Access isn't quite right because it uses the real uid 2184 /* Access isn't quite right because it uses the real uid
2179 and we really want to test with the effective uid. 2185 and we really want to test with the effective uid.
2180 But Unix doesn't give us a right way to do it. */ 2186 But Unix doesn't give us a right way to do it. */
2181 return access (filename, 1) >= 0; 2187 return access (filename, X_OK) >= 0;
2182 #endif /* HAVE_EACCESS */ 2188 #endif /* HAVE_EACCESS */
2183 #endif /* not WINDOWSNT */ 2189 #endif /* not WIN32_NATIVE */
2184 } 2190 }
2185 2191
2186 /* Return nonzero if file FILENAME exists and can be written. */ 2192 /* Return nonzero if file FILENAME exists and can be written. */
2187 2193
2188 static int 2194 static int
2189 check_writable (CONST char *filename) 2195 check_writable (const char *filename)
2190 { 2196 {
2191 #ifdef HAVE_EACCESS 2197 #ifdef HAVE_EACCESS
2192 return (eaccess (filename, 2) >= 0); 2198 return (eaccess (filename, W_OK) >= 0);
2193 #else 2199 #else
2194 /* Access isn't quite right because it uses the real uid 2200 /* Access isn't quite right because it uses the real uid
2195 and we really want to test with the effective uid. 2201 and we really want to test with the effective uid.
2196 But Unix doesn't give us a right way to do it. 2202 But Unix doesn't give us a right way to do it.
2197 Opening with O_WRONLY could work for an ordinary file, 2203 Opening with O_WRONLY could work for an ordinary file,
2198 but would lose for directories. */ 2204 but would lose for directories. */
2199 return (access (filename, 2) >= 0); 2205 return (access (filename, W_OK) >= 0);
2200 #endif 2206 #endif
2201 } 2207 }
2202 2208
2203 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /* 2209 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /*
2204 Return t if file FILENAME exists. (This does not mean you can read it.) 2210 Return t if file FILENAME exists. (This does not mean you can read it.)
2205 See also `file-readable-p' and `file-attributes'. 2211 See also `file-readable-p' and `file-attributes'.
2206 */ 2212 */
2207 (filename)) 2213 (filename))
2208 { 2214 {
2209 /* This function can call lisp */ 2215 /* This function can call lisp; GC checked 2000-07-11 ben */
2210 Lisp_Object abspath; 2216 Lisp_Object abspath;
2211 Lisp_Object handler; 2217 Lisp_Object handler;
2212 struct stat statbuf; 2218 struct stat statbuf;
2213 struct gcpro gcpro1; 2219 struct gcpro gcpro1;
2214 2220
2221 handler = Ffind_file_name_handler (abspath, Qfile_exists_p); 2227 handler = Ffind_file_name_handler (abspath, Qfile_exists_p);
2222 UNGCPRO; 2228 UNGCPRO;
2223 if (!NILP (handler)) 2229 if (!NILP (handler))
2224 return call2 (handler, Qfile_exists_p, abspath); 2230 return call2 (handler, Qfile_exists_p, abspath);
2225 2231
2226 return stat ((char *) XSTRING_DATA (abspath), &statbuf) >= 0 ? Qt : Qnil; 2232 return xemacs_stat ((char *) XSTRING_DATA (abspath), &statbuf) >= 0 ? Qt : Qnil;
2227 } 2233 }
2228 2234
2229 DEFUN ("file-executable-p", Ffile_executable_p, 1, 1, 0, /* 2235 DEFUN ("file-executable-p", Ffile_executable_p, 1, 1, 0, /*
2230 Return t if FILENAME can be executed by you. 2236 Return t if FILENAME can be executed by you.
2231 For a directory, this means you can access files in that directory. 2237 For a directory, this means you can access files in that directory.
2232 */ 2238 */
2233 (filename)) 2239 (filename))
2234 2240
2235 { 2241 {
2236 /* This function can GC. GC checked 1997.04.10. */ 2242 /* This function can GC. GC checked 07-11-2000 ben. */
2237 Lisp_Object abspath; 2243 Lisp_Object abspath;
2238 Lisp_Object handler; 2244 Lisp_Object handler;
2239 struct gcpro gcpro1; 2245 struct gcpro gcpro1;
2240 2246
2241 CHECK_STRING (filename); 2247 CHECK_STRING (filename);
2271 call the corresponding file handler. */ 2277 call the corresponding file handler. */
2272 handler = Ffind_file_name_handler (abspath, Qfile_readable_p); 2278 handler = Ffind_file_name_handler (abspath, Qfile_readable_p);
2273 if (!NILP (handler)) 2279 if (!NILP (handler))
2274 RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath)); 2280 RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath));
2275 2281
2276 #if defined(WINDOWSNT) || defined(__CYGWIN32__) 2282 #if defined(WIN32_NATIVE) || defined(CYGWIN)
2277 /* Under MS-DOS and Windows, open does not work for directories. */ 2283 /* Under MS-DOS and Windows, open does not work for directories. */
2278 UNGCPRO; 2284 UNGCPRO;
2279 if (access (XSTRING_DATA (abspath), 0) == 0) 2285 if (access (XSTRING_DATA (abspath), 0) == 0)
2280 return Qt; 2286 return Qt;
2281 else 2287 else
2282 return Qnil; 2288 return Qnil;
2283 #else /* not WINDOWSNT */ 2289 #else /* not WIN32_NATIVE */
2284 { 2290 {
2285 int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0); 2291 int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0);
2286 UNGCPRO; 2292 UNGCPRO;
2287 if (desc < 0) 2293 if (desc < 0)
2288 return Qnil; 2294 return Qnil;
2289 close (desc); 2295 close (desc);
2290 return Qt; 2296 return Qt;
2291 } 2297 }
2292 #endif /* not WINDOWSNT */ 2298 #endif /* not WIN32_NATIVE */
2293 } 2299 }
2294 2300
2295 /* Having this before file-symlink-p mysteriously caused it to be forgotten 2301 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2296 on the RT/PC. */ 2302 on the RT/PC. */
2297 DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /* 2303 DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /*
2314 handler = Ffind_file_name_handler (abspath, Qfile_writable_p); 2320 handler = Ffind_file_name_handler (abspath, Qfile_writable_p);
2315 UNGCPRO; 2321 UNGCPRO;
2316 if (!NILP (handler)) 2322 if (!NILP (handler))
2317 return call2 (handler, Qfile_writable_p, abspath); 2323 return call2 (handler, Qfile_writable_p, abspath);
2318 2324
2319 if (stat ((char *) XSTRING_DATA (abspath), &statbuf) >= 0) 2325 if (xemacs_stat ((char *) XSTRING_DATA (abspath), &statbuf) >= 0)
2320 return (check_writable ((char *) XSTRING_DATA (abspath)) 2326 return (check_writable ((char *) XSTRING_DATA (abspath))
2321 ? Qt : Qnil); 2327 ? Qt : Qnil);
2322 2328
2323 2329
2324 GCPRO1 (abspath); 2330 GCPRO1 (abspath);
2335 Otherwise returns nil. 2341 Otherwise returns nil.
2336 */ 2342 */
2337 (filename)) 2343 (filename))
2338 { 2344 {
2339 /* This function can GC. GC checked 1997.04.10. */ 2345 /* This function can GC. GC checked 1997.04.10. */
2346 /* XEmacs change: run handlers even if local machine doesn't have symlinks */
2340 #ifdef S_IFLNK 2347 #ifdef S_IFLNK
2341 char *buf; 2348 char *buf;
2342 int bufsize; 2349 int bufsize;
2343 int valsize; 2350 int valsize;
2344 Lisp_Object val; 2351 Lisp_Object val;
2352 #endif
2345 Lisp_Object handler; 2353 Lisp_Object handler;
2346 struct gcpro gcpro1; 2354 struct gcpro gcpro1;
2347 2355
2348 CHECK_STRING (filename); 2356 CHECK_STRING (filename);
2349 filename = Fexpand_file_name (filename, Qnil); 2357 filename = Fexpand_file_name (filename, Qnil);
2354 handler = Ffind_file_name_handler (filename, Qfile_symlink_p); 2362 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
2355 UNGCPRO; 2363 UNGCPRO;
2356 if (!NILP (handler)) 2364 if (!NILP (handler))
2357 return call2 (handler, Qfile_symlink_p, filename); 2365 return call2 (handler, Qfile_symlink_p, filename);
2358 2366
2367 #ifdef S_IFLNK
2359 bufsize = 100; 2368 bufsize = 100;
2360 while (1) 2369 while (1)
2361 { 2370 {
2362 buf = xnew_array_and_zero (char, bufsize); 2371 buf = xnew_array_and_zero (char, bufsize);
2363 valsize = readlink ((char *) XSTRING_DATA (filename), 2372 valsize = readlink ((char *) XSTRING_DATA (filename),
2404 handler = Ffind_file_name_handler (abspath, Qfile_directory_p); 2413 handler = Ffind_file_name_handler (abspath, Qfile_directory_p);
2405 UNGCPRO; 2414 UNGCPRO;
2406 if (!NILP (handler)) 2415 if (!NILP (handler))
2407 return call2 (handler, Qfile_directory_p, abspath); 2416 return call2 (handler, Qfile_directory_p, abspath);
2408 2417
2409 if (stat ((char *) XSTRING_DATA (abspath), &st) < 0) 2418 if (xemacs_stat ((char *) XSTRING_DATA (abspath), &st) < 0)
2410 return Qnil; 2419 return Qnil;
2411 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil; 2420 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
2412 } 2421 }
2413 2422
2414 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, 1, 1, 0, /* 2423 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, 1, 1, 0, /*
2429 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p); 2438 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
2430 if (!NILP (handler)) 2439 if (!NILP (handler))
2431 return call2 (handler, Qfile_accessible_directory_p, 2440 return call2 (handler, Qfile_accessible_directory_p,
2432 filename); 2441 filename);
2433 2442
2434 #if !defined(WINDOWSNT) 2443 #if !defined(WIN32_NATIVE)
2435 if (NILP (Ffile_directory_p (filename))) 2444 if (NILP (Ffile_directory_p (filename)))
2436 return (Qnil); 2445 return (Qnil);
2437 else 2446 else
2438 return Ffile_executable_p (filename); 2447 return Ffile_executable_p (filename);
2439 #else 2448 #else
2450 tem = (NILP (Ffile_directory_p (filename)) 2459 tem = (NILP (Ffile_directory_p (filename))
2451 || NILP (Ffile_executable_p (filename))); 2460 || NILP (Ffile_executable_p (filename)));
2452 UNGCPRO; 2461 UNGCPRO;
2453 return tem ? Qnil : Qt; 2462 return tem ? Qnil : Qt;
2454 } 2463 }
2455 #endif /* !defined(WINDOWSNT) */ 2464 #endif /* !defined(WIN32_NATIVE) */
2456 } 2465 }
2457 2466
2458 DEFUN ("file-regular-p", Ffile_regular_p, 1, 1, 0, /* 2467 DEFUN ("file-regular-p", Ffile_regular_p, 1, 1, 0, /*
2459 Return t if file FILENAME is the name of a regular file. 2468 Return t if file FILENAME is the name of a regular file.
2460 This is the sort of file that holds an ordinary stream of data bytes. 2469 This is the sort of file that holds an ordinary stream of data bytes.
2477 handler = Ffind_file_name_handler (abspath, Qfile_regular_p); 2486 handler = Ffind_file_name_handler (abspath, Qfile_regular_p);
2478 UNGCPRO; 2487 UNGCPRO;
2479 if (!NILP (handler)) 2488 if (!NILP (handler))
2480 return call2 (handler, Qfile_regular_p, abspath); 2489 return call2 (handler, Qfile_regular_p, abspath);
2481 2490
2482 if (stat ((char *) XSTRING_DATA (abspath), &st) < 0) 2491 if (xemacs_stat ((char *) XSTRING_DATA (abspath), &st) < 0)
2483 return Qnil; 2492 return Qnil;
2484 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil; 2493 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
2485 } 2494 }
2486 2495
2487 DEFUN ("file-modes", Ffile_modes, 1, 1, 0, /* 2496 DEFUN ("file-modes", Ffile_modes, 1, 1, 0, /*
2506 handler = Ffind_file_name_handler (abspath, Qfile_modes); 2515 handler = Ffind_file_name_handler (abspath, Qfile_modes);
2507 UNGCPRO; 2516 UNGCPRO;
2508 if (!NILP (handler)) 2517 if (!NILP (handler))
2509 return call2 (handler, Qfile_modes, abspath); 2518 return call2 (handler, Qfile_modes, abspath);
2510 2519
2511 if (stat ((char *) XSTRING_DATA (abspath), &st) < 0) 2520 if (xemacs_stat ((char *) XSTRING_DATA (abspath), &st) < 0)
2512 return Qnil; 2521 return Qnil;
2513 /* Syncing with FSF 19.34.6 note: not in FSF, #if 0'ed out here. */ 2522 /* Syncing with FSF 19.34.6 note: not in FSF, #if 0'ed out here. */
2514 #if 0 2523 #if 0
2515 #ifdef DOS_NT 2524 #ifdef WIN32_NATIVE
2516 if (check_executable (XSTRING_DATA (abspath))) 2525 if (check_executable (XSTRING_DATA (abspath)))
2517 st.st_mode |= S_IEXEC; 2526 st.st_mode |= S_IEXEC;
2518 #endif /* DOS_NT */ 2527 #endif /* WIN32_NATIVE */
2519 #endif /* 0 */ 2528 #endif /* 0 */
2520 2529
2521 return make_int (st.st_mode & 07777); 2530 return make_int (st.st_mode & 07777);
2522 } 2531 }
2523 2532
2587 DEFUN ("unix-sync", Funix_sync, 0, 0, "", /* 2596 DEFUN ("unix-sync", Funix_sync, 0, 0, "", /*
2588 Tell Unix to finish all pending disk updates. 2597 Tell Unix to finish all pending disk updates.
2589 */ 2598 */
2590 ()) 2599 ())
2591 { 2600 {
2592 #ifndef WINDOWSNT 2601 #ifndef WIN32_NATIVE
2593 sync (); 2602 sync ();
2594 #endif 2603 #endif
2595 return Qnil; 2604 return Qnil;
2596 } 2605 }
2597 2606
2628 UNGCPRO; 2637 UNGCPRO;
2629 if (!NILP (handler)) 2638 if (!NILP (handler))
2630 return call3 (handler, Qfile_newer_than_file_p, abspath1, 2639 return call3 (handler, Qfile_newer_than_file_p, abspath1,
2631 abspath2); 2640 abspath2);
2632 2641
2633 if (stat ((char *) XSTRING_DATA (abspath1), &st) < 0) 2642 if (xemacs_stat ((char *) XSTRING_DATA (abspath1), &st) < 0)
2634 return Qnil; 2643 return Qnil;
2635 2644
2636 mtime1 = st.st_mtime; 2645 mtime1 = st.st_mtime;
2637 2646
2638 if (stat ((char *) XSTRING_DATA (abspath2), &st) < 0) 2647 if (xemacs_stat ((char *) XSTRING_DATA (abspath2), &st) < 0)
2639 return Qt; 2648 return Qt;
2640 2649
2641 return (mtime1 > st.st_mtime) ? Qt : Qnil; 2650 return (mtime1 > st.st_mtime) ? Qt : Qnil;
2642 } 2651 }
2643 2652
2723 if ( (!NILP (beg) || !NILP (end)) && !NILP (visit) ) 2732 if ( (!NILP (beg) || !NILP (end)) && !NILP (visit) )
2724 error ("Attempt to visit less than an entire file"); 2733 error ("Attempt to visit less than an entire file");
2725 2734
2726 fd = -1; 2735 fd = -1;
2727 2736
2728 if (stat ((char *) XSTRING_DATA (filename), &st) < 0) 2737 if (xemacs_stat ((char *) XSTRING_DATA (filename), &st) < 0)
2729 { 2738 {
2730 if (fd >= 0) close (fd); 2739 if (fd >= 0) close (fd);
2731 badopen: 2740 badopen:
2732 if (NILP (visit)) 2741 if (NILP (visit))
2733 report_file_error ("Opening input file", list1 (filename)); 2742 report_file_error ("Opening input file", list1 (filename));
3110 If support for Mule exists in this Emacs, the file is encoded according 3119 If support for Mule exists in this Emacs, the file is encoded according
3111 to the value of CODESYS. If this is nil, no code conversion occurs. 3120 to the value of CODESYS. If this is nil, no code conversion occurs.
3112 */ 3121 */
3113 (start, end, filename, append, visit, lockname, codesys)) 3122 (start, end, filename, append, visit, lockname, codesys))
3114 { 3123 {
3115 /* This function can call lisp */ 3124 /* This function can call lisp. GC checked 2000-07-28 ben */
3116 int desc; 3125 int desc;
3117 int failure; 3126 int failure;
3118 int save_errno = 0; 3127 int save_errno = 0;
3119 struct stat st; 3128 struct stat st;
3120 Lisp_Object fn; 3129 Lisp_Object fn = Qnil;
3121 int speccount = specpdl_depth (); 3130 int speccount = specpdl_depth ();
3122 int visiting_other = STRINGP (visit); 3131 int visiting_other = STRINGP (visit);
3123 int visiting = (EQ (visit, Qt) || visiting_other); 3132 int visiting = (EQ (visit, Qt) || visiting_other);
3124 int quietly = (!visiting && !NILP (visit)); 3133 int quietly = (!visiting && !NILP (visit));
3125 Lisp_Object visit_file = Qnil; 3134 Lisp_Object visit_file = Qnil;
3126 Lisp_Object annotations = Qnil; 3135 Lisp_Object annotations = Qnil;
3127 struct buffer *given_buffer; 3136 struct buffer *given_buffer;
3128 Bufpos start1, end1; 3137 Bufpos start1, end1;
3129 3138 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3130 /* #### dmoore - if Fexpand_file_name or handlers kill the buffer, 3139 struct gcpro ngcpro1, ngcpro2;
3140 Lisp_Object curbuf;
3141
3142 XSETBUFFER (curbuf, current_buffer);
3143
3144 /* start, end, visit, and append are never modified in this fun
3145 so we don't protect them. */
3146 GCPRO5 (visit_file, filename, codesys, lockname, annotations);
3147 NGCPRO2 (curbuf, fn);
3148
3149 /* [[ dmoore - if Fexpand_file_name or handlers kill the buffer,
3131 we should signal an error rather than blissfully continuing 3150 we should signal an error rather than blissfully continuing
3132 along. ARGH, this function is going to lose lose lose. We need 3151 along. ARGH, this function is going to lose lose lose. We need
3133 to protect the current_buffer from being destroyed, but the 3152 to protect the current_buffer from being destroyed, but the
3134 multiple return points make this a pain in the butt. */ 3153 multiple return points make this a pain in the butt. ]] we do
3154 protect curbuf now. --ben */
3135 3155
3136 #ifdef FILE_CODING 3156 #ifdef FILE_CODING
3137 codesys = Fget_coding_system (codesys); 3157 codesys = Fget_coding_system (codesys);
3138 #endif /* FILE_CODING */ 3158 #endif /* FILE_CODING */
3139 3159
3140 if (current_buffer->base_buffer && ! NILP (visit)) 3160 if (current_buffer->base_buffer && ! NILP (visit))
3141 error ("Cannot do file visiting in an indirect buffer"); 3161 invalid_operation ("Cannot do file visiting in an indirect buffer",
3162 curbuf);
3142 3163
3143 if (!NILP (start) && !STRINGP (start)) 3164 if (!NILP (start) && !STRINGP (start))
3144 get_buffer_range_char (current_buffer, start, end, &start1, &end1, 0); 3165 get_buffer_range_char (current_buffer, start, end, &start1, &end1, 0);
3145 3166
3146 { 3167 {
3147 Lisp_Object handler; 3168 Lisp_Object handler;
3148 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3149
3150 GCPRO5 (start, filename, visit, visit_file, lockname);
3151 3169
3152 if (visiting_other) 3170 if (visiting_other)
3153 visit_file = Fexpand_file_name (visit, Qnil); 3171 visit_file = Fexpand_file_name (visit, Qnil);
3154 else 3172 else
3155 visit_file = filename; 3173 visit_file = filename;
3156 filename = Fexpand_file_name (filename, Qnil); 3174 filename = Fexpand_file_name (filename, Qnil);
3157 3175
3158 UNGCPRO;
3159
3160 if (NILP (lockname)) 3176 if (NILP (lockname))
3161 lockname = visit_file; 3177 lockname = visit_file;
3162 3178
3179 /* We used to UNGCPRO here. BAD! visit_file is used below after
3180 more Lisp calling. */
3163 /* If the file name has special constructs in it, 3181 /* If the file name has special constructs in it,
3164 call the corresponding file handler. */ 3182 call the corresponding file handler. */
3165 handler = Ffind_file_name_handler (filename, Qwrite_region); 3183 handler = Ffind_file_name_handler (filename, Qwrite_region);
3166 /* If FILENAME has no handler, see if VISIT has one. */ 3184 /* If FILENAME has no handler, see if VISIT has one. */
3167 if (NILP (handler) && STRINGP (visit)) 3185 if (NILP (handler) && STRINGP (visit))
3176 BUF_SAVE_MODIFF (current_buffer) = BUF_MODIFF (current_buffer); 3194 BUF_SAVE_MODIFF (current_buffer) = BUF_MODIFF (current_buffer);
3177 current_buffer->saved_size = make_int (BUF_SIZE (current_buffer)); 3195 current_buffer->saved_size = make_int (BUF_SIZE (current_buffer));
3178 current_buffer->filename = visit_file; 3196 current_buffer->filename = visit_file;
3179 MARK_MODELINE_CHANGED; 3197 MARK_MODELINE_CHANGED;
3180 } 3198 }
3199 NUNGCPRO;
3200 UNGCPRO;
3181 return val; 3201 return val;
3182 } 3202 }
3183 } 3203 }
3184 3204
3185 #ifdef CLASH_DETECTION 3205 #ifdef CLASH_DETECTION
3186 if (!auto_saving) 3206 if (!auto_saving)
3187 { 3207 lock_file (lockname);
3188 Lisp_Object curbuf;
3189 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3190
3191 XSETBUFFER (curbuf, current_buffer);
3192 GCPRO5 (start, filename, visit_file, lockname, curbuf);
3193 lock_file (lockname);
3194 UNGCPRO;
3195 }
3196 #endif /* CLASH_DETECTION */ 3208 #endif /* CLASH_DETECTION */
3197 3209
3198 /* Special kludge to simplify auto-saving. */ 3210 /* Special kludge to simplify auto-saving. */
3199 if (NILP (start)) 3211 if (NILP (start))
3200 { 3212 {
3219 desc = open ((char *) XSTRING_DATA (fn), O_WRONLY | OPEN_BINARY, 0); 3231 desc = open ((char *) XSTRING_DATA (fn), O_WRONLY | OPEN_BINARY, 0);
3220 } 3232 }
3221 if (desc < 0) 3233 if (desc < 0)
3222 { 3234 {
3223 desc = open ((char *) XSTRING_DATA (fn), 3235 desc = open ((char *) XSTRING_DATA (fn),
3224 (O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY), 3236 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
3225 ((auto_saving) ? auto_save_mode_bits : CREAT_MODE)); 3237 auto_saving ? auto_save_mode_bits : CREAT_MODE);
3226 } 3238 }
3227 3239
3228 if (desc < 0) 3240 if (desc < 0)
3229 { 3241 {
3230 #ifdef CLASH_DETECTION 3242 #ifdef CLASH_DETECTION
3236 } 3248 }
3237 3249
3238 { 3250 {
3239 Lisp_Object desc_locative = Fcons (make_int (desc), Qnil); 3251 Lisp_Object desc_locative = Fcons (make_int (desc), Qnil);
3240 Lisp_Object instream = Qnil, outstream = Qnil; 3252 Lisp_Object instream = Qnil, outstream = Qnil;
3241 struct gcpro gcpro1, gcpro2; 3253 struct gcpro nngcpro1, nngcpro2;
3242 /* need to gcpro; QUIT could happen out of call to write() */ 3254 /* need to gcpro; QUIT could happen out of call to write() */
3243 GCPRO2 (instream, outstream); 3255 NNGCPRO2 (instream, outstream);
3244 3256
3245 record_unwind_protect (close_file_unwind, desc_locative); 3257 record_unwind_protect (close_file_unwind, desc_locative);
3246 3258
3247 if (!NILP (append)) 3259 if (!NILP (append))
3248 { 3260 {
3296 { 3308 {
3297 failure = 1; 3309 failure = 1;
3298 save_errno = errno; 3310 save_errno = errno;
3299 } 3311 }
3300 Lstream_close (XLSTREAM (instream)); 3312 Lstream_close (XLSTREAM (instream));
3301 UNGCPRO;
3302 3313
3303 #ifdef HAVE_FSYNC 3314 #ifdef HAVE_FSYNC
3304 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun). 3315 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
3305 Disk full in NFS may be reported here. */ 3316 Disk full in NFS may be reported here. */
3306 /* mib says that closing the file will try to write as fast as NFS can do 3317 /* mib says that closing the file will try to write as fast as NFS can do
3316 3327
3317 /* Spurious "file has changed on disk" warnings used to be seen on 3328 /* Spurious "file has changed on disk" warnings used to be seen on
3318 systems where close() can change the modtime. This is known to 3329 systems where close() can change the modtime. This is known to
3319 happen on various NFS file systems, on Windows, and on Linux. 3330 happen on various NFS file systems, on Windows, and on Linux.
3320 Rather than handling this on a per-system basis, we 3331 Rather than handling this on a per-system basis, we
3321 unconditionally do the stat() after the close(). */ 3332 unconditionally do the xemacs_stat() after the close(). */
3322 3333
3323 /* NFS can report a write failure now. */ 3334 /* NFS can report a write failure now. */
3324 if (close (desc) < 0) 3335 if (close (desc) < 0)
3325 { 3336 {
3326 failure = 1; 3337 failure = 1;
3330 /* Discard the close unwind-protect. Execute the one for 3341 /* Discard the close unwind-protect. Execute the one for
3331 build_annotations (switches back to the original current buffer 3342 build_annotations (switches back to the original current buffer
3332 as necessary). */ 3343 as necessary). */
3333 XCAR (desc_locative) = Qnil; 3344 XCAR (desc_locative) = Qnil;
3334 unbind_to (speccount, Qnil); 3345 unbind_to (speccount, Qnil);
3346
3347 NNUNGCPRO;
3335 } 3348 }
3336 3349
3337 stat ((char *) XSTRING_DATA (fn), &st); 3350 xemacs_stat ((char *) XSTRING_DATA (fn), &st);
3338 3351
3339 #ifdef CLASH_DETECTION 3352 #ifdef CLASH_DETECTION
3340 if (!auto_saving) 3353 if (!auto_saving)
3341 unlock_file (lockname); 3354 unlock_file (lockname);
3342 #endif /* CLASH_DETECTION */ 3355 #endif /* CLASH_DETECTION */
3346 next attempt to save. */ 3359 next attempt to save. */
3347 if (visiting) 3360 if (visiting)
3348 current_buffer->modtime = st.st_mtime; 3361 current_buffer->modtime = st.st_mtime;
3349 3362
3350 if (failure) 3363 if (failure)
3351 error ("IO error writing %s: %s", 3364 {
3352 XSTRING_DATA (fn), 3365 errno = save_errno;
3353 strerror (save_errno)); 3366 report_file_error ("Writing file", list1 (fn));
3367 }
3354 3368
3355 if (visiting) 3369 if (visiting)
3356 { 3370 {
3357 BUF_SAVE_MODIFF (current_buffer) = BUF_MODIFF (current_buffer); 3371 BUF_SAVE_MODIFF (current_buffer) = BUF_MODIFF (current_buffer);
3358 current_buffer->saved_size = make_int (BUF_SIZE (current_buffer)); 3372 current_buffer->saved_size = make_int (BUF_SIZE (current_buffer));
3359 current_buffer->filename = visit_file; 3373 current_buffer->filename = visit_file;
3360 MARK_MODELINE_CHANGED; 3374 MARK_MODELINE_CHANGED;
3361 } 3375 }
3362 else if (quietly) 3376 else if (quietly)
3363 { 3377 {
3378 NUNGCPRO;
3379 UNGCPRO;
3364 return Qnil; 3380 return Qnil;
3365 } 3381 }
3366 3382
3367 if (!auto_saving) 3383 if (!auto_saving)
3368 { 3384 {
3369 if (visiting_other) 3385 if (visiting_other)
3370 message ("Wrote %s", XSTRING_DATA (visit_file)); 3386 message ("Wrote %s", XSTRING_DATA (visit_file));
3371 else 3387 else
3372 { 3388 {
3373 struct gcpro gcpro1;
3374 Lisp_Object fsp; 3389 Lisp_Object fsp;
3375 GCPRO1 (fn); 3390 struct gcpro nngcpro1;
3376 3391
3392 NNGCPRO1 (fsp);
3377 fsp = Ffile_symlink_p (fn); 3393 fsp = Ffile_symlink_p (fn);
3378 if (NILP (fsp)) 3394 if (NILP (fsp))
3379 message ("Wrote %s", XSTRING_DATA (fn)); 3395 message ("Wrote %s", XSTRING_DATA (fn));
3380 else 3396 else
3381 message ("Wrote %s (symlink to %s)", 3397 message ("Wrote %s (symlink to %s)",
3382 XSTRING_DATA (fn), XSTRING_DATA (fsp)); 3398 XSTRING_DATA (fn), XSTRING_DATA (fsp));
3383 UNGCPRO; 3399 NNUNGCPRO;
3384 } 3400 }
3385 } 3401 }
3402 NUNGCPRO;
3403 UNGCPRO;
3386 return Qnil; 3404 return Qnil;
3387 } 3405 }
3388 3406
3389 /* #### This is such a load of shit!!!! There is no way we should define 3407 /* #### This is such a load of shit!!!! There is no way we should define
3390 something so stupid as a subr, just sort the fucking list more 3408 something so stupid as a subr, just sort the fucking list more
3632 Return t if last mod time of BUF's visited file matches what BUF records. 3650 Return t if last mod time of BUF's visited file matches what BUF records.
3633 This means that the file has not been changed since it was visited or saved. 3651 This means that the file has not been changed since it was visited or saved.
3634 */ 3652 */
3635 (buf)) 3653 (buf))
3636 { 3654 {
3637 /* This function can call lisp */ 3655 /* This function can call lisp; GC checked 2000-07-11 ben */
3638 struct buffer *b; 3656 struct buffer *b;
3639 struct stat st; 3657 struct stat st;
3640 Lisp_Object handler; 3658 Lisp_Object handler;
3641 3659
3642 CHECK_BUFFER (buf); 3660 CHECK_BUFFER (buf);
3650 handler = Ffind_file_name_handler (b->filename, 3668 handler = Ffind_file_name_handler (b->filename,
3651 Qverify_visited_file_modtime); 3669 Qverify_visited_file_modtime);
3652 if (!NILP (handler)) 3670 if (!NILP (handler))
3653 return call2 (handler, Qverify_visited_file_modtime, buf); 3671 return call2 (handler, Qverify_visited_file_modtime, buf);
3654 3672
3655 if (stat ((char *) XSTRING_DATA (b->filename), &st) < 0) 3673 if (xemacs_stat ((char *) XSTRING_DATA (b->filename), &st) < 0)
3656 { 3674 {
3657 /* If the file doesn't exist now and didn't exist before, 3675 /* If the file doesn't exist now and didn't exist before,
3658 we say that it isn't modified, provided the error is a tame one. */ 3676 we say that it isn't modified, provided the error is a tame one. */
3659 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR) 3677 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
3660 st.st_mtime = -1; 3678 st.st_mtime = -1;
3722 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime); 3740 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
3723 UNGCPRO; 3741 UNGCPRO;
3724 if (!NILP (handler)) 3742 if (!NILP (handler))
3725 /* The handler can find the file name the same way we did. */ 3743 /* The handler can find the file name the same way we did. */
3726 return call2 (handler, Qset_visited_file_modtime, Qnil); 3744 return call2 (handler, Qset_visited_file_modtime, Qnil);
3727 else if (stat ((char *) XSTRING_DATA (filename), &st) >= 0) 3745 else if (xemacs_stat ((char *) XSTRING_DATA (filename), &st) >= 0)
3728 current_buffer->modtime = st.st_mtime; 3746 current_buffer->modtime = st.st_mtime;
3729 } 3747 }
3730 3748
3731 return Qnil; 3749 return Qnil;
3732 } 3750 }
3763 if (!STRINGP (a)) 3781 if (!STRINGP (a))
3764 return (Qnil); 3782 return (Qnil);
3765 3783
3766 /* Get visited file's mode to become the auto save file's mode. */ 3784 /* Get visited file's mode to become the auto save file's mode. */
3767 if (STRINGP (fn) && 3785 if (STRINGP (fn) &&
3768 stat ((char *) XSTRING_DATA (fn), &st) >= 0) 3786 xemacs_stat ((char *) XSTRING_DATA (fn), &st) >= 0)
3769 /* But make sure we can overwrite it later! */ 3787 /* But make sure we can overwrite it later! */
3770 auto_save_mode_bits = st.st_mode | 0600; 3788 auto_save_mode_bits = st.st_mode | 0600;
3771 else 3789 else
3772 /* default mode for auto-save files of buffers with no file is 3790 /* default mode for auto-save files of buffers with no file is
3773 readable by owner only. This may annoy some small number of 3791 readable by owner only. This may annoy some small number of
3952 continue; 3970 continue;
3953 } 3971 }
3954 set_buffer_internal (b); 3972 set_buffer_internal (b);
3955 if (!auto_saved && NILP (no_message)) 3973 if (!auto_saved && NILP (no_message))
3956 { 3974 {
3957 static CONST unsigned char *msg 3975 static const unsigned char *msg
3958 = (CONST unsigned char *) "Auto-saving..."; 3976 = (const unsigned char *) "Auto-saving...";
3959 echo_area_message (selected_frame (), msg, Qnil, 3977 echo_area_message (selected_frame (), msg, Qnil,
3960 0, strlen ((CONST char *) msg), 3978 0, strlen ((const char *) msg),
3961 Qauto_saving); 3979 Qauto_saving);
3962 } 3980 }
3963 3981
3964 /* Open the auto-save list file, if necessary. 3982 /* Open the auto-save list file, if necessary.
3965 We only do this now so that the file only exists 3983 We only do this now so that the file only exists
3981 the special file that lists them. For each of 3999 the special file that lists them. For each of
3982 these buffers, record visited name (if any) and 4000 these buffers, record visited name (if any) and
3983 auto save name. */ 4001 auto save name. */
3984 if (listdesc >= 0) 4002 if (listdesc >= 0)
3985 { 4003 {
3986 CONST Extbyte *auto_save_file_name_ext; 4004 const Extbyte *auto_save_file_name_ext;
3987 Extcount auto_save_file_name_ext_len; 4005 Extcount auto_save_file_name_ext_len;
3988 4006
3989 TO_EXTERNAL_FORMAT (LISP_STRING, b->auto_save_file_name, 4007 TO_EXTERNAL_FORMAT (LISP_STRING, b->auto_save_file_name,
3990 ALLOCA, (auto_save_file_name_ext, 4008 ALLOCA, (auto_save_file_name_ext,
3991 auto_save_file_name_ext_len), 4009 auto_save_file_name_ext_len),
3992 Qfile_name); 4010 Qfile_name);
3993 if (!NILP (b->filename)) 4011 if (!NILP (b->filename))
3994 { 4012 {
3995 CONST Extbyte *filename_ext; 4013 const Extbyte *filename_ext;
3996 Extcount filename_ext_len; 4014 Extcount filename_ext_len;
3997 4015
3998 TO_EXTERNAL_FORMAT (LISP_STRING, b->filename, 4016 TO_EXTERNAL_FORMAT (LISP_STRING, b->filename,
3999 ALLOCA, (filename_ext, 4017 ALLOCA, (filename_ext,
4000 filename_ext_len), 4018 filename_ext_len),
4059 4077
4060 /* Show "...done" only if the echo area would otherwise be empty. */ 4078 /* Show "...done" only if the echo area would otherwise be empty. */
4061 if (auto_saved && NILP (no_message) 4079 if (auto_saved && NILP (no_message)
4062 && NILP (clear_echo_area (selected_frame (), Qauto_saving, 0))) 4080 && NILP (clear_echo_area (selected_frame (), Qauto_saving, 0)))
4063 { 4081 {
4064 static CONST unsigned char *msg 4082 static const unsigned char *msg
4065 = (CONST unsigned char *)"Auto-saving...done"; 4083 = (const unsigned char *)"Auto-saving...done";
4066 echo_area_message (selected_frame (), msg, Qnil, 0, 4084 echo_area_message (selected_frame (), msg, Qnil, 0,
4067 strlen ((CONST char *) msg), Qauto_saving); 4085 strlen ((const char *) msg), Qauto_saving);
4068 } 4086 }
4069 4087
4070 Vquit_flag = oquit; 4088 Vquit_flag = oquit;
4071 4089
4072 RETURN_UNGCPRO (unbind_to (speccount, Qnil)); 4090 RETURN_UNGCPRO (unbind_to (speccount, Qnil));
4148 4166
4149 defsymbol (&Qformat_decode, "format-decode"); 4167 defsymbol (&Qformat_decode, "format-decode");
4150 defsymbol (&Qformat_annotate_function, "format-annotate-function"); 4168 defsymbol (&Qformat_annotate_function, "format-annotate-function");
4151 4169
4152 defsymbol (&Qcompute_buffer_file_truename, "compute-buffer-file-truename"); 4170 defsymbol (&Qcompute_buffer_file_truename, "compute-buffer-file-truename");
4153 deferror (&Qfile_error, "file-error", "File error", Qio_error); 4171 DEFERROR_STANDARD (Qfile_error, Qio_error);
4154 deferror (&Qfile_already_exists, "file-already-exists", 4172 DEFERROR_STANDARD (Qfile_already_exists, Qfile_error);
4155 "File already exists", Qfile_error);
4156 4173
4157 DEFSUBR (Ffind_file_name_handler); 4174 DEFSUBR (Ffind_file_name_handler);
4158 4175
4159 DEFSUBR (Ffile_name_directory); 4176 DEFSUBR (Ffile_name_directory);
4160 DEFSUBR (Ffile_name_nondirectory); 4177 DEFSUBR (Ffile_name_nondirectory);
4169 DEFSUBR (Fmake_directory_internal); 4186 DEFSUBR (Fmake_directory_internal);
4170 DEFSUBR (Fdelete_directory); 4187 DEFSUBR (Fdelete_directory);
4171 DEFSUBR (Fdelete_file); 4188 DEFSUBR (Fdelete_file);
4172 DEFSUBR (Frename_file); 4189 DEFSUBR (Frename_file);
4173 DEFSUBR (Fadd_name_to_file); 4190 DEFSUBR (Fadd_name_to_file);
4174 #ifdef S_IFLNK
4175 DEFSUBR (Fmake_symbolic_link); 4191 DEFSUBR (Fmake_symbolic_link);
4176 #endif /* S_IFLNK */
4177 #ifdef HPUX_NET 4192 #ifdef HPUX_NET
4178 DEFSUBR (Fsysnetunam); 4193 DEFSUBR (Fsysnetunam);
4179 #endif /* HPUX_NET */ 4194 #endif /* HPUX_NET */
4180 DEFSUBR (Ffile_name_absolute_p); 4195 DEFSUBR (Ffile_name_absolute_p);
4181 DEFSUBR (Ffile_exists_p); 4196 DEFSUBR (Ffile_exists_p);
4297 The value should be either ?/ or ?\\ (any other value is treated as ?\\). 4312 The value should be either ?/ or ?\\ (any other value is treated as ?\\).
4298 This variable affects the built-in functions only on Windows, 4313 This variable affects the built-in functions only on Windows,
4299 on other platforms, it is initialized so that Lisp code can find out 4314 on other platforms, it is initialized so that Lisp code can find out
4300 what the normal separator is. 4315 what the normal separator is.
4301 */ ); 4316 */ );
4302 #ifdef WINDOWSNT 4317 #ifdef WIN32_NATIVE
4303 Vdirectory_sep_char = make_char ('\\'); 4318 Vdirectory_sep_char = make_char ('\\');
4304 #else 4319 #else
4305 Vdirectory_sep_char = make_char ('/'); 4320 Vdirectory_sep_char = make_char ('/');
4306 #endif 4321 #endif
4307 } 4322
4323 reinit_vars_of_fileio ();
4324 }
4325
4326 void
4327 reinit_vars_of_fileio (void)
4328 {
4329 /* We want temp_name_rand to be initialized to a value likely to be
4330 unique to the process, not to the executable. The danger is that
4331 two different XEmacs processes using the same binary on different
4332 machines creating temp files in the same directory will be
4333 unlucky enough to have the same pid. If we randomize using
4334 process startup time, then in practice they will be unlikely to
4335 collide. We use the microseconds field so that scripts that start
4336 simultaneous XEmacs processes on multiple machines will have less
4337 chance of collision. */
4338 {
4339 EMACS_TIME thyme;
4340
4341 EMACS_GET_TIME (thyme);
4342 temp_name_rand = (unsigned int) (EMACS_SECS (thyme) ^ EMACS_USECS (thyme));
4343 }
4344 }