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