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. */