comparison src/fileio.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents 4af0ddfb7c5b
children a86b2b5e0111
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
54 #endif /* HPUX_PRE_8_0 */ 54 #endif /* HPUX_PRE_8_0 */
55 #endif /* HPUX */ 55 #endif /* HPUX */
56 56
57 #ifdef WINDOWSNT 57 #ifdef WINDOWSNT
58 #define NOMINMAX 1 58 #define NOMINMAX 1
59 #include <windows.h>
60 #include <direct.h> 59 #include <direct.h>
61 #include <fcntl.h> 60 #include <fcntl.h>
62 #include <stdlib.h> 61 #include <stdlib.h>
63 #endif /* not WINDOWSNT */ 62 #endif /* not WINDOWSNT */
64 63
69 } while (0) 68 } while (0)
70 #define IS_DRIVE(x) isalpha (x) 69 #define IS_DRIVE(x) isalpha (x)
71 /* Need to lower-case the drive letter, or else expanded 70 /* Need to lower-case the drive letter, or else expanded
72 filenames will sometimes compare inequal, because 71 filenames will sometimes compare inequal, because
73 `expand-file-name' doesn't always down-case the drive letter. */ 72 `expand-file-name' doesn't always down-case the drive letter. */
74 #define DRIVE_LETTER(x) (tolower (x)) 73 #define DRIVE_LETTER(x) tolower (x)
75 #endif /* WINDOWSNT */ 74 #endif /* WINDOWSNT */
76 75
77 int lisp_to_time (Lisp_Object, time_t *); 76 int lisp_to_time (Lisp_Object, time_t *);
78 Lisp_Object time_to_lisp (time_t); 77 Lisp_Object time_to_lisp (time_t);
79 78
107 /* File name in which we write a list of all our auto save files. */ 106 /* File name in which we write a list of all our auto save files. */
108 Lisp_Object Vauto_save_list_file_name; 107 Lisp_Object Vauto_save_list_file_name;
109 108
110 int disable_auto_save_when_buffer_shrinks; 109 int disable_auto_save_when_buffer_shrinks;
111 110
112 Lisp_Object Qfile_name_handler_alist;
113
114 Lisp_Object Vdirectory_sep_char; 111 Lisp_Object Vdirectory_sep_char;
115 112
116 /* These variables describe handlers that have "already" had a chance 113 /* These variables describe handlers that have "already" had a chance
117 to handle the current operation. 114 to handle the current operation.
118 115
136 EXFUN (Frunning_temacs_p, 0); 133 EXFUN (Frunning_temacs_p, 0);
137 134
138 /* signal a file error when errno contains a meaningful value. */ 135 /* signal a file error when errno contains a meaningful value. */
139 136
140 DOESNT_RETURN 137 DOESNT_RETURN
141 report_file_error (CONST char *string, Lisp_Object data) 138 report_file_error (const char *string, Lisp_Object data)
142 { 139 {
143 /* #### dmoore - This uses current_buffer, better make sure no one 140 /* #### dmoore - This uses current_buffer, better make sure no one
144 has GC'd the current buffer. File handlers are giving me a headache 141 has GC'd the current buffer. File handlers are giving me a headache
145 maybe I'll just always protect current_buffer around all of those 142 maybe I'll just always protect current_buffer around all of those
146 calls. */ 143 calls. */
149 Fcons (build_translated_string (string), 146 Fcons (build_translated_string (string),
150 Fcons (lisp_strerror (errno), data))); 147 Fcons (lisp_strerror (errno), data)));
151 } 148 }
152 149
153 void 150 void
154 maybe_report_file_error (CONST char *string, Lisp_Object data, 151 maybe_report_file_error (const char *string, Lisp_Object data,
155 Lisp_Object class, Error_behavior errb) 152 Lisp_Object class, Error_behavior errb)
156 { 153 {
157 /* Optimization: */ 154 /* Optimization: */
158 if (ERRB_EQ (errb, ERROR_ME_NOT)) 155 if (ERRB_EQ (errb, ERROR_ME_NOT))
159 return; 156 return;
165 } 162 }
166 163
167 /* signal a file error when errno does not contain a meaningful value. */ 164 /* signal a file error when errno does not contain a meaningful value. */
168 165
169 DOESNT_RETURN 166 DOESNT_RETURN
170 signal_file_error (CONST char *string, Lisp_Object data) 167 signal_file_error (const char *string, Lisp_Object data)
171 { 168 {
172 signal_error (Qfile_error, 169 signal_error (Qfile_error,
173 list2 (build_translated_string (string), data)); 170 list2 (build_translated_string (string), data));
174 } 171 }
175 172
176 void 173 void
177 maybe_signal_file_error (CONST char *string, Lisp_Object data, 174 maybe_signal_file_error (const char *string, Lisp_Object data,
178 Lisp_Object class, Error_behavior errb) 175 Lisp_Object class, Error_behavior errb)
179 { 176 {
180 /* Optimization: */ 177 /* Optimization: */
181 if (ERRB_EQ (errb, ERROR_ME_NOT)) 178 if (ERRB_EQ (errb, ERROR_ME_NOT))
182 return; 179 return;
184 list2 (build_translated_string (string), data), 181 list2 (build_translated_string (string), data),
185 class, errb); 182 class, errb);
186 } 183 }
187 184
188 DOESNT_RETURN 185 DOESNT_RETURN
189 signal_double_file_error (CONST char *string1, CONST char *string2, 186 signal_double_file_error (const char *string1, const char *string2,
190 Lisp_Object data) 187 Lisp_Object data)
191 { 188 {
192 signal_error (Qfile_error, 189 signal_error (Qfile_error,
193 list3 (build_translated_string (string1), 190 list3 (build_translated_string (string1),
194 build_translated_string (string2), 191 build_translated_string (string2),
195 data)); 192 data));
196 } 193 }
197 194
198 void 195 void
199 maybe_signal_double_file_error (CONST char *string1, CONST char *string2, 196 maybe_signal_double_file_error (const char *string1, const char *string2,
200 Lisp_Object data, Lisp_Object class, 197 Lisp_Object data, Lisp_Object class,
201 Error_behavior errb) 198 Error_behavior errb)
202 { 199 {
203 /* Optimization: */ 200 /* Optimization: */
204 if (ERRB_EQ (errb, ERROR_ME_NOT)) 201 if (ERRB_EQ (errb, ERROR_ME_NOT))
209 data), 206 data),
210 class, errb); 207 class, errb);
211 } 208 }
212 209
213 DOESNT_RETURN 210 DOESNT_RETURN
214 signal_double_file_error_2 (CONST char *string1, CONST char *string2, 211 signal_double_file_error_2 (const char *string1, const char *string2,
215 Lisp_Object data1, Lisp_Object data2) 212 Lisp_Object data1, Lisp_Object data2)
216 { 213 {
217 signal_error (Qfile_error, 214 signal_error (Qfile_error,
218 list4 (build_translated_string (string1), 215 list4 (build_translated_string (string1),
219 build_translated_string (string2), 216 build_translated_string (string2),
220 data1, data2)); 217 data1, data2));
221 } 218 }
222 219
223 void 220 void
224 maybe_signal_double_file_error_2 (CONST char *string1, CONST char *string2, 221 maybe_signal_double_file_error_2 (const char *string1, const char *string2,
225 Lisp_Object data1, Lisp_Object data2, 222 Lisp_Object data1, Lisp_Object data2,
226 Lisp_Object class, Error_behavior errb) 223 Lisp_Object class, Error_behavior errb)
227 { 224 {
228 /* Optimization: */ 225 /* Optimization: */
229 if (ERRB_EQ (errb, ERROR_ME_NOT)) 226 if (ERRB_EQ (errb, ERROR_ME_NOT))
240 The string needs to be converted since it may be localized. 237 The string needs to be converted since it may be localized.
241 Perhaps this should use strerror-coding-system instead? */ 238 Perhaps this should use strerror-coding-system instead? */
242 Lisp_Object 239 Lisp_Object
243 lisp_strerror (int errnum) 240 lisp_strerror (int errnum)
244 { 241 {
245 return build_ext_string (strerror (errnum), FORMAT_NATIVE); 242 return build_ext_string (strerror (errnum), Qnative);
246 } 243 }
247 244
248 static Lisp_Object 245 static Lisp_Object
249 close_file_unwind (Lisp_Object fd) 246 close_file_unwind (Lisp_Object fd)
250 { 247 {
280 /* Versions of read() and write() that allow quitting out of the actual 277 /* Versions of read() and write() that allow quitting out of the actual
281 I/O. We don't use immediate_quit (i.e. direct longjmp() out of the 278 I/O. We don't use immediate_quit (i.e. direct longjmp() out of the
282 signal handler) because that's way too losing. 279 signal handler) because that's way too losing.
283 280
284 (#### Actually, longjmp()ing out of the signal handler may not be 281 (#### Actually, longjmp()ing out of the signal handler may not be
285 as losing as I thought. See sys_do_signal() in sysdep.c.) 282 as losing as I thought. See sys_do_signal() in sysdep.c.) */
286 283
287 Solaris include files declare the return value as ssize_t. 284 ssize_t
288 Is that standard? */
289 int
290 read_allowing_quit (int fildes, void *buf, size_t size) 285 read_allowing_quit (int fildes, void *buf, size_t size)
291 { 286 {
292 QUIT; 287 QUIT;
293 return sys_read_1 (fildes, buf, size, 1); 288 return sys_read_1 (fildes, buf, size, 1);
294 } 289 }
295 290
296 int 291 ssize_t
297 write_allowing_quit (int fildes, CONST void *buf, size_t size) 292 write_allowing_quit (int fildes, const void *buf, size_t size)
298 { 293 {
299 QUIT; 294 QUIT;
300 return sys_write_1 (fildes, buf, size, 1); 295 return sys_write_1 (fildes, buf, size, 1);
301 } 296 }
302 297
584 * 579 *
585 * Value is nonzero if the string output is different from the input. 580 * Value is nonzero if the string output is different from the input.
586 */ 581 */
587 582
588 static int 583 static int
589 directory_file_name (CONST char *src, char *dst) 584 directory_file_name (const char *src, char *dst)
590 { 585 {
591 long slen; 586 long slen = strlen (src);
592
593 slen = strlen (src);
594 /* Process as Unix format: just remove any final slash. 587 /* Process as Unix format: just remove any final slash.
595 But leave "/" unchanged; do not change it to "". */ 588 But leave "/" unchanged; do not change it to "". */
596 strcpy (dst, src); 589 strcpy (dst, src);
597 #ifdef APOLLO
598 /* Handle // as root for apollo's. */
599 if ((slen > 2 && dst[slen - 1] == '/')
600 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
601 dst[slen - 1] = 0;
602 #else
603 if (slen > 1 590 if (slen > 1
604 && IS_DIRECTORY_SEP (dst[slen - 1]) 591 && IS_DIRECTORY_SEP (dst[slen - 1])
605 #ifdef WINDOWSNT 592 #ifdef WINDOWSNT
606 && !IS_ANY_SEP (dst[slen - 2]) 593 && !IS_ANY_SEP (dst[slen - 2])
607 #endif /* WINDOWSNT */ 594 #endif /* WINDOWSNT */
608 ) 595 )
609 dst[slen - 1] = 0; 596 dst[slen - 1] = 0;
610 #endif /* APOLLO */
611 return 1; 597 return 1;
612 } 598 }
613 599
614 DEFUN ("directory-file-name", Fdirectory_file_name, 1, 1, 0, /* 600 DEFUN ("directory-file-name", Fdirectory_file_name, 1, 1, 0, /*
615 Return the file name of the directory named DIR. 601 Return the file name of the directory named DIR.
735 count += 25229; 721 count += 25229;
736 count %= 225307; 722 count %= 225307;
737 723
738 QUIT; 724 QUIT;
739 725
740 if (stat ((CONST char *) data, &ignored) < 0) 726 if (stat ((const char *) data, &ignored) < 0)
741 { 727 {
742 /* We want to return only if errno is ENOENT. */ 728 /* We want to return only if errno is ENOENT. */
743 if (errno == ENOENT) 729 if (errno == ENOENT)
744 return val; 730 return val;
745 731
979 if (nm[0] == '~') /* prefix ~ */ 965 if (nm[0] == '~') /* prefix ~ */
980 { 966 {
981 if (IS_DIRECTORY_SEP (nm[1]) 967 if (IS_DIRECTORY_SEP (nm[1])
982 || nm[1] == 0) /* ~ by itself */ 968 || nm[1] == 0) /* ~ by itself */
983 { 969 {
984 char * newdir_external = get_home_directory (); 970 Extbyte *newdir_external = get_home_directory ();
985 971
986 if (newdir_external == NULL) 972 if (newdir_external == NULL)
987 newdir = (Bufbyte *) ""; 973 newdir = (Bufbyte *) "";
988 else 974 else
989 GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (newdir_external, newdir); 975 TO_INTERNAL_FORMAT (C_STRING, newdir_external,
976 C_STRING_ALLOCA, (* ((char **) &newdir)),
977 Qfile_name);
990 978
991 nm++; 979 nm++;
992 #ifdef WINDOWSNT 980 #ifdef WINDOWSNT
993 collapse_newdir = 0; 981 collapse_newdir = 0;
994 #endif 982 #endif
1020 #else /* not WINDOWSNT */ 1008 #else /* not WINDOWSNT */
1021 #ifdef __CYGWIN32__ 1009 #ifdef __CYGWIN32__
1022 if ((user = user_login_name (NULL)) != NULL) 1010 if ((user = user_login_name (NULL)) != NULL)
1023 { 1011 {
1024 /* Does the user login name match the ~name? */ 1012 /* Does the user login name match the ~name? */
1025 if (strcmp(user,((char *) o + 1)) == 0) 1013 if (strcmp (user, (char *) o + 1) == 0)
1026 { 1014 {
1027 newdir = (Bufbyte *) get_home_directory(); 1015 newdir = (Bufbyte *) get_home_directory();
1028 nm = p; 1016 nm = p;
1029 } 1017 }
1030 } 1018 }
1031 if (! newdir) 1019 if (! newdir)
1032 { 1020 {
1301 if (!NILP (handler)) 1289 if (!NILP (handler))
1302 return call2_check_string (handler, Qfile_truename, expanded_name); 1290 return call2_check_string (handler, Qfile_truename, expanded_name);
1303 1291
1304 { 1292 {
1305 char resolved_path[MAXPATHLEN]; 1293 char resolved_path[MAXPATHLEN];
1306 char path[MAXPATHLEN]; 1294 Extbyte *path;
1307 char *p = path; 1295 Extbyte *p;
1308 int elen = XSTRING_LENGTH (expanded_name); 1296 Extcount elen;
1309 1297
1310 if (elen >= countof (path)) 1298 TO_EXTERNAL_FORMAT (LISP_STRING, expanded_name,
1299 ALLOCA, (path, elen),
1300 Qfile_name);
1301 p = path;
1302 if (elen > MAXPATHLEN)
1311 goto toolong; 1303 goto toolong;
1312 1304
1313 memcpy (path, XSTRING_DATA (expanded_name), elen + 1);
1314 /* memset (resolved_path, 0, sizeof (resolved_path)); */
1315
1316 /* Try doing it all at once. */ 1305 /* Try doing it all at once. */
1317 /* !!#### Does realpath() Mule-encapsulate? */ 1306 /* !! Does realpath() Mule-encapsulate?
1318 if (!xrealpath (path, resolved_path)) 1307 Answer: Nope! So we do it above */
1308 if (!xrealpath ((char *) path, resolved_path))
1319 { 1309 {
1320 /* Didn't resolve it -- have to do it one component at a time. */ 1310 /* Didn't resolve it -- have to do it one component at a time. */
1321 /* "realpath" is a typically useless, stupid un*x piece of crap. 1311 /* "realpath" is a typically useless, stupid un*x piece of crap.
1322 It claims to return a useful value in the "error" case, but since 1312 It claims to return a useful value in the "error" case, but since
1323 there is no indication provided of how far along the pathname 1313 there is no indication provided of how far along the pathname
1324 the function went before erring, there is no way to use the 1314 the function went before erring, there is no way to use the
1325 partial result returned. What a piece of junk. */ 1315 partial result returned. What a piece of junk. */
1326 for (;;) 1316 for (;;)
1327 { 1317 {
1328 p = (char *) memchr (p + 1, '/', elen - (p + 1 - path)); 1318 p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path));
1329 if (p) 1319 if (p)
1330 *p = 0; 1320 *p = 0;
1331 1321
1332 /* memset (resolved_path, 0, sizeof (resolved_path)); */ 1322 /* memset (resolved_path, 0, sizeof (resolved_path)); */
1333 if (xrealpath (path, resolved_path)) 1323 if (xrealpath ((char *) path, resolved_path))
1334 { 1324 {
1335 if (p) 1325 if (p)
1336 *p = '/'; 1326 *p = '/';
1337 else 1327 else
1338 break; 1328 break;
1376 goto toolong; 1366 goto toolong;
1377 resolved_path[rlen] = '/'; 1367 resolved_path[rlen] = '/';
1378 resolved_path[rlen + 1] = 0; 1368 resolved_path[rlen + 1] = 0;
1379 rlen = rlen + 1; 1369 rlen = rlen + 1;
1380 } 1370 }
1381 return make_ext_string ((Bufbyte *) resolved_path, rlen, FORMAT_BINARY); 1371 return make_ext_string ((Bufbyte *) resolved_path, rlen, Qbinary);
1382 } 1372 }
1383 1373
1384 toolong: 1374 toolong:
1385 errno = ENAMETOOLONG; 1375 errno = ENAMETOOLONG;
1386 goto lose; 1376 goto lose;
1427 /* If /~ or // appears, discard everything through first slash. */ 1417 /* If /~ or // appears, discard everything through first slash. */
1428 1418
1429 for (p = nm; p != endp; p++) 1419 for (p = nm; p != endp; p++)
1430 { 1420 {
1431 if ((p[0] == '~' 1421 if ((p[0] == '~'
1432 #if defined (APOLLO) || defined (WINDOWSNT) || defined (__CYGWIN32__) 1422 #if defined (WINDOWSNT) || defined (__CYGWIN32__)
1433 /* // at start of file name is meaningful in Apollo and 1423 /* // at start of file name is meaningful in WindowsNT systems */
1434 WindowsNT systems */
1435 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm) 1424 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1436 #else /* not (APOLLO || WINDOWSNT || __CYGWIN32__) */ 1425 #else /* not (WINDOWSNT || __CYGWIN32__) */
1437 || IS_DIRECTORY_SEP (p[0]) 1426 || IS_DIRECTORY_SEP (p[0])
1438 #endif /* not (APOLLO || WINDOWSNT || __CYGWIN32__) */ 1427 #endif /* not (WINDOWSNT || __CYGWIN32__) */
1439 ) 1428 )
1440 && p != nm 1429 && p != nm
1441 && (IS_DIRECTORY_SEP (p[-1]))) 1430 && (IS_DIRECTORY_SEP (p[-1])))
1442 { 1431 {
1443 nm = p; 1432 nm = p;
1559 1548
1560 /* If /~ or // appears, discard everything through first slash. */ 1549 /* If /~ or // appears, discard everything through first slash. */
1561 1550
1562 for (p = xnm; p != x; p++) 1551 for (p = xnm; p != x; p++)
1563 if ((p[0] == '~' 1552 if ((p[0] == '~'
1564 #if defined (APOLLO) || defined (WINDOWSNT) 1553 #if defined (WINDOWSNT)
1565 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm) 1554 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
1566 #else /* not (APOLLO || WINDOWSNT) */ 1555 #else /* not WINDOWSNT */
1567 || IS_DIRECTORY_SEP (p[0]) 1556 || IS_DIRECTORY_SEP (p[0])
1568 #endif /* APOLLO || WINDOWSNT */ 1557 #endif /* not WINDOWSNT */
1569 ) 1558 )
1570 /* don't do p[-1] if that would go off the beginning --jwz */ 1559 /* don't do p[-1] if that would go off the beginning --jwz */
1571 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1])) 1560 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1]))
1572 xnm = p; 1561 xnm = p;
1573 #ifdef WINDOWSNT 1562 #ifdef WINDOWSNT
1620 to alter the file. 1609 to alter the file.
1621 *STATPTR is used to store the stat information if the file exists. 1610 *STATPTR is used to store the stat information if the file exists.
1622 If the file does not exist, STATPTR->st_mode is set to 0. */ 1611 If the file does not exist, STATPTR->st_mode is set to 0. */
1623 1612
1624 static void 1613 static void
1625 barf_or_query_if_file_exists (Lisp_Object absname, CONST char *querystring, 1614 barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
1626 int interactive, struct stat *statptr) 1615 int interactive, struct stat *statptr)
1627 { 1616 {
1628 /* This function can GC. GC checked 1997.04.06. */ 1617 /* This function can GC. GC checked 1997.04.06. */
1629 struct stat statbuf; 1618 struct stat statbuf;
1630 1619
1638 { 1627 {
1639 Lisp_Object prompt; 1628 Lisp_Object prompt;
1640 struct gcpro gcpro1; 1629 struct gcpro gcpro1;
1641 1630
1642 prompt = emacs_doprnt_string_c 1631 prompt = emacs_doprnt_string_c
1643 ((CONST Bufbyte *) GETTEXT ("File %s already exists; %s anyway? "), 1632 ((const Bufbyte *) GETTEXT ("File %s already exists; %s anyway? "),
1644 Qnil, -1, XSTRING_DATA (absname), 1633 Qnil, -1, XSTRING_DATA (absname),
1645 GETTEXT (querystring)); 1634 GETTEXT (querystring));
1646 1635
1647 GCPRO1 (prompt); 1636 GCPRO1 (prompt);
1648 tem = call1 (Qyes_or_no_p, prompt); 1637 tem = call1 (Qyes_or_no_p, prompt);
1730 1719
1731 if (NILP (ok_if_already_exists) 1720 if (NILP (ok_if_already_exists)
1732 || INTP (ok_if_already_exists)) 1721 || INTP (ok_if_already_exists))
1733 barf_or_query_if_file_exists (newname, "copy to it", 1722 barf_or_query_if_file_exists (newname, "copy to it",
1734 INTP (ok_if_already_exists), &out_st); 1723 INTP (ok_if_already_exists), &out_st);
1735 else if (stat ((CONST char *) XSTRING_DATA (newname), &out_st) < 0) 1724 else if (stat ((const char *) XSTRING_DATA (newname), &out_st) < 0)
1736 out_st.st_mode = 0; 1725 out_st.st_mode = 0;
1737 1726
1738 ifd = interruptible_open ((char *) XSTRING_DATA (filename), O_RDONLY | OPEN_BINARY, 0); 1727 ifd = interruptible_open ((char *) XSTRING_DATA (filename), O_RDONLY | OPEN_BINARY, 0);
1739 if (ifd < 0) 1728 if (ifd < 0)
1740 report_file_error ("Opening input file", list1 (filename)); 1729 report_file_error ("Opening input file", list1 (filename));
1803 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0); 1792 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
1804 if (set_file_times ((char *) XSTRING_DATA (newname), atime, 1793 if (set_file_times ((char *) XSTRING_DATA (newname), atime,
1805 mtime)) 1794 mtime))
1806 report_file_error ("I/O error", list1 (newname)); 1795 report_file_error ("I/O error", list1 (newname));
1807 } 1796 }
1808 chmod ((CONST char *) XSTRING_DATA (newname), 1797 chmod ((const char *) XSTRING_DATA (newname),
1809 st.st_mode & 07777); 1798 st.st_mode & 07777);
1810 } 1799 }
1811 1800
1812 /* We'll close it by hand */ 1801 /* We'll close it by hand */
1813 XCAR (ofd_locative) = Qnil; 1802 XCAR (ofd_locative) = Qnil;
1996 if (errno == EXDEV) 1985 if (errno == EXDEV)
1997 { 1986 {
1998 Fcopy_file (filename, newname, 1987 Fcopy_file (filename, newname,
1999 /* We have already prompted if it was an integer, 1988 /* We have already prompted if it was an integer,
2000 so don't have copy-file prompt again. */ 1989 so don't have copy-file prompt again. */
2001 ((NILP (ok_if_already_exists)) ? Qnil : Qt), 1990 (NILP (ok_if_already_exists) ? Qnil : Qt),
2002 Qt); 1991 Qt);
2003 Fdelete_file (filename); 1992 Fdelete_file (filename);
2004 } 1993 }
2005 else 1994 else
2006 { 1995 {
2134 Open a network connection to PATH using LOGIN as the login string. 2123 Open a network connection to PATH using LOGIN as the login string.
2135 */ 2124 */
2136 (path, login)) 2125 (path, login))
2137 { 2126 {
2138 int netresult; 2127 int netresult;
2128 const char *path_ext;
2129 const char *login_ext;
2139 2130
2140 CHECK_STRING (path); 2131 CHECK_STRING (path);
2141 CHECK_STRING (login); 2132 CHECK_STRING (login);
2142 2133
2143 /* netunam, being a strange-o system call only used once, is not 2134 /* netunam, being a strange-o system call only used once, is not
2144 encapsulated. */ 2135 encapsulated. */
2145 { 2136
2146 char *path_ext; 2137 TO_EXTERNAL_FORMAT (LISP_STRING, path, C_STRING_ALLOCA, path_ext, Qfile_name);
2147 char *login_ext; 2138 TO_EXTERNAL_FORMAT (LISP_STRING, login, C_STRING_ALLOCA, login_ext, Qnative);
2148 2139
2149 GET_C_STRING_FILENAME_DATA_ALLOCA (path, path_ext); 2140 netresult = netunam (path_ext, login_ext);
2150 GET_C_STRING_EXT_DATA_ALLOCA (login, FORMAT_OS, login_ext); 2141
2151 2142 return netresult == -1 ? Qnil : Qt;
2152 netresult = netunam (path_ext, login_ext);
2153 }
2154
2155 if (netresult == -1)
2156 return Qnil;
2157 else
2158 return Qt;
2159 } 2143 }
2160 #endif /* HPUX_NET */ 2144 #endif /* HPUX_NET */
2161 2145
2162 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, 1, 1, 0, /* 2146 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, 1, 1, 0, /*
2163 Return t if file FILENAME specifies an absolute path name. 2147 Return t if file FILENAME specifies an absolute path name.
2200 } 2184 }
2201 2185
2202 /* Return nonzero if file FILENAME exists and can be written. */ 2186 /* Return nonzero if file FILENAME exists and can be written. */
2203 2187
2204 static int 2188 static int
2205 check_writable (CONST char *filename) 2189 check_writable (const char *filename)
2206 { 2190 {
2207 #ifdef HAVE_EACCESS 2191 #ifdef HAVE_EACCESS
2208 return (eaccess (filename, 2) >= 0); 2192 return (eaccess (filename, 2) >= 0);
2209 #else 2193 #else
2210 /* Access isn't quite right because it uses the real uid 2194 /* Access isn't quite right because it uses the real uid
2739 if ( (!NILP (beg) || !NILP (end)) && !NILP (visit) ) 2723 if ( (!NILP (beg) || !NILP (end)) && !NILP (visit) )
2740 error ("Attempt to visit less than an entire file"); 2724 error ("Attempt to visit less than an entire file");
2741 2725
2742 fd = -1; 2726 fd = -1;
2743 2727
2744 if ( 2728 if (stat ((char *) XSTRING_DATA (filename), &st) < 0)
2745 #ifndef APOLLO
2746 (stat ((char *) XSTRING_DATA (filename), &st) < 0)
2747 #else /* APOLLO */
2748 /* Don't even bother with interruptible_open. APOLLO sucks. */
2749 ((fd = open ((char *) XSTRING_DATA (filename), O_RDONLY | OPEN_BINARY, 0)) < 0
2750 || fstat (fd, &st) < 0)
2751 #endif /* APOLLO */
2752 )
2753 { 2729 {
2754 if (fd >= 0) close (fd); 2730 if (fd >= 0) close (fd);
2755 badopen: 2731 badopen:
2756 if (NILP (visit)) 2732 if (NILP (visit))
2757 report_file_error ("Opening input file", list1 (filename)); 2733 report_file_error ("Opening input file", list1 (filename));
2982 /* No need to limit the amount of stuff we attempt to read. (It would 2958 /* No need to limit the amount of stuff we attempt to read. (It would
2983 be incorrect, anyway, when Mule is enabled.) Instead, the limiting 2959 be incorrect, anyway, when Mule is enabled.) Instead, the limiting
2984 occurs inside of the filedesc stream. */ 2960 occurs inside of the filedesc stream. */
2985 while (1) 2961 while (1)
2986 { 2962 {
2987 Bytecount this_len; 2963 ssize_t this_len;
2988 Charcount cc_inserted; 2964 Charcount cc_inserted;
2989 2965
2990 QUIT; 2966 QUIT;
2991 this_len = Lstream_read (XLSTREAM (stream), read_buf, 2967 this_len = Lstream_read (XLSTREAM (stream), read_buf,
2992 sizeof (read_buf)); 2968 sizeof (read_buf));
3031 3007
3032 if (!NILP (visit)) 3008 if (!NILP (visit))
3033 { 3009 {
3034 if (!EQ (buf->undo_list, Qt)) 3010 if (!EQ (buf->undo_list, Qt))
3035 buf->undo_list = Qnil; 3011 buf->undo_list = Qnil;
3036 #ifdef APOLLO
3037 stat ((char *) XSTRING_DATA (filename), &st);
3038 #endif
3039 if (NILP (handler)) 3012 if (NILP (handler))
3040 { 3013 {
3041 buf->modtime = st.st_mtime; 3014 buf->modtime = st.st_mtime;
3042 buf->filename = filename; 3015 buf->filename = filename;
3043 /* XEmacs addition: */ 3016 /* XEmacs addition: */
3339 failure = 1; 3312 failure = 1;
3340 save_errno = errno; 3313 save_errno = errno;
3341 } 3314 }
3342 #endif /* HAVE_FSYNC */ 3315 #endif /* HAVE_FSYNC */
3343 3316
3344 /* Spurious "file has changed on disk" warnings have been 3317 /* Spurious "file has changed on disk" warnings used to be seen on
3345 observed on Suns as well. 3318 systems where close() can change the modtime. This is known to
3346 It seems that `close' can change the modtime, under nfs. 3319 happen on various NFS file systems, on Windows, and on Linux.
3347 3320 Rather than handling this on a per-system basis, we
3348 (This has supposedly been fixed in Sunos 4, 3321 unconditionally do the stat() after the close(). */
3349 but who knows about all the other machines with NFS?) */
3350 /* On VMS and APOLLO, must do the stat after the close
3351 since closing changes the modtime. */
3352 /* As it does on Windows too - kkm */
3353 /* The spurious warnings appear on Linux too. Rather than handling
3354 this on a per-system basis, unconditionally do the stat after the close - cgw */
3355
3356 #if 0 /* !defined (WINDOWSNT) */ /* !defined (VMS) && !defined (APOLLO) */
3357 fstat (desc, &st);
3358 #endif
3359 3322
3360 /* NFS can report a write failure now. */ 3323 /* NFS can report a write failure now. */
3361 if (close (desc) < 0) 3324 if (close (desc) < 0)
3362 { 3325 {
3363 failure = 1; 3326 failure = 1;
3369 as necessary). */ 3332 as necessary). */
3370 XCAR (desc_locative) = Qnil; 3333 XCAR (desc_locative) = Qnil;
3371 unbind_to (speccount, Qnil); 3334 unbind_to (speccount, Qnil);
3372 } 3335 }
3373 3336
3374 /* # if defined (WINDOWSNT) */ /* defined (VMS) || defined (APOLLO) */
3375 stat ((char *) XSTRING_DATA (fn), &st); 3337 stat ((char *) XSTRING_DATA (fn), &st);
3376 /* #endif */
3377 3338
3378 #ifdef CLASH_DETECTION 3339 #ifdef CLASH_DETECTION
3379 if (!auto_saving) 3340 if (!auto_saving)
3380 unlock_file (lockname); 3341 unlock_file (lockname);
3381 #endif /* CLASH_DETECTION */ 3342 #endif /* CLASH_DETECTION */
3907 if (minibuf_level != 0 || preparing_for_armageddon) 3868 if (minibuf_level != 0 || preparing_for_armageddon)
3908 no_message = Qt; 3869 no_message = Qt;
3909 3870
3910 run_hook (Qauto_save_hook); 3871 run_hook (Qauto_save_hook);
3911 3872
3912 if (GC_STRINGP (Vauto_save_list_file_name)) 3873 if (STRINGP (Vauto_save_list_file_name))
3913 listfile = condition_case_1 (Qt, 3874 listfile = condition_case_1 (Qt,
3914 auto_save_expand_name, 3875 auto_save_expand_name,
3915 Vauto_save_list_file_name, 3876 Vauto_save_list_file_name,
3916 auto_save_expand_name_error, Qnil); 3877 auto_save_expand_name_error, Qnil);
3917 3878
3926 autosave perfectly ordinary files because it couldn't handle some 3887 autosave perfectly ordinary files because it couldn't handle some
3927 ange-ftp'd file. */ 3888 ange-ftp'd file. */
3928 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++) 3889 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
3929 { 3890 {
3930 for (tail = Vbuffer_alist; 3891 for (tail = Vbuffer_alist;
3931 GC_CONSP (tail); 3892 CONSP (tail);
3932 tail = XCDR (tail)) 3893 tail = XCDR (tail))
3933 { 3894 {
3934 buf = XCDR (XCAR (tail)); 3895 buf = XCDR (XCAR (tail));
3935 b = XBUFFER (buf); 3896 b = XBUFFER (buf);
3936 3897
3937 if (!GC_NILP (current_only) 3898 if (!NILP (current_only)
3938 && b != current_buffer) 3899 && b != current_buffer)
3939 continue; 3900 continue;
3940 3901
3941 /* Don't auto-save indirect buffers. 3902 /* Don't auto-save indirect buffers.
3942 The base buffer takes care of it. */ 3903 The base buffer takes care of it. */
3944 continue; 3905 continue;
3945 3906
3946 /* Check for auto save enabled 3907 /* Check for auto save enabled
3947 and file changed since last auto save 3908 and file changed since last auto save
3948 and file changed since last real save. */ 3909 and file changed since last real save. */
3949 if (GC_STRINGP (b->auto_save_file_name) 3910 if (STRINGP (b->auto_save_file_name)
3950 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b) 3911 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
3951 && b->auto_save_modified < BUF_MODIFF (b) 3912 && b->auto_save_modified < BUF_MODIFF (b)
3952 /* -1 means we've turned off autosaving for a while--see below. */ 3913 /* -1 means we've turned off autosaving for a while--see below. */
3953 && XINT (b->saved_size) >= 0 3914 && XINT (b->saved_size) >= 0
3954 && (do_handled_files 3915 && (do_handled_files
3989 if (!gc_in_progress) 3950 if (!gc_in_progress)
3990 Fsleep_for (make_int (1)); 3951 Fsleep_for (make_int (1));
3991 continue; 3952 continue;
3992 } 3953 }
3993 set_buffer_internal (b); 3954 set_buffer_internal (b);
3994 if (!auto_saved && GC_NILP (no_message)) 3955 if (!auto_saved && NILP (no_message))
3995 { 3956 {
3996 static CONST unsigned char *msg 3957 static const unsigned char *msg
3997 = (CONST unsigned char *) "Auto-saving..."; 3958 = (const unsigned char *) "Auto-saving...";
3998 echo_area_message (selected_frame (), msg, Qnil, 3959 echo_area_message (selected_frame (), msg, Qnil,
3999 0, strlen ((CONST char *) msg), 3960 0, strlen ((const char *) msg),
4000 Qauto_saving); 3961 Qauto_saving);
4001 } 3962 }
4002 3963
4003 /* Open the auto-save list file, if necessary. 3964 /* Open the auto-save list file, if necessary.
4004 We only do this now so that the file only exists 3965 We only do this now so that the file only exists
4005 if we actually auto-saved any files. */ 3966 if we actually auto-saved any files. */
4006 if (!auto_saved && GC_STRINGP (listfile) && listdesc < 0) 3967 if (!auto_saved && STRINGP (listfile) && listdesc < 0)
4007 { 3968 {
4008 listdesc = open ((char *) XSTRING_DATA (listfile), 3969 listdesc = open ((char *) XSTRING_DATA (listfile),
4009 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, 3970 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
4010 CREAT_MODE); 3971 CREAT_MODE);
4011 3972
4020 the special file that lists them. For each of 3981 the special file that lists them. For each of
4021 these buffers, record visited name (if any) and 3982 these buffers, record visited name (if any) and
4022 auto save name. */ 3983 auto save name. */
4023 if (listdesc >= 0) 3984 if (listdesc >= 0)
4024 { 3985 {
4025 CONST Extbyte *auto_save_file_name_ext; 3986 const Extbyte *auto_save_file_name_ext;
4026 Extcount auto_save_file_name_ext_len; 3987 Extcount auto_save_file_name_ext_len;
4027 3988
4028 GET_STRING_FILENAME_DATA_ALLOCA 3989 TO_EXTERNAL_FORMAT (LISP_STRING, b->auto_save_file_name,
4029 (b->auto_save_file_name, 3990 ALLOCA, (auto_save_file_name_ext,
4030 auto_save_file_name_ext, 3991 auto_save_file_name_ext_len),
4031 auto_save_file_name_ext_len); 3992 Qfile_name);
4032 if (!NILP (b->filename)) 3993 if (!NILP (b->filename))
4033 { 3994 {
4034 CONST Extbyte *filename_ext; 3995 const Extbyte *filename_ext;
4035 Extcount filename_ext_len; 3996 Extcount filename_ext_len;
4036 3997
4037 GET_STRING_FILENAME_DATA_ALLOCA (b->filename, 3998 TO_EXTERNAL_FORMAT (LISP_STRING, b->filename,
4038 filename_ext, 3999 ALLOCA, (filename_ext,
4039 filename_ext_len); 4000 filename_ext_len),
4001 Qfile_name);
4040 write (listdesc, filename_ext, filename_ext_len); 4002 write (listdesc, filename_ext, filename_ext_len);
4041 } 4003 }
4042 write (listdesc, "\n", 1); 4004 write (listdesc, "\n", 1);
4043 write (listdesc, auto_save_file_name_ext, 4005 write (listdesc, auto_save_file_name_ext,
4044 auto_save_file_name_ext_len); 4006 auto_save_file_name_ext_len);
4090 4052
4091 /* If we didn't save anything into the listfile, remove the old 4053 /* If we didn't save anything into the listfile, remove the old
4092 one because nothing needed to be auto-saved. Do this afterwards 4054 one because nothing needed to be auto-saved. Do this afterwards
4093 rather than before in case we get a crash attempting to autosave 4055 rather than before in case we get a crash attempting to autosave
4094 (in that case we'd still want the old one around). */ 4056 (in that case we'd still want the old one around). */
4095 if (listdesc < 0 && !auto_saved && GC_STRINGP (listfile)) 4057 if (listdesc < 0 && !auto_saved && STRINGP (listfile))
4096 unlink ((char *) XSTRING_DATA (listfile)); 4058 unlink ((char *) XSTRING_DATA (listfile));
4097 4059
4098 /* Show "...done" only if the echo area would otherwise be empty. */ 4060 /* Show "...done" only if the echo area would otherwise be empty. */
4099 if (auto_saved && NILP (no_message) 4061 if (auto_saved && NILP (no_message)
4100 && NILP (clear_echo_area (selected_frame (), Qauto_saving, 0))) 4062 && NILP (clear_echo_area (selected_frame (), Qauto_saving, 0)))
4101 { 4063 {
4102 static CONST unsigned char *msg 4064 static const unsigned char *msg
4103 = (CONST unsigned char *)"Auto-saving...done"; 4065 = (const unsigned char *)"Auto-saving...done";
4104 echo_area_message (selected_frame (), msg, Qnil, 0, 4066 echo_area_message (selected_frame (), msg, Qnil, 0,
4105 strlen ((CONST char *) msg), Qauto_saving); 4067 strlen ((const char *) msg), Qauto_saving);
4106 } 4068 }
4107 4069
4108 Vquit_flag = oquit; 4070 Vquit_flag = oquit;
4109 4071
4110 RETURN_UNGCPRO (unbind_to (speccount, Qnil)); 4072 RETURN_UNGCPRO (unbind_to (speccount, Qnil));
4178 defsymbol (&Qwrite_region, "write-region"); 4140 defsymbol (&Qwrite_region, "write-region");
4179 defsymbol (&Qverify_visited_file_modtime, "verify-visited-file-modtime"); 4141 defsymbol (&Qverify_visited_file_modtime, "verify-visited-file-modtime");
4180 defsymbol (&Qset_visited_file_modtime, "set-visited-file-modtime"); 4142 defsymbol (&Qset_visited_file_modtime, "set-visited-file-modtime");
4181 defsymbol (&Qcar_less_than_car, "car-less-than-car"); /* Vomitous! */ 4143 defsymbol (&Qcar_less_than_car, "car-less-than-car"); /* Vomitous! */
4182 4144
4183 defsymbol (&Qfile_name_handler_alist, "file-name-handler-alist");
4184 defsymbol (&Qauto_save_hook, "auto-save-hook"); 4145 defsymbol (&Qauto_save_hook, "auto-save-hook");
4185 defsymbol (&Qauto_save_error, "auto-save-error"); 4146 defsymbol (&Qauto_save_error, "auto-save-error");
4186 defsymbol (&Qauto_saving, "auto-saving"); 4147 defsymbol (&Qauto_saving, "auto-saving");
4187 4148
4188 defsymbol (&Qformat_decode, "format-decode"); 4149 defsymbol (&Qformat_decode, "format-decode");
4336 The value should be either ?/ or ?\\ (any other value is treated as ?\\). 4297 The value should be either ?/ or ?\\ (any other value is treated as ?\\).
4337 This variable affects the built-in functions only on Windows, 4298 This variable affects the built-in functions only on Windows,
4338 on other platforms, it is initialized so that Lisp code can find out 4299 on other platforms, it is initialized so that Lisp code can find out
4339 what the normal separator is. 4300 what the normal separator is.
4340 */ ); 4301 */ );
4341 Vdirectory_sep_char = make_char ('/'); 4302 #ifdef WINDOWSNT
4342 } 4303 Vdirectory_sep_char = make_char ('\\');
4304 #else
4305 Vdirectory_sep_char = make_char ('/');
4306 #endif
4307 }