6$(TITLE)$(STARS)

 $(EXCERPT)
& $(URL)

ÿÿht (c) 1998 *F 57 * by DIGITAL Equipment Corporation, Maynard, Mass. * 58 * *W 59 * this software is furnished under a license and may be used and copied *W 60 * only in accordance with the terms of such license and with the *W 61 * inclusion of the above copyright notice. this software or any other *W 62 * copies thereof may not be provided or otherwise made available to any *W 63 * other person. no title to and ownership of the software is hereby *& 64 * transferred. * 65 * *W 66 * the information in this software is subject to change without notice *W 67 * and should not be construed as a commitment by DIGITAL Equipment *& 68 * Corporation. * 69 * *W 70 * DIGITAL assumes no responsibility for the use or reliability of its *L 71 * software on equipment which is not supplied by DIGITAL. * 72 * *W 73 ***************************************************************************** 74 *++ 75 * 76 * facility: 77 *, 78 * DEC C run-time library routines 79 * 80 * abstract: 81 *R 82 * This module contains routines which maintain the cache of VMS-specific" 83 * environment variables. 84 *! 85 * modification history: 86 ** 87 * 001 Boris Gubenko 12-May-1997( 88 * Initial creation. CRTL 1734 89 ** 90 * 002 Boris Gubenko 14-May-1997H 91 * Make caching environment variables the default mode, unlessK 92 * DECC$DISABLE_CACHING_ENVIRONMENT_VARIABLES logical is defined.H 93 * Save and restore errno which may be set by malloc. Add some 94 * comment. 95 ** 96 * 003 Boris Gubenko 15-May-1997I 97 * Fix the bug: decc$$environ_cache_put() routine must allocateH 98 * memory for the null terminator and copy the null terminated1 99 * name and value strings to the cache. 100 ** 101 * 004 Boris Gubenko 15-May-1997B 102 * As Duane suggested in CRTL 14.32, THE_LOGICAL will be3 103 * "DECC$DISABLE_GETENV_CACHE" instead ofL 104 * "DECC$DISABLE_CACHING_ENVIRONMENT_VARIABLES" which is too long. 105 ** 106 * 005 Boris Gubenko 19-May-1997 ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 2 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1: 107 * Add decc$$environ_cache_invalidate() routine. 108 ** 109 * 006 Boris Gubenko 11-Feb-1998K 110 * CRTL 1895: reverse the default: by default the cache disabled.J 111 * It is enabled if DECC$ENABLE_GETENV_CACHE logical is defined. 112 */ ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 3 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1 114 /* INCLUDE FILES */ 115  116 #include 643  644 #include " 1037 #include  5241 #include 5383 # 5384 #include  ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 4} 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL.SRC]MULTITHREAD.SRC;1H 1 10385 cma$tis_key_get_context(key, (void *)&prepend_data);; ....1 y%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_key_get_context" is implicitly declared as a function.< 2 10388 cma$tis_key_set_context(key, prepend_data);6 ........1 y%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_key_set_context" is implicitly declared as a function.H 1 10405 cma$tis_key_get_context(key, (void *)&prepend_data);; ....1 y%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_key_get_context" is implicitly declared as a function.< 2 10408 cma$tis_key_set_context(key, prepend_data);6 ........1 y%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_key_set_context" is implicitly declared as a function. ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 5 16-JUN-1998 14:45:00 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1 10548  10549 /* MACROS */ 10550 8 10551 #define THE_LOGICAL "DECC$ENABLE_GETENV_CACHE" 10552 ( 10553 #define NOT_TRANSLATED_YET (-1)" 10554 #define CACHE_DISABLED 0! 10555 #define CACHE_ENABLED 1 10556 7 10557 #define MIN(X,Y) ( ( X > Y ) ? ( Y ) : ( X ) ) 10558 & 10559 #define CHECK_CACHE_STATE { \> 10560 if ( cache_state_flag == NOT_TRANSLATED_YET ) { \ 10561 \A 10562 if ( decc$$translate_lognam( tmp, THE_LOGICAL ) > 0 ) \1 10563 cache_state_flag = CACHE_ENABLED; \ 10564 else \2 10565 cache_state_flag = CACHE_DISABLED; \ 10566 } \ 10567 } 10568  10569 #define SAVE_ERRNO { \6 10570 errno_save = *cma$tis_errno_get_addr(); \> 10571 vaxc$errno_save = *cma$tis_vmserrno_get_addr(); \ 10572 } 10573 " 10574 #define RESTORE_ERRNO { \4 10575 cma$tis_errno_set_addr( &errno_save ); \< 10576 cma$tis_vmserrno_set_addr( &vaxc$errno_save ); \ 10577 } 10578  10579 /* TYPE DEFINITIONS */ 10580  10581 /* Cache Symbol */( 10582 typedef struct __cache_symbol_t 10583 {. 10584 char *name; /* name *// 10585 char *value; /* value */0 10586 int namelen; /* length of name */0 10587 int valuelen; /* length of value */2 10588 } _cache_symbol_t, * _cache_symbol_ptr_t; 10589 $ 10590 /* Tree of Cache Symbols */ 10591 typedef struct __node_t 10592 {= 10593 struct __node_t *link[2]; /* Left & right links */2 10594 unsigned short reserved; /* Reserved */> 10595 unsigned short pad; /* Pad to longword boundary */" 10596 _cache_symbol_t symbol;" 10597 } _node_t, * _node_ptr_t; 10598 10599 " 10600 /* FUNCTION PROTOTYPES */ 10601 P 10602 extern int decc$$translate_lognam ( char *string, const char *lognam ); 10603 P 10604 static int decc$$allocate_cache_node ( _cache_symbol_ptr_t symbol_addr, ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 6 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1M 10605 _node_ptr_t *new_node_addr ); 10606 Q 10607 static int decc$$compare_cache_symbols( _cache_symbol_ptr_t symbol_addr,T 10608 _node_ptr_t comparison_node_addr ); 10609 + 10610 int *cma$tis_errno_get_addr(void);. 10611 int *cma$tis_vmserrno_get_addr(void);/ 10612 void cma$tis_errno_set_addr( void * );2 10613 void cma$tis_vmserrno_set_addr( void * ); 10614  10615 /* STATIC STORAGE */ 10616 10617 /* 10618 **9 10619 ** tmp is the storage for the equivalence string0 10620 ** of DECC$ENABLE_GETENV_CACHE logical. 10621 **> 10622 ** We are not interested in the value of the logical.> 10623 ** What we're interested in is whether the logical is 10624 ** defined or not. 10625 ** 10626 */, 10627 static char tmp[LNM$C_NAMLENGTH+1]; 10628 ; 10629 static int cache_state_flag = NOT_TRANSLATED_YET ;W 10630 /* protect this flag with mutex means justY 10631 to waste time. The worst case is that theS 10632 two threads will translate the sameT 10633 logical and assign the same value to< 10634 this flag */ 10635 G 10636 static _node_ptr_t cache_tree_head; /* protected with mutex */ 10637 10638 3 10639 /* CACHE MUTEX and Lock/Unlock routines */ 10640 : 1 10641 C$$DECLARE_MUTEX(decc$$envir_cache_mutex);- 1 v%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_mutex_create" is implicitly declared as a function. 10642 9 1 10643 static int decc$$lock_cache_mutex(void) {J 1 10644 return(c$$make_locked_mutex(decc$$envir_cache_mutex));= ...........1 n%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_once" is implicitly declared as a function.v%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_mutex_create" is implicitly declared as a function.w%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_mutex_trylock" is implicitly declared as a function.t%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_mutex_lock" is implicitly declared as a function. 1 10645 } 10646 < 1 10647 static void decc$$unlock_cache_mutex(void) { ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 7 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1= 1 10648 c$$unlock_mutex(decc$$envir_cache_mutex);0 ....1 v%CC-I-IMPLICITFUNC, (1) In this statement, the identifier "cma$tis_mutex_unlock" is implicitly declared as a function. 1 10649 } ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 8 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1 10651 /*++ 10652 *# 10653 * decc$$environ_cache_get 10654 * 10655 * routine description: 10656 * Q 10657 * this routine determines if the logical disabling the cache is definedR 10658 * (only once!). If the logical is not defined which means, that the CRTLS 10659 * is in the default caching environment variables mode, the routine callsM 10660 * LIB$LOOKUP_TREE to search the binary tree for the name specified. 10661 * 10662 * inputs: 10663 *, 10664 * the name of environment variable 10665 * 10666 * implicit inputs: 10667 *T 10668 * cache_state_flag flag - a static variable. Does not need to be protected 10669 * - see comment above. 10670 *S 10671 * tree head for the binary tree - a static variable. The access protected 10672 * with mutex. 10673 * 10674 * outputs: 10675 *O 10676 * if caching environment variables is enabled and the name was found,R 10677 * then a pointer to the "value" from the cache is returned, otherwise, a% 10678 * NULL pointer is returned. 10679 * 10680 * implicit outputs: 10681 * 10682 * none 10683 *-- 10684 */< 10685 char * decc$$environ_cache_get( const char * name ) 1 10686 {+ 1 10687 int locked;+ 1 10688 _cache_symbol_t symbol;2 1 10689 _node_ptr_t new_node_addr; 1 10690 int status; 1 10691 & 1 10692 CHECK_CACHE_STATE; 1 10693 = 1 10694 if ( cache_state_flag == CACHE_DISABLED )$ 1 10695 return NULL; 1 10696 0 1 10697 symbol.name = (char *) name; 1 10698 6 1 10699 locked = decc$$lock_cache_mutex(); 1 10700 H 1 10701 status = lib$lookup_tree( &cache_tree_head, &symbol,\ 1 10702 decc$$compare_cache_symbols, &new_node_addr ); 1 10703 < 1 10704 if (locked) decc$$unlock_cache_mutex (); 1 10705 0 1 10706 if ( status == LIB$_NORMAL )4 1 10707 return new_node_addr->symbol.value; ~ c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 9 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1 1 10708 else 1 10709 return NULL; 1 10710 }  c$environ_cache 20-NOV-1998 19:53:21 DEC C V5.7-006 Page 10 12-FEB-1998 17:39:43 $64$DUA564:[ACRTL_4.SRC]ENVIRON_CACHE.C;1 10712 /*++ 10713 *# 10714 * decc$$environ_cache_put 10715 * 10716 * routine description: 10717 * Q 10718 * this routine determines if the logical disabling the cache is definedR 10719 * (only once!). If the logical is not defined which means, that the CRTLM 10720 * is in the default caching environment variables mode, the routineQ 10721 * copies the name and the value of the environment variable to the heapR 10722 * and calls LIB$INSERT_TREE to insert the new node into the binary tree. 10723 * 10724 * inputs: 10725 *T 10726 * cache_state_flag flag - a static variable. Does not need to be protected 10727 * - see comment above. 10728 *Q 10729 * the name and the value of the environment variable and their lenghts. 10730 * 10731 * implicit inputs: 10732 *S 10733 * tree head for the binary tree - a static variable. The access protected 10734 * with mutex. 10735 * 10736 * outputs: 10737 *T 10738 * if caching environment variables is enabled, the memory was successfullyR 10739 * allocated and LIB$INSERT_TREE succeeded, then a pointer to the "value"N 10740 * from the cache is returned, otherwise, a NULL pointer is returned. 10741 * 10742 * implicit outputs: 10743 * 10744 * none 10745 *-- 10746 */I 10747 char * decc$$environ_cache_put( const char * name, int namelen,K 10748 const char * value, int valuelen ) 1 10749 {+ 1 10750 int locked;+ 1 10751 _cache_symbol_t symbol;2 1 10752 _node_ptr_t new_node_addr; 1 10753 int status;& 1 10754 int zero_flag = 0;4 1 10755 int errno_save, vaxc$errno_save; 1 10756 & 1 10757 CHECK_CACHE_STATE; 1 10758 = 1 10759 if ( cache_state_flag == CACHE_DISABLED )$ 1 10760 return NULL; 1 10761  1 10762 /* 1 10763 ** Note.Y 1 10764 ** I don't use strdup() - the most appropriate routine here - for the2 1 10765 ** performance considerations.\ 1 10766 ** The calling routine - getenv() - knows the lengths of the strings and] 1 1076