VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/posix/path2-posix.cpp@ 76878

Last change on this file since 76878 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 10.6 KB
Line 
1/* $Id: path2-posix.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT - Path Manipulation, POSIX, Part 2 - RTPathQueryInfo.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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_PATH
32#include <stdlib.h>
33#include <limits.h>
34#include <errno.h>
35#include <unistd.h>
36#include <sys/stat.h>
37#include <sys/time.h>
38#include <stdio.h>
39#include <sys/types.h>
40
41#include <iprt/path.h>
42#include <iprt/env.h>
43#include <iprt/assert.h>
44#include <iprt/string.h>
45#include <iprt/err.h>
46#include <iprt/log.h>
47#include "internal/path.h"
48#include "internal/process.h"
49#include "internal/fs.h"
50
51
52RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
53{
54 return RTPathQueryInfoEx(pszPath, pObjInfo, enmAdditionalAttribs, RTPATH_F_ON_LINK);
55}
56
57
58RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
59{
60 /*
61 * Validate input.
62 */
63 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
64 AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
65 AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER);
66 AssertMsgReturn( enmAdditionalAttribs >= RTFSOBJATTRADD_NOTHING
67 && enmAdditionalAttribs <= RTFSOBJATTRADD_LAST,
68 ("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs),
69 VERR_INVALID_PARAMETER);
70 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
71
72 /*
73 * Convert the filename.
74 */
75 char const *pszNativePath;
76 int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
77 if (RT_SUCCESS(rc))
78 {
79 struct stat Stat;
80 if (fFlags & RTPATH_F_FOLLOW_LINK)
81 rc = stat(pszNativePath, &Stat);
82 else
83 rc = lstat(pszNativePath, &Stat); /** @todo how doesn't have lstat again? */
84 if (!rc)
85 {
86 rtFsConvertStatToObjInfo(pObjInfo, &Stat, pszPath, 0);
87 switch (enmAdditionalAttribs)
88 {
89 case RTFSOBJATTRADD_NOTHING:
90 case RTFSOBJATTRADD_UNIX:
91 Assert(pObjInfo->Attr.enmAdditional == RTFSOBJATTRADD_UNIX);
92 break;
93
94 case RTFSOBJATTRADD_UNIX_OWNER:
95 rtFsObjInfoAttrSetUnixOwner(pObjInfo, Stat.st_uid);
96 break;
97
98 case RTFSOBJATTRADD_UNIX_GROUP:
99 rtFsObjInfoAttrSetUnixGroup(pObjInfo, Stat.st_gid);
100 break;
101
102 case RTFSOBJATTRADD_EASIZE:
103 /** @todo Use SGI extended attribute interface to query EA info. */
104 pObjInfo->Attr.enmAdditional = RTFSOBJATTRADD_EASIZE;
105 pObjInfo->Attr.u.EASize.cb = 0;
106 break;
107
108 default:
109 AssertMsgFailed(("Impossible!\n"));
110 return VERR_INTERNAL_ERROR;
111 }
112 }
113 else
114 rc = RTErrConvertFromErrno(errno);
115 rtPathFreeNative(pszNativePath, pszPath);
116 }
117
118 LogFlow(("RTPathQueryInfoEx(%p:{%s}, pObjInfo=%p, %d): returns %Rrc\n",
119 pszPath, pszPath, pObjInfo, enmAdditionalAttribs, rc));
120 return rc;
121}
122
123
124RTR3DECL(int) RTPathSetTimes(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
125 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
126{
127 return RTPathSetTimesEx(pszPath, pAccessTime, pModificationTime, pChangeTime, pBirthTime, RTPATH_F_ON_LINK);
128}
129
130
131RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
132 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags)
133{
134 /*
135 * Validate input.
136 */
137 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
138 AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
139 AssertPtrNullReturn(pAccessTime, VERR_INVALID_POINTER);
140 AssertPtrNullReturn(pModificationTime, VERR_INVALID_POINTER);
141 AssertPtrNullReturn(pChangeTime, VERR_INVALID_POINTER);
142 AssertPtrNullReturn(pBirthTime, VERR_INVALID_POINTER);
143 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
144
145 /*
146 * Convert the paths.
147 */
148 char const *pszNativePath;
149 int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
150 if (RT_SUCCESS(rc))
151 {
152 RTFSOBJINFO ObjInfo;
153
154 /*
155 * If it's a no-op, we'll only verify the existance of the file.
156 */
157 if (!pAccessTime && !pModificationTime)
158 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, fFlags);
159 else
160 {
161 /*
162 * Convert the input to timeval, getting the missing one if necessary,
163 * and call the API which does the change.
164 */
165 struct timeval aTimevals[2];
166 if (pAccessTime && pModificationTime)
167 {
168 RTTimeSpecGetTimeval(pAccessTime, &aTimevals[0]);
169 RTTimeSpecGetTimeval(pModificationTime, &aTimevals[1]);
170 }
171 else
172 {
173 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
174 if (RT_SUCCESS(rc))
175 {
176 RTTimeSpecGetTimeval(pAccessTime ? pAccessTime : &ObjInfo.AccessTime, &aTimevals[0]);
177 RTTimeSpecGetTimeval(pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, &aTimevals[1]);
178 }
179 else
180 Log(("RTPathSetTimes('%s',%p,%p,,): RTPathQueryInfo failed with %Rrc\n",
181 pszPath, pAccessTime, pModificationTime, rc));
182 }
183 if (RT_SUCCESS(rc))
184 {
185 if (fFlags & RTPATH_F_FOLLOW_LINK)
186 {
187 if (utimes(pszNativePath, aTimevals))
188 rc = RTErrConvertFromErrno(errno);
189 }
190#if (defined(RT_OS_DARWIN) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) \
191 || defined(RT_OS_FREEBSD) \
192 || defined(RT_OS_LINUX) \
193 || defined(RT_OS_OS2) /** @todo who really has lutimes? */
194 else
195 {
196 if (lutimes(pszNativePath, aTimevals))
197 rc = RTErrConvertFromErrno(errno);
198 }
199#else
200 else
201 {
202 if (pAccessTime && pModificationTime)
203 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
204 if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
205 rc = VERR_NS_SYMLINK_SET_TIME;
206 else if (RT_SUCCESS(rc))
207 {
208 if (utimes(pszNativePath, aTimevals))
209 rc = RTErrConvertFromErrno(errno);
210 }
211 }
212#endif
213 if (RT_FAILURE(rc))
214 Log(("RTPathSetTimes('%s',%p,%p,,): failed with %Rrc and errno=%d\n",
215 pszPath, pAccessTime, pModificationTime, rc, errno));
216 }
217 }
218 rtPathFreeNative(pszNativePath, pszPath);
219 }
220
221 LogFlow(("RTPathSetTimes(%p:{%s}, %p:{%RDtimespec}, %p:{%RDtimespec}, %p:{%RDtimespec}, %p:{%RDtimespec}): return %Rrc\n",
222 pszPath, pszPath, pAccessTime, pAccessTime, pModificationTime, pModificationTime,
223 pChangeTime, pChangeTime, pBirthTime, pBirthTime, rc));
224 return rc;
225}
226
227
228RTR3DECL(int) RTPathSetOwner(const char *pszPath, uint32_t uid, uint32_t gid)
229{
230 return RTPathSetOwnerEx(pszPath, uid, gid, RTPATH_F_ON_LINK);
231}
232
233
234RTR3DECL(int) RTPathSetOwnerEx(const char *pszPath, uint32_t uid, uint32_t gid, uint32_t fFlags)
235{
236 /*
237 * Validate input.
238 */
239 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
240 AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
241 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
242 uid_t uidNative = uid != NIL_RTUID ? (uid_t)uid : (uid_t)-1;
243 AssertReturn(uid == uidNative, VERR_INVALID_PARAMETER);
244 gid_t gidNative = gid != NIL_RTGID ? (gid_t)gid : (uid_t)-1;
245 AssertReturn(gid == gidNative, VERR_INVALID_PARAMETER);
246
247 /*
248 * Convert the path.
249 */
250 char const *pszNativePath;
251 int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
252 if (RT_SUCCESS(rc))
253 {
254 if (fFlags & RTPATH_F_FOLLOW_LINK)
255 {
256 if (chown(pszNativePath, uidNative, gidNative))
257 rc = RTErrConvertFromErrno(errno);
258 }
259#if 1
260 else
261 {
262 if (lchown(pszNativePath, uidNative, gidNative))
263 rc = RTErrConvertFromErrno(errno);
264 }
265#else
266 else
267 {
268 RTFSOBJINFO ObjInfo;
269 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
270 if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
271 rc = VERR_NS_SYMLINK_CHANGE_OWNER;
272 else if (RT_SUCCESS(rc))
273 {
274 if (lchown(pszNativePath, uidNative, gidNative))
275 rc = RTErrConvertFromErrno(errno);
276 }
277 }
278#endif
279 if (RT_FAILURE(rc))
280 Log(("RTPathSetOwnerEx('%s',%d,%d): failed with %Rrc and errno=%d\n",
281 pszPath, uid, gid, rc, errno));
282
283 rtPathFreeNative(pszNativePath, pszPath);
284 }
285
286 LogFlow(("RTPathSetOwnerEx(%p:{%s}, uid=%d, gid=%d): return %Rrc\n",
287 pszPath, pszPath, uid, gid, rc));
288 return rc;
289}
290
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