da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <cdt.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define env_change() (++ast.env_serial)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _venv_ Evar_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct _venv_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin union
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Evar_t *next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } un;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dtlink_t link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _env_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *dt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Evar_t *freelist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **env;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int max;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Env_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _BLD_env 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <env.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ENV_VALID 2 /* set if env is valid */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ENV_PMALLOC 1 /* set if Evar_t->un.ptr *s malloced */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ENV_VMALLOC 2 /* set of Evar_t was malloced */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ENV_BITS 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Compares the name portion of name=... only.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int compare(Dt_t *dt, Void_t* key1, Void_t* key2, Dtdisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const unsigned char *s1=(unsigned const char*)key1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const unsigned char *s2=(unsigned const char*)key2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c= *s1++) && c!='=' && c==*s2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s2++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((d=*s2)=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c-d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Dtdisc_t env_disc =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0, -1,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sizeof(char*),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin compare
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return a pointer to the environment in sorted order
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NULL is returned if there if there is nospace
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar **env_get(Env_t* ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Evar_t *vp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n=ep->extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->flags&ENV_VALID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ep->env+n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->count > ep->max)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->flags&ENV_MALLOCED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)ep->env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(ep->env = (char**)malloc(sizeof(char*)*(ep->count+1))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->flags |= ENV_MALLOCED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->max = ep->count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(vp=(Evar_t*)dtfirst(ep->dt);vp; vp=(Evar_t*)dtnext(ep->dt,vp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->index = (n<<ENV_BITS) | (vp->index&((1<<ENV_BITS)-1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->env[n++] = vp->un.ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->env[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->flags |= ENV_VALID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin environ = ep->env+ep->extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ep->env+ep->extra);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add name=value pair given by <str> to <ep>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if malloced is set, the variable will be freed when reassigned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The environment list may become invalidated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Returns 1 for success, 0 for failure
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint env_add(Env_t *ep, const char *str, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Evar_t *vp = (Evar_t*)dtmatch(ep->dt,(void*)str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp && strcmp(str,vp->un.ptr)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&ENV_STRDUP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = strdup(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp->index&ENV_PMALLOC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)vp->un.ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->un.ptr = (char*)str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->env && (ep->flags&ENV_VALID))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->env[vp->index>>ENV_BITS] = vp->un.ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->flags &= ~ENV_VALID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp = ep->freelist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->freelist = vp->un.next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(vp = newof((Evar_t*)0,Evar_t,2,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->index = ENV_VMALLOC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->freelist = (vp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->freelist->un.next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->un.ptr = (void*)str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(vp=dtinsert(ep->dt,vp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->count++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->index |= ENV_PMALLOC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->index &= ~ENV_PMALLOC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env_change();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * delete name from <ep>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The environment list may become invalidated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Returns 1 for success, 0 for if name is not present
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint env_delete(Env_t *ep, const char *str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Evar_t *vp = (Evar_t*)dtmatch(ep->dt,(void*)str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!vp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->flags &= ~ENV_VALID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp->index&ENV_PMALLOC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)vp->un.ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtdelete(ep->dt,vp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->un.next = ep->freelist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->freelist = vp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env_change();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open up a structure to support environment variables
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize with environment give by <envp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <extra> > 0, <extra> slots will be left at beginning of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * environment list when env_get() is involed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <extra>==ENV_USABLE, then the original environ can be
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * used and returned. Otherwise, a new one will be returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEnv_t *env_open(char **envp, int extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **env;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Env_t *ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Evar_t *vp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(ep = newof((Env_t*)0,Env_t,1,0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(ep->dt = dtopen(&env_disc,Dtoset)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(env=envp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*env++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (env+2)-envp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(extra==ENV_STABLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->env = envp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->max = n-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->count = ep->extra = extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->freelist = vp = newof((Evar_t*)0,Evar_t,n,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->index = ENV_VMALLOC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--n>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->un.next = (vp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->un.next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(env)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(env=envp; *env; env++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env_add(ep,*env,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close <ep> and free up all space used by it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid env_close(Env_t *ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Evar_t *vp, *vpnext,*top;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->env && (ep->flags&ENV_MALLOCED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)ep->env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(vp=(Evar_t*)dtfirst(ep->dt);vp; vp=vpnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vpnext = (Evar_t*)dtnext(ep->dt,vp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env_delete(ep,vp->un.ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(top=0,vp = ep->freelist; vp; vp = vpnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vpnext = vp->un.next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp->index&ENV_VMALLOC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->un.next = top;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin top = vp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(vp=top; vp; vp = vpnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vpnext = vp->un.next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)vp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtclose(ep->dt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}