Mercurial > emacs
comparison src/msdos.c @ 16524:84440bd95727
[__DJGPP_MINOR__ == 0] (_rename): New function, a
substitute for library low-level file-renaming function which
works around Windows 95 bug.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Wed, 06 Nov 1996 19:51:38 +0000 |
parents | c987c025d448 |
children | 4b0b6719bbd2 |
comparison
equal
deleted
inserted
replaced
16523:53306ee8953d | 16524:84440bd95727 |
---|---|
2325 } | 2325 } |
2326 return total_written; | 2326 return total_written; |
2327 } | 2327 } |
2328 } | 2328 } |
2329 | 2329 |
2330 /* A low-level file-renaming function which works around Windows 95 bug. | |
2331 This is pulled directly out of DJGPP v2.01 library sources, and only | |
2332 used when you compile with DJGPP v2.0. */ | |
2333 | |
2334 #include <io.h> | |
2335 | |
2336 int _rename(const char *old, const char *new) | |
2337 { | |
2338 __dpmi_regs r; | |
2339 int olen = strlen(old) + 1; | |
2340 int i; | |
2341 int use_lfn = _USE_LFN; | |
2342 char tempfile[FILENAME_MAX]; | |
2343 const char *orig = old; | |
2344 int lfn_fd = -1; | |
2345 | |
2346 r.x.dx = __tb_offset; | |
2347 r.x.di = __tb_offset + olen; | |
2348 r.x.ds = r.x.es = __tb_segment; | |
2349 | |
2350 if (use_lfn) | |
2351 { | |
2352 /* Windows 95 bug: for some filenames, when you rename | |
2353 file -> file~ (as in Emacs, to leave a backup), the | |
2354 short 8+3 alias doesn't change, which effectively | |
2355 makes OLD and NEW the same file. We must rename | |
2356 through a temporary file to work around this. */ | |
2357 | |
2358 char *pbase = 0, *p; | |
2359 static char try_char[] = "abcdefghijklmnopqrstuvwxyz012345789"; | |
2360 int idx = sizeof(try_char) - 1; | |
2361 | |
2362 /* Generate a temporary name. Can't use `tmpnam', since $TMPDIR | |
2363 might point to another drive, which will fail the DOS call. */ | |
2364 strcpy(tempfile, old); | |
2365 for (p = tempfile; *p; p++) /* ensure temporary is on the same drive */ | |
2366 if (*p == '/' || *p == '\\' || *p == ':') | |
2367 pbase = p; | |
2368 if (pbase) | |
2369 pbase++; | |
2370 else | |
2371 pbase = tempfile; | |
2372 strcpy(pbase, "X$$djren$$.$$temp$$"); | |
2373 | |
2374 do | |
2375 { | |
2376 if (idx <= 0) | |
2377 return -1; | |
2378 *pbase = try_char[--idx]; | |
2379 } while (_chmod(tempfile, 0) != -1); | |
2380 | |
2381 r.x.ax = 0x7156; | |
2382 _put_path2(tempfile, olen); | |
2383 _put_path(old); | |
2384 __dpmi_int(0x21, &r); | |
2385 if (r.x.flags & 1) | |
2386 { | |
2387 errno = __doserr_to_errno(r.x.ax); | |
2388 return -1; | |
2389 } | |
2390 | |
2391 /* Now create a file with the original name. This will | |
2392 ensure that NEW will always have a 8+3 alias | |
2393 different from that of OLD. (Seems to be required | |
2394 when NameNumericTail in the Registry is set to 0.) */ | |
2395 lfn_fd = _creat(old, 0); | |
2396 | |
2397 olen = strlen(tempfile) + 1; | |
2398 old = tempfile; | |
2399 r.x.di = __tb_offset + olen; | |
2400 } | |
2401 | |
2402 for (i=0; i<2; i++) | |
2403 { | |
2404 if(use_lfn) | |
2405 r.x.ax = 0x7156; | |
2406 else | |
2407 r.h.ah = 0x56; | |
2408 _put_path2(new, olen); | |
2409 _put_path(old); | |
2410 __dpmi_int(0x21, &r); | |
2411 if(r.x.flags & 1) | |
2412 { | |
2413 if (r.x.ax == 5 && i == 0) /* access denied */ | |
2414 remove(new); /* and try again */ | |
2415 else | |
2416 { | |
2417 errno = __doserr_to_errno(r.x.ax); | |
2418 | |
2419 /* Restore to original name if we renamed it to temporary. */ | |
2420 if (use_lfn) | |
2421 { | |
2422 if (lfn_fd != -1) | |
2423 { | |
2424 _close (lfn_fd); | |
2425 remove (orig); | |
2426 } | |
2427 _put_path2(orig, olen); | |
2428 _put_path(tempfile); | |
2429 r.x.ax = 0x7156; | |
2430 __dpmi_int(0x21, &r); | |
2431 } | |
2432 return -1; | |
2433 } | |
2434 } | |
2435 else | |
2436 break; | |
2437 } | |
2438 | |
2439 /* Success. Delete the file possibly created to work | |
2440 around the Windows 95 bug. */ | |
2441 if (lfn_fd != -1) | |
2442 return (_close (lfn_fd) == 0) ? remove (orig) : -1; | |
2443 return 0; | |
2444 } | |
2445 | |
2330 #endif /* __DJGPP__ == 2 && __DJGPP_MINOR__ == 0 */ | 2446 #endif /* __DJGPP__ == 2 && __DJGPP_MINOR__ == 0 */ |
2331 | 2447 |
2332 DEFUN ("msdos-long-file-names", Fmsdos_long_file_names, Smsdos_long_file_names, | 2448 DEFUN ("msdos-long-file-names", Fmsdos_long_file_names, Smsdos_long_file_names, |
2333 0, 0, 0, | 2449 0, 0, 0, |
2334 "Return non-nil if long file names are supported on MSDOS.") | 2450 "Return non-nil if long file names are supported on MSDOS.") |