VirtualBox

source: vbox/trunk/src/VBox/Runtime/generic/RTFileMove-generic.cpp@ 4968

Last change on this file since 4968 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.4 KB
Line 
1/* $Id: RTFileMove-generic.cpp 4071 2007-08-07 17:07:59Z vboxsync $ */
2/** @file
3 * innotek Portable Runtime - RTFileMove, Generic.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#define LOG_GROUP RTLOGGROUP_FILE
19#include <iprt/file.h>
20#include <iprt/path.h>
21#include <iprt/err.h>
22#include <iprt/assert.h>
23#include <iprt/log.h>
24
25
26RTDECL(int) RTFileMove(const char *pszSrc, const char *pszDst, unsigned fMove)
27{
28 /*
29 * Validate input.
30 */
31 AssertMsgReturn(VALID_PTR(pszSrc), ("%p\n", pszSrc), VERR_INVALID_POINTER);
32 AssertMsgReturn(VALID_PTR(pszDst), ("%p\n", pszDst), VERR_INVALID_POINTER);
33 AssertMsgReturn(*pszSrc, ("%p\n", pszSrc), VERR_INVALID_PARAMETER);
34 AssertMsgReturn(*pszDst, ("%p\n", pszDst), VERR_INVALID_PARAMETER);
35 AssertMsgReturn(!(fMove & ~RTFILEMOVE_FLAGS_REPLACE), ("%#x\n", fMove), VERR_INVALID_PARAMETER);
36
37 /*
38 * Try RTFileRename first.
39 */
40 Assert(RTPATHRENAME_FLAGS_REPLACE == RTFILEMOVE_FLAGS_REPLACE);
41 unsigned fRename = fMove;
42 int rc = RTFileRename(pszSrc, pszDst, fRename);
43 if (rc == VERR_NOT_SAME_DEVICE)
44 {
45 const char *pszDelete = NULL;
46
47 /*
48 * The source and target are not on the same device, darn.
49 * We'll try open both ends and perform a copy.
50 */
51 RTFILE FileSrc;
52 rc = RTFileOpen(&FileSrc, pszSrc, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN);
53 if (RT_SUCCESS(rc))
54 {
55 RTFILE FileDst;
56 rc = RTFileOpen(&FileDst, pszDst, RTFILE_O_WRITE | RTFILE_O_DENY_ALL | RTFILE_O_CREATE_REPLACE);
57 if (RT_SUCCESS(rc))
58 {
59 rc = RTFileCopyByHandles(FileSrc, FileDst);
60 if (RT_SUCCESS(rc))
61 pszDelete = pszSrc;
62 else
63 {
64 pszDelete = pszDst;
65 Log(("RTFileMove('%s', '%s', %#x): copy failed, rc=%Rrc\n",
66 pszSrc, pszDst, fMove, rc));
67 }
68
69 /* try delete without closing, and could perhaps avoid some trouble */
70 int rc2 = RTFileDelete(pszDelete);
71 if (RT_SUCCESS(rc2))
72 pszDelete = NULL;
73 RTFileClose(FileDst);
74 }
75 else
76 Log(("RTFileMove('%s', '%s', %#x): failed to create destination, rc=%Rrc\n",
77 pszSrc, pszDst, fMove, rc));
78 RTFileClose(FileSrc);
79 }
80 else
81 Log(("RTFileMove('%s', '%s', %#x): failed to open source, rc=%Rrc\n",
82 pszSrc, pszDst, fMove, rc));
83
84 /* if we failed to close it while open, close it now */
85 if (pszDelete)
86 {
87 int rc2 = RTFileDelete(pszDelete);
88 if (RT_FAILURE(rc2))
89 Log(("RTFileMove('%s', '%s', %#x): failed to delete '%s', rc2=%Rrc (rc=%Rrc)\n",
90 pszSrc, pszDst, fMove, pszDelete, rc2, rc));
91 }
92 }
93
94 LogFlow(("RTDirRename(%p:{%s}, %p:{%s}, %#x): returns %Rrc\n",
95 pszSrc, pszSrc, pszDst, pszDst, fMove, rc));
96 return rc;
97}
98
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette