VirtualBox

source: vbox/trunk/include/iprt/dir.h@ 62896

Last change on this file since 62896 was 62723, checked in by vboxsync, 8 years ago

RTDirCreateUniqueNumbered: Changed the implementation to count from zero and only do 20 sequential tries before switching to random numbers. Also, don't bother retrying more than 10000 times. Corrected the cchDigits parameter (nobody counts in signed int!).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 KB
Line 
1/** @file
2 * IPRT - Directory Manipulation.
3 */
4
5/*
6 * Copyright (C) 2006-2016 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_dir_h
27#define ___iprt_dir_h
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31#include <iprt/fs.h>
32
33
34RT_C_DECLS_BEGIN
35
36/** @defgroup grp_rt_dir RTDir - Directory Manipulation
37 * @ingroup grp_rt
38 * @{
39 */
40
41/**
42 * Check for the existence of a directory.
43 *
44 * All symbolic links will be attemped resolved. If that is undesirable, please
45 * use RTPathQueryInfo instead.
46 *
47 * @returns true if exist and is a directory.
48 * @returns false if not exists or isn't a directory.
49 * @param pszPath Path to the directory.
50 */
51RTDECL(bool) RTDirExists(const char *pszPath);
52
53/** @name RTDirCreate flags.
54 * @{ */
55/** Don't allow symbolic links as part of the path.
56 * @remarks this flag is currently not implemented and will be ignored. */
57#define RTDIRCREATE_FLAGS_NO_SYMLINKS RT_BIT(0)
58/** Set the not-content-indexed flag (default). Windows only atm. */
59#define RTDIRCREATE_FLAGS_NOT_CONTENT_INDEXED_DONT_SET RT_BIT(1)
60/** Do not set the not-content-indexed flag. Windows only atm. */
61#define RTDIRCREATE_FLAGS_NOT_CONTENT_INDEXED_DONT_SET RT_BIT(1)
62/** Ignore errors setting the not-content-indexed flag. Windows only atm. */
63#define RTDIRCREATE_FLAGS_NOT_CONTENT_INDEXED_NOT_CRITICAL RT_BIT(2)
64/** @} */
65
66/**
67 * Creates a directory.
68 *
69 * @returns iprt status code.
70 * @param pszPath Path to the directory to create.
71 * @param fMode The mode of the new directory.
72 * @param fCreate Create flags, RTDIRCREATE_FLAGS_*.
73 */
74RTDECL(int) RTDirCreate(const char *pszPath, RTFMODE fMode, uint32_t fCreate);
75
76/**
77 * Creates a directory including all parent directories in the path
78 * if they don't exist.
79 *
80 * @returns iprt status code.
81 * @param pszPath Path to the directory to create.
82 * @param fMode The mode of the new directories.
83 */
84RTDECL(int) RTDirCreateFullPath(const char *pszPath, RTFMODE fMode);
85
86/**
87 * Creates a new directory with a unique name using the given template.
88 *
89 * One or more trailing X'es in the template will be replaced by random alpha
90 * numeric characters until a RTDirCreate succeeds or we run out of patience.
91 * For instance:
92 * "/tmp/myprog-XXXXXX"
93 *
94 * As an alternative to trailing X'es, it
95 * is possible to put 3 or more X'es somewhere inside the directory name. In
96 * the following string only the last bunch of X'es will be modified:
97 * "/tmp/myprog-XXX-XXX.tmp"
98 *
99 * @returns iprt status code.
100 * @param pszTemplate The directory name template on input. The actual
101 * directory name on success. Empty string on failure.
102 * @param fMode The mode to create the directory with. Use 0700
103 * unless you have reason not to.
104 */
105RTDECL(int) RTDirCreateTemp(char *pszTemplate, RTFMODE fMode);
106
107/**
108 * Secure version of @a RTDirCreateTemp with a fixed mode of 0700.
109 *
110 * This function behaves in the same way as @a RTDirCreateTemp with two
111 * additional points. Firstly the mode is fixed to 0700. Secondly it will
112 * fail if it is not possible to perform the operation securely. Possible
113 * reasons include that the directory could be removed by another unprivileged
114 * user before it is used (e.g. if is created in a non-sticky /tmp directory)
115 * or that the path contains symbolic links which another unprivileged user
116 * could manipulate; however the exact criteria will be specified on a
117 * platform-by-platform basis as platform support is added.
118 * @see RTPathIsSecure for the current list of criteria.
119 * @returns iprt status code.
120 * @returns VERR_NOT_SUPPORTED if the interface can not be supported on the
121 * current platform at this time.
122 * @returns VERR_INSECURE if the directory could not be created securely.
123 * @param pszTemplate The directory name template on input. The
124 * actual directory name on success. Empty string
125 * on failure.
126 */
127RTDECL(int) RTDirCreateTempSecure(char *pszTemplate);
128
129/**
130 * Creates a new directory with a unique name by appending a number.
131 *
132 * This API differs from RTDirCreateTemp & RTDirCreateTempSecure in that it
133 * first tries to create the directory without any random bits, thus the best
134 * case result will be prettier. It also differs in that it does not take a
135 * template, but is instead given a template description, and will only use
136 * digits for the filling.
137 *
138 * For sake of convenience and debugging , the current implementation
139 * starts at 0 and will increment sequentally for a while before switching to
140 * random numbers.
141 *
142 * On success @a pszPath contains the path created.
143 *
144 * @returns iprt status code.
145 * @param pszPath The path to the directory. On input the base template
146 * name. On successful return, the unique directory we
147 * created.
148 * @param cbSize The size of the pszPath buffer. Needs enough space for
149 * holding the digits and the optional separator.
150 * @param fMode The mode of the new directory.
151 * @param cchDigits How many digits should the number have (zero padded).
152 * @param chSep The separator used between the path and the number. Can
153 * be zero. (optional)
154 */
155RTDECL(int) RTDirCreateUniqueNumbered(char *pszPath, size_t cbSize, RTFMODE fMode, size_t cchDigits, char chSep);
156
157/**
158 * Removes a directory if empty.
159 *
160 * @returns iprt status code.
161 * @param pszPath Path to the directory to remove.
162 */
163RTDECL(int) RTDirRemove(const char *pszPath);
164
165/**
166 * Removes a directory tree recursively.
167 *
168 * @returns iprt status code.
169 * @param pszPath Path to the directory to remove recursively.
170 * @param fFlags Flags, see RTDIRRMREC_F_XXX.
171 *
172 * @remarks This will not work on a root directory.
173 */
174RTDECL(int) RTDirRemoveRecursive(const char *pszPath, uint32_t fFlags);
175
176/** @name RTDirRemoveRecursive flags.
177 * @{ */
178/** Delete the content of the directory and the directory itself. */
179#define RTDIRRMREC_F_CONTENT_AND_DIR UINT32_C(0)
180/** Only delete the content of the directory, omit the directory it self. */
181#define RTDIRRMREC_F_CONTENT_ONLY RT_BIT_32(0)
182/** Mask of valid flags. */
183#define RTDIRRMREC_F_VALID_MASK UINT32_C(0x00000001)
184/** @} */
185
186/**
187 * Flushes the specified directory.
188 *
189 * This API is not implemented on all systems. On some systems it may be
190 * unnecessary if you've already flushed the file. If you really care for your
191 * data and is entering dangerous territories, it doesn't hurt calling it after
192 * flushing and closing the file.
193 *
194 * @returns IPRT status code.
195 * @retval VERR_NOT_IMPLEMENTED must be expected.
196 * @retval VERR_NOT_SUPPORTED must be expected.
197 * @param pszPath Path to the directory.
198 */
199RTDECL(int) RTDirFlush(const char *pszPath);
200
201/**
202 * Flushes the parent directory of the specified file.
203 *
204 * This is just a wrapper around RTDirFlush.
205 *
206 * @returns IPRT status code, see RTDirFlush for details.
207 * @param pszChild Path to the file which parent should be flushed.
208 */
209RTDECL(int) RTDirFlushParent(const char *pszChild);
210
211
212/** Pointer to an open directory (sort of handle). */
213typedef struct RTDIR *PRTDIR;
214
215
216/**
217 * Filter option for RTDirOpenFiltered().
218 */
219typedef enum RTDIRFILTER
220{
221 /** The usual invalid 0 entry. */
222 RTDIRFILTER_INVALID = 0,
223 /** No filter should be applied (and none was specified). */
224 RTDIRFILTER_NONE,
225 /** The Windows NT filter.
226 * The following wildcard chars: *, ?, <, > and "
227 * The matching is done on the uppercased strings. */
228 RTDIRFILTER_WINNT,
229 /** The UNIX filter.
230 * The following wildcard chars: *, ?, [..]
231 * The matching is done on exact case. */
232 RTDIRFILTER_UNIX,
233 /** The UNIX filter, uppercased matching.
234 * Same as RTDIRFILTER_UNIX except that the strings are uppercased before comparing. */
235 RTDIRFILTER_UNIX_UPCASED,
236
237 /** The usual full 32-bit value. */
238 RTDIRFILTER_32BIT_HACK = 0x7fffffff
239} RTDIRFILTER;
240
241
242/**
243 * Directory entry type.
244 *
245 * This is the RTFS_TYPE_MASK stuff shifted down 12 bits and
246 * identical to the BSD/LINUX ABI. See RTFS_TYPE_DIRENTRYTYPE_SHIFT.
247 */
248typedef enum RTDIRENTRYTYPE
249{
250 /** Unknown type (DT_UNKNOWN). */
251 RTDIRENTRYTYPE_UNKNOWN = 0,
252 /** Named pipe (fifo) (DT_FIFO). */
253 RTDIRENTRYTYPE_FIFO = 001,
254 /** Character device (DT_CHR). */
255 RTDIRENTRYTYPE_DEV_CHAR = 002,
256 /** Directory (DT_DIR). */
257 RTDIRENTRYTYPE_DIRECTORY = 004,
258 /** Block device (DT_BLK). */
259 RTDIRENTRYTYPE_DEV_BLOCK = 006,
260 /** Regular file (DT_REG). */
261 RTDIRENTRYTYPE_FILE = 010,
262 /** Symbolic link (DT_LNK). */
263 RTDIRENTRYTYPE_SYMLINK = 012,
264 /** Socket (DT_SOCK). */
265 RTDIRENTRYTYPE_SOCKET = 014,
266 /** Whiteout (DT_WHT). */
267 RTDIRENTRYTYPE_WHITEOUT = 016
268} RTDIRENTRYTYPE;
269
270
271/**
272 * Directory entry.
273 *
274 * This is inspired by the POSIX interfaces.
275 */
276#pragma pack(1)
277typedef struct RTDIRENTRY
278{
279 /** The unique identifier (within the file system) of this file system object (d_ino).
280 *
281 * Together with INodeIdDevice, this field can be used as a OS wide unique id
282 * when both their values are not 0. This field is 0 if the information is not
283 * available. */
284 RTINODE INodeId;
285 /** The entry type. (d_type)
286 * RTDIRENTRYTYPE_UNKNOWN is a common return value here since not all file
287 * systems (or Unixes) stores the type of a directory entry and instead
288 * expects the user to use stat() to get it. So, when you see this you
289 * should use RTDirQueryUnknownType or RTDirQueryUnknownTypeEx to get the type,
290 * or if if you're lazy, use RTDirReadEx. */
291 RTDIRENTRYTYPE enmType;
292 /** The length of the filename, excluding the terminating nul character. */
293 uint16_t cbName;
294 /** The filename. (no path)
295 * Using the pcbDirEntry parameter of RTDirRead makes this field variable in size. */
296 char szName[260];
297} RTDIRENTRY;
298#pragma pack()
299/** Pointer to a directory entry. */
300typedef RTDIRENTRY *PRTDIRENTRY;
301/** Pointer to a const directory entry. */
302typedef RTDIRENTRY const *PCRTDIRENTRY;
303
304
305/**
306 * Directory entry with extended information.
307 *
308 * This is inspired by the PC interfaces.
309 */
310#pragma pack(1)
311typedef struct RTDIRENTRYEX
312{
313 /** Full information about the object. */
314 RTFSOBJINFO Info;
315 /** The length of the short field (number of RTUTF16 entries (not chars)).
316 * It is 16-bit for reasons of alignment. */
317 uint16_t cwcShortName;
318 /** The short name for 8.3 compatibility.
319 * Empty string if not available.
320 * Since the length is a bit tricky for a UTF-8 encoded name, and since this
321 * is practically speaking only a windows thing, it is encoded as UCS-2. */
322 RTUTF16 wszShortName[14];
323 /** The length of the filename. */
324 uint16_t cbName;
325 /** The filename. (no path)
326 * Using the pcbDirEntry parameter of RTDirReadEx makes this field variable in size. */
327 char szName[260];
328} RTDIRENTRYEX;
329#pragma pack()
330/** Pointer to a directory entry. */
331typedef RTDIRENTRYEX *PRTDIRENTRYEX;
332/** Pointer to a const directory entry. */
333typedef RTDIRENTRYEX const *PCRTDIRENTRYEX;
334
335
336/**
337 * Opens a directory.
338 *
339 * @returns iprt status code.
340 * @param ppDir Where to store the open directory pointer.
341 * @param pszPath Path to the directory to open.
342 */
343RTDECL(int) RTDirOpen(PRTDIR *ppDir, const char *pszPath);
344
345/** @name RTDirOpenFiltered flags.
346 * @{ */
347/** Don't allow symbolic links as part of the path.
348 * @remarks this flag is currently not implemented and will be ignored. */
349#define RTDIROPEN_FLAGS_NO_SYMLINKS RT_BIT(0)
350/** @} */
351
352/**
353 * Opens a directory filtering the entries using dos style wildcards.
354 *
355 * @returns iprt status code.
356 * @param ppDir Where to store the open directory pointer.
357 * @param pszPath Path to the directory to search, this must include wildcards.
358 * @param enmFilter The kind of filter to apply. Setting this to RTDIRFILTER_NONE makes
359 * this function behave like RTDirOpen.
360 * @param fOpen Open flags, RTDIROPENFILTERED_FLAGS_*.
361 */
362RTDECL(int) RTDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER enmFilter, uint32_t fOpen);
363
364/**
365 * Closes a directory.
366 *
367 * @returns iprt status code.
368 * @param pDir Pointer to open directory returned by RTDirOpen() or RTDirOpenFiltered().
369 */
370RTDECL(int) RTDirClose(PRTDIR pDir);
371
372/**
373 * Reads the next entry in the directory.
374 *
375 * @returns VINF_SUCCESS and data in pDirEntry on success.
376 * @returns VERR_NO_MORE_FILES when the end of the directory has been reached.
377 * @returns VERR_BUFFER_OVERFLOW if the buffer is too small to contain the filename. If
378 * pcbDirEntry is specified it will be updated with the required buffer size.
379 * @returns suitable iprt status code on other errors.
380 *
381 * @param pDir Pointer to the open directory.
382 * @param pDirEntry Where to store the information about the next
383 * directory entry on success.
384 * @param pcbDirEntry Optional parameter used for variable buffer size.
385 *
386 * On input the variable pointed to contains the size of the pDirEntry
387 * structure. This must be at least OFFSET(RTDIRENTRY, szName[2]) bytes.
388 *
389 * On successful output the field is updated to
390 * OFFSET(RTDIRENTRY, szName[pDirEntry->cbName + 1]).
391 *
392 * When the data doesn't fit in the buffer and VERR_BUFFER_OVERFLOW is
393 * returned, this field contains the required buffer size.
394 *
395 * The value is unchanged in all other cases.
396 */
397RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry);
398
399/**
400 * Reads the next entry in the directory returning extended information.
401 *
402 * @returns VINF_SUCCESS and data in pDirEntry on success.
403 * @returns VERR_NO_MORE_FILES when the end of the directory has been reached.
404 * @returns VERR_BUFFER_OVERFLOW if the buffer is too small to contain the filename. If
405 * pcbDirEntry is specified it will be updated with the required buffer size.
406 * @returns suitable iprt status code on other errors.
407 *
408 * @param pDir Pointer to the open directory.
409 * @param pDirEntry Where to store the information about the next
410 * directory entry on success.
411 * @param pcbDirEntry Optional parameter used for variable buffer size.
412 *
413 * On input the variable pointed to contains the size of the pDirEntry
414 * structure. This must be at least OFFSET(RTDIRENTRYEX, szName[2]) bytes.
415 *
416 * On successful output the field is updated to
417 * OFFSET(RTDIRENTRYEX, szName[pDirEntry->cbName + 1]).
418 *
419 * When the data doesn't fit in the buffer and VERR_BUFFER_OVERFLOW is
420 * returned, this field contains the required buffer size.
421 *
422 * The value is unchanged in all other cases.
423 * @param enmAdditionalAttribs
424 * Which set of additional attributes to request.
425 * Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
426 * @param fFlags RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
427 */
428RTDECL(int) RTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags);
429
430/**
431 * Resolves RTDIRENTRYTYPE_UNKNOWN values returned by RTDirRead.
432 *
433 * @returns IPRT status code (see RTPathQueryInfo).
434 * @param pszComposedName The path to the directory entry. The caller must
435 * compose this, it's NOT sufficient to pass
436 * RTDIRENTRY::szName!
437 * @param fFollowSymlinks Whether to follow symbolic links or not.
438 * @param penmType Pointer to the RTDIRENTRY::enmType member. If this
439 * is not RTDIRENTRYTYPE_UNKNOWN and, if
440 * @a fFollowSymlinks is false, not
441 * RTDIRENTRYTYPE_SYMLINK, the function will return
442 * immediately without doing anything. Otherwise it
443 * will use RTPathQueryInfo to try figure out the
444 * correct value. On failure, this will be unchanged.
445 */
446RTDECL(int) RTDirQueryUnknownType(const char *pszComposedName, bool fFollowSymlinks, RTDIRENTRYTYPE *penmType);
447
448/**
449 * Resolves RTDIRENTRYTYPE_UNKNOWN values returned by RTDirRead, extended
450 * version.
451 *
452 * @returns IPRT status code (see RTPathQueryInfo).
453 * @param pszComposedName The path to the directory entry. The caller must
454 * compose this, it's NOT sufficient to pass
455 * RTDIRENTRY::szName!
456 * @param fFollowSymlinks Whether to follow symbolic links or not.
457 * @param penmType Pointer to the RTDIRENTRY::enmType member or
458 * similar. Will NOT be checked on input.
459 * @param pObjInfo The object info buffer to use with RTPathQueryInfo.
460 */
461RTDECL(int) RTDirQueryUnknownTypeEx(const char *pszComposedName, bool fFollowSymlinks, RTDIRENTRYTYPE *penmType, PRTFSOBJINFO pObjInfo);
462
463/**
464 * Checks if the directory entry returned by RTDirRead is '.', '..' or similar.
465 *
466 * @returns true / false.
467 * @param pDirEntry The directory entry to check.
468 */
469RTDECL(bool) RTDirEntryIsStdDotLink(PRTDIRENTRY pDirEntry);
470
471/**
472 * Checks if the directory entry returned by RTDirReadEx is '.', '..' or
473 * similar.
474 *
475 * @returns true / false.
476 * @param pDirEntryEx The extended directory entry to check.
477 */
478RTDECL(bool) RTDirEntryExIsStdDotLink(PCRTDIRENTRYEX pDirEntryEx);
479
480/**
481 * Renames a file.
482 *
483 * Identical to RTPathRename except that it will ensure that the source is a directory.
484 *
485 * @returns IPRT status code.
486 * @returns VERR_ALREADY_EXISTS if the destination file exists.
487 *
488 * @param pszSrc The path to the source file.
489 * @param pszDst The path to the destination file.
490 * This file will be created.
491 * @param fRename See RTPathRename.
492 */
493RTDECL(int) RTDirRename(const char *pszSrc, const char *pszDst, unsigned fRename);
494
495
496/**
497 * Query information about an open directory.
498 *
499 * @returns iprt status code.
500 *
501 * @param pDir Pointer to the open directory.
502 * @param pObjInfo Object information structure to be filled on successful return.
503 * @param enmAdditionalAttribs Which set of additional attributes to request.
504 * Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
505 */
506RTR3DECL(int) RTDirQueryInfo(PRTDIR pDir, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs);
507
508
509/**
510 * Changes one or more of the timestamps associated of file system object.
511 *
512 * @returns iprt status code.
513 * @returns VERR_NOT_SUPPORTED is returned if the operation isn't supported by the OS.
514 *
515 * @param pDir Pointer to the open directory.
516 * @param pAccessTime Pointer to the new access time. NULL if not to be changed.
517 * @param pModificationTime Pointer to the new modifcation time. NULL if not to be changed.
518 * @param pChangeTime Pointer to the new change time. NULL if not to be changed.
519 * @param pBirthTime Pointer to the new time of birth. NULL if not to be changed.
520 *
521 * @remark The file system might not implement all these time attributes,
522 * the API will ignore the ones which aren't supported.
523 *
524 * @remark The file system might not implement the time resolution
525 * employed by this interface, the time will be chopped to fit.
526 *
527 * @remark The file system may update the change time even if it's
528 * not specified.
529 *
530 * @remark POSIX can only set Access & Modification and will always set both.
531 */
532RTR3DECL(int) RTDirSetTimes(PRTDIR pDir, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
533 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
534
535/** @} */
536
537RT_C_DECLS_END
538
539#endif
540
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