envLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:15k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* envLib.c - environment variable library */
  2. /* Copyright 1984-1993 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01k,22jan93,jdi  documentation cleanup for 5.1.
  8. 01j,19jul92,smb  added some ANSI documentation.
  9.  made getenv parameter list ANSI.
  10. 01i,26may92,rrr  the tree shuffle
  11. 01h,19nov91,rrr  shut up some ansi warnings.
  12. 01g,04oct91,rrr  passed through the ansification filter
  13.                   -changed functions to ansi style
  14.   -changed includes to have absolute path from h/
  15.   -changed VOID to void
  16.   -changed copyright notice
  17. 01f,10aug90,kdl  added forward declaration for envDestroy.
  18. 01e,01aug90,jcf  cleanup.
  19. 01d,30jul90,rdc  ick, more lint.
  20. 01c,18jul90,rdc  lint.
  21. 01b,15jul90,dnw  fixed to coerce malloc() to (char*) where necessary
  22. 01a,12jul90,rdc  written.
  23. */
  24. /*
  25. This library provides a UNIX-compatible environment variable facility.  
  26. Environment variables are created or modified with a call to putenv():
  27. .CS
  28.     putenv ("variableName=value");
  29. .CE
  30. The value of a variable may be retrieved with a call to getenv(), which returns
  31. a pointer to the value string.
  32. Tasks may share a common set of environment variables, or they may optionally
  33. create their own private environments, either automatically when the task
  34. create hook is installed, or by an explicit call to envPrivateCreate().
  35. The task must be spawned with the VX_PRIVATE_ENV option set to receive a
  36. private set of environment variables.  Private environments created by the
  37. task creation hook inherit the values of the environment of the task that called
  38. taskSpawn() (since task create hooks run in the context of the calling task).
  39. INCLUDE FILES: envLib.h
  40. SEE ALSO: UNIX BSD 4.3 manual entry for f3environ(5V)f1,
  41. * .I "American National Standard for Information Systems -"
  42. * .I "Programming Language - C, ANSI X3.159-1989: General Utilities (stdlib.h)"
  43. */
  44. /* LINTLIBRARY */
  45. #include "vxWorks.h"
  46. #include "taskLib.h"
  47. #include "taskHookLib.h"
  48. #include "string.h"
  49. #include "stdio.h"
  50. #include "stdlib.h"
  51. #include "logLib.h"
  52. #define ENV_NENTRIES_TO_ALLOC 50
  53. /* globals */
  54. char **ppGlobalEnviron;  /* global envivonment variable table */
  55. /* locals */
  56. LOCAL int envTblSize; /* global table size */
  57. LOCAL int nEntries; /* number of entries in global table */
  58. /* forward static functions */
  59. static void envCreateHook (WIND_TCB *pNewTcb);
  60. static STATUS envDuplicate (char ** srcEnv, int srcEnvTblSize, int
  61. srcNEnvVarEntries, WIND_TCB *pTcb);
  62. static void envDestroy (char ** ppEnv, int nEnvVarEntries);
  63. static void envDeleteHook (WIND_TCB *pTcb);
  64. static char ** envFind (char *name, int nameLen);
  65. /*********************************************************************
  66. *
  67. * envLibInit - initialize environment variable facility
  68. *
  69. * If <installHooks> is TRUE, task create and delete hooks are installed that
  70. * will optionally create and destroy private environments for the task being
  71. * created or destroyed, depending on the state of VX_PRIVATE_ENV in the task
  72. * options word.  If <installHooks> is FALSE and a task requires a private
  73. * environment, it is the application's responsibility to create and destroy
  74. * the private environment, using envPrivateCreate() and envPrivateDestroy().
  75. *
  76. * RETURNS: OK, or ERROR if an environment cannot be allocated or the hooks
  77. * cannot be installed.
  78. */
  79. STATUS envLibInit
  80.     (
  81.     BOOL installHooks
  82.     )
  83.     {
  84.     /* allocate the global environ array */
  85.     ppGlobalEnviron = (char **) calloc (ENV_NENTRIES_TO_ALLOC, sizeof (char *));
  86.     if (ppGlobalEnviron == NULL)
  87. return (ERROR);
  88.     envTblSize = ENV_NENTRIES_TO_ALLOC;
  89.     nEntries   = 0;
  90.     /* optionally install task create/delete hooks */
  91.     if (installHooks)
  92. {
  93. if(taskCreateHookAdd ((FUNCPTR)envCreateHook) != OK)
  94.     return (ERROR);
  95. if (taskDeleteHookAdd ((FUNCPTR)envDeleteHook) != OK)
  96.     return (ERROR);
  97. }
  98.     return (OK);
  99.     }
  100. /*********************************************************************
  101. *
  102. * envCreateHook - create a private environment for the new task
  103. *
  104. * installed by envLibInit to optionally create a private environment
  105. * for tasks that have VX_PRIVATE_ENV set in their task options word.
  106. */
  107. LOCAL void envCreateHook
  108.     (
  109.     WIND_TCB *pNewTcb
  110.     )
  111.     {
  112.     char ** ppSrcEnviron;
  113.     int srcEnvTblSize;
  114.     int srcNEnvVarEntries;
  115.     WIND_TCB * pMyTcb;
  116.     /* if VX_PRIVATE_ENV is set, copy spawning task's environment to a
  117.        private environment and stash a pointer to it in the new task's tcb */
  118.     if (pNewTcb->options & VX_PRIVATE_ENV)
  119. {
  120. pMyTcb = taskTcb (0);
  121. if ((ppSrcEnviron = pMyTcb->ppEnviron) == NULL)
  122.     {
  123.     ppSrcEnviron = ppGlobalEnviron;
  124.     srcEnvTblSize = envTblSize;
  125.     srcNEnvVarEntries = nEntries;
  126.     }
  127. else
  128.     {
  129.     srcEnvTblSize = pMyTcb->envTblSize;
  130.     srcNEnvVarEntries = pMyTcb->nEnvVarEntries;
  131.     }
  132. /* allocate the private environ array - make it the same size
  133.  * as the "current" environ array.
  134.  */
  135. if (envDuplicate (ppSrcEnviron, srcEnvTblSize, srcNEnvVarEntries,
  136.   pNewTcb) == ERROR)
  137.     {
  138.     logMsg ("evnCreateHook: couldn't create private environment!n",
  139.     0,0,0,0,0,0);
  140.     /* turn VX_PRIVATE_ENV off in options word so we don't deallocate
  141.      * an environment that doesn't exist when the task exits.
  142.      */
  143.     taskOptionsSet ((int) pNewTcb, VX_PRIVATE_ENV, 0);
  144.     return;
  145.     }
  146. }
  147.     else
  148. {
  149. /* set the environment pointer in the tcb to NULL so the global
  150.  * environment will be used.
  151.  */
  152. pNewTcb->ppEnviron = NULL;
  153. }
  154.     }
  155. /*********************************************************************
  156. *
  157. * envDuplicate - duplicate the given environment
  158. *
  159. * create a new environment and copy the information in the given
  160. * source environment.
  161. *
  162. * RETURNS: OK, or ERROR if not enough memory
  163. */
  164. LOCAL STATUS envDuplicate
  165.     (
  166.     FAST char **srcEnv,         /* environment table to duplicate */
  167.     int srcEnvTblSize,          /* table size */
  168.     int srcNEnvVarEntries,      /* N entries in use */
  169.     WIND_TCB *pTcb              /* tcb of task to receive duplicate env */
  170.     )
  171.     {
  172.     FAST char **privateEnv;
  173.     FAST int i;
  174.     privateEnv = (char **) calloc ((unsigned) srcEnvTblSize, sizeof (char *));
  175.     if (privateEnv == (char **) NULL)
  176. return (ERROR);
  177.     pTcb->envTblSize  = srcEnvTblSize;
  178.     pTcb->nEnvVarEntries = 0;
  179.     pTcb->ppEnviron  = privateEnv;
  180.     /* copy the source environment to the new environment */
  181.     for (i = 0; i < srcNEnvVarEntries; i++)
  182. {
  183. FAST char *destString;
  184. FAST char *srcString;
  185. srcString = srcEnv[i];
  186. destString = (char *) malloc ((unsigned) strlen (srcString) + 1);
  187. if (destString == NULL)
  188.     {
  189.     envDestroy (privateEnv, pTcb->nEnvVarEntries);
  190.     return (ERROR);
  191.     }
  192. strcpy (destString, srcString);
  193. privateEnv[i] = destString;
  194. pTcb->nEnvVarEntries++;
  195. }
  196.     return (OK);
  197.     }
  198. /*********************************************************************
  199. *
  200. * envDestroy - free the given environment
  201. *
  202. * free all the strings and data structures associated with an
  203. * environment.
  204. */
  205. LOCAL void envDestroy
  206.     (
  207.     char **ppEnv,
  208.     int nEnvVarEntries
  209.     )
  210.     {
  211.     FAST int i;
  212.     for (i = 0; i < nEnvVarEntries; i++)
  213. {
  214. free (ppEnv[i]);
  215. }
  216.     /* deallocate the env array */
  217.     free ((char *) ppEnv);
  218.     }
  219. /*********************************************************************
  220. *
  221. * envDeleteHook - delete a task's private environment
  222. *
  223. * installed by envLibInit to optionally delete private environments
  224. * when a task exits.
  225. */
  226. LOCAL void envDeleteHook
  227.     (
  228.     WIND_TCB *pTcb         /* pointer to deleted task's TCB */
  229.     )
  230.     {
  231.     /* if VX_PRIVATE_ENV is set, destroy the environment */
  232.     if (pTcb->options & VX_PRIVATE_ENV)
  233. if (pTcb->ppEnviron != NULL)
  234.     envDestroy (pTcb->ppEnviron, pTcb->nEnvVarEntries);
  235.     }
  236. /*********************************************************************
  237. *
  238. * envPrivateCreate - create a private environment
  239. *
  240. * This routine creates a private set of environment variables for a specified
  241. * task, if the environment variable task create hook is not installed.
  242. *
  243. * RETURNS: OK, or ERROR if memory is insufficient.
  244. *
  245. * SEE ALSO: envLibInit(), envPrivateDestroy()
  246. */
  247. STATUS envPrivateCreate
  248.     (
  249.     int taskId,         /* task to have private environment */
  250.     int envSource       /* -1 = make an empty private environment */
  251.                         /* 0 = copy global env to new private env */
  252.                         /* taskId = copy the specified task's env */
  253.     )
  254.     {
  255.     char **ppPrivateEnv;
  256.     FAST WIND_TCB *pTcb;
  257.     /* create specified environment and set VX_PRIVATE_ENV in tcb */
  258.     switch (envSource)
  259. {
  260. case (-1):
  261.     ppPrivateEnv = (char **)
  262.    calloc (ENV_NENTRIES_TO_ALLOC, sizeof (char *));
  263.     if (ppPrivateEnv == NULL)
  264. return (ERROR);
  265.     pTcb = taskTcb (taskId);
  266.     if (pTcb == NULL)
  267. return (ERROR);
  268.     pTcb->envTblSize  = ENV_NENTRIES_TO_ALLOC;
  269.     pTcb->nEnvVarEntries = 0;
  270.     pTcb->ppEnviron  = ppPrivateEnv;
  271.     break;
  272. case (0):
  273.     /* duplicate the global environment */
  274.     if (envDuplicate (ppGlobalEnviron, envTblSize,
  275.       nEntries, (WIND_TCB *) taskIdSelf ()) == ERROR)
  276. return (ERROR);
  277.     break;
  278. default:
  279.     /* duplicate the given task's environment */
  280.     if ((pTcb = taskTcb (taskId)) == NULL)
  281. return (ERROR);
  282.     if (envDuplicate (pTcb->ppEnviron, pTcb->envTblSize,
  283.           pTcb->nEnvVarEntries, taskTcb (0)) == ERROR)
  284. return (ERROR);
  285. }
  286.     taskOptionsSet (taskId, VX_PRIVATE_ENV, VX_PRIVATE_ENV);
  287.     return (OK);
  288.     }
  289. /*********************************************************************
  290. *
  291. * envPrivateDestroy - destroy a private environment
  292. *
  293. * This routine destroys a private set of environment variables that were
  294. * created with envPrivateCreate().  Calling this routine is unnecessary if
  295. * the environment variable task create hook is installed and the task
  296. * was spawned with VX_PRIVATE_ENV.
  297. * RETURNS: OK, or ERROR if the task does not exist.
  298. *
  299. * SEE ALSO: envPrivateCreate()
  300. */
  301. STATUS envPrivateDestroy
  302.     (
  303.     int taskId /* task with private env to destroy */
  304.     )
  305.     {
  306.     FAST WIND_TCB *pTcb;
  307.     if ((pTcb = taskTcb (taskId)) == NULL)
  308. return (ERROR);
  309.     envDestroy (pTcb->ppEnviron, pTcb->nEnvVarEntries);
  310.     pTcb->ppEnviron = NULL;
  311.     taskOptionsSet (taskId, VX_PRIVATE_ENV, 0);
  312.     return (OK);
  313.     }
  314. /*********************************************************************
  315. *
  316. * putenv - set an environment variable
  317. *
  318. * This routine sets an environment variable to a value by altering an
  319. * existing variable or creating a new one.  The parameter points to a string
  320. * of the form "variableName=value".  Unlike the UNIX implementation, the string
  321. * passed as a parameter is copied to a private buffer.
  322. *
  323. * RETURNS: OK, or ERROR if space cannot be malloc'd.
  324. *
  325. * SEE ALSO: envLibInit(), getenv()
  326. */
  327. STATUS putenv
  328.     (
  329.     char *pEnvString            /* string to add to env */
  330.     )
  331.     {
  332.     FAST char **ppEnvLine;
  333.     char      **ppThisEnviron;
  334.     int thisEnvironTblSize;
  335.     int  thisEnvironNEntries;
  336.     FAST char  *pChar = pEnvString;
  337.     WIND_TCB   *pTcb  = taskTcb (0);
  338.     /* find end of environment variable name */
  339.     while ((*pChar != ' ') && (*pChar != 't') &&
  340.    (*pChar != '=') && (*pChar != NULL))
  341. pChar++;
  342.     ppEnvLine = envFind (pEnvString, pChar - pEnvString);
  343.     /* new environment variable? */
  344.     if (ppEnvLine == NULL)
  345. {
  346. if (pTcb->ppEnviron == NULL)
  347.     {  /* use global environment */
  348.     ppThisEnviron   = ppGlobalEnviron;
  349.     thisEnvironTblSize  = envTblSize;
  350.     thisEnvironNEntries = nEntries;
  351.     ppEnvLine   = &ppGlobalEnviron[nEntries++];
  352.     }
  353. else
  354.     {  /* use private environment */
  355.     ppThisEnviron   = pTcb->ppEnviron;
  356.     thisEnvironTblSize  = pTcb->envTblSize;
  357.     thisEnvironNEntries = pTcb->nEnvVarEntries;
  358.     ppEnvLine   = &pTcb->ppEnviron[pTcb->nEnvVarEntries++];
  359.     }
  360. /* make more room in environ if necessary */
  361. if (thisEnvironTblSize == thisEnvironNEntries)
  362.     {
  363.     FAST char **environBuf;
  364.     environBuf = (char **) realloc ((char *) ppThisEnviron,
  365.     (unsigned ) (thisEnvironTblSize + ENV_NENTRIES_TO_ALLOC) *
  366.  sizeof (char *));
  367.     if (environBuf == NULL)
  368. return (ERROR);
  369.     /* zero out the new area */
  370.     bzero ((char *) &(environBuf[thisEnvironTblSize]),
  371.    sizeof (char *) * ENV_NENTRIES_TO_ALLOC);
  372.     if (pTcb->ppEnviron == NULL)
  373. {
  374. ppGlobalEnviron = environBuf;
  375. envTblSize += ENV_NENTRIES_TO_ALLOC;
  376. }
  377.     else
  378. {
  379. pTcb->ppEnviron = environBuf;
  380. pTcb->envTblSize += ENV_NENTRIES_TO_ALLOC;
  381. }
  382.     ppEnvLine = &environBuf[thisEnvironNEntries];
  383.     }
  384. }
  385.     else
  386. {
  387. /* free the string for the given environment variable */
  388. free (*ppEnvLine);
  389. }
  390.     /* allocate memory to hold a copy of the string */
  391.     *ppEnvLine = (char *) malloc ((unsigned) strlen (pEnvString) + 1);
  392.     strcpy (*ppEnvLine, pEnvString);
  393.     return (OK);
  394.     }
  395. /*********************************************************************
  396. *
  397. * getenv - get an environment variable (ANSI)
  398. *
  399. * This routine searches the environment list (see the UNIX BSD 4.3 manual
  400. * entry for f3environ(5V)f1) for a string of the form "name=value" and
  401. * returns the value portion of the string, if the string is present;
  402. * otherwise it returns a NULL pointer.
  403. *
  404. * RETURNS: A pointer to the string value, or a NULL pointer.
  405. *
  406. * SEE ALSO: envLibInit(), putenv(), UNIX BSD 4.3 manual entry 
  407. * for f3environ(5V)f1,
  408. * .I "American National Standard for Information Systems -"
  409. * .I "Programming Language - C, ANSI X3.159-1989: General Utilities (stdlib.h)"
  410. */
  411. char *getenv
  412.     (
  413.     FAST const char *name  /* env variable to get value for */
  414.     )
  415.     {
  416.     FAST char **pEnvLine = envFind (CHAR_FROM_CONST (name), strlen (name));
  417.     FAST char *pValue;
  418.     if (pEnvLine == NULL)
  419. return (NULL);
  420.     /* advance past the '=' and any white space */
  421.     pValue = *pEnvLine + strlen (name);
  422.     while ((*pValue == ' ') || (*pValue == 't') || (*pValue == '='))
  423. pValue++;
  424.     return (pValue);
  425.     }
  426. /*********************************************************************
  427. *
  428. * envFind - find an environment variable
  429. *
  430. */
  431. LOCAL char **envFind
  432.     (
  433.     FAST char *name,
  434.     FAST int nameLen
  435.     )
  436.     {
  437.     FAST char **envVar;
  438.     WIND_TCB *pTcb = taskTcb (0);
  439.     FAST int i;
  440.     FAST int nEnvEntries;
  441.     FAST char endChar;
  442.     if (pTcb->ppEnviron == NULL)
  443. {
  444. envVar = ppGlobalEnviron;
  445. nEnvEntries = nEntries;
  446. }
  447.     else
  448. {
  449. envVar = pTcb->ppEnviron;
  450. nEnvEntries = pTcb->nEnvVarEntries;
  451. }
  452.     for (i = 0; i < nEnvEntries; envVar++, i++)
  453. if (strncmp (name, *envVar, nameLen) == 0)
  454.     {
  455.     /* make sure it's not just a substring */
  456.     endChar = (*envVar)[nameLen];
  457.     if ((endChar == ' ') || (endChar == 't') ||
  458.        (endChar == '=') || (endChar == NULL))
  459. return (envVar);
  460.     }
  461.     return (NULL); /* not found */
  462.     }
  463. /*********************************************************************
  464. *
  465. * envShow - display the environment for a task
  466. *
  467. * This routine prints to standard output all the environment variables for a
  468. * specified task.  If <taskId> is NULL, then the calling task's environment
  469. * is displayed.
  470. *
  471. * RETURNS: N/A
  472. */
  473. void envShow
  474.     (
  475.     int taskId /* task for which environment is printed */
  476.     )
  477.     {
  478.     FAST char **ppEnvVar;
  479.     FAST int    i;
  480.     FAST int    nEnvEntries;
  481.     WIND_TCB   *pTcb = taskTcb (taskId);
  482.     if (pTcb->ppEnviron == NULL)
  483. {
  484. printf ("(global environment)n");
  485. ppEnvVar    = ppGlobalEnviron;
  486. nEnvEntries = nEntries;
  487. }
  488.     else
  489. {
  490. printf ("(private environment)n");
  491. ppEnvVar    = pTcb->ppEnviron;
  492. nEnvEntries = pTcb->nEnvVarEntries;
  493. }
  494.     for (i = 0; i < nEnvEntries; ppEnvVar++, i++)
  495. printf ("%d: %sn", i, *ppEnvVar);
  496.     }