VirtualBox

source: vbox/trunk/include/iprt/env.h@ 95897

Last change on this file since 95897 was 95842, checked in by vboxsync, 2 years ago

IPRT/env-generic.cpp: Refactored RTEnvCloneEx, rewriting the cloning of the default environment on windows to be more no-crt compatible and race free. Don't expose RTEnvGetExecEnvP on Windows, removing it from the stable function list. bugref:10261

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.5 KB
Line 
1/** @file
2 * IPRT - Process Environment Strings.
3 */
4
5/*
6 * Copyright (C) 2006-2022 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_INCLUDED_env_h
27#define IPRT_INCLUDED_env_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
34
35RT_C_DECLS_BEGIN
36
37/** @defgroup grp_rt_env RTEnv - Process Environment Strings
38 * @ingroup grp_rt
39 * @{
40 */
41
42#ifdef IN_RING3
43
44/** Special handle that indicates the default process environment. */
45#define RTENV_DEFAULT ((RTENV)~(uintptr_t)0)
46
47/**
48 * Creates an empty environment block.
49 *
50 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
51 *
52 * @param pEnv Where to store the handle of the new environment block.
53 */
54RTDECL(int) RTEnvCreate(PRTENV pEnv);
55
56/**
57 * Creates an empty environment block.
58 *
59 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
60 *
61 * @param phEnv Where to store the handle of the new environment block.
62 * @param fFlags Zero or more RTENV_CREATE_F_XXX flags.
63 */
64RTDECL(int) RTEnvCreateEx(PRTENV phEnv, uint32_t fFlags);
65
66/** @name RTENV_CREATE_F_XXX - Flags for RTEnvCreateEx() and RTEnvCreateChangeRecordEx()
67 * @{ */
68/** Allow equal ('=') as the first character of a variable name.
69 * This is useful for compatibility with Windows' handling of CWD on drives, as
70 * these are stored on the form "=D:=D:\tmp\asdf". It is only really useful
71 * for creating environment blocks for processes and such, since the CRT doesn't
72 * allow us to apply it directly to the process enviornment. */
73#define RTENV_CREATE_F_ALLOW_EQUAL_FIRST_IN_VAR RT_BIT_32(0)
74/** Valid flags. */
75#define RTENV_CREATE_F_VALID_MASK UINT32_C(0x00000001)
76/** @} */
77
78/**
79 * Creates an environment block and fill it with variables from the given
80 * environment array.
81 *
82 * @returns IPRT status code.
83 * @retval VWRN_ENV_NOT_FULLY_TRANSLATED may be returned when passing
84 * RTENV_DEFAULT and one or more of the environment variables have
85 * codeset incompatibilities. The problematic variables will be
86 * ignored and not included in the clone, thus the clone will have
87 * fewer variables.
88 * @retval VERR_NO_MEMORY
89 * @retval VERR_NO_STR_MEMORY
90 * @retval VERR_INVALID_HANDLE
91 *
92 * @param pEnv Where to store the handle of the new environment block.
93 * @param EnvToClone The environment to clone.
94 */
95RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone);
96
97/**
98 * Creates an environment block from an UTF-16 environment raw block.
99 *
100 * This is the reverse of RTEnvQueryUtf16Block.
101 *
102 * @returns IPRT status code.
103 * @retval VERR_NO_MEMORY
104 * @retval VERR_NO_STR_MEMORY
105 *
106 * @param phEnv Where to store the handle of the new environment block.
107 * @param pwszzBlock List of zero terminated string end with a zero length
108 * string (or two zero terminators if you prefer). The
109 * strings are on the RTPutEnv format (VAR=VALUE), except
110 * they are all expected to include an equal sign.
111 * @param fFlags Flags served for the future.
112 */
113RTDECL(int) RTEnvCloneUtf16Block(PRTENV phEnv, PCRTUTF16 pwszzBlock, uint32_t fFlags);
114
115/**
116 * Destroys an environment block.
117 *
118 * @returns IPRT status code.
119 *
120 * @param Env Environment block handle.
121 * Both RTENV_DEFAULT and NIL_RTENV are silently ignored.
122 */
123RTDECL(int) RTEnvDestroy(RTENV Env);
124
125/**
126 * Resets the environment block to contain zero variables.
127 *
128 * @returns IPRT status code.
129 *
130 * @param hEnv Environment block handle. RTENV_DEFAULT is not supported.
131 */
132RTDECL(int) RTEnvReset(RTENV hEnv);
133
134/**
135 * Get the execve/spawnve/main envp.
136 *
137 * All returned strings are in the current process' codepage.
138 * This array is only valid until the next RTEnv call.
139 *
140 * @returns Pointer to the raw array of environment variables.
141 * @returns NULL if Env is NULL or invalid.
142 *
143 * @param Env Environment block handle.
144 *
145 * @note This is NOT available on Windows. It is also not a stable export
146 * and will hopefully be replaced before long (see todo).
147 *
148 * @todo This needs to change to return a copy of the env vars like
149 * RTEnvQueryUtf16Block does!
150 */
151RTDECL(char const * const *) RTEnvGetExecEnvP(RTENV Env);
152
153/**
154 * Get a sorted, UTF-16 environment block for CreateProcess.
155 *
156 * @returns IPRT status code.
157 *
158 * @param hEnv Environment block handle.
159 * @param ppwszzBlock Where to return the environment block. This must be
160 * freed by calling RTEnvFreeUtf16Block.
161 */
162RTDECL(int) RTEnvQueryUtf16Block(RTENV hEnv, PRTUTF16 *ppwszzBlock);
163
164/**
165 * Frees an environment block returned by RTEnvGetUtf16Block().
166 *
167 * @param pwszzBlock What RTEnvGetUtf16Block returned. NULL is ignored.
168 */
169RTDECL(void) RTEnvFreeUtf16Block(PRTUTF16 pwszzBlock);
170
171/**
172 * Get a sorted, UTF-8 environment block.
173 *
174 * The environment block is a sequence of putenv formatted ("NAME=VALUE" or
175 * "NAME") zero terminated strings ending with an empty string (i.e. last string
176 * has two zeros).
177 *
178 * @returns IPRT status code.
179 *
180 * @param hEnv Environment block handle.
181 * @param fSorted Whether to sort it, this will affect @a hEnv.
182 * @param ppszzBlock Where to return the environment block. This must be
183 * freed by calling RTEnvFreeUtf8Block.
184 * @param pcbBlock Where to return the size of the block. Optional.
185 */
186RTDECL(int) RTEnvQueryUtf8Block(RTENV hEnv, bool fSorted, char **ppszzBlock, size_t *pcbBlock);
187
188/**
189 * Frees an environment block returned by RTEnvGetUtf8Block().
190 *
191 * @param pszzBlock What RTEnvGetUtf8Block returned. NULL is ignored.
192 */
193RTDECL(void) RTEnvFreeUtf8Block(char *pszzBlock);
194
195/**
196 * Checks if an environment variable exists in the default environment block.
197 *
198 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
199 *
200 * @param pszVar The environment variable name.
201 * @remark WARNING! The current implementation does not perform the appropriate
202 * codeset conversion. We'll figure this out when it becomes necessary.
203 */
204RTDECL(bool) RTEnvExist(const char *pszVar);
205RTDECL(bool) RTEnvExistsBad(const char *pszVar);
206RTDECL(bool) RTEnvExistsUtf8(const char *pszVar);
207
208/**
209 * Checks if an environment variable exists in a specific environment block.
210 *
211 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
212 *
213 * @param Env The environment handle.
214 * @param pszVar The environment variable name.
215 */
216RTDECL(bool) RTEnvExistEx(RTENV Env, const char *pszVar);
217
218/**
219 * Gets an environment variable from the default environment block. (getenv).
220 *
221 * The caller is responsible for ensuring that nobody changes the environment
222 * while it's using the returned string pointer!
223 *
224 * @returns Pointer to read only string on success, NULL if the variable wasn't found.
225 *
226 * @param pszVar The environment variable name.
227 *
228 * @remark WARNING! The current implementation does not perform the appropriate
229 * codeset conversion. We'll figure this out when it becomes necessary.
230 */
231RTDECL(const char *) RTEnvGet(const char *pszVar);
232RTDECL(const char *) RTEnvGetBad(const char *pszVar);
233RTDECL(int) RTEnvGetUtf8(const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual);
234
235/**
236 * Gets an environment variable in a specific environment block.
237 *
238 * @returns IPRT status code.
239 * @retval VERR_ENV_VAR_NOT_FOUND if the variable was not found.
240 * @retval VERR_ENV_VAR_UNSET if @a hEnv is an environment change record and
241 * the variable has been recorded as unset.
242 *
243 * @param hEnv The environment handle.
244 * @param pszVar The environment variable name.
245 * @param pszValue Where to put the buffer.
246 * @param cbValue The size of the value buffer.
247 * @param pcchActual Returns the actual value string length. Optional.
248 */
249RTDECL(int) RTEnvGetEx(RTENV hEnv, const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual);
250
251/**
252 * Puts an variable=value string into the environment (putenv).
253 *
254 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
255 *
256 * @param pszVarEqualValue The variable '=' value string. If the value and '=' is
257 * omitted, the variable is removed from the environment.
258 *
259 * @remark Don't assume the value is copied.
260 * @remark WARNING! The current implementation does not perform the appropriate
261 * codeset conversion. We'll figure this out when it becomes necessary.
262 */
263RTDECL(int) RTEnvPut(const char *pszVarEqualValue);
264RTDECL(int) RTEnvPutBad(const char *pszVarEqualValue);
265RTDECL(int) RTEnvPutUtf8(const char *pszVarEqualValue);
266
267/**
268 * Puts a copy of the passed in 'variable=value' string into the environment block.
269 *
270 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
271 *
272 * @param Env Handle of the environment block.
273 * @param pszVarEqualValue The variable '=' value string. If the value and '=' is
274 * omitted, the variable is removed from the environment.
275 */
276RTDECL(int) RTEnvPutEx(RTENV Env, const char *pszVarEqualValue);
277
278/**
279 * Sets an environment variable (setenv(,,1)).
280 *
281 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
282 *
283 * @param pszVar The environment variable name.
284 * @param pszValue The environment variable value.
285 *
286 * @remark WARNING! The current implementation does not perform the appropriate
287 * codeset conversion. We'll figure this out when it becomes necessary.
288 */
289RTDECL(int) RTEnvSet(const char *pszVar, const char *pszValue);
290RTDECL(int) RTEnvSetBad(const char *pszVar, const char *pszValue);
291RTDECL(int) RTEnvSetUtf8(const char *pszVar, const char *pszValue);
292
293/**
294 * Sets an environment variable (setenv(,,1)).
295 *
296 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
297 *
298 * @param Env The environment handle.
299 * @param pszVar The environment variable name.
300 * @param pszValue The environment variable value.
301 */
302RTDECL(int) RTEnvSetEx(RTENV Env, const char *pszVar, const char *pszValue);
303
304/**
305 * Removes an environment variable from the default environment block.
306 *
307 * @returns IPRT status code.
308 * @returns VINF_ENV_VAR_NOT_FOUND if the variable was not found.
309 *
310 * @param pszVar The environment variable name.
311 *
312 * @remark WARNING! The current implementation does not perform the appropriate
313 * codeset conversion. We'll figure this out when it becomes necessary.
314 */
315RTDECL(int) RTEnvUnset(const char *pszVar);
316RTDECL(int) RTEnvUnsetBad(const char *pszVar);
317RTDECL(int) RTEnvUnsetUtf8(const char *pszVar);
318
319/**
320 * Removes an environment variable from the specified environment block.
321 *
322 * @returns IPRT status code.
323 * @returns VINF_ENV_VAR_NOT_FOUND if the variable was not found.
324 *
325 * @param Env The environment handle.
326 * @param pszVar The environment variable name.
327 */
328RTDECL(int) RTEnvUnsetEx(RTENV Env, const char *pszVar);
329
330
331/**
332 * Returns the value of a environment variable from the default
333 * environment block in a heap buffer.
334 *
335 * @returns Pointer to a string containing the value, free it using RTStrFree.
336 * NULL if the variable was not found or we're out of memory.
337 *
338 * @param pszVar The environment variable name (UTF-8).
339 */
340RTDECL(char *) RTEnvDup(const char *pszVar);
341
342/**
343 * Duplicates the value of a environment variable if it exists.
344 *
345 * @returns Pointer to a string containing the value, free it using RTStrFree.
346 * NULL if the variable was not found or we're out of memory.
347 *
348 * @param Env The environment handle.
349 * @param pszVar The environment variable name.
350 */
351RTDECL(char *) RTEnvDupEx(RTENV Env, const char *pszVar);
352
353/**
354 * Counts the variables in the environment.
355 *
356 * @returns Number of variables in the environment. UINT32_MAX on error.
357 * @param hEnv The environment handle.
358 * RTENV_DEFAULT is currently not accepted.
359 */
360RTDECL(uint32_t) RTEnvCountEx(RTENV hEnv);
361
362/**
363 * Queries an environment variable by it's index.
364 *
365 * This can be used together with RTEnvCount to enumerate the environment block.
366 *
367 * @returns IPRT status code.
368 * @retval VERR_ENV_VAR_NOT_FOUND if the index is out of bounds, output buffers
369 * untouched.
370 * @retval VERR_BUFFER_OVERFLOW if one of the buffers are too small. We'll
371 * fill it with as much we can in RTStrCopy fashion.
372 * @retval VINF_ENV_VAR_UNSET if @a hEnv is an environment change record and
373 * the variable at @a iVar is recorded as being unset.
374 *
375 * @param hEnv The environment handle.
376 * RTENV_DEFAULT is currently not accepted.
377 * @param iVar The variable index.
378 * @param pszVar Variable name buffer.
379 * @param cbVar The size of the variable name buffer.
380 * @param pszValue Value buffer.
381 * @param cbValue The size of the value buffer.
382 */
383RTDECL(int) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue);
384
385/**
386 * Leaner and meaner version of RTEnvGetByIndexEx.
387 *
388 * This can be used together with RTEnvCount to enumerate the environment block.
389 *
390 * Use with caution as the returned pointer may change by the next call using
391 * the environment handle. Please only use this API in cases where there is no
392 * chance of races.
393 *
394 * @returns Pointer to the internal environment variable=value string on
395 * success. If @a hEnv is an environment change recordthe string may
396 * also be on the "variable" form, representing an unset operation. Do
397 * NOT change this string, it is read only!
398 *
399 * If the index is out of range on the environment handle is invalid,
400 * NULL is returned.
401 *
402 * @param hEnv The environment handle.
403 * RTENV_DEFAULT is currently not accepted.
404 * @param iVar The variable index.
405 */
406RTDECL(const char *) RTEnvGetByIndexRawEx(RTENV hEnv, uint32_t iVar);
407
408
409/**
410 * Creates an empty environment change record.
411 *
412 * This is a special environment for use with RTEnvApplyChanges and similar
413 * purposes. The
414 *
415 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
416 *
417 * @param phEnv Where to store the handle of the new environment block.
418 */
419RTDECL(int) RTEnvCreateChangeRecord(PRTENV phEnv);
420
421/**
422 * Extended version of RTEnvCreateChangeRecord that takes flags.
423 *
424 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
425 *
426 * @param phEnv Where to store the handle of the new environment block.
427 * @param fFlags Zero or more RTENV_CREATE_F_XXX flags.
428 */
429RTDECL(int) RTEnvCreateChangeRecordEx(PRTENV phEnv, uint32_t fFlags);
430
431/**
432 * Checks if @a hEnv is an environment change record.
433 *
434 * @returns true if it is, false if it's not or if the handle is invalid.
435 * @param hEnv The environment handle.
436 * @sa RTEnvCreateChangeRecord.
437 */
438RTDECL(bool) RTEnvIsChangeRecord(RTENV hEnv);
439
440/**
441 * Applies changes from one environment onto another.
442 *
443 * If @a hEnvChanges is a normal environment, its content is just added to @a
444 * hEnvDst, where variables in the destination can only be overwritten. However
445 * if @a hEnvChanges is a change record environment, variables in the
446 * destination can also be removed.
447 *
448 * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
449 * @param hEnvDst The destination environment.
450 * @param hEnvChanges Handle to the environment containig the changes to
451 * apply. As said, especially useful if it's a environment
452 * change record. RTENV_DEFAULT is not supported here.
453 */
454RTDECL(int) RTEnvApplyChanges(RTENV hEnvDst, RTENV hEnvChanges);
455
456#endif /* IN_RING3 */
457
458/** @} */
459
460RT_C_DECLS_END
461
462#endif /* !IPRT_INCLUDED_env_h */
463
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