mv.c (149790) | mv.c (174664) |
---|---|
1/*- 2 * Copyright (c) 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ken Smith of The State University of New York at Buffalo. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41static char sccsid[] = "@(#)mv.c 8.2 (Berkeley) 4/2/94"; 42#endif /* not lint */ 43#endif 44#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ken Smith of The State University of New York at Buffalo. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41static char sccsid[] = "@(#)mv.c 8.2 (Berkeley) 4/2/94"; 42#endif /* not lint */ 43#endif 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: head/bin/mv/mv.c 149790 2005-09-05 04:36:08Z csjp $"); | 45__FBSDID("$FreeBSD: head/bin/mv/mv.c 174664 2007-12-16 14:14:31Z dds $"); |
46 47#include <sys/types.h> 48#include <sys/acl.h> 49#include <sys/param.h> 50#include <sys/time.h> 51#include <sys/wait.h> 52#include <sys/stat.h> 53#include <sys/mount.h> --- 296 unchanged lines hidden (view full) --- 350 if (vflg) 351 printf("%s -> %s\n", from, to); 352 return (0); 353} 354 355int 356copy(char *from, char *to) 357{ | 46 47#include <sys/types.h> 48#include <sys/acl.h> 49#include <sys/param.h> 50#include <sys/time.h> 51#include <sys/wait.h> 52#include <sys/stat.h> 53#include <sys/mount.h> --- 296 unchanged lines hidden (view full) --- 350 if (vflg) 351 printf("%s -> %s\n", from, to); 352 return (0); 353} 354 355int 356copy(char *from, char *to) 357{ |
358 int pid, status; | 358 struct stat sb; 359 enum clean {CLEAN_SOURCE, CLEAN_DEST, CLEAN_ODEST, CLEAN_MAX}; 360 char *cleanup[CLEAN_MAX]; 361 int pid, status, rval, i; |
359 | 362 |
363 rval = 0; 364 for (i = 0; i < CLEAN_MAX; i++) 365 cleanup[i] = NULL; 366 /* 367 * If "to" exists and is a directory, get it out of the way. 368 * When the copy succeeds, delete it. 369 */ 370 if (stat(to, &sb) == 0 && S_ISDIR(sb.st_mode)) { 371 if (asprintf(&cleanup[CLEAN_ODEST], "%s.XXXXXX", to) == -1) { 372 warnx("asprintf failed"); 373 return (1); 374 375 } 376 if (rename(to, cleanup[CLEAN_ODEST]) < 0) { 377 warn("rename of existing target from %s to %s failed", 378 to, cleanup[CLEAN_ODEST]); 379 free(cleanup[CLEAN_ODEST]); 380 return (1); 381 } 382 } 383 /* Copy source to destination. */ 384 cleanup[CLEAN_DEST] = to; |
|
360 if ((pid = fork()) == 0) { 361 execl(_PATH_CP, "mv", vflg ? "-PRpv" : "-PRp", "--", from, to, 362 (char *)NULL); 363 warn("%s", _PATH_CP); 364 _exit(1); 365 } 366 if (waitpid(pid, &status, 0) == -1) { 367 warn("%s: waitpid", _PATH_CP); | 385 if ((pid = fork()) == 0) { 386 execl(_PATH_CP, "mv", vflg ? "-PRpv" : "-PRp", "--", from, to, 387 (char *)NULL); 388 warn("%s", _PATH_CP); 389 _exit(1); 390 } 391 if (waitpid(pid, &status, 0) == -1) { 392 warn("%s: waitpid", _PATH_CP); |
368 return (1); | 393 rval = 1; 394 goto done; |
369 } 370 if (!WIFEXITED(status)) { 371 warnx("%s: did not terminate normally", _PATH_CP); | 395 } 396 if (!WIFEXITED(status)) { 397 warnx("%s: did not terminate normally", _PATH_CP); |
372 return (1); | 398 rval = 1; 399 goto done; |
373 } 374 if (WEXITSTATUS(status)) { 375 warnx("%s: terminated with %d (non-zero) status", 376 _PATH_CP, WEXITSTATUS(status)); | 400 } 401 if (WEXITSTATUS(status)) { 402 warnx("%s: terminated with %d (non-zero) status", 403 _PATH_CP, WEXITSTATUS(status)); |
377 return (1); | 404 rval = 1; 405 goto done; |
378 } | 406 } |
379 if (!(pid = vfork())) { 380 execl(_PATH_RM, "mv", "-rf", "--", from, (char *)NULL); 381 warn("%s", _PATH_RM); 382 _exit(1); | 407 /* 408 * The copy succeeded. From now on the destination is where users 409 * will find their files. 410 */ 411 cleanup[CLEAN_DEST] = NULL; 412 cleanup[CLEAN_SOURCE] = from; 413done: 414 /* Clean what needs to be cleaned. */ 415 for (i = 0; i < CLEAN_MAX; i++) { 416 if (cleanup[i] == NULL) 417 continue; 418 if (!(pid = vfork())) { 419 execl(_PATH_RM, "mv", "-rf", "--", cleanup[i], 420 (char *)NULL); 421 warn("%s %s", _PATH_RM, cleanup[i]); 422 _exit(1); 423 } 424 if (waitpid(pid, &status, 0) == -1) { 425 warn("%s %s: waitpid", _PATH_RM, cleanup[i]); 426 rval = 1; 427 continue; 428 } 429 if (!WIFEXITED(status)) { 430 warnx("%s %s: did not terminate normally", 431 _PATH_RM, cleanup[i]); 432 rval = 1; 433 continue; 434 } 435 if (WEXITSTATUS(status)) { 436 warnx("%s %s: terminated with %d (non-zero) status", 437 _PATH_RM, cleanup[i], WEXITSTATUS(status)); 438 rval = 1; 439 continue; 440 } 441 /* 442 * If the copy failed, and we just deleted the copy's trash, 443 * try to salvage the original destination, 444 */ 445 if (i == CLEAN_DEST && cleanup[CLEAN_ODEST]) { 446 if (rename(cleanup[CLEAN_ODEST], to) < 0) { 447 warn("rename back renamed existing target from %s to %s failed", 448 cleanup[CLEAN_ODEST], to); 449 rval = 1; 450 } 451 free(cleanup[CLEAN_ODEST]); 452 cleanup[CLEAN_ODEST] = NULL; 453 } |
383 } | 454 } |
384 if (waitpid(pid, &status, 0) == -1) { 385 warn("%s: waitpid", _PATH_RM); 386 return (1); 387 } 388 if (!WIFEXITED(status)) { 389 warnx("%s: did not terminate normally", _PATH_RM); 390 return (1); 391 } 392 if (WEXITSTATUS(status)) { 393 warnx("%s: terminated with %d (non-zero) status", 394 _PATH_RM, WEXITSTATUS(status)); 395 return (1); 396 } 397 return (0); | 455 if (cleanup[CLEAN_ODEST]) 456 free(cleanup[CLEAN_ODEST]); 457 return (rval); |
398} 399 400void 401usage(void) 402{ 403 404 (void)fprintf(stderr, "%s\n%s\n", 405 "usage: mv [-f | -i | -n] [-v] source target", 406 " mv [-f | -i | -n] [-v] source ... directory"); 407 exit(EX_USAGE); 408} | 458} 459 460void 461usage(void) 462{ 463 464 (void)fprintf(stderr, "%s\n%s\n", 465 "usage: mv [-f | -i | -n] [-v] source target", 466 " mv [-f | -i | -n] [-v] source ... directory"); 467 exit(EX_USAGE); 468} |