patch.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2024 The libtcl9_0-go Authors. All rights reserved.
  2. // Use of the source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build !windows
  5. package libtcl9_0 // import "modernc.org/libtcl9_0"
  6. import (
  7. "fmt"
  8. goexec "os/exec"
  9. "syscall"
  10. "unsafe"
  11. "modernc.org/libc"
  12. )
  13. // tclBasic.c:85:1:
  14. func _TclGetCStackPtr(tls *libc.TLS) (r uintptr) {
  15. p := tls.Alloc(8)
  16. defer tls.Free(8)
  17. return p
  18. }
  19. func _TclWinCPUID(tls *libc.TLS, index uint32, regsPtr uintptr) (r int32) {
  20. return TCL_ERROR
  21. }
  22. // int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
  23. func _pthread_once(tls *libc.TLS, p, f uintptr) int32 {
  24. panic(todo(""))
  25. }
  26. // int pthread_kill(pthread_t thread, int sig);
  27. func _pthread_kill(tls *libc.TLS, thread uintptr, sig int32) int32 {
  28. panic(todo(""))
  29. }
  30. /*
  31. *---------------------------------------------------------------------------
  32. *
  33. * TclpCreateProcess --
  34. *
  35. * Create a child process that has the specified files as its standard
  36. * input, output, and error. The child process runs asynchronously and
  37. * runs with the same environment variables as the creating process.
  38. *
  39. * The path is searched to find the specified executable.
  40. *
  41. * Results:
  42. * The return value is TCL_ERROR and an error message is left in the
  43. * interp's result if there was a problem creating the child process.
  44. * Otherwise, the return value is TCL_OK and *pidPtr is filled with the
  45. * process id of the child process.
  46. *
  47. * Side effects:
  48. * A process is created.
  49. *
  50. *---------------------------------------------------------------------------
  51. */
  52. // C documentation
  53. func _TclpCreateProcess(tls *libc.TLS, interp uintptr, argc Tsize_t, argv uintptr, inputFile uintptr, outputFile uintptr, errorFile uintptr, pidPtr uintptr) (r int32) {
  54. bp := tls.Alloc(2 * 8)
  55. defer tls.Free(2 * 8)
  56. var args []string
  57. for i := 0; i < int(argc); i++ {
  58. p := *(*uintptr)(unsafe.Pointer(argv + unsafe.Sizeof(uintptr(0))*uintptr(i)))
  59. args = append(args, libc.GoString(p))
  60. }
  61. if len(args) == 0 {
  62. panic(todo(""))
  63. }
  64. args0, err := goexec.LookPath(args[0])
  65. if err != nil {
  66. *(*int32)(unsafe.Pointer(libc.X__errno_location(tls))) = libc.ENOENT
  67. s, err := libc.CString(fmt.Sprintf("couldn't execute \"%.150s\"", args[0]))
  68. if err != nil {
  69. panic(todo(""))
  70. }
  71. defer libc.Xfree(tls, s)
  72. XTcl_SetObjResult(tls, interp, XTcl_ObjPrintf(tls, uintptr(unsafe.Pointer(&createProcessMsg[0])), libc.VaList(bp, s, XTcl_PosixError(tls, interp))))
  73. return TCL_ERROR
  74. }
  75. args[0] = args0
  76. env := libc.GetEnviron()
  77. attr := &syscall.ProcAttr{
  78. Env: env,
  79. Files: []uintptr{^uintptr(0), ^uintptr(0), ^uintptr(0)},
  80. }
  81. if inputFile != 0 {
  82. attr.Files[syscall.Stdin] = inputFile - 1
  83. }
  84. if outputFile != 0 {
  85. attr.Files[syscall.Stdout] = outputFile - 1
  86. }
  87. if errorFile != 0 {
  88. attr.Files[syscall.Stderr] = errorFile - 1
  89. }
  90. pid, err := syscall.ForkExec(args0, args, attr)
  91. if err != nil {
  92. trc("TclpCreateProcess(%#x, %d, %q, %v, %v, %v, %#x): %v", interp, len(args), args, inputFile, outputFile, errorFile, pidPtr, err)
  93. panic(todo(""))
  94. }
  95. *(*uintptr)(unsafe.Pointer(pidPtr)) = uintptr(pid)
  96. return TCL_OK
  97. }
  98. var createProcessMsg = [...]byte{'%', 's', ':', ' ', '%', 's', 0}