Mercurial > hg > xemacs-beta
comparison src/fileio.c @ 209:41ff10fd062f r20-4b3
Import from CVS: tag r20-4b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:04:58 +0200 |
parents | a2f645c6b9f8 |
children | 78478c60bfcd |
comparison
equal
deleted
inserted
replaced
208:f427b8ec4379 | 209:41ff10fd062f |
---|---|
79 this holds the annotations made by the previous functions. */ | 79 this holds the annotations made by the previous functions. */ |
80 Lisp_Object Vwrite_region_annotations_so_far; | 80 Lisp_Object Vwrite_region_annotations_so_far; |
81 | 81 |
82 /* File name in which we write a list of all our auto save files. */ | 82 /* File name in which we write a list of all our auto save files. */ |
83 Lisp_Object Vauto_save_list_file_name; | 83 Lisp_Object Vauto_save_list_file_name; |
84 | |
85 /* On VMS, nonzero means write new files with record format stmlf. | |
86 Zero means use var format. */ | |
87 int vms_stmlf_recfm; | |
88 | 84 |
89 int disable_auto_save_when_buffer_shrinks; | 85 int disable_auto_save_when_buffer_shrinks; |
90 | 86 |
91 Lisp_Object Qfile_name_handler_alist; | 87 Lisp_Object Qfile_name_handler_alist; |
92 | 88 |
394 | 390 |
395 DEFUN ("file-name-directory", Ffile_name_directory, 1, 1, 0, /* | 391 DEFUN ("file-name-directory", Ffile_name_directory, 1, 1, 0, /* |
396 Return the directory component in file name NAME. | 392 Return the directory component in file name NAME. |
397 Return nil if NAME does not include a directory. | 393 Return nil if NAME does not include a directory. |
398 Otherwise return a directory spec. | 394 Otherwise return a directory spec. |
399 Given a Unix syntax file name, returns a string ending in slash; | 395 Given a Unix syntax file name, returns a string ending in slash. |
400 on VMS, perhaps instead a string ending in `:', `]' or `>'. | |
401 */ | 396 */ |
402 (file)) | 397 (file)) |
403 { | 398 { |
404 /* This function can GC. GC checked 1997.04.06. */ | 399 /* This function can GC. GC checked 1997.04.06. */ |
405 Bufbyte *beg; | 400 Bufbyte *beg; |
418 file = FILE_SYSTEM_CASE (file); | 413 file = FILE_SYSTEM_CASE (file); |
419 #endif | 414 #endif |
420 beg = XSTRING_DATA (file); | 415 beg = XSTRING_DATA (file); |
421 p = beg + XSTRING_LENGTH (file); | 416 p = beg + XSTRING_LENGTH (file); |
422 | 417 |
423 while (p != beg && !IS_ANY_SEP (p[-1]) | 418 while (p != beg && !IS_ANY_SEP (p[-1])) |
424 #ifdef VMS | 419 p--; |
425 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>' | |
426 #endif /* VMS */ | |
427 ) p--; | |
428 | 420 |
429 if (p == beg) | 421 if (p == beg) |
430 return Qnil; | 422 return Qnil; |
431 #ifdef DOS_NT | 423 #ifdef DOS_NT |
432 /* Expansion of "c:" to drive and default directory. */ | 424 /* Expansion of "c:" to drive and default directory. */ |
481 return call2_check_string (handler, Qfile_name_nondirectory, file); | 473 return call2_check_string (handler, Qfile_name_nondirectory, file); |
482 | 474 |
483 beg = XSTRING_DATA (file); | 475 beg = XSTRING_DATA (file); |
484 end = p = beg + XSTRING_LENGTH (file); | 476 end = p = beg + XSTRING_LENGTH (file); |
485 | 477 |
486 while (p != beg && !IS_ANY_SEP (p[-1]) | 478 while (p != beg && !IS_ANY_SEP (p[-1])) |
487 #ifdef VMS | 479 p--; |
488 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>' | |
489 #endif /* VMS */ | |
490 ) p--; | |
491 | 480 |
492 return make_string (p, end - p); | 481 return make_string (p, end - p); |
493 } | 482 } |
494 | 483 |
495 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory, 1, 1, 0, /* | 484 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory, 1, 1, 0, /* |
522 { | 511 { |
523 int size = strlen (in) - 1; | 512 int size = strlen (in) - 1; |
524 | 513 |
525 strcpy (out, in); | 514 strcpy (out, in); |
526 | 515 |
527 #ifdef VMS | |
528 /* Is it already a directory string? */ | |
529 if (in[size] == ':' || in[size] == ']' || in[size] == '>') | |
530 return out; | |
531 /* Is it a VMS directory file name? If so, hack VMS syntax. */ | |
532 else if (! strchr (in, '/') | |
533 && ((size > 3 && ! strcmp (&in[size - 3], ".DIR")) | |
534 || (size > 3 && ! strcmp (&in[size - 3], ".dir")) | |
535 || (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4) | |
536 || ! strncmp (&in[size - 5], ".dir", 4)) | |
537 && (in[size - 1] == '.' || in[size - 1] == ';') | |
538 && in[size] == '1'))) | |
539 { | |
540 char *p, *dot; | |
541 char brack; | |
542 | |
543 /* x.dir -> [.x] | |
544 dir:x.dir --> dir:[x] | |
545 dir:[x]y.dir --> dir:[x.y] */ | |
546 p = in + size; | |
547 while (p != in && *p != ':' && *p != '>' && *p != ']') p--; | |
548 if (p != in) | |
549 { | |
550 strncpy (out, in, p - in); | |
551 out[p - in] = '\0'; | |
552 if (*p == ':') | |
553 { | |
554 brack = ']'; | |
555 strcat (out, ":["); | |
556 } | |
557 else | |
558 { | |
559 brack = *p; | |
560 strcat (out, "."); | |
561 } | |
562 p++; | |
563 } | |
564 else | |
565 { | |
566 brack = ']'; | |
567 strcpy (out, "[."); | |
568 } | |
569 dot = strchr (p, '.'); | |
570 if (dot) | |
571 { | |
572 /* blindly remove any extension */ | |
573 size = strlen (out) + (dot - p); | |
574 strncat (out, p, dot - p); | |
575 } | |
576 else | |
577 { | |
578 strcat (out, p); | |
579 size = strlen (out); | |
580 } | |
581 out[size++] = brack; | |
582 out[size] = '\0'; | |
583 } | |
584 #else /* not VMS */ | |
585 /* For Unix syntax, Append a slash if necessary */ | 516 /* For Unix syntax, Append a slash if necessary */ |
586 if (!IS_ANY_SEP (out[size])) | 517 if (!IS_ANY_SEP (out[size])) |
587 { | 518 { |
588 out[size + 1] = DIRECTORY_SEP; | 519 out[size + 1] = DIRECTORY_SEP; |
589 out[size + 2] = '\0'; | 520 out[size + 2] = '\0'; |
590 } | 521 } |
591 #endif /* not VMS */ | |
592 return out; | 522 return out; |
593 } | 523 } |
594 | 524 |
595 DEFUN ("file-name-as-directory", Ffile_name_as_directory, 1, 1, 0, /* | 525 DEFUN ("file-name-as-directory", Ffile_name_as_directory, 1, 1, 0, /* |
596 Return a string representing file FILENAME interpreted as a directory. | 526 Return a string representing file FILENAME interpreted as a directory. |
597 This operation exists because a directory is also a file, but its name as | 527 This operation exists because a directory is also a file, but its name as |
598 a directory is different from its name as a file. | 528 a directory is different from its name as a file. |
599 The result can be used as the value of `default-directory' | 529 The result can be used as the value of `default-directory' |
600 or passed as second argument to `expand-file-name'. | 530 or passed as second argument to `expand-file-name'. |
601 For a Unix-syntax file name, just appends a slash. | 531 For a Unix-syntax file name, just appends a slash. |
602 On VMS, converts "[X]FOO.DIR" to "[X.FOO]", etc. | |
603 */ | 532 */ |
604 (file)) | 533 (file)) |
605 { | 534 { |
606 /* This function can GC. GC checked 1997.04.06. */ | 535 /* This function can GC. GC checked 1997.04.06. */ |
607 char *buf; | 536 char *buf; |
620 (buf, (char *) XSTRING_DATA (file))); | 549 (buf, (char *) XSTRING_DATA (file))); |
621 } | 550 } |
622 | 551 |
623 /* | 552 /* |
624 * Convert from directory name to filename. | 553 * Convert from directory name to filename. |
625 * On VMS: | |
626 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1 | |
627 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1 | |
628 * On UNIX, it's simple: just make sure there is a terminating / | 554 * On UNIX, it's simple: just make sure there is a terminating / |
629 | 555 |
630 * Value is nonzero if the string output is different from the input. | 556 * Value is nonzero if the string output is different from the input. |
631 */ | 557 */ |
632 | 558 |
633 static int | 559 static int |
634 directory_file_name (CONST char *src, char *dst) | 560 directory_file_name (CONST char *src, char *dst) |
635 { | 561 { |
636 long slen; | 562 long slen; |
637 #ifdef VMS | |
638 long rlen; | |
639 char * ptr, * rptr; | |
640 char bracket; | |
641 struct FAB fab = cc$rms_fab; | |
642 struct NAM nam = cc$rms_nam; | |
643 char esa[NAM$C_MAXRSS]; | |
644 #endif /* VMS */ | |
645 | 563 |
646 slen = strlen (src); | 564 slen = strlen (src); |
647 #ifdef VMS | |
648 if (! strchr (src, '/') | |
649 && (src[slen - 1] == ']' | |
650 || src[slen - 1] == ':' | |
651 || src[slen - 1] == '>')) | |
652 { | |
653 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */ | |
654 fab.fab$l_fna = src; | |
655 fab.fab$b_fns = slen; | |
656 fab.fab$l_nam = &nam; | |
657 fab.fab$l_fop = FAB$M_NAM; | |
658 | |
659 nam.nam$l_esa = esa; | |
660 nam.nam$b_ess = sizeof esa; | |
661 nam.nam$b_nop |= NAM$M_SYNCHK; | |
662 | |
663 /* We call SYS$PARSE to handle such things as [--] for us. */ | |
664 if (SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL) | |
665 { | |
666 slen = nam.nam$b_esl; | |
667 if (esa[slen - 1] == ';' && esa[slen - 2] == '.') | |
668 slen -= 2; | |
669 esa[slen] = '\0'; | |
670 src = esa; | |
671 } | |
672 if (src[slen - 1] != ']' && src[slen - 1] != '>') | |
673 { | |
674 /* what about when we have logical_name:???? */ | |
675 if (src[slen - 1] == ':') | |
676 { /* Xlate logical name and see what we get */ | |
677 ptr = strcpy (dst, src); /* upper case for getenv */ | |
678 while (*ptr) | |
679 { | |
680 *ptr = toupper ((unsigned char) *ptr); | |
681 ptr++; | |
682 } | |
683 dst[slen - 1] = 0; /* remove colon */ | |
684 if (!(src = egetenv (dst))) | |
685 return 0; | |
686 /* should we jump to the beginning of this procedure? | |
687 Good points: allows us to use logical names that xlate | |
688 to Unix names, | |
689 Bad points: can be a problem if we just translated to a device | |
690 name... | |
691 For now, I'll punt and always expect VMS names, and hope for | |
692 the best! */ | |
693 slen = strlen (src); | |
694 if (src[slen - 1] != ']' && src[slen - 1] != '>') | |
695 { /* no recursion here! */ | |
696 strcpy (dst, src); | |
697 return 0; | |
698 } | |
699 } | |
700 else | |
701 { /* not a directory spec */ | |
702 strcpy (dst, src); | |
703 return 0; | |
704 } | |
705 } | |
706 bracket = src[slen - 1]; | |
707 | |
708 /* If bracket is ']' or '>', bracket - 2 is the corresponding | |
709 opening bracket. */ | |
710 ptr = strchr (src, bracket - 2); | |
711 if (ptr == 0) | |
712 { /* no opening bracket */ | |
713 strcpy (dst, src); | |
714 return 0; | |
715 } | |
716 if (!(rptr = strrchr (src, '.'))) | |
717 rptr = ptr; | |
718 slen = rptr - src; | |
719 strncpy (dst, src, slen); | |
720 dst[slen] = '\0'; | |
721 if (*rptr == '.') | |
722 { | |
723 dst[slen++] = bracket; | |
724 dst[slen] = '\0'; | |
725 } | |
726 else | |
727 { | |
728 /* If we have the top-level of a rooted directory (i.e. xx:[000000]), | |
729 then translate the device and recurse. */ | |
730 if (dst[slen - 1] == ':' | |
731 && dst[slen - 2] != ':' /* skip decnet nodes */ | |
732 && strcmp(src + slen, "[000000]") == 0) | |
733 { | |
734 dst[slen - 1] = '\0'; | |
735 if ((ptr = egetenv (dst)) | |
736 && (rlen = strlen (ptr) - 1) > 0 | |
737 && (ptr[rlen] == ']' || ptr[rlen] == '>') | |
738 && ptr[rlen - 1] == '.') | |
739 { | |
740 char * buf = (char *) alloca (strlen (ptr) + 1); | |
741 strcpy (buf, ptr); | |
742 buf[rlen - 1] = ']'; | |
743 buf[rlen] = '\0'; | |
744 return directory_file_name (buf, dst); | |
745 } | |
746 else | |
747 dst[slen - 1] = ':'; | |
748 } | |
749 strcat (dst, "[000000]"); | |
750 slen += 8; | |
751 } | |
752 rptr++; | |
753 rlen = strlen (rptr) - 1; | |
754 strncat (dst, rptr, rlen); | |
755 dst[slen + rlen] = '\0'; | |
756 strcat (dst, ".DIR.1"); | |
757 return 1; | |
758 } | |
759 #endif /* VMS */ | |
760 /* Process as Unix format: just remove any final slash. | 565 /* Process as Unix format: just remove any final slash. |
761 But leave "/" unchanged; do not change it to "". */ | 566 But leave "/" unchanged; do not change it to "". */ |
762 strcpy (dst, src); | 567 strcpy (dst, src); |
763 #ifdef APOLLO | 568 #ifdef APOLLO |
764 /* Handle // as root for apollo's. */ | 569 /* Handle // as root for apollo's. */ |
781 Return the file name of the directory named DIR. | 586 Return the file name of the directory named DIR. |
782 This is the name of the file that holds the data for the directory DIR. | 587 This is the name of the file that holds the data for the directory DIR. |
783 This operation exists because a directory is also a file, but its name as | 588 This operation exists because a directory is also a file, but its name as |
784 a directory is different from its name as a file. | 589 a directory is different from its name as a file. |
785 In Unix-syntax, this function just removes the final slash. | 590 In Unix-syntax, this function just removes the final slash. |
786 On VMS, given a VMS-syntax directory name such as "[X.Y]", | |
787 it returns a file name such as "[X]Y.DIR.1". | |
788 */ | 591 */ |
789 (directory)) | 592 (directory)) |
790 { | 593 { |
791 /* This function can GC. GC checked 1997.04.06. */ | 594 /* This function can GC. GC checked 1997.04.06. */ |
792 char *buf; | 595 char *buf; |
802 /* If the file name has special constructs in it, | 605 /* If the file name has special constructs in it, |
803 call the corresponding file handler. */ | 606 call the corresponding file handler. */ |
804 handler = Ffind_file_name_handler (directory, Qdirectory_file_name); | 607 handler = Ffind_file_name_handler (directory, Qdirectory_file_name); |
805 if (!NILP (handler)) | 608 if (!NILP (handler)) |
806 return call2_check_string (handler, Qdirectory_file_name, directory); | 609 return call2_check_string (handler, Qdirectory_file_name, directory); |
807 #ifdef VMS | |
808 /* 20 extra chars is insufficient for VMS, since we might perform a | |
809 logical name translation. an equivalence string can be up to 255 | |
810 chars long, so grab that much extra space... - sss */ | |
811 buf = (char *) alloca (XSTRING_LENGTH (directory) + 20 + 255); | |
812 #else | |
813 buf = (char *) alloca (XSTRING_LENGTH (directory) + 20); | 610 buf = (char *) alloca (XSTRING_LENGTH (directory) + 20); |
814 #endif | |
815 directory_file_name ((char *) XSTRING_DATA (directory), buf); | 611 directory_file_name ((char *) XSTRING_DATA (directory), buf); |
816 return build_string (buf); | 612 return build_string (buf); |
817 } | 613 } |
818 | 614 |
819 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* | 615 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /* |
860 | 656 |
861 Bufbyte *newdir, *p, *o; | 657 Bufbyte *newdir, *p, *o; |
862 int tlen; | 658 int tlen; |
863 Bufbyte *target; | 659 Bufbyte *target; |
864 struct passwd *pw; | 660 struct passwd *pw; |
865 #ifdef VMS | |
866 Bufbyte * colon = 0; | |
867 Bufbyte * close = 0; | |
868 Bufbyte * slash = 0; | |
869 Bufbyte * brack = 0; | |
870 int lbrack = 0, rbrack = 0; | |
871 int dots = 0; | |
872 #endif /* VMS */ | |
873 #ifdef DOS_NT | 661 #ifdef DOS_NT |
874 /* Demacs 1.1.2 91/10/20 Manabu Higashida */ | 662 /* Demacs 1.1.2 91/10/20 Manabu Higashida */ |
875 int drive = -1; | 663 int drive = -1; |
876 int relpath = 0; | 664 int relpath = 0; |
877 Bufbyte *tmp, *defdir; | 665 Bufbyte *tmp, *defdir; |
934 GCPRO1 (default_); /* may be current_buffer->directory */ | 722 GCPRO1 (default_); /* may be current_buffer->directory */ |
935 default_ = Fexpand_file_name (default_, Qnil); | 723 default_ = Fexpand_file_name (default_, Qnil); |
936 UNGCPRO; | 724 UNGCPRO; |
937 } | 725 } |
938 | 726 |
939 #ifdef VMS | |
940 /* Filenames on VMS are always upper case. */ | |
941 name = Fupcase (name, Fcurrent_buffer ()); | |
942 #endif | |
943 #ifdef FILE_SYSTEM_CASE | 727 #ifdef FILE_SYSTEM_CASE |
944 name = FILE_SYSTEM_CASE (name); | 728 name = FILE_SYSTEM_CASE (name); |
945 #endif | 729 #endif |
946 | 730 |
947 /* #### dmoore - this is ugly, clean this up. Looks like nm | 731 /* #### dmoore - this is ugly, clean this up. Looks like nm |
1002 } | 786 } |
1003 #endif | 787 #endif |
1004 | 788 |
1005 /* If nm is absolute, flush ...// and detect /./ and /../. | 789 /* If nm is absolute, flush ...// and detect /./ and /../. |
1006 If no /./ or /../ we can return right away. */ | 790 If no /./ or /../ we can return right away. */ |
1007 if ( | 791 if (IS_DIRECTORY_SEP (nm[0])) |
1008 IS_DIRECTORY_SEP (nm[0]) | |
1009 #ifdef VMS | |
1010 || strchr (nm, ':') | |
1011 #endif /* VMS */ | |
1012 ) | |
1013 { | 792 { |
1014 /* If it turns out that the filename we want to return is just a | 793 /* If it turns out that the filename we want to return is just a |
1015 suffix of FILENAME, we don't need to go through and edit | 794 suffix of FILENAME, we don't need to go through and edit |
1016 things; we just need to construct a new string using data | 795 things; we just need to construct a new string using data |
1017 starting at the middle of FILENAME. If we set lose to a | 796 starting at the middle of FILENAME. If we set lose to a |
1031 && (IS_DIRECTORY_SEP (p[2]) | 810 && (IS_DIRECTORY_SEP (p[2]) |
1032 || p[2] == 0 | 811 || p[2] == 0 |
1033 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) | 812 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) |
1034 || p[3] == 0)))) | 813 || p[3] == 0)))) |
1035 lose = 1; | 814 lose = 1; |
1036 #ifdef VMS | |
1037 if (p[0] == '\\') | |
1038 lose = 1; | |
1039 if (p[0] == '/') { | |
1040 /* if dev:[dir]/, move nm to / */ | |
1041 if (!slash && p > nm && (brack || colon)) { | |
1042 nm = (brack ? brack + 1 : colon + 1); | |
1043 lbrack = rbrack = 0; | |
1044 brack = 0; | |
1045 colon = 0; | |
1046 } | |
1047 slash = p; | |
1048 } | |
1049 if (p[0] == '-') | |
1050 #ifndef VMS4_4 | |
1051 /* VMS pre V4.4,convert '-'s in filenames. */ | |
1052 if (lbrack == rbrack) | |
1053 { | |
1054 if (dots < 2) /* this is to allow negative version numbers */ | |
1055 p[0] = '_'; | |
1056 } | |
1057 else | |
1058 #endif /* VMS4_4 */ | |
1059 if (lbrack > rbrack && | |
1060 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') && | |
1061 (p[1] == '.' || p[1] == ']' || p[1] == '>'))) | |
1062 lose = 1; | |
1063 #ifndef VMS4_4 | |
1064 else | |
1065 p[0] = '_'; | |
1066 #endif /* VMS4_4 */ | |
1067 /* count open brackets, reset close bracket pointer */ | |
1068 if (p[0] == '[' || p[0] == '<') | |
1069 lbrack++, brack = 0; | |
1070 /* count close brackets, set close bracket pointer */ | |
1071 if (p[0] == ']' || p[0] == '>') | |
1072 rbrack++, brack = p; | |
1073 /* detect ][ or >< */ | |
1074 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<')) | |
1075 lose = 1; | |
1076 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~') | |
1077 nm = p + 1, lose = 1; | |
1078 if (p[0] == ':' && (colon || slash)) | |
1079 /* if dev1:[dir]dev2:, move nm to dev2: */ | |
1080 if (brack) | |
1081 { | |
1082 nm = brack + 1; | |
1083 brack = 0; | |
1084 } | |
1085 /* if /pathname/dev:, move nm to dev: */ | |
1086 else if (slash) | |
1087 nm = slash + 1; | |
1088 /* if node::dev:, move colon following dev */ | |
1089 else if (colon && colon[-1] == ':') | |
1090 colon = p; | |
1091 /* if dev1:dev2:, move nm to dev2: */ | |
1092 else if (colon && colon[-1] != ':') | |
1093 { | |
1094 nm = colon + 1; | |
1095 colon = 0; | |
1096 } | |
1097 if (p[0] == ':' && !colon) | |
1098 { | |
1099 if (p[1] == ':') | |
1100 p++; | |
1101 colon = p; | |
1102 } | |
1103 if (lbrack == rbrack) | |
1104 if (p[0] == ';') | |
1105 dots = 2; | |
1106 else if (p[0] == '.') | |
1107 dots++; | |
1108 #endif /* VMS */ | |
1109 p++; | 815 p++; |
1110 } | 816 } |
1111 if (!lose) | 817 if (!lose) |
1112 { | 818 { |
1113 #ifdef VMS | |
1114 if (strchr (nm, '/')) | |
1115 return build_string (sys_translate_unix (nm)); | |
1116 #endif /* VMS */ | |
1117 #ifndef DOS_NT | 819 #ifndef DOS_NT |
1118 if (nm == XSTRING_DATA (name)) | 820 if (nm == XSTRING_DATA (name)) |
1119 return name; | 821 return name; |
1120 return build_string ((char *) nm); | 822 return build_string ((char *) nm); |
1121 #endif /* not DOS_NT */ | 823 #endif /* not DOS_NT */ |
1127 newdir = 0; | 829 newdir = 0; |
1128 | 830 |
1129 if (nm[0] == '~') /* prefix ~ */ | 831 if (nm[0] == '~') /* prefix ~ */ |
1130 { | 832 { |
1131 if (IS_DIRECTORY_SEP (nm[1]) | 833 if (IS_DIRECTORY_SEP (nm[1]) |
1132 #ifdef VMS | |
1133 || nm[1] == ':' | |
1134 #endif /* VMS */ | |
1135 || nm[1] == 0) /* ~ by itself */ | 834 || nm[1] == 0) /* ~ by itself */ |
1136 { | 835 { |
1137 if (!(newdir = (Bufbyte *) egetenv ("HOME"))) | 836 if (!(newdir = (Bufbyte *) egetenv ("HOME"))) |
1138 newdir = (Bufbyte *) ""; | 837 newdir = (Bufbyte *) ""; |
1139 #ifdef DOS_NT | 838 #ifdef DOS_NT |
1142 if (newdir[1] == ':') | 841 if (newdir[1] == ':') |
1143 drive = newdir[0]; | 842 drive = newdir[0]; |
1144 dostounix_filename (newdir); | 843 dostounix_filename (newdir); |
1145 #endif /* DOS_NT */ | 844 #endif /* DOS_NT */ |
1146 nm++; | 845 nm++; |
1147 #ifdef VMS | |
1148 nm++; /* Don't leave the slash in nm. */ | |
1149 #endif /* VMS */ | |
1150 } | 846 } |
1151 else /* ~user/filename */ | 847 else /* ~user/filename */ |
1152 { | 848 { |
1153 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p) | 849 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++); |
1154 #ifdef VMS | |
1155 && *p != ':' | |
1156 #endif /* VMS */ | |
1157 ); p++); | |
1158 o = (Bufbyte *) alloca (p - nm + 1); | 850 o = (Bufbyte *) alloca (p - nm + 1); |
1159 memcpy (o, (char *) nm, p - nm); | 851 memcpy (o, (char *) nm, p - nm); |
1160 o [p - nm] = 0; | 852 o [p - nm] = 0; |
1161 | 853 |
1162 #ifdef WINDOWSNT | 854 #ifdef WINDOWSNT |
1176 pw = (struct passwd *) getpwnam ((char *) o + 1); | 868 pw = (struct passwd *) getpwnam ((char *) o + 1); |
1177 speed_up_interrupts (); | 869 speed_up_interrupts (); |
1178 if (pw) | 870 if (pw) |
1179 { | 871 { |
1180 newdir = (Bufbyte *) pw -> pw_dir; | 872 newdir = (Bufbyte *) pw -> pw_dir; |
1181 #ifdef VMS | |
1182 nm = p + 1; /* skip the terminator */ | |
1183 #else | |
1184 nm = p; | 873 nm = p; |
1185 #endif /* VMS */ | |
1186 } | 874 } |
1187 #endif /* not WINDOWSNT */ | 875 #endif /* not WINDOWSNT */ |
1188 | 876 |
1189 /* If we don't find a user of that name, leave the name | 877 /* If we don't find a user of that name, leave the name |
1190 unchanged; don't move nm forward to p. */ | 878 unchanged; don't move nm forward to p. */ |
1191 } | 879 } |
1192 } | 880 } |
1193 | 881 |
1194 if (!IS_ANY_SEP (nm[0]) | 882 if (!IS_ANY_SEP (nm[0]) |
1195 #ifdef VMS | |
1196 && !strchr (nm, ':') | |
1197 #endif /* not VMS */ | |
1198 #ifdef DOS_NT | 883 #ifdef DOS_NT |
1199 && drive == -1 | 884 && drive == -1 |
1200 #endif /* DOS_NT */ | 885 #endif /* DOS_NT */ |
1201 && !newdir | 886 && !newdir |
1202 && STRINGP (default_)) | 887 && STRINGP (default_)) |
1242 #endif /* not DOS_NT */ | 927 #endif /* not DOS_NT */ |
1243 *target = 0; | 928 *target = 0; |
1244 | 929 |
1245 if (newdir) | 930 if (newdir) |
1246 { | 931 { |
1247 #ifndef VMS | |
1248 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) | 932 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) |
1249 strcpy ((char *) target, (char *) newdir); | 933 strcpy ((char *) target, (char *) newdir); |
1250 else | 934 else |
1251 #endif | |
1252 file_name_as_directory ((char *) target, (char *) newdir); | 935 file_name_as_directory ((char *) target, (char *) newdir); |
1253 } | 936 } |
1254 | 937 |
1255 strcat ((char *) target, (char *) nm); | 938 strcat ((char *) target, (char *) nm); |
1256 #ifdef VMS | |
1257 if (strchr (target, '/')) | |
1258 strcpy (target, sys_translate_unix (target)); | |
1259 #endif /* VMS */ | |
1260 | 939 |
1261 /* Now canonicalize by removing /. and /foo/.. if they appear. */ | 940 /* Now canonicalize by removing /. and /foo/.. if they appear. */ |
1262 | 941 |
1263 p = target; | 942 p = target; |
1264 o = target; | 943 o = target; |
1265 | 944 |
1266 while (*p) | 945 while (*p) |
1267 { | 946 { |
1268 #ifdef VMS | |
1269 if (*p != ']' && *p != '>' && *p != '-') | |
1270 { | |
1271 if (*p == '\\') | |
1272 p++; | |
1273 *o++ = *p++; | |
1274 } | |
1275 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2) | |
1276 /* brackets are offset from each other by 2 */ | |
1277 { | |
1278 p += 2; | |
1279 if (*p != '.' && *p != '-' && o[-1] != '.') | |
1280 /* convert [foo][bar] to [bar] */ | |
1281 while (o[-1] != '[' && o[-1] != '<') | |
1282 o--; | |
1283 else if (*p == '-' && *o != '.') | |
1284 *--p = '.'; | |
1285 } | |
1286 else if (p[0] == '-' && o[-1] == '.' && | |
1287 (p[1] == '.' || p[1] == ']' || p[1] == '>')) | |
1288 /* flush .foo.- ; leave - if stopped by '[' or '<' */ | |
1289 { | |
1290 do | |
1291 o--; | |
1292 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<'); | |
1293 if (p[1] == '.') /* foo.-.bar ==> bar. */ | |
1294 p += 2; | |
1295 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */ | |
1296 p++, o--; | |
1297 /* else [foo.-] ==> [-] */ | |
1298 } | |
1299 else | |
1300 { | |
1301 #ifndef VMS4_4 | |
1302 if (*p == '-' && | |
1303 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' && | |
1304 p[1] != ']' && p[1] != '>' && p[1] != '.') | |
1305 *p = '_'; | |
1306 #endif /* VMS4_4 */ | |
1307 *o++ = *p++; | |
1308 } | |
1309 #else /* not VMS */ | |
1310 if (!IS_DIRECTORY_SEP (*p)) | 947 if (!IS_DIRECTORY_SEP (*p)) |
1311 { | 948 { |
1312 *o++ = *p++; | 949 *o++ = *p++; |
1313 } | 950 } |
1314 else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]) | 951 else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]) |
1352 } | 989 } |
1353 else | 990 else |
1354 { | 991 { |
1355 *o++ = *p++; | 992 *o++ = *p++; |
1356 } | 993 } |
1357 #endif /* not VMS */ | |
1358 } | 994 } |
1359 | 995 |
1360 #ifdef DOS_NT | 996 #ifdef DOS_NT |
1361 /* at last, set drive name. */ | 997 /* at last, set drive name. */ |
1362 if (target[1] != ':' | 998 if (target[1] != ':' |
1406 UNGCPRO; | 1042 UNGCPRO; |
1407 | 1043 |
1408 if (!NILP (handler)) | 1044 if (!NILP (handler)) |
1409 return call2_check_string (handler, Qfile_truename, expanded_name); | 1045 return call2_check_string (handler, Qfile_truename, expanded_name); |
1410 | 1046 |
1411 #ifdef VMS | |
1412 return expanded_name; | |
1413 #else | |
1414 { | 1047 { |
1415 char resolved_path[MAXPATHLEN]; | 1048 char resolved_path[MAXPATHLEN]; |
1416 char path[MAXPATHLEN]; | 1049 char path[MAXPATHLEN]; |
1417 char *p = path; | 1050 char *p = path; |
1418 int elen = XSTRING_LENGTH (expanded_name); | 1051 int elen = XSTRING_LENGTH (expanded_name); |
1446 *p = '/'; | 1079 *p = '/'; |
1447 else | 1080 else |
1448 break; | 1081 break; |
1449 | 1082 |
1450 } | 1083 } |
1451 else if (errno == ENOENT) | 1084 else if (errno == ENOENT || errno == EACCES) |
1452 { | 1085 { |
1453 /* Failed on this component. Just tack on the rest of | 1086 /* Failed on this component. Just tack on the rest of |
1454 the string and we are done. */ | 1087 the string and we are done. */ |
1455 int rlen = strlen (resolved_path); | 1088 int rlen = strlen (resolved_path); |
1456 | 1089 |
1486 goto toolong; | 1119 goto toolong; |
1487 resolved_path[rlen] = '/'; | 1120 resolved_path[rlen] = '/'; |
1488 resolved_path[rlen + 1] = 0; | 1121 resolved_path[rlen + 1] = 0; |
1489 rlen = rlen + 1; | 1122 rlen = rlen + 1; |
1490 } | 1123 } |
1491 return make_string ((Bufbyte *) resolved_path, rlen); | 1124 return make_ext_string ((Bufbyte *) resolved_path, rlen, FORMAT_BINARY); |
1492 } | 1125 } |
1493 | 1126 |
1494 toolong: | 1127 toolong: |
1495 errno = ENAMETOOLONG; | 1128 errno = ENAMETOOLONG; |
1496 goto lose; | 1129 goto lose; |
1497 lose: | 1130 lose: |
1498 report_file_error ("Finding truename", list1 (expanded_name)); | 1131 report_file_error ("Finding truename", list1 (expanded_name)); |
1499 } | 1132 } |
1500 return Qnil; /* suppress compiler warning */ | 1133 return Qnil; /* suppress compiler warning */ |
1501 #endif /* not VMS */ | |
1502 } | 1134 } |
1503 | 1135 |
1504 | 1136 |
1505 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 1, 1, 0, /* | 1137 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 1, 1, 0, /* |
1506 Substitute environment variables referred to in FILENAME. | 1138 Substitute environment variables referred to in FILENAME. |
1508 the value of that variable. The variable name should be terminated | 1140 the value of that variable. The variable name should be terminated |
1509 with a character not a letter, digit or underscore; otherwise, enclose | 1141 with a character not a letter, digit or underscore; otherwise, enclose |
1510 the entire variable name in braces. | 1142 the entire variable name in braces. |
1511 If `/~' appears, all of FILENAME through that `/' is discarded. | 1143 If `/~' appears, all of FILENAME through that `/' is discarded. |
1512 | 1144 |
1513 On VMS, `$' substitution is not done; this function does little and only | |
1514 duplicates what `expand-file-name' does. | |
1515 */ | 1145 */ |
1516 (string)) | 1146 (string)) |
1517 { | 1147 { |
1518 /* This function can GC. GC checked 1997.04.06. */ | 1148 /* This function can GC. GC checked 1997.04.06. */ |
1519 Bufbyte *nm; | 1149 Bufbyte *nm; |
1556 p[0] == '/' | 1186 p[0] == '/' |
1557 #endif /* not WINDOWSNT */ | 1187 #endif /* not WINDOWSNT */ |
1558 #endif /* not APOLLO */ | 1188 #endif /* not APOLLO */ |
1559 ) | 1189 ) |
1560 && p != nm | 1190 && p != nm |
1561 && (0 | 1191 && (IS_DIRECTORY_SEP (p[-1]))) |
1562 #ifdef VMS | |
1563 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>' | |
1564 #endif /* VMS */ | |
1565 || IS_DIRECTORY_SEP (p[-1]))) | |
1566 { | 1192 { |
1567 nm = p; | 1193 nm = p; |
1568 substituted = 1; | 1194 substituted = 1; |
1569 } | 1195 } |
1570 #ifdef DOS_NT | 1196 #ifdef DOS_NT |
1573 nm = p; | 1199 nm = p; |
1574 substituted = 1; | 1200 substituted = 1; |
1575 } | 1201 } |
1576 #endif /* DOS_NT */ | 1202 #endif /* DOS_NT */ |
1577 } | 1203 } |
1578 | |
1579 #ifdef VMS | |
1580 return build_string (nm); | |
1581 #else | |
1582 | 1204 |
1583 /* See if any variables are substituted into the string | 1205 /* See if any variables are substituted into the string |
1584 and find the total length of their values in `total' */ | 1206 and find the total length of their values in `total' */ |
1585 | 1207 |
1586 for (p = nm; p != endp;) | 1208 for (p = nm; p != endp;) |
1716 error ("Substituting nonexistent environment variable \"%s\"", | 1338 error ("Substituting nonexistent environment variable \"%s\"", |
1717 target); | 1339 target); |
1718 | 1340 |
1719 /* NOTREACHED */ | 1341 /* NOTREACHED */ |
1720 return Qnil; /* suppress compiler warning */ | 1342 return Qnil; /* suppress compiler warning */ |
1721 #endif /* not VMS */ | |
1722 } | 1343 } |
1723 | 1344 |
1724 /* (directory-file-name (expand-file-name FOO)) */ | 1345 /* (directory-file-name (expand-file-name FOO)) */ |
1725 | 1346 |
1726 Lisp_Object | 1347 Lisp_Object |
1730 Lisp_Object abspath; | 1351 Lisp_Object abspath; |
1731 struct gcpro gcpro1; | 1352 struct gcpro gcpro1; |
1732 | 1353 |
1733 abspath = Fexpand_file_name (filename, defdir); | 1354 abspath = Fexpand_file_name (filename, defdir); |
1734 GCPRO1 (abspath); | 1355 GCPRO1 (abspath); |
1735 #ifdef VMS | |
1736 { | |
1737 Bufbyte c = | |
1738 XSTRING_BYTE (abspath, XSTRING_LENGTH (abspath) - 1); | |
1739 if (c == ':' || c == ']' || c == '>') | |
1740 abspath = Fdirectory_file_name (abspath); | |
1741 } | |
1742 #else | |
1743 /* Remove final slash, if any (unless path is root). | 1356 /* Remove final slash, if any (unless path is root). |
1744 stat behaves differently depending! */ | 1357 stat behaves differently depending! */ |
1745 if (XSTRING_LENGTH (abspath) > 1 | 1358 if (XSTRING_LENGTH (abspath) > 1 |
1746 && IS_DIRECTORY_SEP (XSTRING_BYTE (abspath, XSTRING_LENGTH (abspath) - 1)) | 1359 && IS_DIRECTORY_SEP (XSTRING_BYTE (abspath, XSTRING_LENGTH (abspath) - 1)) |
1747 && !IS_DEVICE_SEP (XSTRING_BYTE (abspath, XSTRING_LENGTH (abspath) - 2))) | 1360 && !IS_DEVICE_SEP (XSTRING_BYTE (abspath, XSTRING_LENGTH (abspath) - 2))) |
1748 /* We cannot take shortcuts; they might be wrong for magic file names. */ | 1361 /* We cannot take shortcuts; they might be wrong for magic file names. */ |
1749 abspath = Fdirectory_file_name (abspath); | 1362 abspath = Fdirectory_file_name (abspath); |
1750 #endif | |
1751 UNGCPRO; | 1363 UNGCPRO; |
1752 return abspath; | 1364 return abspath; |
1753 } | 1365 } |
1754 | 1366 |
1755 /* Signal an error if the file ABSNAME already exists. | 1367 /* Signal an error if the file ABSNAME already exists. |
1911 report_file_error ("Non-regular file", Fcons (filename, Qnil)); | 1523 report_file_error ("Non-regular file", Fcons (filename, Qnil)); |
1912 } | 1524 } |
1913 } | 1525 } |
1914 #endif /* S_ISREG && S_ISLNK */ | 1526 #endif /* S_ISREG && S_ISLNK */ |
1915 | 1527 |
1916 #ifdef VMS | |
1917 /* Create the copy file with the same record format as the input file */ | |
1918 ofd = sys_creat ((char *) XSTRING_DATA (newname), 0666, ifd); | |
1919 #else | |
1920 #ifdef MSDOS | 1528 #ifdef MSDOS |
1921 /* System's default file type was set to binary by _fmode in emacs.c. */ | 1529 /* System's default file type was set to binary by _fmode in emacs.c. */ |
1922 ofd = creat ((char *) XSTRING_DATA (newname), S_IREAD | S_IWRITE); | 1530 ofd = creat ((char *) XSTRING_DATA (newname), S_IREAD | S_IWRITE); |
1923 #else /* not MSDOS */ | 1531 #else /* not MSDOS */ |
1924 ofd = creat ((char *) XSTRING_DATA (newname), 0666); | 1532 ofd = creat ((char *) XSTRING_DATA (newname), 0666); |
1925 #endif /* not MSDOS */ | 1533 #endif /* not MSDOS */ |
1926 #endif /* VMS */ | |
1927 if (ofd < 0) | 1534 if (ofd < 0) |
1928 report_file_error ("Opening output file", list1 (newname)); | 1535 report_file_error ("Opening output file", list1 (newname)); |
1929 | 1536 |
1930 { | 1537 { |
1931 Lisp_Object ofd_locative = noseeum_cons (make_int (ofd), Qnil); | 1538 Lisp_Object ofd_locative = noseeum_cons (make_int (ofd), Qnil); |
2006 dirname_)); | 1613 dirname_)); |
2007 } | 1614 } |
2008 strncpy (dir, (char *) XSTRING_DATA (dirname_), | 1615 strncpy (dir, (char *) XSTRING_DATA (dirname_), |
2009 XSTRING_LENGTH (dirname_) + 1); | 1616 XSTRING_LENGTH (dirname_) + 1); |
2010 | 1617 |
2011 #ifndef VMS | |
2012 if (dir [XSTRING_LENGTH (dirname_) - 1] == '/') | 1618 if (dir [XSTRING_LENGTH (dirname_) - 1] == '/') |
2013 dir [XSTRING_LENGTH (dirname_) - 1] = 0; | 1619 dir [XSTRING_LENGTH (dirname_) - 1] = 0; |
2014 #endif | |
2015 | 1620 |
2016 #ifdef WINDOWSNT | 1621 #ifdef WINDOWSNT |
2017 if (mkdir (dir) != 0) | 1622 if (mkdir (dir) != 0) |
2018 #else | 1623 #else |
2019 if (mkdir (dir, 0777) != 0) | 1624 if (mkdir (dir, 0777) != 0) |
2293 UNGCPRO; | 1898 UNGCPRO; |
2294 return Qnil; | 1899 return Qnil; |
2295 } | 1900 } |
2296 #endif /* S_IFLNK */ | 1901 #endif /* S_IFLNK */ |
2297 | 1902 |
2298 #ifdef VMS | |
2299 | |
2300 DEFUN ("define-logical-name", Fdefine_logical_name, 2, 2, | |
2301 "sDefine logical name: \nsDefine logical name %s as: ", /* | |
2302 Define the job-wide logical name NAME to have the value STRING. | |
2303 If STRING is nil or a null string, the logical name NAME is deleted. | |
2304 */ | |
2305 (varname, string)) | |
2306 { | |
2307 CHECK_STRING (varname); | |
2308 if (NILP (string)) | |
2309 delete_logical_name ((char *) XSTRING_DATA (varname)); | |
2310 else | |
2311 { | |
2312 CHECK_STRING (string); | |
2313 | |
2314 if (XSTRING_LENGTH (string) == 0) | |
2315 delete_logical_name ((char *) XSTRING_DATA (varname)); | |
2316 else | |
2317 define_logical_name ((char *) XSTRING_DATA (varname), (char *) XSTRING_DATA (string)); | |
2318 } | |
2319 | |
2320 return string; | |
2321 } | |
2322 #endif /* VMS */ | |
2323 | |
2324 #ifdef HPUX_NET | 1903 #ifdef HPUX_NET |
2325 | 1904 |
2326 DEFUN ("sysnetunam", Fsysnetunam, 2, 2, 0, /* | 1905 DEFUN ("sysnetunam", Fsysnetunam, 2, 2, 0, /* |
2327 Open a network connection to PATH using LOGIN as the login string. | 1906 Open a network connection to PATH using LOGIN as the login string. |
2328 */ | 1907 */ |
2362 Bufbyte *ptr; | 1941 Bufbyte *ptr; |
2363 | 1942 |
2364 CHECK_STRING (filename); | 1943 CHECK_STRING (filename); |
2365 ptr = XSTRING_DATA (filename); | 1944 ptr = XSTRING_DATA (filename); |
2366 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~' | 1945 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~' |
2367 #ifdef VMS | |
2368 /* ??? This criterion is probably wrong for '<'. */ | |
2369 || strchr (ptr, ':') || strchr (ptr, '<') | |
2370 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']')) | |
2371 && ptr[1] != '.') | |
2372 #endif /* VMS */ | |
2373 #ifdef DOS_NT | 1946 #ifdef DOS_NT |
2374 || (*ptr != 0 && ptr[1] == ':' && (ptr[2] == '/' || ptr[2] == '\\')) | 1947 || (*ptr != 0 && ptr[1] == ':' && (ptr[2] == '/' || ptr[2] == '\\')) |
2375 #endif | 1948 #endif |
2376 ) | 1949 ) |
2377 return Qt; | 1950 return Qt; |
2548 | 2121 |
2549 | 2122 |
2550 GCPRO1 (abspath); | 2123 GCPRO1 (abspath); |
2551 dir = Ffile_name_directory (abspath); | 2124 dir = Ffile_name_directory (abspath); |
2552 UNGCPRO; | 2125 UNGCPRO; |
2553 #if defined (VMS) || defined (MSDOS) | 2126 #ifdef MSDOS |
2554 if (!NILP (dir)) | 2127 if (!NILP (dir)) |
2555 { | 2128 { |
2556 GCPRO1(dir); | 2129 GCPRO1(dir); |
2557 dir = Fdirectory_file_name (dir); | 2130 dir = Fdirectory_file_name (dir); |
2558 UNGCPRO; | 2131 UNGCPRO; |
2559 } | 2132 } |
2560 #endif /* VMS or MSDOS */ | 2133 #endif /* MSDOS */ |
2561 return (check_writable (!NILP (dir) ? (char *) XSTRING_DATA (dir) | 2134 return (check_writable (!NILP (dir) ? (char *) XSTRING_DATA (dir) |
2562 : "") | 2135 : "") |
2563 ? Qt : Qnil); | 2136 ? Qt : Qnil); |
2564 } | 2137 } |
2565 | 2138 |
2795 umask (mode); | 2368 umask (mode); |
2796 | 2369 |
2797 return make_int ((~ mode) & 0777); | 2370 return make_int ((~ mode) & 0777); |
2798 } | 2371 } |
2799 | 2372 |
2800 #ifndef VMS | |
2801 DEFUN ("unix-sync", Funix_sync, 0, 0, "", /* | 2373 DEFUN ("unix-sync", Funix_sync, 0, 0, "", /* |
2802 Tell Unix to finish all pending disk updates. | 2374 Tell Unix to finish all pending disk updates. |
2803 */ | 2375 */ |
2804 ()) | 2376 ()) |
2805 { | 2377 { |
2806 #ifndef WINDOWSNT | 2378 #ifndef WINDOWSNT |
2807 sync (); | 2379 sync (); |
2808 #endif | 2380 #endif |
2809 return Qnil; | 2381 return Qnil; |
2810 } | 2382 } |
2811 #endif /* !VMS */ | |
2812 | 2383 |
2813 | 2384 |
2814 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, 2, 2, 0, /* | 2385 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, 2, 2, 0, /* |
2815 Return t if file FILE1 is newer than file FILE2. | 2386 Return t if file FILE1 is newer than file FILE2. |
2816 If FILE1 does not exist, the answer is nil; | 2387 If FILE1 does not exist, the answer is nil; |
2959 st.st_mtime = -1; | 2530 st.st_mtime = -1; |
2960 goto notfound; | 2531 goto notfound; |
2961 } | 2532 } |
2962 | 2533 |
2963 #ifdef S_IFREG | 2534 #ifdef S_IFREG |
2964 /* This code will need to be changed in order to work on named | 2535 /* Signal an error if we are accessing a non-regular file, with |
2965 pipes, and it's probably just not worth it. So we should at | 2536 REPLACE, BEG or END being non-nil. */ |
2966 least signal an error. */ | |
2967 if (!S_ISREG (st.st_mode)) | 2537 if (!S_ISREG (st.st_mode)) |
2968 { | 2538 { |
2969 not_regular = 1; | 2539 not_regular = 1; |
2970 | 2540 |
2971 if (!NILP (visit)) | 2541 if (!NILP (visit)) |
2988 beg = Qzero; | 2558 beg = Qzero; |
2989 | 2559 |
2990 if (!NILP (end)) | 2560 if (!NILP (end)) |
2991 CHECK_INT (end); | 2561 CHECK_INT (end); |
2992 | 2562 |
2563 /* Here, we should call some form of interruptable_open, so the user | |
2564 can quit gracefully when opening named pipes. interruptable_open | |
2565 should be just like sys_open in sysdep.c, only it would call QUIT | |
2566 if interrupted by EINTR. */ | |
2993 if (fd < 0) | 2567 if (fd < 0) |
2994 if ((fd = open ((char *) XSTRING_DATA (filename), O_RDONLY, 0)) < 0) | 2568 if ((fd = open ((char *) XSTRING_DATA (filename), O_RDONLY, 0)) < 0) |
2995 goto badopen; | 2569 goto badopen; |
2996 | 2570 |
2997 /* Replacement should preserve point as it preserves markers. */ | 2571 /* Replacement should preserve point as it preserves markers. */ |
3368 int failure; | 2942 int failure; |
3369 int save_errno = 0; | 2943 int save_errno = 0; |
3370 struct stat st; | 2944 struct stat st; |
3371 Lisp_Object fn; | 2945 Lisp_Object fn; |
3372 int speccount = specpdl_depth (); | 2946 int speccount = specpdl_depth (); |
3373 #ifdef VMS | |
3374 unsigned char *fname = 0; /* If non-0, original filename (must rename) */ | |
3375 #endif /* VMS */ | |
3376 int visiting_other = STRINGP (visit); | 2947 int visiting_other = STRINGP (visit); |
3377 int visiting = (EQ (visit, Qt) || visiting_other); | 2948 int visiting = (EQ (visit, Qt) || visiting_other); |
3378 int quietly = (!visiting && !NILP (visit)); | 2949 int quietly = (!visiting && !NILP (visit)); |
3379 Lisp_Object visit_file = Qnil; | 2950 Lisp_Object visit_file = Qnil; |
3380 Lisp_Object annotations = Qnil; | 2951 Lisp_Object annotations = Qnil; |
3483 #else /* not DOS_NT */ | 3054 #else /* not DOS_NT */ |
3484 desc = open ((char *) XSTRING_DATA (fn), O_WRONLY, 0); | 3055 desc = open ((char *) XSTRING_DATA (fn), O_WRONLY, 0); |
3485 #endif /* not DOS_NT */ | 3056 #endif /* not DOS_NT */ |
3486 | 3057 |
3487 if (desc < 0) | 3058 if (desc < 0) |
3488 #ifndef VMS | |
3489 { | 3059 { |
3490 #ifdef DOS_NT | 3060 #ifdef DOS_NT |
3491 desc = open ((char *) XSTRING_DATA (fn), | 3061 desc = open ((char *) XSTRING_DATA (fn), |
3492 (O_WRONLY | O_TRUNC | O_CREAT | O_BINARY), | 3062 (O_WRONLY | O_TRUNC | O_CREAT | O_BINARY), |
3493 (S_IREAD | S_IWRITE)); | 3063 (S_IREAD | S_IWRITE)); |
3494 #else /* not DOS_NT */ | 3064 #else /* not DOS_NT */ |
3495 desc = creat ((char *) XSTRING_DATA (fn), | 3065 desc = creat ((char *) XSTRING_DATA (fn), |
3496 ((auto_saving) ? auto_save_mode_bits : 0666)); | 3066 ((auto_saving) ? auto_save_mode_bits : 0666)); |
3497 #endif /* DOS_NT */ | 3067 #endif /* DOS_NT */ |
3498 } | 3068 } |
3499 #else /* VMS */ | |
3500 { | |
3501 if (auto_saving) /* Overwrite any previous version of autosave file */ | |
3502 { | |
3503 char *fn_data = XSTRING_DATA (fn); | |
3504 /* if fn exists, truncate to zero length */ | |
3505 vms_truncate (fn_data); | |
3506 desc = open (fn_data, O_RDWR, 0); | |
3507 if (desc < 0) | |
3508 desc = creat_copy_attrs ((STRINGP (current_buffer->filename) | |
3509 ? (char *) | |
3510 XSTRING_DATA (current_buffer->filename) | |
3511 : 0), | |
3512 fn_data); | |
3513 } | |
3514 else /* Write to temporary name and rename if no errors */ | |
3515 { | |
3516 Lisp_Object temp_name; | |
3517 | |
3518 struct gcpro gcpro1, gcpro2, gcpro3; | |
3519 GCPRO3 (start, filename, visit_file); | |
3520 { | |
3521 struct gcpro gcpro1, gcpro2, gcpro3; /* Don't have GCPRO6 */ | |
3522 | |
3523 GCPRO3 (fn, fname, annotations); | |
3524 | |
3525 temp_name = Ffile_name_directory (filename); | |
3526 | |
3527 if (NILP (temp_name)) | |
3528 desc = creat ((char *) XSTRING_DATA (fn), 0666); | |
3529 else | |
3530 { | |
3531 temp_name = | |
3532 Fmake_temp_name (concat2 (temp_name, | |
3533 build_string ("$$SAVE$$"))); | |
3534 fname = filename; | |
3535 fn = temp_name; | |
3536 desc = creat_copy_attrs (fname, | |
3537 (char *) XSTRING_DATA (fn)); | |
3538 if (desc < 0) | |
3539 { | |
3540 char *fn_data; | |
3541 /* If we can't open the temporary file, try creating a new | |
3542 version of the original file. VMS "creat" creates a | |
3543 new version rather than truncating an existing file. */ | |
3544 fn = fname; | |
3545 fname = Qnil; | |
3546 fn_data = XSTRING_DATA (fn); | |
3547 desc = creat (fn_data, 0666); | |
3548 #if 0 /* This can clobber an existing file and fail | |
3549 to replace it, if the user runs out of | |
3550 space. */ | |
3551 if (desc < 0) | |
3552 { | |
3553 /* We can't make a new version; | |
3554 try to truncate and rewrite existing version if any. | |
3555 */ | |
3556 vms_truncate (fn_data); | |
3557 desc = open (fn_data, O_RDWR, 0); | |
3558 } | |
3559 #endif /* 0 */ | |
3560 } | |
3561 } | |
3562 UNGCPRO; | |
3563 } | |
3564 UNGCPRO; | |
3565 } | |
3566 } | |
3567 #endif /* VMS */ | |
3568 | 3069 |
3569 if (desc < 0) | 3070 if (desc < 0) |
3570 { | 3071 { |
3571 #ifdef CLASH_DETECTION | 3072 #ifdef CLASH_DETECTION |
3572 save_errno = errno; | 3073 save_errno = errno; |
3595 #endif /* CLASH_DETECTION */ | 3096 #endif /* CLASH_DETECTION */ |
3596 report_file_error ("Lseek error", | 3097 report_file_error ("Lseek error", |
3597 list1 (filename)); | 3098 list1 (filename)); |
3598 } | 3099 } |
3599 } | 3100 } |
3600 | |
3601 #ifdef VMS | |
3602 /* | |
3603 * Kludge Warning: The VMS C RTL likes to insert carriage returns | |
3604 * if we do writes that don't end with a carriage return. Furthermore | |
3605 * it cannot handle writes of more then 16K. The modified | |
3606 * version of "sys_write" in SYSDEP.C (see comment there) copes with | |
3607 * this EXCEPT for the last record (iff it doesn't end with a carriage | |
3608 * return). This implies that if your buffer doesn't end with a carriage | |
3609 * return, you get one free... tough. However it also means that if | |
3610 * we make two calls to sys_write (a la the following code) you can | |
3611 * get one at the gap as well. The easiest way to fix this (honest) | |
3612 * is to move the gap to the next newline (or the end of the buffer). | |
3613 * Thus this change. | |
3614 * | |
3615 * Yech! | |
3616 */ | |
3617 you lose -- fix this | |
3618 if (GPT > BUF_BEG (current_buffer) && *GPT_ADDR[-1] != '\n') | |
3619 move_gap (find_next_newline (current_buffer, GPT, 1)); | |
3620 #endif /* VMS */ | |
3621 | 3101 |
3622 failure = 0; | 3102 failure = 0; |
3623 | 3103 |
3624 /* Note: I tried increasing the buffering size, along with | 3104 /* Note: I tried increasing the buffering size, along with |
3625 various other tricks, but nothing seemed to make much of | 3105 various other tricks, but nothing seemed to make much of |
3702 XCAR (desc_locative) = Qnil; | 3182 XCAR (desc_locative) = Qnil; |
3703 unbind_to (speccount, Qnil); | 3183 unbind_to (speccount, Qnil); |
3704 } | 3184 } |
3705 | 3185 |
3706 | 3186 |
3707 #ifdef VMS | |
3708 /* If we wrote to a temporary name and had no errors, rename to real name. */ | |
3709 if (!NILP (fname)) | |
3710 { | |
3711 if (!failure) | |
3712 { | |
3713 failure = (rename ((char *) XSTRING_DATA (fn), | |
3714 (char *) XSTRING_DATA (fname)) | |
3715 != 0); | |
3716 save_errno = errno; | |
3717 } | |
3718 fn = fname; | |
3719 } | |
3720 #endif /* VMS */ | |
3721 | |
3722 #if 1 /* defined (VMS) || defined (APOLLO) */ | 3187 #if 1 /* defined (VMS) || defined (APOLLO) */ |
3723 stat ((char *) XSTRING_DATA (fn), &st); | 3188 stat ((char *) XSTRING_DATA (fn), &st); |
3724 #endif | 3189 #endif |
3725 | 3190 |
3726 #ifdef CLASH_DETECTION | 3191 #ifdef CLASH_DETECTION |
4636 DEFSUBR (Frename_file); | 4101 DEFSUBR (Frename_file); |
4637 DEFSUBR (Fadd_name_to_file); | 4102 DEFSUBR (Fadd_name_to_file); |
4638 #ifdef S_IFLNK | 4103 #ifdef S_IFLNK |
4639 DEFSUBR (Fmake_symbolic_link); | 4104 DEFSUBR (Fmake_symbolic_link); |
4640 #endif /* S_IFLNK */ | 4105 #endif /* S_IFLNK */ |
4641 #ifdef VMS | |
4642 DEFSUBR (Fdefine_logical_name); | |
4643 #endif /* VMS */ | |
4644 #ifdef HPUX_NET | 4106 #ifdef HPUX_NET |
4645 DEFSUBR (Fsysnetunam); | 4107 DEFSUBR (Fsysnetunam); |
4646 #endif /* HPUX_NET */ | 4108 #endif /* HPUX_NET */ |
4647 DEFSUBR (Ffile_name_absolute_p); | 4109 DEFSUBR (Ffile_name_absolute_p); |
4648 DEFSUBR (Ffile_exists_p); | 4110 DEFSUBR (Ffile_exists_p); |
4688 If it is t, which is the default, auto-save files are written in the | 4150 If it is t, which is the default, auto-save files are written in the |
4689 same format as a regular save would use. | 4151 same format as a regular save would use. |
4690 */ ); | 4152 */ ); |
4691 Vauto_save_file_format = Qt; | 4153 Vauto_save_file_format = Qt; |
4692 | 4154 |
4693 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm /* | |
4694 *Non-nil means write new files with record format `stmlf'. | |
4695 nil means use format `var'. This variable is meaningful only on VMS. | |
4696 */ ); | |
4697 vms_stmlf_recfm = 0; | |
4698 | |
4699 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist /* | 4155 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist /* |
4700 *Alist of elements (REGEXP . HANDLER) for file names handled specially. | 4156 *Alist of elements (REGEXP . HANDLER) for file names handled specially. |
4701 If a file name matches REGEXP, then all I/O on that file is done by calling | 4157 If a file name matches REGEXP, then all I/O on that file is done by calling |
4702 HANDLER. | 4158 HANDLER. |
4703 | 4159 |