Mercurial > emacs
comparison src/w32.c @ 14912:8d25697cc14b
(rename): New function.
author | Geoff Voelker <voelker@cs.washington.edu> |
---|---|
date | Fri, 29 Mar 1996 04:24:58 +0000 |
parents | ebdd1b50daba |
children | 6565b268b12a |
comparison
equal
deleted
inserted
replaced
14911:f736e9cb067e | 14912:8d25697cc14b |
---|---|
214 This is much easier. */ | 214 This is much easier. */ |
215 void | 215 void |
216 nt_sleep (int seconds) | 216 nt_sleep (int seconds) |
217 { | 217 { |
218 Sleep (seconds * 1000); | 218 Sleep (seconds * 1000); |
219 } | |
220 | |
221 /* Emulate rename. */ | |
222 | |
223 #ifndef ENOENT | |
224 #define ENOENT 2 | |
225 #endif | |
226 #ifndef EXDEV | |
227 #define EXDEV 18 | |
228 #endif | |
229 #ifndef EINVAL | |
230 #define EINVAL 22 | |
231 #endif | |
232 | |
233 int | |
234 rename (const char *oldname, const char *newname) | |
235 { | |
236 #ifdef WINDOWS95 | |
237 int i, len, len0, len1; | |
238 char *dirs[2], *names[2], *ptr; | |
239 | |
240 /* A bug in MoveFile under Windows 95 incorrectly renames files in | |
241 some cases. If the old name is of the form FILENAME or | |
242 FILENAME.SUF, and the new name is of the form FILENAME~ or | |
243 FILENAME.SUF~, and both the source and target are in the same | |
244 directory, then MoveFile renames the long form of the filename to | |
245 FILENAME~ (FILENAME.SUF~) but leaves the DOS short form as | |
246 FILENAME (FILENAME.SUF). The result is that the two different | |
247 filenames refer to the same file. In this case, rename the | |
248 source to a temporary name that can then successfully be renamed | |
249 to the target. */ | |
250 | |
251 dirs[0] = names[0] = oldname; | |
252 dirs[1] = names[1] = newname; | |
253 for (i = 0; i < 2; i++) | |
254 { | |
255 /* Canonicalize and remove prefix. */ | |
256 len = strlen (names[i]); | |
257 for (ptr = names[i] + len - 1; ptr > names[i]; ptr--) | |
258 { | |
259 if (IS_ANY_SEP (ptr[0]) && ptr[1] != '\0') | |
260 { | |
261 names[i] = ptr + 1; | |
262 break; | |
263 } | |
264 } | |
265 } | |
266 | |
267 len0 = strlen (names[0]); | |
268 len1 = strlen (names[1]); | |
269 | |
270 /* The predicate is whether the file is being renamed to a filename | |
271 with ~ appended. This is conservative, but should be correct. */ | |
272 if ((len0 == len1 - 1) | |
273 && (names[1][len0] == '~') | |
274 && (!strnicmp (names[0], names[1], len0))) | |
275 { | |
276 /* Rename the source to a temporary name that can succesfully be | |
277 renamed to the target. The temporary name is in the directory | |
278 of the target. */ | |
279 char *tmp, *fulltmp; | |
280 | |
281 tmp = "eXXXXXX"; | |
282 fulltmp = alloca (strlen (dirs[1]) + strlen (tmp) + 1); | |
283 fulltmp[0] = '\0'; | |
284 if (dirs[1] != names[1]) | |
285 { | |
286 len = names[1] - dirs[1]; | |
287 strncpy (fulltmp, dirs[1], len); | |
288 fulltmp[len] = '\0'; | |
289 } | |
290 strcat (fulltmp, tmp); | |
291 mktemp (fulltmp); | |
292 | |
293 if (rename (oldname, fulltmp) < 0) | |
294 return -1; | |
295 | |
296 oldname = fulltmp; | |
297 } | |
298 #endif | |
299 | |
300 if (!MoveFile (oldname, newname)) | |
301 { | |
302 switch (GetLastError ()) | |
303 { | |
304 case ERROR_FILE_NOT_FOUND: | |
305 errno = ENOENT; | |
306 break; | |
307 case ERROR_ACCESS_DENIED: | |
308 /* This gets returned when going across devices. */ | |
309 errno = EXDEV; | |
310 break; | |
311 case ERROR_FILE_EXISTS: | |
312 case ERROR_ALREADY_EXISTS: | |
313 default: | |
314 errno = EINVAL; | |
315 break; | |
316 } | |
317 return -1; | |
318 } | |
319 errno = 0; | |
320 return 0; | |
219 } | 321 } |
220 | 322 |
221 /* Emulate the Unix directory procedures opendir, closedir, | 323 /* Emulate the Unix directory procedures opendir, closedir, |
222 and readdir. We can't use the procedures supplied in sysdep.c, | 324 and readdir. We can't use the procedures supplied in sysdep.c, |
223 so we provide them here. */ | 325 so we provide them here. */ |