VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/posix/fs-posix.cpp@ 93115

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 12.4 KB
Line 
1/* $Id: fs-posix.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT - File System, Linux.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_FS
32#include <sys/statvfs.h>
33#include <errno.h>
34#include <stdio.h>
35#ifdef RT_OS_LINUX
36# include <mntent.h>
37#endif
38#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
39# include <sys/mount.h>
40#endif
41
42#include <iprt/fs.h>
43#include "internal/iprt.h"
44
45#include <iprt/assert.h>
46#include <iprt/errcore.h>
47#include <iprt/log.h>
48#include <iprt/string.h>
49#include "internal/fs.h"
50#include "internal/path.h"
51
52
53
54RTR3DECL(int) RTFsQuerySizes(const char *pszFsPath, RTFOFF *pcbTotal, RTFOFF *pcbFree,
55 uint32_t *pcbBlock, uint32_t *pcbSector)
56{
57 /*
58 * Validate input.
59 */
60 AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
61 AssertReturn(*pszFsPath != '\0', VERR_INVALID_PARAMETER);
62
63 /*
64 * Convert the path and query the information.
65 */
66 char const *pszNativeFsPath;
67 int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL);
68 if (RT_SUCCESS(rc))
69 {
70 /** @todo I'm not quite sure if statvfs was properly specified by SuS, I have to check my own
71 * implementation and FreeBSD before this can eventually be promoted to posix. */
72 struct statvfs StatVFS;
73 RT_ZERO(StatVFS);
74 if (!statvfs(pszNativeFsPath, &StatVFS))
75 {
76 /*
77 * Calc the returned values.
78 */
79 if (pcbTotal)
80 *pcbTotal = (RTFOFF)StatVFS.f_blocks * StatVFS.f_frsize;
81 if (pcbFree)
82 *pcbFree = (RTFOFF)StatVFS.f_bavail * StatVFS.f_frsize;
83 if (pcbBlock)
84 *pcbBlock = StatVFS.f_frsize;
85 /* no idea how to get the sector... */
86 if (pcbSector)
87 *pcbSector = 512;
88 }
89 else
90 rc = RTErrConvertFromErrno(errno);
91 rtPathFreeNative(pszNativeFsPath, pszFsPath);
92 }
93
94 LogFlow(("RTFsQuerySizes(%p:{%s}, %p:{%RTfoff}, %p:{%RTfoff}, %p:{%RX32}, %p:{%RX32}): returns %Rrc\n",
95 pszFsPath, pszFsPath, pcbTotal, pcbTotal ? *pcbTotal : 0, pcbFree, pcbFree ? *pcbFree : 0,
96 pcbBlock, pcbBlock ? *pcbBlock : 0, pcbSector, pcbSector ? *pcbSector : 0, rc));
97 return rc;
98}
99
100
101RTR3DECL(int) RTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)
102{
103 /*
104 * Validate input.
105 */
106 AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
107 AssertReturn(*pszFsPath != '\0', VERR_INVALID_PARAMETER);
108 AssertPtrReturn(pu32Serial, VERR_INVALID_POINTER);
109
110 /*
111 * Convert the path and query the stats.
112 * We're simply return the device id.
113 */
114 char const *pszNativeFsPath;
115 int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL);
116 if (RT_SUCCESS(rc))
117 {
118 struct stat Stat;
119 if (!stat(pszNativeFsPath, &Stat))
120 {
121 if (pu32Serial)
122 *pu32Serial = (uint32_t)Stat.st_dev;
123 }
124 else
125 rc = RTErrConvertFromErrno(errno);
126 rtPathFreeNative(pszNativeFsPath, pszFsPath);
127 }
128 LogFlow(("RTFsQuerySerial(%p:{%s}, %p:{%RX32}: returns %Rrc\n",
129 pszFsPath, pszFsPath, pu32Serial, pu32Serial ? *pu32Serial : 0, rc));
130 return rc;
131}
132
133
134RTR3DECL(int) RTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties)
135{
136 /*
137 * Validate.
138 */
139 AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
140 AssertReturn(*pszFsPath != '\0', VERR_INVALID_PARAMETER);
141 AssertPtrReturn(pProperties, VERR_INVALID_POINTER);
142
143 /*
144 * Convert the path and query the information.
145 */
146 char const *pszNativeFsPath;
147 int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL);
148 if (RT_SUCCESS(rc))
149 {
150 struct statvfs StatVFS;
151 RT_ZERO(StatVFS);
152 if (!statvfs(pszNativeFsPath, &StatVFS))
153 {
154 /*
155 * Calc/fake the returned values.
156 */
157 pProperties->cbMaxComponent = StatVFS.f_namemax;
158#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
159 pProperties->fCaseSensitive = false;
160#else
161 pProperties->fCaseSensitive = true;
162#endif
163 pProperties->fCompressed = false;
164 pProperties->fFileCompression = false;
165 pProperties->fReadOnly = !!(StatVFS.f_flag & ST_RDONLY);
166 pProperties->fRemote = false;
167 pProperties->fSupportsUnicode = true;
168 }
169 else
170 rc = RTErrConvertFromErrno(errno);
171 rtPathFreeNative(pszNativeFsPath, pszFsPath);
172 }
173
174 LogFlow(("RTFsQueryProperties(%p:{%s}, %p:{.cbMaxComponent=%u, .fReadOnly=%RTbool}): returns %Rrc\n",
175 pszFsPath, pszFsPath, pProperties, pProperties->cbMaxComponent, pProperties->fReadOnly, rc));
176 return rc;
177}
178
179
180RTR3DECL(bool) RTFsIsCaseSensitive(const char *pszFsPath)
181{
182 RT_NOREF_PV(pszFsPath);
183#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
184 return false;
185#else
186 return true;
187#endif
188}
189
190
191RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType)
192{
193 *penmType = RTFSTYPE_UNKNOWN;
194
195 /*
196 * Validate input.
197 */
198 AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
199 AssertReturn(*pszFsPath, VERR_INVALID_PARAMETER);
200
201 /*
202 * Convert the path and query the stats.
203 * We're simply return the device id.
204 */
205 char const *pszNativeFsPath;
206 int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL);
207 if (RT_SUCCESS(rc))
208 {
209 struct stat Stat;
210 if (!stat(pszNativeFsPath, &Stat))
211 {
212#if defined(RT_OS_LINUX)
213 FILE *mounted = setmntent("/proc/mounts", "r");
214 if (!mounted)
215 mounted = setmntent("/etc/mtab", "r");
216 if (mounted)
217 {
218 char szBuf[1024];
219 struct stat mntStat;
220 struct mntent mntEnt;
221 while (getmntent_r(mounted, &mntEnt, szBuf, sizeof(szBuf)))
222 {
223 if (!stat(mntEnt.mnt_dir, &mntStat))
224 {
225 if (mntStat.st_dev == Stat.st_dev)
226 {
227 if (!strcmp("ext4", mntEnt.mnt_type))
228 *penmType = RTFSTYPE_EXT4;
229 else if (!strcmp("ext3", mntEnt.mnt_type))
230 *penmType = RTFSTYPE_EXT3;
231 else if (!strcmp("ext2", mntEnt.mnt_type))
232 *penmType = RTFSTYPE_EXT2;
233 else if (!strcmp("jfs", mntEnt.mnt_type))
234 *penmType = RTFSTYPE_JFS;
235 else if (!strcmp("xfs", mntEnt.mnt_type))
236 *penmType = RTFSTYPE_XFS;
237 else if (!strcmp("btrfs", mntEnt.mnt_type))
238 *penmType = RTFSTYPE_BTRFS;
239 else if ( !strcmp("vfat", mntEnt.mnt_type)
240 || !strcmp("msdos", mntEnt.mnt_type))
241 *penmType = RTFSTYPE_FAT;
242 else if (!strcmp("ntfs", mntEnt.mnt_type))
243 *penmType = RTFSTYPE_NTFS;
244 else if (!strcmp("hpfs", mntEnt.mnt_type))
245 *penmType = RTFSTYPE_HPFS;
246 else if (!strcmp("ufs", mntEnt.mnt_type))
247 *penmType = RTFSTYPE_UFS;
248 else if (!strcmp("tmpfs", mntEnt.mnt_type))
249 *penmType = RTFSTYPE_TMPFS;
250 else if (!strcmp("hfsplus", mntEnt.mnt_type))
251 *penmType = RTFSTYPE_HFS;
252 else if (!strcmp("udf", mntEnt.mnt_type))
253 *penmType = RTFSTYPE_UDF;
254 else if (!strcmp("iso9660", mntEnt.mnt_type))
255 *penmType = RTFSTYPE_ISO9660;
256 else if (!strcmp("smbfs", mntEnt.mnt_type))
257 *penmType = RTFSTYPE_SMBFS;
258 else if (!strcmp("cifs", mntEnt.mnt_type))
259 *penmType = RTFSTYPE_CIFS;
260 else if (!strcmp("nfs", mntEnt.mnt_type))
261 *penmType = RTFSTYPE_NFS;
262 else if (!strcmp("nfs4", mntEnt.mnt_type))
263 *penmType = RTFSTYPE_NFS;
264 else if (!strcmp("ocfs2", mntEnt.mnt_type))
265 *penmType = RTFSTYPE_OCFS2;
266 else if (!strcmp("sysfs", mntEnt.mnt_type))
267 *penmType = RTFSTYPE_SYSFS;
268 else if (!strcmp("proc", mntEnt.mnt_type))
269 *penmType = RTFSTYPE_PROC;
270 else if ( !strcmp("fuse", mntEnt.mnt_type)
271 || !strncmp("fuse.", mntEnt.mnt_type, 5)
272 || !strcmp("fuseblk", mntEnt.mnt_type))
273 *penmType = RTFSTYPE_FUSE;
274 else
275 {
276 /* sometimes there are more than one entry for the same partition */
277 continue;
278 }
279 break;
280 }
281 }
282 }
283 endmntent(mounted);
284 }
285
286#elif defined(RT_OS_SOLARIS)
287 if (!strcmp("zfs", Stat.st_fstype))
288 *penmType = RTFSTYPE_ZFS;
289 else if (!strcmp("ufs", Stat.st_fstype))
290 *penmType = RTFSTYPE_UFS;
291 else if (!strcmp("nfs", Stat.st_fstype))
292 *penmType = RTFSTYPE_NFS;
293
294#elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
295 struct statfs statfsBuf;
296 if (!statfs(pszNativeFsPath, &statfsBuf))
297 {
298 if (!strcmp("hfs", statfsBuf.f_fstypename))
299 *penmType = RTFSTYPE_HFS;
300 else if (!strcmp("apfs", statfsBuf.f_fstypename)) /** @todo verify apfs signature. */
301 *penmType = RTFSTYPE_APFS;
302 else if ( !strcmp("fat", statfsBuf.f_fstypename)
303 || !strcmp("msdos", statfsBuf.f_fstypename))
304 *penmType = RTFSTYPE_FAT;
305 else if (!strcmp("ntfs", statfsBuf.f_fstypename))
306 *penmType = RTFSTYPE_NTFS;
307 else if (!strcmp("autofs", statfsBuf.f_fstypename))
308 *penmType = RTFSTYPE_AUTOFS;
309 else if (!strcmp("devfs", statfsBuf.f_fstypename))
310 *penmType = RTFSTYPE_DEVFS;
311 else if (!strcmp("nfs", statfsBuf.f_fstypename))
312 *penmType = RTFSTYPE_NFS;
313 else if (!strcmp("ufs", statfsBuf.f_fstypename))
314 *penmType = RTFSTYPE_UFS;
315 else if (!strcmp("zfs", statfsBuf.f_fstypename))
316 *penmType = RTFSTYPE_ZFS;
317 }
318 else
319 rc = RTErrConvertFromErrno(errno);
320#endif
321 }
322 else
323 rc = RTErrConvertFromErrno(errno);
324 rtPathFreeNative(pszNativeFsPath, pszFsPath);
325 }
326
327 return rc;
328}
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