OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [generic/] [tclEnv.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclEnv.c --
3
 *
4
 *      Tcl support for environment variables, including a setenv
5
 *      procedure.  This file contains the generic portion of the
6
 *      environment module.  It is primarily responsible for keeping
7
 *      the "env" arrays in sync with the system environment variables.
8
 *
9
 * Copyright (c) 1991-1994 The Regents of the University of California.
10
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
11
 *
12
 * See the file "license.terms" for information on usage and redistribution
13
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14
 *
15
 * RCS: @(#) $Id: tclEnv.c,v 1.1.1.1 2002-01-16 10:25:26 markom Exp $
16
 */
17
 
18
#include "tclInt.h"
19
#include "tclPort.h"
20
 
21
/* CYGNUS LOCAL */
22
#if defined(__CYGWIN__) && defined(__WIN32__)
23
 
24
/* Under cygwin, the environment is imported from the cygwin DLL.  */
25
 
26
extern char ***_imp____cygwin_environ;
27
 
28
#define environ (*_imp____cygwin_environ)
29
 
30
/* We need to use a special putenv function to handle PATH.  */
31
#ifndef USE_PUTENV
32
#define USE_PUTENV
33
#endif
34
#define putenv TclCygwin32Putenv
35
 
36
#endif
37
/* END CYGNUS LOCAL */
38
 
39
/*
40
 * The structure below is used to keep track of all of the interpereters
41
 * for which we're managing the "env" array.  It's needed so that they
42
 * can all be updated whenever an environment variable is changed
43
 * anywhere.
44
 */
45
 
46
typedef struct EnvInterp {
47
    Tcl_Interp *interp;         /* Interpreter for which we're managing
48
                                 * the env array. */
49
    struct EnvInterp *nextPtr;  /* Next in list of all such interpreters,
50
                                 * or zero. */
51
} EnvInterp;
52
 
53
static EnvInterp *firstInterpPtr = NULL;
54
                                /* First in list of all managed interpreters,
55
                                 * or NULL if none. */
56
 
57
static int cacheSize = 0;        /* Number of env strings in environCache. */
58
static char **environCache = NULL;
59
                                /* Array containing all of the environment
60
                                 * strings that Tcl has allocated. */
61
 
62
#ifndef USE_PUTENV
63
static int environSize = 0;      /* Non-zero means that the environ array was
64
                                 * malloced and has this many total entries
65
                                 * allocated to it (not all may be in use at
66
                                 * once).  Zero means that the environment
67
                                 * array is in its original static state. */
68
#endif
69
 
70
/*
71
 * Declarations for local procedures defined in this file:
72
 */
73
 
74
static char *           EnvTraceProc _ANSI_ARGS_((ClientData clientData,
75
                            Tcl_Interp *interp, char *name1, char *name2,
76
                            int flags));
77
static int              FindVariable _ANSI_ARGS_((CONST char *name,
78
                            int *lengthPtr));
79
static void             ReplaceString _ANSI_ARGS_((CONST char *oldStr,
80
                            char *newStr));
81
void                    TclSetEnv _ANSI_ARGS_((CONST char *name,
82
                            CONST char *value));
83
void                    TclUnsetEnv _ANSI_ARGS_((CONST char *name));
84
 
85
/* CYGNUS LOCAL */
86
#if defined (__CYGWIN__) && defined(__WIN32__)
87
static void             TclCygwin32Putenv _ANSI_ARGS_((CONST char *string));
88
#endif
89
 
90
/*
91
 *----------------------------------------------------------------------
92
 *
93
 * TclSetupEnv --
94
 *
95
 *      This procedure is invoked for an interpreter to make environment
96
 *      variables accessible from that interpreter via the "env"
97
 *      associative array.
98
 *
99
 * Results:
100
 *      None.
101
 *
102
 * Side effects:
103
 *      The interpreter is added to a list of interpreters managed
104
 *      by us, so that its view of envariables can be kept consistent
105
 *      with the view in other interpreters.  If this is the first
106
 *      call to Tcl_SetupEnv, then additional initialization happens,
107
 *      such as copying the environment to dynamically-allocated space
108
 *      for ease of management.
109
 *
110
 *----------------------------------------------------------------------
111
 */
112
 
113
void
114
TclSetupEnv(interp)
115
    Tcl_Interp *interp;         /* Interpreter whose "env" array is to be
116
                                 * managed. */
117
{
118
    EnvInterp *eiPtr;
119
    char *p, *p2;
120
    Tcl_DString ds;
121
    int i, sz;
122
 
123
#ifdef MAC_TCL
124
    if (environ == NULL) {
125
        environSize = TclMacCreateEnv();
126
    }
127
#endif
128
 
129
    /*
130
     * Next, initialize the DString we are going to use for copying
131
     * the names of the environment variables.
132
     */
133
 
134
    Tcl_DStringInit(&ds);
135
 
136
    /*
137
     * Next, add the interpreter to the list of those that we manage.
138
     */
139
 
140
    eiPtr = (EnvInterp *) ckalloc(sizeof(EnvInterp));
141
    eiPtr->interp = interp;
142
    eiPtr->nextPtr = firstInterpPtr;
143
    firstInterpPtr = eiPtr;
144
 
145
    /*
146
     * Store the environment variable values into the interpreter's
147
     * "env" array, and arrange for us to be notified on future
148
     * writes and unsets to that array.
149
     */
150
 
151
    (void) Tcl_UnsetVar2(interp, "env", (char *) NULL, TCL_GLOBAL_ONLY);
152
    for (i = 0; ; i++) {
153
        p = environ[i];
154
        if (p == NULL) {
155
            break;
156
        }
157
        for (p2 = p; *p2 != '='; p2++) {
158
            if (*p2 == 0) {
159
                /*
160
                 * This condition doesn't seem like it should ever happen,
161
                 * but it does seem to happen occasionally under some
162
                 * versions of Solaris; ignore the entry.
163
                 */
164
 
165
                goto nextEntry;
166
            }
167
        }
168
        sz = p2 - p;
169
        Tcl_DStringSetLength(&ds, 0);
170
        Tcl_DStringAppend(&ds, p, sz);
171
        (void) Tcl_SetVar2(interp, "env", Tcl_DStringValue(&ds),
172
                p2+1, TCL_GLOBAL_ONLY);
173
        nextEntry:
174
        continue;
175
    }
176
    Tcl_TraceVar2(interp, "env", (char *) NULL,
177
            TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
178
            EnvTraceProc, (ClientData) NULL);
179
 
180
    /*
181
     * Finally clean up the DString.
182
     */
183
 
184
    Tcl_DStringFree(&ds);
185
}
186
 
187
/*
188
 *----------------------------------------------------------------------
189
 *
190
 * TclSetEnv --
191
 *
192
 *      Set an environment variable, replacing an existing value
193
 *      or creating a new variable if there doesn't exist a variable
194
 *      by the given name.  This procedure is intended to be a
195
 *      stand-in for the  UNIX "setenv" procedure so that applications
196
 *      using that procedure will interface properly to Tcl.  To make
197
 *      it a stand-in, the Makefile must define "TclSetEnv" to "setenv".
198
 *
199
 * Results:
200
 *      None.
201
 *
202
 * Side effects:
203
 *      The environ array gets updated, as do all of the interpreters
204
 *      that we manage.
205
 *
206
 *----------------------------------------------------------------------
207
 */
208
 
209
void
210
TclSetEnv(name, value)
211
    CONST char *name;           /* Name of variable whose value is to be
212
                                 * set. */
213
    CONST char *value;          /* New value for variable. */
214
{
215
    int index, length, nameLength;
216
    char *p, *oldValue;
217
    EnvInterp *eiPtr;
218
 
219
#ifdef MAC_TCL
220
    if (environ == NULL) {
221
        environSize = TclMacCreateEnv();
222
    }
223
#endif
224
 
225
    /*
226
     * Figure out where the entry is going to go.  If the name doesn't
227
     * already exist, enlarge the array if necessary to make room.  If
228
     * the name exists, free its old entry.
229
     */
230
 
231
    index = FindVariable(name, &length);
232
    if (index == -1) {
233
#ifndef USE_PUTENV
234
        if ((length+2) > environSize) {
235
            char **newEnviron;
236
 
237
            newEnviron = (char **) ckalloc((unsigned)
238
                    ((length+5) * sizeof(char *)));
239
 
240
            /* CYGNUS LOCAL: Added to avoid an error from Purify,
241
               although I don't personally see where the error would
242
               occur--ian.  */
243
            memset((VOID *) newEnviron, 0, (length+5) * sizeof(char *));
244
 
245
            memcpy((VOID *) newEnviron, (VOID *) environ,
246
                    length*sizeof(char *));
247
            if (environSize != 0) {
248
                ckfree((char *) environ);
249
            }
250
            environ = newEnviron;
251
            environSize = length+5;
252
        }
253
        index = length;
254
        environ[index+1] = NULL;
255
#endif
256
        oldValue = NULL;
257
        nameLength = strlen(name);
258
    } else {
259
        /*
260
         * Compare the new value to the existing value.  If they're
261
         * the same then quit immediately (e.g. don't rewrite the
262
         * value or propagate it to other interpreters).  Otherwise,
263
         * when there are N interpreters there will be N! propagations
264
         * of the same value among the interpreters.
265
         */
266
 
267
        if (strcmp(value, environ[index]+length+1) == 0) {
268
            return;
269
        }
270
        oldValue = environ[index];
271
        nameLength = length;
272
    }
273
 
274
 
275
    /*
276
     * Create a new entry.
277
     */
278
 
279
    p = (char *) ckalloc((unsigned) (nameLength + strlen(value) + 2));
280
    strcpy(p, name);
281
    p[nameLength] = '=';
282
    strcpy(p+nameLength+1, value);
283
 
284
    /*
285
     * Update the system environment.
286
     */
287
 
288
#ifdef USE_PUTENV
289
    putenv(p);
290
#else
291
    environ[index] = p;
292
#endif
293
 
294
    /*
295
     * Replace the old value with the new value in the cache.
296
     */
297
 
298
    ReplaceString(oldValue, p);
299
 
300
    /*
301
     * Update all of the interpreters.
302
     */
303
 
304
    /* CYGNUS LOCAL: The original code was bogus.  If we are being
305
       called because of a trace on the env array, then the call to
306
       Tcl_SetVar2 would free value.  We avoid that by checking
307
       whether the value is the same before calling Tcl_SetVar2.
308
 
309
       NOTE: This is not necessary in tcl8.1a2 which handles this in a
310
       completely different, and better, way.  */
311
 
312
    for (eiPtr= firstInterpPtr; eiPtr != NULL; eiPtr = eiPtr->nextPtr) {
313
        CONST char *v;
314
 
315
        v = Tcl_GetVar2(eiPtr->interp, "env", (char *) name, TCL_GLOBAL_ONLY);
316
        if (v == NULL || (v != value && strcmp (v, value) != 0)) {
317
            (void) Tcl_SetVar2(eiPtr->interp, "env", (char *) name,
318
                    (char *) value, TCL_GLOBAL_ONLY);
319
        }
320
    }
321
 
322
}
323
 
324
/*
325
 *----------------------------------------------------------------------
326
 *
327
 * Tcl_PutEnv --
328
 *
329
 *      Set an environment variable.  Similar to setenv except that
330
 *      the information is passed in a single string of the form
331
 *      NAME=value, rather than as separate name strings.  This procedure
332
 *      is intended to be a stand-in for the  UNIX "putenv" procedure
333
 *      so that applications using that procedure will interface
334
 *      properly to Tcl.  To make it a stand-in, the Makefile will
335
 *      define "Tcl_PutEnv" to "putenv".
336
 *
337
 * Results:
338
 *      None.
339
 *
340
 * Side effects:
341
 *      The environ array gets updated, as do all of the interpreters
342
 *      that we manage.
343
 *
344
 *----------------------------------------------------------------------
345
 */
346
 
347
int
348
Tcl_PutEnv(string)
349
    CONST char *string;         /* Info about environment variable in the
350
                                 * form NAME=value. */
351
{
352
    int nameLength;
353
    char *name, *value;
354
 
355
    if (string == NULL) {
356
        return 0;
357
    }
358
 
359
    /*
360
     * Separate the string into name and value parts, then call
361
     * TclSetEnv to do all of the real work.
362
     */
363
 
364
    value = strchr(string, '=');
365
    if (value == NULL) {
366
        return 0;
367
    }
368
    nameLength = value - string;
369
    if (nameLength == 0) {
370
        return 0;
371
    }
372
    name = (char *) ckalloc((unsigned) nameLength+1);
373
    memcpy((VOID *) name, (VOID *) string, (size_t) nameLength);
374
    name[nameLength] = 0;
375
    TclSetEnv(name, value+1);
376
    ckfree(name);
377
    return 0;
378
}
379
 
380
/*
381
 *----------------------------------------------------------------------
382
 *
383
 * TclUnsetEnv --
384
 *
385
 *      Remove an environment variable, updating the "env" arrays
386
 *      in all interpreters managed by us.  This function is intended
387
 *      to replace the UNIX "unsetenv" function (but to do this the
388
 *      Makefile must be modified to redefine "TclUnsetEnv" to
389
 *      "unsetenv".
390
 *
391
 * Results:
392
 *      None.
393
 *
394
 * Side effects:
395
 *      Interpreters are updated, as is environ.
396
 *
397
 *----------------------------------------------------------------------
398
 */
399
 
400
void
401
TclUnsetEnv(name)
402
    CONST char *name;                   /* Name of variable to remove. */
403
{
404
    EnvInterp *eiPtr;
405
    char *oldValue;
406
    int length, index;
407
#ifdef USE_PUTENV
408
    char *string;
409
#else
410
    char **envPtr;
411
#endif
412
 
413
#ifdef MAC_TCL
414
    if (environ == NULL) {
415
        environSize = TclMacCreateEnv();
416
    }
417
#endif
418
 
419
    index = FindVariable(name, &length);
420
 
421
    /*
422
     * First make sure that the environment variable exists to avoid
423
     * doing needless work and to avoid recursion on the unset.
424
     */
425
 
426
    if (index == -1) {
427
        return;
428
    }
429
    /*
430
     * Remember the old value so we can free it if Tcl created the string.
431
     */
432
 
433
    oldValue = environ[index];
434
 
435
    /*
436
     * Update the system environment.  This must be done before we
437
     * update the interpreters or we will recurse.
438
     */
439
 
440
#ifdef USE_PUTENV
441
    string = ckalloc(length+2);
442
    memcpy((VOID *) string, (VOID *) name, (size_t) length);
443
    string[length] = '=';
444
    string[length+1] = '\0';
445
    putenv(string);
446
    ckfree(string);
447
#else
448
    for (envPtr = environ+index+1; ; envPtr++) {
449
        envPtr[-1] = *envPtr;
450
        if (*envPtr == NULL) {
451
            break;
452
        }
453
    }
454
#endif
455
 
456
    /*
457
     * Replace the old value in the cache.
458
     */
459
 
460
    ReplaceString(oldValue, NULL);
461
 
462
    /*
463
     * Update all of the interpreters.
464
     */
465
 
466
    for (eiPtr = firstInterpPtr; eiPtr != NULL; eiPtr = eiPtr->nextPtr) {
467
        (void) Tcl_UnsetVar2(eiPtr->interp, "env", (char *) name,
468
                TCL_GLOBAL_ONLY);
469
    }
470
}
471
 
472
/*
473
 *----------------------------------------------------------------------
474
 *
475
 * TclGetEnv --
476
 *
477
 *      Retrieve the value of an environment variable.
478
 *
479
 * Results:
480
 *      Returns a pointer to a static string in the environment,
481
 *      or NULL if the value was not found.
482
 *
483
 * Side effects:
484
 *      None.
485
 *
486
 *----------------------------------------------------------------------
487
 */
488
 
489
char *
490
TclGetEnv(name)
491
    CONST char *name;           /* Name of variable to find. */
492
{
493
    int length, index;
494
 
495
#ifdef MAC_TCL
496
    if (environ == NULL) {
497
        environSize = TclMacCreateEnv();
498
    }
499
#endif
500
 
501
    index = FindVariable(name, &length);
502
    if ((index != -1) &&  (*(environ[index]+length) == '=')) {
503
        return environ[index]+length+1;
504
    } else {
505
        return NULL;
506
    }
507
}
508
 
509
/*
510
 *----------------------------------------------------------------------
511
 *
512
 * EnvTraceProc --
513
 *
514
 *      This procedure is invoked whenever an environment variable
515
 *      is modified or deleted.  It propagates the change to the
516
 *      "environ" array and to any other interpreters for whom
517
 *      we're managing an "env" array.
518
 *
519
 * Results:
520
 *      Always returns NULL to indicate success.
521
 *
522
 * Side effects:
523
 *      Environment variable changes get propagated.  If the whole
524
 *      "env" array is deleted, then we stop managing things for
525
 *      this interpreter (usually this happens because the whole
526
 *      interpreter is being deleted).
527
 *
528
 *----------------------------------------------------------------------
529
 */
530
 
531
        /* ARGSUSED */
532
static char *
533
EnvTraceProc(clientData, interp, name1, name2, flags)
534
    ClientData clientData;      /* Not used. */
535
    Tcl_Interp *interp;         /* Interpreter whose "env" variable is
536
                                 * being modified. */
537
    char *name1;                /* Better be "env". */
538
    char *name2;                /* Name of variable being modified, or
539
                                 * NULL if whole array is being deleted. */
540
    int flags;                  /* Indicates what's happening. */
541
{
542
    /*
543
     * First see if the whole "env" variable is being deleted.  If
544
     * so, just forget about this interpreter.
545
     */
546
 
547
    if (name2 == NULL) {
548
        register EnvInterp *eiPtr, *prevPtr;
549
 
550
        if ((flags & (TCL_TRACE_UNSETS|TCL_TRACE_DESTROYED))
551
                != (TCL_TRACE_UNSETS|TCL_TRACE_DESTROYED)) {
552
            panic("EnvTraceProc called with confusing arguments");
553
        }
554
        eiPtr = firstInterpPtr;
555
        if (eiPtr->interp == interp) {
556
            firstInterpPtr = eiPtr->nextPtr;
557
        } else {
558
            for (prevPtr = eiPtr, eiPtr = eiPtr->nextPtr; ;
559
                    prevPtr = eiPtr, eiPtr = eiPtr->nextPtr) {
560
                if (eiPtr == NULL) {
561
                    panic("EnvTraceProc couldn't find interpreter");
562
                }
563
                if (eiPtr->interp == interp) {
564
                    prevPtr->nextPtr = eiPtr->nextPtr;
565
                    break;
566
                }
567
            }
568
        }
569
        ckfree((char *) eiPtr);
570
        return NULL;
571
    }
572
 
573
    /*
574
     * If a value is being set, call TclSetEnv to do all of the work.
575
     */
576
 
577
    if (flags & TCL_TRACE_WRITES) {
578
        TclSetEnv(name2, Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY));
579
    }
580
 
581
    if (flags & TCL_TRACE_UNSETS) {
582
        TclUnsetEnv(name2);
583
    }
584
    return NULL;
585
}
586
 
587
/*
588
 *----------------------------------------------------------------------
589
 *
590
 * ReplaceString --
591
 *
592
 *      Replace one string with another in the environment variable
593
 *      cache.  The cache keeps track of all of the environment
594
 *      variables that Tcl has modified so they can be freed later.
595
 *
596
 * Results:
597
 *      None.
598
 *
599
 * Side effects:
600
 *      May free the old string.
601
 *
602
 *----------------------------------------------------------------------
603
 */
604
 
605
static void
606
ReplaceString(oldStr, newStr)
607
    CONST char *oldStr;         /* Old environment string. */
608
    char *newStr;               /* New environment string. */
609
{
610
    int i;
611
    char **newCache;
612
 
613
    /*
614
     * Check to see if the old value was allocated by Tcl.  If so,
615
     * it needs to be deallocated to avoid memory leaks.  Note that this
616
     * algorithm is O(n), not O(1).  This will result in n-squared behavior
617
     * if lots of environment changes are being made.
618
     */
619
 
620
    for (i = 0; i < cacheSize; i++) {
621
        if ((environCache[i] == oldStr) || (environCache[i] == NULL)) {
622
            break;
623
        }
624
    }
625
    if (i < cacheSize) {
626
        /*
627
         * Replace or delete the old value.
628
         */
629
 
630
        if (environCache[i]) {
631
            ckfree(environCache[i]);
632
        }
633
 
634
        if (newStr) {
635
            environCache[i] = newStr;
636
        } else {
637
            for (; i < cacheSize-1; i++) {
638
                environCache[i] = environCache[i+1];
639
            }
640
            environCache[cacheSize-1] = NULL;
641
        }
642
    } else {
643
        int allocatedSize = (cacheSize + 5) * sizeof(char *);
644
 
645
        /*
646
         * We need to grow the cache in order to hold the new string.
647
         */
648
 
649
        newCache = (char **) ckalloc((size_t) allocatedSize);
650
        (VOID *) memset(newCache, (int) 0, (size_t) allocatedSize);
651
 
652
        if (environCache) {
653
            memcpy((VOID *) newCache, (VOID *) environCache,
654
                    (size_t) (cacheSize * sizeof(char*)));
655
            ckfree((char *) environCache);
656
        }
657
        environCache = newCache;
658
        environCache[cacheSize] = (char *) newStr;
659
        environCache[cacheSize+1] = NULL;
660
        cacheSize += 5;
661
    }
662
}
663
 
664
/*
665
 *----------------------------------------------------------------------
666
 *
667
 * FindVariable --
668
 *
669
 *      Locate the entry in environ for a given name.
670
 *
671
 * Results:
672
 *      The return value is the index in environ of an entry with the
673
 *      name "name", or -1 if there is no such entry.   The integer at
674
 *      *lengthPtr is filled in with the length of name (if a matching
675
 *      entry is found) or the length of the environ array (if no matching
676
 *      entry is found).
677
 *
678
 * Side effects:
679
 *      None.
680
 *
681
 *----------------------------------------------------------------------
682
 */
683
 
684
static int
685
FindVariable(name, lengthPtr)
686
    CONST char *name;           /* Name of desired environment variable. */
687
    int *lengthPtr;             /* Used to return length of name (for
688
                                 * successful searches) or number of non-NULL
689
                                 * entries in environ (for unsuccessful
690
                                 * searches). */
691
{
692
    int i;
693
    register CONST char *p1, *p2;
694
 
695
    for (i = 0, p1 = environ[i]; p1 != NULL; i++, p1 = environ[i]) {
696
        for (p2 = name; *p2 == *p1; p1++, p2++) {
697
            /* NULL loop body. */
698
        }
699
        if ((*p1 == '=') && (*p2 == '\0')) {
700
            *lengthPtr = p2-name;
701
            return i;
702
        }
703
    }
704
    *lengthPtr = i;
705
    return -1;
706
}
707
 
708
/*
709
 *----------------------------------------------------------------------
710
 *
711
 * TclFinalizeEnvironment --
712
 *
713
 *      This function releases any storage allocated by this module
714
 *      that isn't still in use by the global environment.  Any
715
 *      strings that are still in the environment will be leaked.
716
 *
717
 * Results:
718
 *      None.
719
 *
720
 * Side effects:
721
 *      May deallocate storage.
722
 *
723
 *----------------------------------------------------------------------
724
 */
725
 
726
void
727
TclFinalizeEnvironment()
728
{
729
    /*
730
     * For now we just deallocate the cache array and none of the environment
731
     * strings.  This may leak more memory that strictly necessary, since some
732
     * of the strings may no longer be in the environment.  However,
733
     * determining which ones are ok to delete is n-squared, and is pretty
734
     * unlikely, so we don't bother.
735
     */
736
 
737
    if (environCache) {
738
        ckfree((char *) environCache);
739
        environCache = NULL;
740
        cacheSize    = 0;
741
#ifndef USE_PUTENV
742
        environSize  = 0;
743
#endif
744
    }
745
}
746
 
747
/* CYGNUS LOCAL */
748
#if defined(__CYGWIN__) && defined(__WIN32__)
749
 
750
#include "windows.h"
751
 
752
/* When using cygwin, when an environment variable changes, we need
753
   to synch with both the cygwin environment (in case the
754
   application C code calls fork) and the Windows environment (in case
755
   the application TCL code calls exec, which calls the Windows
756
   CreateProcess function).  */
757
 
758
static void
759
TclCygwin32Putenv(str)
760
     const char *str;
761
{
762
  char *name, *value;
763
 
764
  /* Get the name and value, so that we can change the environment
765
     variable for Windows.  */
766
  name = (char *) alloca (strlen (str) + 1);
767
  strcpy (name, str);
768
  for (value = name; *value != '=' && *value != '\0'; ++value)
769
    ;
770
  if (*value == '\0')
771
    {
772
      /* Can't happen.  */
773
      return;
774
    }
775
  *value = '\0';
776
  ++value;
777
  if (*value == '\0')
778
    value = NULL;
779
 
780
  /* Set the cygwin environment variable.  */
781
#undef putenv
782
  if (value == NULL)
783
    unsetenv (name);
784
  else
785
    putenv(str);
786
 
787
  /* Before changing the environment variable in Windows, if this is
788
     PATH, we need to convert the value back to a Windows style path.
789
 
790
     FIXME: The calling program may now it is running under windows,
791
     and may have set the path to a Windows path, or, worse, appended
792
     or prepended a Windows path to PATH.  */
793
  if (strcmp (name, "PATH") != 0)
794
    {
795
      /* If this is Path, eliminate any PATH variable, to prevent any
796
         confusion.  */
797
      if (strcmp (name, "Path") == 0)
798
        {
799
          SetEnvironmentVariable ("PATH", (char *) NULL);
800
          unsetenv ("PATH");
801
        }
802
 
803
      SetEnvironmentVariable (name, value);
804
    }
805
  else
806
    {
807
      char *buf;
808
 
809
      /* Eliminate any Path variable, to prevent any confusion.  */
810
      SetEnvironmentVariable ("Path", (char *) NULL);
811
      unsetenv ("Path");
812
 
813
      if (value == NULL)
814
        buf = NULL;
815
      else
816
        {
817
          int size;
818
 
819
          size = cygwin_posix_to_win32_path_list_buf_size (value);
820
          buf = (char *) alloca (size + 1);
821
          cygwin_posix_to_win32_path_list (value, buf);
822
        }
823
 
824
      SetEnvironmentVariable (name, buf);
825
    }
826
}
827
 
828
#endif /* __CYGWIN__ */
829
/* END CYGNUS LOCAL */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.