env.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package frankenphp
  2. // #include "frankenphp.h"
  3. import "C"
  4. import (
  5. "os"
  6. "strings"
  7. "unsafe"
  8. )
  9. //export go_putenv
  10. func go_putenv(str *C.char, length C.int) C.bool {
  11. // Create a byte slice from C string with a specified length
  12. s := C.GoBytes(unsafe.Pointer(str), length)
  13. // Convert byte slice to string
  14. envString := string(s)
  15. // Check if '=' is present in the string
  16. if key, val, found := strings.Cut(envString, "="); found {
  17. if os.Setenv(key, val) != nil {
  18. return false // Failure
  19. }
  20. } else {
  21. // No '=', unset the environment variable
  22. if os.Unsetenv(envString) != nil {
  23. return false // Failure
  24. }
  25. }
  26. return true // Success
  27. }
  28. //export go_getfullenv
  29. func go_getfullenv(threadIndex C.uintptr_t) (*C.go_string, C.size_t) {
  30. thread := phpThreads[threadIndex]
  31. env := os.Environ()
  32. goStrings := make([]C.go_string, len(env)*2)
  33. for i, envVar := range env {
  34. key, val, _ := strings.Cut(envVar, "=")
  35. goStrings[i*2] = C.go_string{C.size_t(len(key)), thread.pinString(key)}
  36. goStrings[i*2+1] = C.go_string{C.size_t(len(val)), thread.pinString(val)}
  37. }
  38. value := unsafe.SliceData(goStrings)
  39. thread.Pin(value)
  40. return value, C.size_t(len(env))
  41. }
  42. //export go_getenv
  43. func go_getenv(threadIndex C.uintptr_t, name *C.go_string) (C.bool, *C.go_string) {
  44. thread := phpThreads[threadIndex]
  45. // Create a byte slice from C string with a specified length
  46. envName := C.GoStringN(name.data, C.int(name.len))
  47. // Get the environment variable value
  48. envValue, exists := os.LookupEnv(envName)
  49. if !exists {
  50. // Environment variable does not exist
  51. return false, nil // Return 0 to indicate failure
  52. }
  53. // Convert Go string to C string
  54. value := &C.go_string{C.size_t(len(envValue)), thread.pinString(envValue)}
  55. thread.Pin(value)
  56. return true, value // Return 1 to indicate success
  57. }
  58. //export go_sapi_getenv
  59. func go_sapi_getenv(threadIndex C.uintptr_t, name *C.go_string) *C.char {
  60. envName := C.GoStringN(name.data, C.int(name.len))
  61. envValue, exists := os.LookupEnv(envName)
  62. if !exists {
  63. return nil
  64. }
  65. return phpThreads[threadIndex].pinCString(envValue)
  66. }