Mercurial > hg > xemacs-beta
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 } |