package php import ( "io" "os" "unsafe" ) // #include // #include "runtime.h" import "C" type ioContext struct { // Output and Error are unbuffered writers used for regular and error output, // respectively. If left unset, any data written into either by the calling // context will be lost. Output io.Writer Error io.Writer } var currentContext *ioContext = nil func write(w io.Writer, buffer unsafe.Pointer, length C.uint) C.int { // Do not return error if writer is unavailable. if w == nil { return C.int(length) } if written, err := w.Write(C.GoBytes(buffer, C.int(length))); err == nil { return C.int(written) } return -1 } //export writeOut func writeOut(buffer unsafe.Pointer, length C.uint) C.int { return write(currentContext.Output, buffer, length) } //export writeErr func writeErr(buffer unsafe.Pointer, length C.uint) C.int { return write(currentContext.Error, buffer, length) } // Exec - Execute a program in the given context. func Exec(ctx *Context, prog *program) Value { var retval C.zval // Bit of a hack to change directory and restore it again. if len(ctx.Path) > 0 { origCwd, _ := os.Getwd() defer os.Chdir(origCwd) os.Chdir(ctx.Path) } currentContext = &ctx.ioContext C.exec(prog.op_array, &retval) currentContext = nil return zval_to_go(retval) }