@@ -3,114 +3,32 @@ package frankenphp
33// #cgo nocallback frankenphp_init_persistent_string
44// #cgo noescape frankenphp_init_persistent_string
55// #include "frankenphp.h"
6- // #include <Zend/zend_API.h>
6+ // #include "types.h"
77import "C"
88import (
99 "os"
1010 "strings"
11- "unsafe"
1211)
1312
14- func initializeEnv () map [string ]* C.zend_string {
15- env := os .Environ ()
16- envMap := make (map [string ]* C.zend_string , len (env ))
17-
18- for _ , envVar := range env {
13+ //export go_init_os_env
14+ func go_init_os_env (mainThreadEnv * C.zend_array ) {
15+ for _ , envVar := range os .Environ () {
1916 key , val , _ := strings .Cut (envVar , "=" )
20- envMap [key ] = C .frankenphp_init_persistent_string (toUnsafeChar (val ), C .size_t (len (val )))
21- }
22-
23- return envMap
24- }
25-
26- // get the main thread env or the thread specific env
27- func getSandboxedEnv (thread * phpThread ) map [string ]* C.zend_string {
28- if thread .sandboxedEnv != nil {
29- return thread .sandboxedEnv
30- }
31-
32- return mainThread .sandboxedEnv
33- }
34-
35- func clearSandboxedEnv (thread * phpThread ) {
36- if thread .sandboxedEnv == nil {
37- return
38- }
39-
40- for key , val := range thread .sandboxedEnv {
41- valInMainThread , ok := mainThread .sandboxedEnv [key ]
42- if ! ok || val != valInMainThread {
43- C .free (unsafe .Pointer (val ))
44- }
45- }
46-
47- thread .sandboxedEnv = nil
48- }
49-
50- // if an env var already exists, it needs to be freed
51- func removeEnvFromThread (thread * phpThread , key string ) {
52- valueInThread , existsInThread := thread .sandboxedEnv [key ]
53- if ! existsInThread {
54- return
55- }
56-
57- valueInMainThread , ok := mainThread .sandboxedEnv [key ]
58- if ! ok || valueInThread != valueInMainThread {
59- C .free (unsafe .Pointer (valueInThread ))
60- }
61-
62- delete (thread .sandboxedEnv , key )
63- }
64-
65- // copy the main thread env to the thread specific env
66- func cloneSandboxedEnv (thread * phpThread ) {
67- if thread .sandboxedEnv != nil {
68- return
69- }
70- thread .sandboxedEnv = make (map [string ]* C.zend_string , len (mainThread .sandboxedEnv ))
71- for key , value := range mainThread .sandboxedEnv {
72- thread .sandboxedEnv [key ] = value
17+ zkey := C .frankenphp_init_persistent_string (toUnsafeChar (key ), C .size_t (len (key )))
18+ zStr := C .frankenphp_init_persistent_string (toUnsafeChar (val ), C .size_t (len (val )))
19+ C .__hash_update_string__ (mainThreadEnv , zkey , zStr )
7320 }
7421}
7522
7623//export go_putenv
77- func go_putenv (threadIndex C.uintptr_t , str * C.char , length C.int ) C.bool {
78- thread := phpThreads [threadIndex ]
79- envString := C .GoStringN (str , length )
80- cloneSandboxedEnv (thread )
81-
82- // Check if '=' is present in the string
83- if key , val , found := strings .Cut (envString , "=" ); found {
84- removeEnvFromThread (thread , key )
85- thread .sandboxedEnv [key ] = C .frankenphp_init_persistent_string (toUnsafeChar (val ), C .size_t (len (val )))
86- return os .Setenv (key , val ) == nil
87- }
88-
89- // No '=', unset the environment variable
90- removeEnvFromThread (thread , envString )
91- return os .Unsetenv (envString ) == nil
92- }
93-
94- //export go_getfullenv
95- func go_getfullenv (threadIndex C.uintptr_t , trackVarsArray * C.zval ) {
96- thread := phpThreads [threadIndex ]
97- env := getSandboxedEnv (thread )
98-
99- for key , val := range env {
100- C .add_assoc_str_ex (trackVarsArray , toUnsafeChar (key ), C .size_t (len (key )), val )
101- }
102- }
103-
104- //export go_getenv
105- func go_getenv (threadIndex C.uintptr_t , name * C.char ) (C.bool , * C.zend_string ) {
106- thread := phpThreads [threadIndex ]
24+ func go_putenv (name * C.char , nameLen C.int , val * C.char , valLen C.int ) C.bool {
25+ goName := C .GoStringN (name , nameLen )
10726
108- // Get the environment variable value
109- envValue , exists := getSandboxedEnv (thread )[C .GoString (name )]
110- if ! exists {
111- // Environment variable does not exist
112- return false , nil // Return 0 to indicate failure
27+ if val == nil {
28+ // If no "=" is present, unset the environment variable
29+ return C .bool (os .Unsetenv (goName ) == nil )
11330 }
11431
115- return true , envValue // Return 1 to indicate success
32+ goVal := C .GoStringN (val , valLen )
33+ return C .bool (os .Setenv (goName , goVal ) == nil )
11634}
0 commit comments