_WCRTLINK CHAR_TYPE *__F_NAME(getenv,_wgetenv)( const CHAR_TYPE *name ) { #ifdef __NETWARE__ name = name; #else CHAR_TYPE **envp; CHAR_TYPE *p; int len; #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) { __create_wide_environment(); } #endif /*** Find the environment string ***/ __ptr_check( name, 0 ); envp = __F_NAME(_RWD_environ,_RWD_wenviron); if( (envp != NULL) && (name != NULL) ) { len = __F_NAME(strlen,wcslen)( name ); for( ; p = *envp; ++envp ) { if( CMP_FUNC( p, name, len ) == 0 ) { if( p[len] == STRING( '=' ) ) { return( &p[len+1] ); } } } } #endif return( NULL ); /* not found */ }
int __F_NAME(__setenv,__wsetenv)( const CHAR_TYPE *name, const CHAR_TYPE *newvalue, int overwrite ) { #ifdef __NETWARE__ name = name; newvalue = newvalue; overwrite = overwrite; return( -1 ); #else int rc; if( name == NULL || *name == NULLCHAR ) { return( -1 ); } #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) { __create_wide_environment(); } #endif rc = __F_NAME(__findenv,__wfindenv)( name, ( newvalue == NULL ) ); if( rc > 0 ) { rc = __F_NAME(addenv,waddenv)( rc - 1, name, newvalue ); } return( rc ); #endif }
_WCRTLINK int __F_NAME(execvp,_wexecvp)( const CHAR_TYPE *file, const CHAR_TYPE * const *argv ) { #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) __create_wide_environment(); return( _wexecvpe( file, argv, (const CHAR_TYPE **)_RWD_wenviron ) ); #else #ifdef __RDOS__ return( execv( file, argv ) ); #else return( execvpe( file, argv, (const CHAR_TYPE **)_RWD_environ ) ); #endif #endif }
_WCRTLINK CHAR_TYPE *__F_NAME(getenv,_wgetenv)( const CHAR_TYPE *name ) { #ifdef __NETWARE__ name = name; #else CHAR_TYPE **envp; CHAR_TYPE *p; #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) { __create_wide_environment(); } #endif /*** Find the environment string ***/ __ptr_check( name, 0 ); envp = __F_NAME(_RWD_environ,_RWD_wenviron); if( (envp != NULL) && (name != NULL) ) { for( ; p = *envp; ++envp ) { const CHAR_TYPE *s = name; while( !_TCSTERM( p ) ) { if( _TCSTERM( s ) ) { if( _TCSNEXTC( p ) == STRING( '=' ) ) return( _TCSINC( p ) ); break; } #if defined(__UNIX__) if( _TCSCMP( p, s ) ) #else if( _TCSICMP( p, s ) ) #endif break; p = _TCSINC( p ); /* skip over character */ s = _TCSINC( s ); /* skip over character */ } } } #endif return( NULL ); /* not found */ }
int __F_NAME(__cenvarg,__wcenvarg)( /* * Build environment and command line for new process. Length of environment * (in bytes) is returned on success. -1 is returned on failure. */ const CHAR_TYPE *const argv[], /* i: arguments for new process */ const CHAR_TYPE *const envp[], /* i: env strings for new process */ CHAR_TYPE **envptr, /* o: allocated memory for env */ CHAR_TYPE **envstrings, /* o: pointer to environment strings */ unsigned *envseg, /* o: start of env (on para boundary) */ size_t *cmdline_len, /* o: size required to hold cmd line */ int exec ) /* i: TRUE if for exec */ { unsigned length; unsigned oamblksiz; CHAR_TYPE *p; CHAR_TYPE _WCNEAR *np; unsigned len; int i; if( envp == NULL ){ #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) __create_wide_environment(); #endif envp = (const CHAR_TYPE * const *)__F_NAME(_RWD_environ,_RWD_wenviron); } length = 0; if( envp != NULL ){ for( i = 0; envp[i] != NULL; i++ ) { length += __F_NAME(strlen,wcslen)( envp[i] ) + 1; } } ++length; /* trailing \0 for env */ if( exec ){ /* store argv[0] at 2 bytes past end of env */ length += 2 + __F_NAME(strlen,wcslen)( argv[0] ) + 1; } length += 15; /* so we can start on a paragraph boundary */ oamblksiz = _RWD_amblksiz; _RWD_amblksiz = 16; /* force allocation in 16 byte increments */ p = np = lib_nmalloc( length*sizeof(CHAR_TYPE) ); if( np == NULL ){ /* 03-aug-88 */ p = lib_malloc( length*sizeof(CHAR_TYPE) ); if( p == NULL ){ __set_errno( ENOMEM ); __set_doserrno( E_nomem ); _RWD_amblksiz = oamblksiz; return( -1 ); } } _RWD_amblksiz = oamblksiz; *envptr = p; #if defined( _M_I86 ) && defined( __DOS__ ) #if defined(__SMALL_DATA__) p = (char *) (((unsigned) p + 15) & 0xfff0); #else /* large data models */ /* 12-aug-88 */ p = MK_FP( FP_SEG(p), (( FP_OFF(p) + 15) & 0xfff0) ); #endif { CHAR_TYPE _WCFAR *temp; temp = p; *envseg = FP_SEG( temp ) + FP_OFF( temp )/16; } #else *envseg = 0; #endif *envstrings = p; /* save ptr to env strings. 07-oct-92 */ if( envp != NULL ){ for( i = 0; envp[i] != NULL; ++i ){ p = stpcpy( p, envp[i] ) + 1; } } *p++ = '\0'; if( exec ) { __F_NAME(strcpy,wcscpy)( p + 2, argv[0] ); } len = 0; if( argv[0] != NULL ) { for( i = 1; argv[i] != NULL; ++i ){ if( len != 0 ) ++len; /* plus 1 for blank separator */ len += __F_NAME(strlen,wcslen)( argv[i] ); } } #if defined( __NT__ ) // we are going to add quotes around program name (argv[0]) len += _MAX_PATH2 + 3; #elif defined( __OS2__ ) len += _MAX_PATH2 + 1; #elif defined( __RDOS__ ) || defined( __RDOSDEV__ ) len += _MAX_PATH2 + 1; #else if( len > 126 ) { __set_errno( E2BIG ); __set_doserrno( E_badenv ); lib_free( *envptr ); return( -1 ); } len = _MAX_PATH; /* always use _MAX_PATH chars for DOS */ #endif *cmdline_len = len; return( length / 16 ); }
// _wsetenv and setenv are implemented this way so that each can call the // other without having the other call it, which would call the other, and // so on, making bad things happen. This inter-calling is necessary to keep // the wide and MBCS environments consistent. _WCRTLINK int __F_NAME(setenv,_wsetenv)( const CHAR_TYPE *name, const CHAR_TYPE *newvalue, int overwrite ) { #if !defined( __UNIX__ ) && !defined( __RDOS__ ) && !defined( __RDOSDEV__ ) #ifdef __WIDECHAR__ char *otherName; char *otherNewval; const size_t charsize = sizeof( wchar_t ); const size_t fact = MB_CUR_MAX; #else wchar_t *otherName; wchar_t *otherNewval; const size_t charsize = MB_CUR_MAX; const size_t fact = 1; #endif size_t otherNameLen; size_t otherNewvalLen; #endif int rc; /*** Ensure variable is deleted if newvalue == "" ***/ #ifndef __UNIX__ if( (newvalue != NULL) && (*newvalue == NULLCHAR) ) { if( overwrite || (__F_NAME(getenv,_wgetenv)( name ) == NULL) ) { newvalue = NULL; } } #endif #ifdef __NT__ /*** Update the process environment if using Win32 ***/ if( overwrite || __F_NAME(getenv,_wgetenv)( name ) == NULL ) { if( __F_NAME(SetEnvironmentVariableA,__lib_SetEnvironmentVariableW)( name, newvalue ) == FALSE ) { return( -1 ); } } #elif defined( __RDOS__ ) /*** Update the process environment if using RDOS ***/ if( overwrite || __F_NAME(getenv,_wgetenv)( name ) == NULL ) { int handle; handle = RdosOpenProcessEnv(); RdosDeleteEnvVar( handle, name ); if( *newvalue != NULLCHAR ) RdosAddEnvVar( handle, name, newvalue ); RdosCloseEnv( handle ); } #elif defined( __RDOSDEV__ ) /*** Update the process environment if using RDOSDEV ***/ if( overwrite || __F_NAME(getenv,_wgetenv)( name ) == NULL ) { int handle; handle = RdosOpenSysEnv(); RdosDeleteEnvVar( handle, name ); if( *newvalue != NULLCHAR ) RdosAddEnvVar( handle, name, newvalue ); RdosCloseEnv( handle ); } #endif /*** Update the (__WIDECHAR__ ? wide : MBCS) environment ***/ #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) { __create_wide_environment(); } #endif rc = __F_NAME(__setenv,__wsetenv)( name, newvalue, overwrite ); if( rc == -1 ) { return( -1 ); } #if !defined( __UNIX__ ) && !defined( __RDOS__ ) && !defined( __RDOSDEV__ ) /*** Update the other environment ***/ #ifndef __WIDECHAR__ if( _RWD_wenviron == NULL ) { return( 0 ); // _wenviron uninitialized } #endif otherNameLen = __F_NAME(_mbslen,wcslen)( name ) + 1; otherName = lib_malloc( otherNameLen * charsize ); if( otherName == NULL ) { __set_errno( ENOMEM ); return( -1 ); } if( newvalue != NULL ) { otherNewvalLen = __F_NAME(_mbslen,wcslen)( newvalue ) + 1; otherNewval = lib_malloc( otherNewvalLen * charsize ); if( otherNewval == NULL ) { lib_free( otherName ); __set_errno( ENOMEM ); return( -1 ); } } else { otherNewval = NULL; } rc = __F_NAME(mbstowcs,wcstombs)( otherName, name, otherNameLen * fact ); if( rc != -1 ) { if( otherNewval != NULL ) { rc = __F_NAME(mbstowcs,wcstombs)( otherNewval, newvalue, otherNewvalLen * fact ); } if( rc != -1 ) { rc = __F_NAME(__wsetenv,__setenv)( otherName, otherNewval, overwrite ); } } lib_free( otherName ); lib_free( otherNewval ); if( rc == -1 ) { return( -1 ); } #endif return( 0 ); }
_WCRTLINK void __F_NAME(_searchenv,_wsearchenv)( const CHAR_TYPE *name, const CHAR_TYPE *env_var, CHAR_TYPE *buffer ) { CHAR_TYPE *p, *p2; int prev_errno; size_t len; #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) { __create_wide_environment(); } #endif prev_errno = _RWD_errno; if( __F_NAME(access,_waccess)( name, F_OK ) == 0 ) { p = buffer; /* JBS 90/3/30 */ len = 0; /* JBS 04/1/06 */ for( ;; ) { if( name[0] == PATH_SEPARATOR ) break; if( name[0] == STRING( '.' ) ) break; #ifndef __UNIX__ if( name[0] == STRING( '/' ) ) break; if( name[0] != NULLCHAR && name[1] == STRING( ':' ) ) break; #endif __F_NAME(getcwd,_wgetcwd)( buffer, _MAX_PATH ); len = __F_NAME(strlen,wcslen)( buffer ); p = &buffer[ len ]; if( p[-1] != PATH_SEPARATOR ) { if( len < (_MAX_PATH - 1) ) { *p++ = PATH_SEPARATOR; len++; } } break; } *p = NULLCHAR; __F_NAME(strncat,wcsncat)( p, name, (_MAX_PATH - 1) - len ); return; } p = __F_NAME(getenv,_wgetenv)( env_var ); if( p != NULL ) { for( ;; ) { if( *p == NULLCHAR ) break; p2 = buffer; len = 0; /* JBS 04/1/06 */ while( *p ) { if( *p == LIST_SEPARATOR ) break; if( *p != STRING( '"' ) ) { if( len < (_MAX_PATH-1) ) { *p2++ = *p; /* JBS 00/9/29 */ len++; } } p++; } /* check for zero-length prefix which represents CWD */ if( p2 != buffer ) { /* JBS 90/3/30 */ if( p2[-1] != PATH_SEPARATOR #ifndef __UNIX__ && p2[-1] != STRING( '/' ) && p2[-1] != STRING( ':' ) #endif ) { if( len < (_MAX_PATH - 1) ) { *p2++ = PATH_SEPARATOR; len++; } } *p2 = NULLCHAR; len += __F_NAME(strlen,wcslen)( name );/* JBS 04/12/23 */ if( len < _MAX_PATH ) { __F_NAME(strcat,wcscat)( p2, name ); /* check to see if file exists */ if( __F_NAME(access,_waccess)( buffer, 0 ) == 0 ) { __set_errno( prev_errno ); return; } } } if( *p == NULLCHAR ) break; ++p; } } buffer[0] = NULLCHAR; }
int __F_NAME(__cenvarg,__wcenvarg)( /* * Build environment and command line for new process. Length of environment * (in bytes) is returned on success. -1 is returned on failure. */ const CHAR_TYPE *const argv[], /* i: arguments for new process */ const CHAR_TYPE *const envp[], /* i: env strings for new process */ CHAR_TYPE **_envptr, /* o: environment ptr (unaligned) */ CHAR_TYPE **envptr, /* o: environment ptr (DOS 16-bit aligned to para) */ unsigned *envseg, /* o: environment segment (DOS 16-bit normalized, zero for others) */ size_t *cmdline_len, /* o: size required to hold cmd line */ int exec ) /* i: TRUE if for exec */ { unsigned length; /* environment length in bytes */ unsigned old_amblksiz; CHAR_TYPE *p; CHAR_TYPE _WCNEAR *np; unsigned len; /* command line length in characters */ int i; #if !defined( __DOS_086__ ) exec = exec; #endif if( envp == NULL ) { #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) __create_wide_environment(); #endif envp = (const CHAR_TYPE * const *)__F_NAME(_RWD_environ,_RWD_wenviron); } length = 0; if( envp != NULL ) { for( i = 0; envp[i] != NULL; i++ ) { length += ( __F_NAME(strlen,wcslen)( envp[i] ) + 1 ) * sizeof( CHAR_TYPE ); } } length += sizeof( CHAR_TYPE ); /* trailing \0 for env */ #if defined( __DOS_086__ ) if( exec ) { /* store argv[0] at 2 bytes past end of env */ length += 2; length += strlen( argv[0] ) + 1; } #endif /* round environment length to para */ length = __ROUND_UP_SIZE_PARA( length ); #if defined( __DOS_086__ ) /* add space for pointer alignment */ /* so we can start on a paragraph boundary even if memory pointer is not aligned to para */ length += 15; #endif /* allocate space for new environment */ old_amblksiz = _RWD_amblksiz; _RWD_amblksiz = 16; /* force allocation in 16 byte increments */ p = np = lib_nmalloc( length ); if( np == NULL ) { p = lib_malloc( length ); if( p == NULL ) { _RWD_errno = ENOMEM; _RWD_doserrno = E_nomem; _RWD_amblksiz = old_amblksiz; return( -1 ); } } _RWD_amblksiz = old_amblksiz; *_envptr = p; #if defined( __DOS_086__ ) /* align DOS 16-bit environment pointer to para boundary */ #if defined(__SMALL_DATA__) p = (char *)__ROUND_UP_SIZE_PARA( FP_OFF( p ) ); #else /* __LARGE_DATA__ */ p = MK_FP( FP_SEG( p ), __ROUND_UP_SIZE_PARA( FP_OFF( p ) ) ); #endif /* normalize DOS 16-bit aligned environment pointer to segment */ *envseg = FP_SEG( p ) + __ROUND_DOWN_SIZE_TO_PARA( FP_OFF( p ) ); /* correct environment length (subtract aditional pointer alignment space) */ length -= 15; #else *envseg = 0; #endif *envptr = p; /* save ptr to env strings. */ if( envp != NULL ) { for( i = 0; envp[i] != NULL; ++i ) { p = stpcpy( p, envp[i] ) + 1; } } *p++ = NULLCHAR; #if defined( __DOS_086__ ) if( exec ) { *p++ = 1; *p++ = 0; strcpy( p, argv[0] ); } #endif len = 0; if( argv[0] != NULL ) { for( i = 1; argv[i] != NULL; ++i ) { if( len != 0 ) ++len; /* plus 1 for blank separator */ len += __F_NAME(strlen,wcslen)( argv[i] ); } } #if defined( __NT__ ) // we are going to add quotes around program name (argv[0]) len += _MAX_PATH2 + 3; #elif defined( __OS2__ ) len += _MAX_PATH2 + 1; #elif defined( __RDOS__ ) || defined( __RDOSDEV__ ) len += _MAX_PATH2 + 1; #else /* __DOS__ */ if( len > 126 ) { _RWD_errno = E2BIG; _RWD_doserrno = E_badenv; lib_free( *_envptr ); return( -1 ); } len = _MAX_PATH; /* always use _MAX_PATH chars for DOS */ #endif *cmdline_len = len; /* convert environment length in bytes to length in para */ return( __ROUND_DOWN_SIZE_TO_PARA( length ) ); }
// _wpetenv and putenv are implemented this way so that each can call the // other without having the other call it, which would call the other, and // so on, making bad things happen. This inter-calling is necessary to keep // the wide and MBCS environments consistent. Also, with this method // __create_wide_environment can call __wputenv, without having the function // it calls call __create_wide_environment, causing similar bad things. _WCRTLINK int __F_NAME(putenv,_wputenv)( const CHAR_TYPE *env_string ) { #if !defined( __UNIX__ ) && !defined( __RDOS__ ) && !defined( __RDOSDEV__ ) #ifdef __WIDECHAR__ char *otherStr; const size_t charsize = sizeof(wchar_t); const size_t fact = MB_CUR_MAX; #else wchar_t *otherStr; const size_t charsize = MB_CUR_MAX; const size_t fact = 1; #endif size_t otherStrLen; #endif #if defined( __NT__ ) || defined( __RDOS__ ) || defined( __RDOSDEV__ ) CHAR_TYPE *name; CHAR_TYPE *value; CHAR_TYPE *p; size_t len; #if defined( __NT__ ) BOOL osRc; #else int handle; #endif /*** Update the process environment if using Win32 ***/ /*** Validate the input string ***/ p = _TCSCHR( env_string, STRING( '=' ) ); if( p == NULL || p == env_string ) return( -1 ); /* must have form name=value */ /*** Extract the variable name ***/ len = p - env_string; name = lib_malloc( ( len + 1 ) * CHARSIZE ); if( name == NULL ) return( -1 ); memcpy( name, env_string, len * CHARSIZE ); name[len] = NULLCHAR; /*** Extract the new value, if any ***/ p++; /* point past the '=' */ len = _TCSLEN( p ); if( len != 0 ) { value = lib_malloc( ( len + 1 ) * CHARSIZE ); if( value == NULL ) { lib_free( name ); return( -1 ); } memcpy( value, p, len * CHARSIZE ); value[len] = NULLCHAR; } else { value = NULL; /* don't need a buffer to delete */ } #ifdef __NT__ /*** Tell the OS about the change ***/ osRc = __lib_SetEnvironmentVariable( name, value ); #elif defined( __RDOS__ ) handle = RdosOpenProcessEnv(); RdosDeleteEnvVar( handle, name ); RdosAddEnvVar( handle, name, value ); RdosCloseEnv( handle ); #elif defined( __RDOSDEV__ ) handle = RdosOpenSysEnv(); RdosDeleteEnvVar( handle, name ); RdosAddEnvVar( handle, name, value ); RdosCloseEnv( handle ); #endif lib_free( name ); lib_free( value ); #ifdef __NT__ if( osRc == FALSE ) { if( value == NULL ) { // we couldn't find the envvar but since we are deleting it, // the putenv() is successful return( 0 ); } return( -1 ); } #endif #endif /*** Update the (__WIDECHAR__ ? wide : MBCS) environment ***/ #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) { __create_wide_environment(); } #endif #if defined( __UNIX__ ) || defined( __RDOS__ ) || defined( __RDOSDEV__ ) return( __F_NAME(__putenv,__wputenv)( env_string ) ); #else if( __F_NAME(__putenv,__wputenv)( env_string ) != 0 ) return( -1 ); /*** Update the other environment ***/ #ifndef __WIDECHAR__ if( _RWD_wenviron == NULL ) return( 0 ); // _wenviron uninitialized #endif otherStrLen = _TCSLEN( env_string ) + 1; otherStr = lib_malloc( otherStrLen * charsize ); if( otherStr == NULL ) { _RWD_errno = ENOMEM; return( -1 ); } if( __F_NAME(mbstowcs,wcstombs)( otherStr, env_string, otherStrLen * fact ) == -1 ) { lib_free( otherStr ); _RWD_errno = ERANGE; return( -1 ); } return( __F_NAME(__wputenv,__putenv)( otherStr ) ); #endif }
_WCRTLINK void __F_NAME(_searchenv,_wsearchenv)( const CHAR_TYPE *name, const CHAR_TYPE *env_var, CHAR_TYPE *buffer ) { CHAR_TYPE *p, *p2; int prev_errno; size_t len; #ifdef __WIDECHAR__ if( _RWD_wenviron == NULL ) { __create_wide_environment(); } #endif prev_errno = _RWD_errno; if( __F_NAME(access,_waccess)( name, F_OK ) == 0 ) { p = buffer; len = 0; if( !IS_DIR_SEP( name[0] ) && name[0] != STRING( '.' ) ) { #ifndef __UNIX__ if( name[0] == NULLCHAR || name[1] != DRV_SEP ) { #endif __F_NAME(getcwd,_wgetcwd)( buffer, _MAX_PATH ); if( *buffer != NULLCHAR ) { len = __F_NAME(strlen,wcslen)( buffer ); p = buffer + len; if( p[-1] != DIR_SEP ) { if( len < ( _MAX_PATH - 1 ) ) { *p++ = DIR_SEP; len++; } } } #ifndef __UNIX__ } #endif } *p = NULLCHAR; __F_NAME(strncat,wcsncat)( p, name, ( _MAX_PATH - 1 ) - len ); return; } p = __F_NAME(getenv,_wgetenv)( env_var ); if( p != NULL ) { for( ;; ) { if( *p == NULLCHAR ) break; p2 = buffer; len = 0; while( *p != NULLCHAR ) { if( *p == LIST_SEPARATOR ) break; if( *p != STRING( '"' ) ) { if( len < ( _MAX_PATH - 1 ) ) { *p2++ = *p; len++; } } p++; } /* check for zero-length prefix which represents CWD */ if( p2 != buffer ) { #ifdef __UNIX__ if( !IS_DIR_SEP( p2[-1] ) ) { #else if( !IS_DIR_SEP( p2[-1] ) && p2[-1] != DRV_SEP ) { #endif if( len < (_MAX_PATH - 1) ) { *p2++ = DIR_SEP; len++; } } *p2 = NULLCHAR; len += __F_NAME(strlen,wcslen)( name ); if( len < _MAX_PATH ) { __F_NAME(strcat,wcscat)( p2, name ); /* check to see if file exists */ if( __F_NAME(access,_waccess)( buffer, 0 ) == 0 ) { _RWD_errno = prev_errno; return; } } } if( *p == NULLCHAR ) break; ++p; } } buffer[0] = NULLCHAR; }