zend_ini.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package zend
  2. /*
  3. #include <zend_API.h>
  4. #include <zend_ini.h>
  5. #ifdef ZEND_ENGINE_2
  6. typedef zend_ini_entry zend_ini_entry_def;
  7. typedef char zend_string; // 为了让gozend_ini_modifier7在php5下能够编译过
  8. #endif
  9. extern int gozend_ini_modifier7(zend_ini_entry *entry, zend_string *new_value, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage);
  10. extern int gozend_ini_modifier5(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage);
  11. extern void gozend_ini_displayer(zend_ini_entry *ini_entry, int type);
  12. */
  13. import "C"
  14. import "unsafe"
  15. import (
  16. "fmt"
  17. // "reflect"
  18. "log"
  19. "runtime"
  20. )
  21. type IniEntries struct {
  22. zies []C.zend_ini_entry_def
  23. }
  24. var zend_ini_entry_def_zero C.zend_ini_entry_def
  25. func NewIniEntries() *IniEntries {
  26. this := &IniEntries{}
  27. this.zies = make([]C.zend_ini_entry_def, 1)
  28. this.zies[0] = zend_ini_entry_def_zero
  29. return this
  30. }
  31. func (this *IniEntries) Register(module_number int) int {
  32. r := C.zend_register_ini_entries(&this.zies[0], C.int(module_number))
  33. log.Println(r)
  34. return int(r)
  35. }
  36. func (this *IniEntryDef) Unregister(module_number int) {
  37. C.zend_unregister_ini_entries(C.int(module_number))
  38. }
  39. func (this *IniEntries) Add(ie *IniEntryDef) {
  40. this.zies[len(this.zies)-1] = ie.zie
  41. this.zies = append(this.zies, zend_ini_entry_def_zero)
  42. }
  43. type IniEntry struct {
  44. zie *C.zend_ini_entry
  45. }
  46. func newZendIniEntryFrom(ie *C.zend_ini_entry) *IniEntry {
  47. return &IniEntry{ie}
  48. }
  49. func (this *IniEntry) Name() string { return fromZString(this.zie.name) }
  50. func (this *IniEntry) Value() string { return fromZString(this.zie.value) }
  51. func (this *IniEntry) OrigValue() string { return fromZString(this.zie.orig_value) }
  52. const (
  53. INI_USER = int(C.ZEND_INI_USER)
  54. INI_PERDIR = int(C.ZEND_INI_PERDIR)
  55. INI_SYSTEM = int(C.ZEND_INI_SYSTEM)
  56. )
  57. type IniEntryDef struct {
  58. zie C.zend_ini_entry_def
  59. onModify func(ie *IniEntry, newValue string, stage int) int
  60. onDisplay func(ie *IniEntry, itype int)
  61. }
  62. func NewIniEntryDef() *IniEntryDef {
  63. this := &IniEntryDef{}
  64. // this.zie = (*C.zend_ini_entry_def)(C.calloc(1, C.sizeof_zend_ini_entry_def))
  65. runtime.SetFinalizer(this, zendIniEntryDefFree)
  66. return this
  67. }
  68. func zendIniEntryDefFree(this *IniEntryDef) {
  69. if _, ok := iniNameEntries[C.GoString(this.zie.name)]; ok {
  70. delete(iniNameEntries, C.GoString(this.zie.name))
  71. }
  72. if this.zie.name != nil {
  73. C.free(unsafe.Pointer(this.zie.name))
  74. }
  75. if this.zie.value != nil {
  76. C.free(unsafe.Pointer(this.zie.value))
  77. }
  78. }
  79. func (this *IniEntryDef) Fill3(name string, defaultValue interface{}, modifiable bool,
  80. onModify func(), arg1, arg2, arg3 interface{}, displayer func()) {
  81. this.zie.name = C.CString(name)
  82. this.zie.modifiable = go2cBool(modifiable)
  83. // this.zie.orig_modifiable = go2cBool(modifiable)
  84. if ZEND_ENGINE == ZEND_ENGINE_3 {
  85. this.zie.on_modify = go2cfn(C.gozend_ini_modifier7)
  86. } else {
  87. this.zie.on_modify = go2cfn(C.gozend_ini_modifier5)
  88. }
  89. this.zie.displayer = go2cfn(C.gozend_ini_displayer)
  90. value := fmt.Sprintf("%v", defaultValue)
  91. this.zie.value = C.CString(value)
  92. if arg1 == nil {
  93. this.zie.mh_arg1 = nil
  94. }
  95. if arg2 == nil {
  96. this.zie.mh_arg2 = nil
  97. }
  98. if arg3 == nil {
  99. this.zie.mh_arg3 = nil
  100. }
  101. if ZEND_ENGINE == ZEND_ENGINE_3 {
  102. this.zie.name_length = C.uint32_t(len(name))
  103. this.zie.value_length = C.uint32_t(len(value))
  104. } else {
  105. // why need +1 for php5?
  106. // if not, zend_alter_ini_entry_ex:280行会出现zend_hash_find无结果失败
  107. this.zie.name_length = C.uint32_t(len(name) + 1)
  108. this.zie.value_length = C.uint32_t(len(value) + 1)
  109. }
  110. log.Println(name, len(name))
  111. iniNameEntries[name] = this
  112. }
  113. func (this *IniEntryDef) Fill2(name string, defaultValue interface{}, modifiable bool,
  114. onModify func(), arg1, arg2 interface{}, displayer func()) {
  115. this.Fill3(name, defaultValue, modifiable, onModify, arg1, arg2, nil, displayer)
  116. }
  117. func (this *IniEntryDef) Fill1(name string, defaultValue interface{}, modifiable bool,
  118. onModify func(), arg1 interface{}, displayer func()) {
  119. this.Fill3(name, defaultValue, modifiable, onModify, arg1, nil, nil, displayer)
  120. }
  121. func (this *IniEntryDef) Fill(name string, defaultValue interface{}, modifiable bool,
  122. onModify func(), displayer func()) {
  123. this.Fill3(name, defaultValue, modifiable, onModify, nil, nil, nil, displayer)
  124. }
  125. func (this *IniEntryDef) SetModifier(modifier func(ie *IniEntry, newValue string, state int) int) {
  126. this.onModify = modifier
  127. }
  128. func (this *IniEntryDef) SetDisplayer(displayer func(ie *IniEntry, itype int)) {
  129. this.onDisplay = displayer
  130. }
  131. var iniNameEntries = make(map[string]*IniEntryDef, 0)
  132. // the new_value is really not *C.char, it's *C.zend_string
  133. //export gozend_ini_modifier7
  134. func gozend_ini_modifier7(ie *C.zend_ini_entry, new_value *C.zend_string, mh_arg1 unsafe.Pointer, mh_arg2 unsafe.Pointer, mh_arg3 unsafe.Pointer, stage C.int) C.int {
  135. // log.Println(ie, "//", new_value, stage, ie.modifiable)
  136. // log.Println(ie.orig_modifiable, ie.modified, fromZString(ie.orig_value))
  137. // log.Println(fromZString(new_value), fromZString(ie.name), fromZString(ie.value))
  138. if iedef, ok := iniNameEntries[fromZString(ie.name)]; ok {
  139. iedef.onModify(newZendIniEntryFrom(ie), fromZString(new_value), int(stage))
  140. } else {
  141. log.Println("wtf", fromZString(ie.name))
  142. }
  143. return 0
  144. }
  145. //export gozend_ini_modifier5
  146. func gozend_ini_modifier5(ie *C.zend_ini_entry, new_value *C.char, new_value_length C.uint, mh_arg1 unsafe.Pointer, mh_arg2 unsafe.Pointer, mh_arg3 unsafe.Pointer, stage C.int) C.int {
  147. // log.Println(ie, "//", new_value, new_value_length, stage, ie.modifiable)
  148. // log.Println(ie.orig_modifiable, ie.modified, fromZString(ie.orig_value))
  149. // log.Println(fromZString(new_value), fromZString(ie.name), fromZString(ie.value))
  150. if iedef, ok := iniNameEntries[fromZString(ie.name)]; ok {
  151. iedef.onModify(newZendIniEntryFrom(ie), fromZString(new_value), int(stage))
  152. } else {
  153. log.Println("wtf", fromZString(ie.name))
  154. }
  155. return 0
  156. }
  157. //export gozend_ini_displayer
  158. func gozend_ini_displayer(ie *C.zend_ini_entry, itype C.int) {
  159. log.Println(ie, itype)
  160. if iedef, ok := iniNameEntries[fromZString(ie.name)]; ok {
  161. iedef.onDisplay(newZendIniEntryFrom(ie), int(itype))
  162. } else {
  163. log.Println("wtf", fromZString(ie.name))
  164. }
  165. }