VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTPathUnlink.cpp@ 106061

Last change on this file since 106061 was 105631, checked in by vboxsync, 6 weeks ago

IPRT/RTPathUnlink: Implemented NT and posix versions w/ simple testcase.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/* $Id: tstRTPathUnlink.cpp 105631 2024-08-09 00:59:18Z vboxsync $ */
2/** @file
3 * IPRT Testcase - Test RTPathUnlink
4 */
5
6/*
7 * Copyright (C) 2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/path.h>
42
43#include <iprt/env.h>
44#include <iprt/err.h>
45#include <iprt/dir.h>
46#include <iprt/file.h>
47#include <iprt/rand.h>
48#include <iprt/string.h>
49#include <iprt/symlink.h>
50#include <iprt/test.h>
51
52
53/*********************************************************************************************************************************
54* Defined Constants And Macros *
55*********************************************************************************************************************************/
56#define TMP_PATH_STRCOPY(a_szName) memcpy(&g_szTmpName[g_cchTmpNamePrefix], a_szName, sizeof(a_szName))
57
58
59/*********************************************************************************************************************************
60* Global Variables *
61*********************************************************************************************************************************/
62static RTTEST g_hTest;
63/** Temporary filename buffer.
64 * The main function initializes this with a unique filename/dirname prefix in
65 * a temporary directory. */
66static char g_szTmpName[RTPATH_MAX];
67/** Length of g_szTmpPrefix. */
68static size_t g_cchTmpNamePrefix;
69
70
71static void specialStatuses(void)
72{
73 RTTestSub(g_hTest, "special status codes");
74
75 /* VERR_FILE_NOT_FOUND */
76 TMP_PATH_STRCOPY("no-such-file.tmp");
77 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_FILE_NOT_FOUND);
78
79 /* VERR_PATH_NOT_FOUND */
80 TMP_PATH_STRCOPY("no-such-dir.tmp" RTPATH_SLASH_STR "no-such-file.tmp");
81 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_PATH_NOT_FOUND);
82
83 /* VERR_NOT_A_DIRECTORY (posix) / VERR_PATH_NOT_FOUND (win) */
84 TMP_PATH_STRCOPY("not-a-directory-file.tmp");
85 size_t offSlash = strlen(g_szTmpName);
86 RTFILE hFile = NIL_RTFILE;
87 RTTESTI_CHECK_RC(RTFileOpen(&hFile, g_szTmpName, RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE), VINF_SUCCESS);
88 RTTESTI_CHECK_RC(RTFileClose(hFile), VINF_SUCCESS);
89
90 TMP_PATH_STRCOPY("not-a-directory-file.tmp" RTPATH_SLASH_STR "sub-dir-name.tmp");
91 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_PATH_NOT_FOUND);
92
93 /* Cleanup. */
94 g_szTmpName[offSlash] = '\0';
95 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VINF_SUCCESS);
96 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_FILE_NOT_FOUND);
97}
98
99
100static void removeSymlink(void)
101{
102 RTTestSub(g_hTest, "remove symlink");
103
104 /* Create a directory to use as a symlink target. */
105 TMP_PATH_STRCOPY("targetdir.tmp");
106 char szTargetDir[RTPATH_MAX];
107 RTStrCopy(szTargetDir, sizeof(szTargetDir), g_szTmpName);
108 RTTESTI_CHECK_RC_RETV(RTDirCreate(szTargetDir, 0755, 0), VINF_SUCCESS);
109
110 /* Create a symlink pointing to it. */
111 TMP_PATH_STRCOPY("symlink.tmp");
112 int rc = RTSymlinkCreate(g_szTmpName, szTargetDir, RTSYMLINKTYPE_DIR, 0);
113 if (RT_SUCCESS(rc))
114 {
115 /* Remove the symlink. */
116 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VINF_SUCCESS);
117
118 /* The 2nd try should fail. */
119 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_FILE_NOT_FOUND);
120 }
121 else if (rc == VERR_NOT_SUPPORTED)
122 RTTestSkipped(g_hTest, "Symlink creation not supported");
123 else
124 RTTestFailed(g_hTest, "Failed to create symlink %s: %Rrc", g_szTmpName, rc);
125
126 /* Cleanup the target directory. */
127 RTTESTI_CHECK_RC(RTPathUnlink(szTargetDir, 0), VINF_SUCCESS);
128}
129
130
131static void removeDir(void)
132{
133 RTTestSub(g_hTest, "remove dir");
134
135 /* Create an empty directory. */
136 TMP_PATH_STRCOPY("emptydir.tmp");
137 RTTESTI_CHECK_RC_RETV(RTDirCreate(g_szTmpName, 0755, 0), VINF_SUCCESS);
138 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VINF_SUCCESS);
139 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_FILE_NOT_FOUND); /* A 2nd call fails. */
140
141 /* Create a directory with a subdirectory in it. */
142 TMP_PATH_STRCOPY("nonemptydir.tmp");
143 size_t offSlash = strlen(g_szTmpName);
144 RTTESTI_CHECK_RC(RTDirCreate(g_szTmpName, 0755, 0), VINF_SUCCESS);
145 TMP_PATH_STRCOPY("nonemptydir.tmp" RTPATH_SLASH_STR "subdir.tmp");
146 RTTESTI_CHECK_RC(RTDirCreate(g_szTmpName, 0755, 0), VINF_SUCCESS);
147
148 /* Removing the parent directory should fail. */
149 g_szTmpName[offSlash] = '\0';
150 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_DIR_NOT_EMPTY);
151
152 /* Remove the subdir and then the parent, though, should work fine. */
153 g_szTmpName[offSlash] = RTPATH_SLASH;
154 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VINF_SUCCESS);
155 g_szTmpName[offSlash] = '\0';
156 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VINF_SUCCESS);
157}
158
159
160static void removeFile(void)
161{
162 RTTestSub(g_hTest, "remove file");
163
164 /* Create a file. */
165 TMP_PATH_STRCOPY("file.tmp");
166 RTFILE hFile = NIL_RTFILE;
167 RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFile, g_szTmpName, RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE),
168 VINF_SUCCESS);
169 RTTESTI_CHECK_RC(RTFileClose(hFile), VINF_SUCCESS);
170 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VINF_SUCCESS);
171
172 /* A 2nd call fails. */
173 RTTESTI_CHECK_RC(RTPathUnlink(g_szTmpName, 0), VERR_FILE_NOT_FOUND);
174}
175
176
177int main()
178{
179 /*
180 * Init RT+Test.
181 */
182 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTPathUnlink", &g_hTest);
183 if (rcExit != RTEXITCODE_SUCCESS)
184 return rcExit;
185 RTTestBanner(g_hTest);
186
187 /*
188 * Determine temporary a directory with testboxes in mind.
189 */
190 AssertCompile(sizeof(g_szTmpName) >= 128*2);
191 int rc = RTEnvGetEx(RTENV_DEFAULT, "TESTBOX_PATH_SCRATCH", g_szTmpName, sizeof(g_szTmpName) - 128, NULL);
192 if (RT_FAILURE(rc))
193 rc = RTPathTemp(g_szTmpName, sizeof(g_szTmpName) - 128);
194 if (RT_SUCCESS(rc))
195 {
196 /* Add a new prefix. */
197 size_t off = RTPathEnsureTrailingSeparator(g_szTmpName, sizeof(g_szTmpName));
198 off += RTStrPrintf(&g_szTmpName[off], sizeof(g_szTmpName) - off, "tstRTPathUnlink-%RX32-", RTRandU32());
199 g_cchTmpNamePrefix = off;
200
201 /*
202 * Do the testing.
203 */
204 removeFile();
205 removeDir();
206 removeSymlink();
207 specialStatuses();
208 }
209 else
210 RTTestIFailed("Failed to get the path to a temporary directory: %Rrc", rc);
211
212 /*
213 * Summary.
214 */
215 return RTTestSummaryAndDestroy(g_hTest);
216}
217
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