home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / syscall / procEnviron.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-07-30  |  8.5 KB  |  350 lines

  1. /* 
  2. * procEnviron.c --
  3. *
  4. *    Routines to map from the original environment-related kernel
  5. *    calls into the standard unix operations on the stack.  The
  6. *    old kernel calls are still available by changing the name of the
  7. *    call to Proc_OLD...
  8. *
  9. *    If a process's environment on the stack is nonexistent, then it
  10. *    assumes it has been called by Proc_Exec rather than Proc_ExecEnv,
  11. *    and getenv, et al., call Proc_OLD*.  This will go away once all
  12. *    programs pass the environment on the stack.
  13. *
  14. * Copyright 1987 Regents of the University of California
  15. * All rights reserved.
  16. */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: procEnviron.c,v 1.5 88/07/29 17:08:48 ouster Exp $ SPRITE (Berkeley)";
  20. #endif not lint
  21.  
  22.  
  23. #include <sprite.h>
  24. #include <bstring.h>
  25. #include <proc.h>
  26. #include <status.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30.  
  31. /*
  32.  * Library imports:
  33.  */
  34.  
  35. extern char **environ;
  36. extern void unsetenv();
  37.  
  38.  
  39. /*
  40. *----------------------------------------------------------------------
  41. *
  42. * Proc_GetEnvironVar --
  43. *
  44. *    Routine to map from the original Sprite call into getenv.
  45. *
  46. * Results:
  47. *    None.
  48. *
  49. * Side effects:
  50. *    The process's environment is modified.
  51. *
  52. *----------------------------------------------------------------------
  53. */
  54.  
  55. ReturnStatus
  56. Proc_GetEnvironVar(environVar)
  57. Proc_EnvironVar    environVar;    /* Variable to add to environment. */
  58. {
  59.     char *value;
  60.     extern char *getenv();
  61.  
  62.     value = getenv(environVar.name);
  63.     if (value == NULL) {
  64.     return(FAILURE);
  65.     }
  66.     strncpy(environVar.value, value, PROC_MAX_ENVIRON_VALUE_LENGTH);
  67.     return(SUCCESS);
  68. }
  69.  
  70. /*
  71. * ----------------------------------------------------------------------------
  72. *
  73. * Proc_GetEnvironRange --
  74. *
  75. *    Return as many environment variables as possible in the given range.  
  76. *    Variables are numbered from 0.  The actual number of environment 
  77. *    variables returned is returned in numActualVarsPtr.  The null 
  78. *    string is returned for any environment variables that are not set.
  79. *
  80. * Results:
  81. *    Error status if some error occcurs.  SUCCESS otherwise.
  82. *
  83. * Side effects:
  84. *    None.
  85. *
  86. * ----------------------------------------------------------------------------
  87. */
  88.  
  89. ReturnStatus
  90. Proc_GetEnvironRange(first, last, envArray, numActualVarsPtr)
  91.     int                first;            /* First var to 
  92.                              * retrieve. */
  93.     int             last;            /* Last var to 
  94.                              * retrieve. */
  95.     register    Proc_EnvironVar    *envArray;        /* Where to 
  96.                              * store vars.*/
  97.     int                *numActualVarsPtr;    /* Number of vars
  98.                              * retrieved. */
  99. {
  100.     ReturnStatus            status = SUCCESS;
  101.     int                    i;
  102.     char                 **envPtr;
  103.     char                *varPtr;
  104.     char                *namePtr;
  105.  
  106.     /*
  107.      * We might not be set up with a valid environment on the stack. In
  108.      * this case, punt and make the kernel call.
  109.      */
  110.     if (environ == NULL || *environ == NULL) {
  111.     status = Proc_OLDGetEnvironRange(first, last, envArray,
  112.                      numActualVarsPtr);
  113.     return(status);
  114.     }
  115.  
  116.     if (last < first || first < 0) {
  117.     return(SYS_INVALID_ARG);
  118.     }
  119.  
  120.     /*
  121.      * Copy out the environment variables.
  122.      */
  123.     envPtr = environ;
  124.     for (i = 0; i < first; i++) {
  125.     if (*envPtr == NULL) {
  126.         *numActualVarsPtr = 0;
  127.         return(SUCCESS);
  128.     }
  129.     envPtr++;
  130.     }
  131.     for (i = first; i <= last && *envPtr != NULL; i++, envPtr++, envArray++) {
  132.     varPtr = *envPtr;
  133.     if (*varPtr == NULL) {
  134.         envArray->name[0] = NULL;
  135.         envArray->value[0] = NULL;
  136.     } else {
  137.         char *value;
  138.         
  139.         value = index(varPtr, '=');
  140.         if (value != NULL) {
  141.         (void) strcpy(envArray->value, (char *) (value + 1));
  142.         } else {
  143.         envArray->value[0] = NULL;
  144.         }
  145.  
  146.         namePtr = envArray->name;
  147.         while ((*varPtr != '\0') && (*varPtr != '=')) {
  148.         *namePtr = *varPtr;
  149.         varPtr++, namePtr++;
  150.         }
  151.         *namePtr = '\0';
  152.     }
  153.     }
  154.     *numActualVarsPtr = i - first;
  155.     return(status);
  156. }
  157.  
  158.  
  159.  
  160. /*
  161.  *----------------------------------------------------------------------
  162.  *
  163.  * Proc_SetEnviron --
  164.  *
  165.  *    Routine to map from the original Sprite call into setenv.
  166.  *
  167.  * Results:
  168.  *    None.
  169.  *
  170.  * Side effects:
  171.  *    The process's environment is modified.
  172.  *
  173.  *----------------------------------------------------------------------
  174.  */
  175.  
  176. ReturnStatus
  177. Proc_SetEnviron(environVar)
  178.     Proc_EnvironVar    environVar;    /* Variable to add to environment. */
  179. {
  180.     setenv(environVar.name, environVar.value);
  181.     return(SUCCESS);
  182. }
  183.  
  184.  
  185.  /*
  186.  *----------------------------------------------------------------------
  187.  *
  188.  * Proc_UnsetEnviron --
  189.  *
  190.  *    Routine to map from the original Sprite call into unsetenv.
  191.  *
  192.  * Results:
  193.  *    None.
  194.  *
  195.  * Side effects:
  196.  *    The process's environment is modified.
  197.  *
  198.  *----------------------------------------------------------------------
  199.  */
  200.  
  201. ReturnStatus
  202. Proc_UnsetEnviron(environVar)
  203.     Proc_EnvironVar    environVar;    /* Variable to add to environment. */
  204. {
  205.     unsetenv(environVar.name);
  206.     return(SUCCESS);
  207. }
  208.  
  209.  
  210. /*
  211.  *----------------------------------------------------------------------
  212.  *
  213.  * Proc_InstallEnviron --
  214.  *
  215.  *    Routine to create a new environment, from scratch.  Formerly,
  216.  *    this would be a system call, but now we just set up the global
  217.  *    variable 'environ'.  Note, this doesn't free the old environ or
  218.  *    the data it pointed to, since the data might have been allocated
  219.  *    on the stack rather than with malloc.  However, this routine is not
  220.  *     likely to be called more than once, if that.
  221.  *
  222.  *    It's possible that the caller will be installing its current
  223.  *    environment, in which case no changes would be necessary (since
  224.  *    each process now gets its own copy anyway, making a private copy
  225.  *    via this routine is unnecessary).  However, let's just create
  226.  *    the new environment anyway: this is a temporary placeholder after
  227.  *    all.
  228.  *
  229.  * Results:
  230.  *    None.
  231.  *
  232.  * Side effects:
  233.  *    The process's environment is modified.
  234.  *
  235.  *----------------------------------------------------------------------
  236.  */
  237.  
  238. ReturnStatus
  239. Proc_InstallEnviron(newEnviron, numVars)
  240.     Proc_EnvironVar    newEnviron[];    /* Array of new environment variables */
  241.     int         numVars;     /* Size of array */
  242. {
  243.     int i;
  244.     char *newVar;
  245.     extern char *malloc();
  246.     Proc_EnvironVar *envPtr;    /* pointer into array of vars */
  247.  
  248.     environ = (char **) malloc((unsigned) ((numVars + 1) * sizeof(char *)));
  249.     for (i = 0, envPtr = newEnviron; i < numVars; i++, envPtr++) {
  250.     newVar = malloc ((unsigned) (strlen (envPtr->name) +
  251.                      strlen (envPtr->value) + 2));
  252.     if (newVar == NULL) {
  253.         return (FAILURE);
  254.     }
  255.     (void) sprintf (newVar, "%s=%s", envPtr->name, envPtr->value);
  256.     environ[i] = newVar;
  257.     }
  258.     environ[numVars] = NULL;
  259.     return(SUCCESS);
  260. }
  261.  
  262.  
  263. /*
  264.  *----------------------------------------------------------------------
  265.  *
  266.  * Proc_CopyEnviron --
  267.  *
  268.  *    Routine to copy the environment. If environ is set, then do nothing.
  269.  *    otherwise, we're using the system-wide environment, so call
  270.  *    the original kernel routine.
  271.  *
  272.  * Results:
  273.  *    Propagated from the kernel call, or SUCCESS.
  274.  *
  275.  * Side effects:
  276.  *    None.
  277.  *
  278.  *----------------------------------------------------------------------
  279.  */
  280.  
  281. ReturnStatus
  282. Proc_CopyEnviron()
  283. {
  284. #define COMPAT_ENV
  285. #ifndef COMPAT_ENV
  286.     if (environ == NULL || *environ == NULL) {
  287. #endif COMPAT_ENV
  288.     return(Proc_OLDCopyEnviron());
  289. #ifndef COMPAT_ENV
  290.     }
  291.     return(SUCCESS);
  292. #endif COMPAT_ENV
  293. }
  294.  
  295. /*
  296.  *----------------------------------------------------------------------
  297.  *
  298.  * Proc_FetchGlobalEnv --
  299.  *
  300.  *    Reads the process's environment from the kernel into new storage
  301.  *    allocated on the heap (to be used to pass environment into 
  302.  *    Proc_ExecEnv).
  303.  *
  304.  *    The strings are done in the traditional fashion of 'name=value', though
  305.  *    they appear on the stack in reverse order.
  306.  *
  307.  * Results:
  308.  *    The address of the start of the vector. 
  309.  *
  310.  * Side Effects:
  311.  *    Memory is allocated to hold the environment.
  312.  *
  313.  *----------------------------------------------------------------------
  314.  */
  315. char **
  316. Proc_FetchGlobalEnv()
  317. {
  318.     register char    **vecPtr;
  319.     register int    numVariables;
  320.     register int    varNum;
  321.  
  322.     char        value[PROC_MAX_ENVIRON_VALUE_LENGTH];
  323.     char        name[PROC_MAX_ENVIRON_NAME_LENGTH];
  324.     Proc_EnvironVar    var;
  325.     char        *tempEnv[PROC_MAX_ENVIRON_SIZE];
  326.     int        i;
  327.  
  328.     vecPtr = tempEnv;
  329.     varNum = 0;
  330.     var.name = name; var.value = value;
  331.  
  332.     while ((Proc_OLDGetEnvironRange(varNum, varNum, &var, &i) == SUCCESS) && i) {
  333.     varNum += 1;
  334.     if (name[0]){
  335.         *vecPtr = malloc((unsigned) (strlen(name)+1+
  336.                 strlen(value)+1));
  337.         (void) strcpy(*vecPtr, name);
  338.         (void) strcat(*vecPtr, "=");
  339.         (void) strcat(*vecPtr, value);
  340.         vecPtr++;
  341.     }
  342.     }
  343.     *vecPtr = (char *)NULL;
  344.     numVariables = vecPtr - tempEnv + 1;
  345.     vecPtr = (char **) malloc((unsigned) (numVariables*sizeof(char *)));
  346.     bcopy((char *) tempEnv, (char *) vecPtr, numVariables*sizeof(char *));
  347.  
  348.     return (vecPtr);
  349. }
  350.