Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-Id: <5.1.0.14.2.20021231133759.02f9b2a0@pop3.corvu.com.au> X-Sender: troy AT pop3 DOT corvu DOT com DOT au Date: Tue, 31 Dec 2002 14:13:49 +1100 To: cygwin AT cygwin DOT com From: Troy Rollo Subject: Re: Sorting environment Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; format=flowed Note-from-DJ: This may be spam A number of years back there was a discussion on this mailing list regarding sorting of the environment, and there was some suggestion that it might or might not be necessary. There may have also been some later discussion as to what exactly is involved in sorting the environment the way Windows wants it, although I can't find any such discussion, and the current implementation in Cygwin is incorrect (see below). On Windows 95, the environment is not sorted. When a new environment variable is added, it removes any existing value from the environment block, and puts the new value on the end. I haven't tried any other editions of the Windows 95 family, but I suspect the situation is the same throughout that family of operating systems. Under Windows 2000 (and presumably the rest of the NT family), the environment is sorted. The current Cygwin code is doing this by means of qsort, effectively using strcmp as the sorting function (in env_sort). The Microsoft documentation states that the sort order is "case-insensitive, Unicode order, without regard to locale". This being the case, the use of strcmp is clearly incorrect. In fact under Windows environment variable names are case insensitive, so this is important - using strcmp means that a lower case environment variable will come out of position and may not be found by a Windows program calling the GetEnvironmentVariable API call, or there may be (incorrectly) two instances of the environment variable if the Windows program tries to change it using the SetEnvironmentVariable API call. strcmp being incorrect, stricmp would be better, however Windows NT versions use NTDLL.RtlCompareUnicodeString as the comparison function for performing this sort (actually, they don't perform the sort, rather they assume the environment is sorted, and seek through it when setting to find the correct location to insert the new variable), so the ideal thing to do would be to convert the byte strings to Unicode and perform the comparison using that API call. It is probably best to convert before seeking the equals sign, since this avoids any nastiness associated with "=" being the second byte in a two byte character. The Windows 95 family of operating systems do not have NTDLL.RtlCompareUnicodeString, so if there is a perceived need to sort there, the following is probably the nearest substitute to what is done under NT: DWORD lcid = MAKELCID( MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); CompareString( lcid, NORM_IGNORECASE | SORT_STRINGSORT, *(TCHAR **) pv1, -1, *(TCHAR **) pv2, -1); The foregoing is also generally useful for calls to CreateProcess in which lpEnvironment will be set. The Microsoft documentation at this point is woefully inadequate, and without the information above it is difficult to construct a correct environment block to pass in this parameter. For further information, see the MSDN library under: "Changing Environment Variables", under "Using Processes and Threads" CreateProcess It would probably also be convenient for anybody who finds this message through a search engine if I point out that lpEnvironment is not an envp pointer, rather it is of the form "VAR1=val1\0VAR2=val2\0....VARn=valn\0\0" ___________________________________________________________________________ WARNING: DO NOT add my email address to any mailing list or database without my PRIOR, EXPLICIT permission. Fight spam in Australia - Join CAUBE.AU - http://www.caube.org.au/ Troy Rollo, Technical Director, CorVu Australasia troy AT corvu DOT com DOT au -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/