2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Internal functions for environment variables handling.
8 #include "__posixc_intbase.h"
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <proto/utility.h>
19 #if AROS_AMIGAOS_COMPLIANCE && (AROS_AMIGAOS_COMPLIANCE >= 30)
20 /* ScanVars is a Morphos addition in dos.library v50, so we
21 * have this stub here for posixc.library compatability with
22 * dos.library v30..v39.
24 static LONG
v30_ScanVars(struct Hook
*hook
, ULONG flags
, APTR userdata
)
26 /* We scan through the process->pr_LocalVars list */
29 struct ScanVarsMsg msg
;
33 UtilityBase
= OpenLibrary("utility.library", 0);
34 if (UtilityBase
== NULL
)
37 msg
.sv_SVMSize
= sizeof(struct ScanVarsMsg
);
39 pr
= (struct Process
*)FindTask(NULL
);
41 /* We know that the callers of this routine
42 * will be asking for GVF_LOCAL_ONLY
44 var
= (struct LocalVar
*)pr
->pr_LocalVars
.mlh_Head
;
46 ForeachNode(&pr
->pr_LocalVars
, var
)
48 if (var
->lv_Node
.ln_Type
== LV_VAR
)
50 msg
.sv_Name
= var
->lv_Node
.ln_Name
;
51 msg
.sv_Var
= var
->lv_Value
;
52 msg
.sv_VarLen
= var
->lv_Len
;
54 res
= CallHookPkt(hook
, userdata
, &msg
);
60 CloseLibrary(UtilityBase
);
64 #define ScanVars(a,b,c) v30_ScanVars(a,b,c)
67 static __env_item
*__env_newvar(const char *name
, int valuesize
)
71 item
= malloc(sizeof(__env_item
));
74 item
->name
= strdup(name
);
75 if (!item
->name
) goto err2
;
77 item
->value
= malloc(valuesize
);
78 if (!item
->value
) goto err3
;
92 static __env_item
**internal_findvar(register const char *name
)
94 struct PosixCIntBase
*PosixCBase
=
95 (struct PosixCIntBase
*)__aros_getbase_PosixCBase();
100 curr
= &PosixCBase
->env_list
;
101 *curr
&& strcmp((*curr
)->name
, name
);
102 curr
= &((*curr
)->next
)
109 Allocates space for a variable with name 'name' returning a pointer to it.
110 If a variable with this name already exists then returns a pointer to that
113 Returns NULL on error.
115 __env_item
*__env_getvar(const char *name
, int valuesize
)
117 register __env_item
**curr
;
119 curr
= internal_findvar(name
);
123 if (strlen((*curr
)->value
) < valuesize
)
125 free((*curr
)->value
);
126 (*curr
)->value
= malloc(valuesize
);
130 __env_item
*tmp
= (*curr
)->next
;
139 *curr
= __env_newvar(name
, valuesize
);
145 void __env_delvar(const char *name
)
147 register __env_item
**curr
;
149 curr
= internal_findvar(name
);
153 register __env_item
*tmp
= *curr
;
155 *curr
= (*curr
)->next
;
170 /* Hook function counting the number of variables and computing the buffer size
171 needed for name=value character buffer. */
172 LONG
get_var_len(struct Hook
*hook
, APTR userdata
, struct ScanVarsMsg
*message
)
174 struct EnvData
*data
= (struct EnvData
*) userdata
;
177 (ptrdiff_t) strlen((char*)message
->sv_Name
) +
178 message
->sv_VarLen
+ 2;
182 /* Hook function storing name=value strings in buffer */
183 LONG
get_var(struct Hook
*hook
, APTR userdata
, struct ScanVarsMsg
*message
)
185 struct EnvData
*data
= userdata
;
186 data
->varbufptr
[0] = '\0';
187 strcat(data
->varbufptr
, (char*) message
->sv_Name
);
188 strcat(data
->varbufptr
, "=");
189 strncat(data
->varbufptr
, (char*) message
->sv_Var
, message
->sv_VarLen
);
190 data
->varbufptr
= data
->varbufptr
+ strlen(data
->varbufptr
) + 1;
194 /* Function storing name=value strings in given environ buffer. When buffer is
195 null, it returns minimal necessary size of the buffer needed to store all
196 name=value strings. */
197 int __env_get_environ(char **environ
, int size
)
207 memset(&hook
, 0, sizeof(struct Hook
));
208 hook
.h_Entry
= (HOOKFUNC
) get_var_len
;
209 ScanVars(&hook
, GVF_LOCAL_ONLY
, &u
);
212 return sizeof(char*) * (u
.envcount
+ 1) + u
.varbufsize
;
213 else if(size
< sizeof(char*) *(u
.envcount
+ 1) + u
.varbufsize
)
216 /* store name=value strings after table of pointers */
217 varbuf
= (char*) (environ
+ (u
.envcount
+ 1));
219 /* time to fill in the buffers */
220 u
.varbufptr
= varbuf
;
221 u
.varbufptr
[0] = '\0';
222 hook
.h_Entry
= (HOOKFUNC
) get_var
;
223 ScanVars(&hook
, GVF_LOCAL_ONLY
, &u
);
225 for(i
= 0; i
< u
.envcount
; i
++)
228 varbuf
= strchr(varbuf
, '\0') + 1;
230 environ
[u
.envcount
] = NULL
;