github.com/primecitizens/pcz/std@v0.2.1/ffi/wasm/wasi/00-types.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2023 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  //go:build wasip1
     9  
    10  package wasi
    11  
    12  import (
    13  	"unsafe"
    14  
    15  	"github.com/primecitizens/pcz/std/io"
    16  )
    17  
    18  // An Errno is an unsigned number describing an error condition.
    19  // The zero Errno is by convention a non-error.
    20  type Errno uint32
    21  
    22  func (e Errno) Temporary() bool {
    23  	return e == EINTR || e == EMFILE || e.Timeout()
    24  }
    25  
    26  func (e Errno) Timeout() bool {
    27  	return e == EAGAIN || e == ETIMEDOUT
    28  }
    29  
    30  const (
    31  	E2BIG           Errno = 1
    32  	EACCES          Errno = 2
    33  	EADDRINUSE      Errno = 3
    34  	EADDRNOTAVAIL   Errno = 4
    35  	EAFNOSUPPORT    Errno = 5
    36  	EAGAIN          Errno = 6
    37  	EALREADY        Errno = 7
    38  	EBADF           Errno = 8
    39  	EBADMSG         Errno = 9
    40  	EBUSY           Errno = 10
    41  	ECANCELED       Errno = 11
    42  	ECHILD          Errno = 12
    43  	ECONNABORTED    Errno = 13
    44  	ECONNREFUSED    Errno = 14
    45  	ECONNRESET      Errno = 15
    46  	EDEADLK         Errno = 16
    47  	EDESTADDRREQ    Errno = 17
    48  	EDOM            Errno = 18
    49  	EDQUOT          Errno = 19
    50  	EEXIST          Errno = 20
    51  	EFAULT          Errno = 21
    52  	EFBIG           Errno = 22
    53  	EHOSTUNREACH    Errno = 23
    54  	EIDRM           Errno = 24
    55  	EILSEQ          Errno = 25
    56  	EINPROGRESS     Errno = 26
    57  	EINTR           Errno = 27
    58  	EINVAL          Errno = 28
    59  	EIO             Errno = 29
    60  	EISCONN         Errno = 30
    61  	EISDIR          Errno = 31
    62  	ELOOP           Errno = 32
    63  	EMFILE          Errno = 33
    64  	EMLINK          Errno = 34
    65  	EMSGSIZE        Errno = 35
    66  	EMULTIHOP       Errno = 36
    67  	ENAMETOOLONG    Errno = 37
    68  	ENETDOWN        Errno = 38
    69  	ENETRESET       Errno = 39
    70  	ENETUNREACH     Errno = 40
    71  	ENFILE          Errno = 41
    72  	ENOBUFS         Errno = 42
    73  	ENODEV          Errno = 43
    74  	ENOENT          Errno = 44
    75  	ENOEXEC         Errno = 45
    76  	ENOLCK          Errno = 46
    77  	ENOLINK         Errno = 47
    78  	ENOMEM          Errno = 48
    79  	ENOMSG          Errno = 49
    80  	ENOPROTOOPT     Errno = 50
    81  	ENOSPC          Errno = 51
    82  	ENOSYS          Errno = 52
    83  	ENOTCONN        Errno = 53
    84  	ENOTDIR         Errno = 54
    85  	ENOTEMPTY       Errno = 55
    86  	ENOTRECOVERABLE Errno = 56
    87  	ENOTSOCK        Errno = 57
    88  	ENOTSUP         Errno = 58
    89  	ENOTTY          Errno = 59
    90  	ENXIO           Errno = 60
    91  	EOVERFLOW       Errno = 61
    92  	EOWNERDEAD      Errno = 62
    93  	EPERM           Errno = 63
    94  	EPIPE           Errno = 64
    95  	EPROTO          Errno = 65
    96  	EPROTONOSUPPORT Errno = 66
    97  	EPROTOTYPE      Errno = 67
    98  	ERANGE          Errno = 68
    99  	EROFS           Errno = 69
   100  	ESPIPE          Errno = 70
   101  	ESRCH           Errno = 71
   102  	ESTALE          Errno = 72
   103  	ETIMEDOUT       Errno = 73
   104  	ETXTBSY         Errno = 74
   105  	EXDEV           Errno = 75
   106  	ENOTCAPABLE     Errno = 76
   107  )
   108  
   109  func (errno Errno) IOErr() io.Status {
   110  	if errno == 0 {
   111  		return io.StatusOK
   112  	}
   113  
   114  	switch errno {
   115  	case ENOTDIR:
   116  		return io.StatusNotDir
   117  	case ENOTSUP:
   118  		return io.StatusUnsupported
   119  	default:
   120  		return io.StatusUnkown
   121  	}
   122  }
   123  
   124  type (
   125  	FD          int32
   126  	uintptr32   = uint32
   127  	Size        uint32
   128  	FDflags     uint32
   129  	Filesize    uint64
   130  	Filetype    uint8
   131  	LookupFlags uint32
   132  	OFlags      uint32
   133  	Rights      uint64
   134  	Timestamp   uint64
   135  	Dircookie   uint64
   136  	FileDelta   int64
   137  	FstFlags    uint32
   138  )
   139  
   140  func Uintptr(p unsafe.Pointer) uintptr32 {
   141  	return uintptr32(uintptr(p))
   142  }
   143  
   144  type IOBuffer struct {
   145  	Ptr uintptr32
   146  	Len Size
   147  }
   148  
   149  const (
   150  	LOOKUP_SYMLINK_FOLLOW LookupFlags = 0x00000001
   151  )
   152  
   153  const (
   154  	OFlag_CREAT     OFlags = 0x0001 // Create file if it does not exist.
   155  	OFlag_DIRECTORY OFlags = 0x0002 // Fail if not a directory.
   156  	OFlag_EXCL      OFlags = 0x0004 // Fail if file already exists.
   157  	OFlag_TRUNC     OFlags = 0x0008 // Truncate file to size 0.
   158  )
   159  
   160  const (
   161  	FDflag_APPEND   FDflags = 0x0001 //
   162  	FDflag_DSYNC    FDflags = 0x0002 //
   163  	FDflag_NONBLOCK FDflags = 0x0004 //
   164  	FDflag_RSYNC    FDflags = 0x0008 //
   165  	FDflag_SYNC     FDflags = 0x0010 //
   166  )
   167  
   168  const (
   169  	Right_FD_DATASYNC             Rights = 1 << iota //
   170  	Right_FD_READ                                    //
   171  	Right_FD_SEEK                                    //
   172  	Right_FDSTAT_SET_FLAGS                           //
   173  	Right_FD_SYNC                                    //
   174  	Right_FD_TELL                                    //
   175  	Right_FD_WRITE                                   //
   176  	Right_FD_ADVISE                                  //
   177  	Right_FD_ALLOCATE                                //
   178  	Right_PATH_CREATE_DIRECTORY                      //
   179  	Right_PATH_CREATE_FILE                           //
   180  	Right_PATH_LINK_SOURCE                           //
   181  	Right_PATH_LINK_TARGET                           //
   182  	Right_PATH_OPEN                                  //
   183  	Right_FD_READDIR                                 //
   184  	Right_PATH_READLINK                              //
   185  	Right_PATH_RENAME_SOURCE                         //
   186  	Right_PATH_RENAME_TARGET                         //
   187  	Right_PATH_FILESTAT_GET                          //
   188  	Right_PATH_FILESTAT_SET_SIZE                     //
   189  	Right_PATH_FILESTAT_SET_TIMES                    //
   190  	Right_FD_FILESTAT_GET                            //
   191  	Right_FD_FILESTAT_SET_SIZE                       //
   192  	Right_FD_FILESTAT_SET_TIMES                      //
   193  	Right_PATH_SYMLINK                               //
   194  	Right_PATH_REMOVE_DIRECTORY                      //
   195  	Right_PATH_UNLINK_FILE                           //
   196  	Right_POLL_FD_READWRITE                          //
   197  	Right_SOCK_SHUTDOWN                              //
   198  	Right_SOCK_ACCEPT                                //
   199  )
   200  
   201  const (
   202  	WHENCE_SET = 0
   203  	WHENCE_CUR = 1
   204  	WHENCE_END = 2
   205  )
   206  
   207  const (
   208  	FILESTAT_SET_ATIM     = 0x0001
   209  	FILESTAT_SET_ATIM_NOW = 0x0002
   210  	FILESTAT_SET_MTIM     = 0x0004
   211  	FILESTAT_SET_MTIM_NOW = 0x0008
   212  )
   213  
   214  const (
   215  	// Despite the rights being defined as a 64 bits integer in the spec,
   216  	// wasmtime crashes the program if we set any of the upper 32 bits.
   217  	FullRights  Rights = ^Rights(0)
   218  	ReadRights  Rights = Right_FD_READ | Right_FD_READDIR
   219  	WriteRights Rights = Right_FD_DATASYNC | Right_FD_WRITE | Right_FD_ALLOCATE | Right_PATH_FILESTAT_SET_SIZE
   220  
   221  	// Some runtimes have very strict expectations when it comes to which
   222  	// rights can be enabled on files opened by path_open. The fileRights
   223  	// constant is used as a mask to retain only bits for operations that
   224  	// are supported on files.
   225  	FileRights Rights = 0 |
   226  		Right_FD_DATASYNC |
   227  		Right_FD_READ |
   228  		Right_FD_SEEK |
   229  		Right_FDSTAT_SET_FLAGS |
   230  		Right_FD_SYNC |
   231  		Right_FD_TELL |
   232  		Right_FD_WRITE |
   233  		Right_FD_ADVISE |
   234  		Right_FD_ALLOCATE |
   235  		Right_PATH_CREATE_DIRECTORY |
   236  		Right_PATH_CREATE_FILE |
   237  		Right_PATH_LINK_SOURCE |
   238  		Right_PATH_LINK_TARGET |
   239  		Right_PATH_OPEN |
   240  		Right_FD_READDIR |
   241  		Right_PATH_READLINK |
   242  		Right_PATH_RENAME_SOURCE |
   243  		Right_PATH_RENAME_TARGET |
   244  		Right_PATH_FILESTAT_GET |
   245  		Right_PATH_FILESTAT_SET_SIZE |
   246  		Right_PATH_FILESTAT_SET_TIMES |
   247  		Right_FD_FILESTAT_GET |
   248  		Right_FD_FILESTAT_SET_SIZE |
   249  		Right_FD_FILESTAT_SET_TIMES |
   250  		Right_PATH_SYMLINK |
   251  		Right_PATH_REMOVE_DIRECTORY |
   252  		Right_PATH_UNLINK_FILE |
   253  		Right_POLL_FD_READWRITE |
   254  		0
   255  
   256  	// Runtimes like wasmtime and wasmedge will refuse to open directories
   257  	// if the rights requested by the application exceed the operations that
   258  	// can be performed on a directory.
   259  	DirRights Rights = 0 |
   260  		Right_FD_SEEK |
   261  		Right_FDSTAT_SET_FLAGS |
   262  		Right_FD_SYNC |
   263  		Right_PATH_CREATE_DIRECTORY |
   264  		Right_PATH_CREATE_FILE |
   265  		Right_PATH_LINK_SOURCE |
   266  		Right_PATH_LINK_TARGET |
   267  		Right_PATH_OPEN |
   268  		Right_FD_READDIR |
   269  		Right_PATH_READLINK |
   270  		Right_PATH_RENAME_SOURCE |
   271  		Right_PATH_RENAME_TARGET |
   272  		Right_PATH_FILESTAT_GET |
   273  		Right_PATH_FILESTAT_SET_SIZE |
   274  		Right_PATH_FILESTAT_SET_TIMES |
   275  		Right_FD_FILESTAT_GET |
   276  		Right_FD_FILESTAT_SET_TIMES |
   277  		Right_PATH_SYMLINK |
   278  		Right_PATH_REMOVE_DIRECTORY |
   279  		Right_PATH_UNLINK_FILE |
   280  		0
   281  )
   282  
   283  const (
   284  	Filetype_UNKNOWN          Filetype = iota
   285  	Filetype_BLOCK_DEVICE              //
   286  	Filetype_CHARACTER_DEVICE          //
   287  	Filetype_DIRECTORY                 //
   288  	Filetype_REGULAR_FILE              //
   289  	Filetype_SOCKET_DGRAM              //
   290  	Filetype_SOCKET_STREAM             //
   291  	Filetype_SYMBOLIC_LINK             //
   292  )
   293  
   294  const (
   295  	Stdin  FD = 0
   296  	Stdout FD = 1
   297  	Stderr FD = 2
   298  )
   299  
   300  // func init() {
   301  // 	dirNameBuf := make([]byte, 256)
   302  // 	// We start looking for preopens at fd=3 because 0, 1, and 2 are reserved
   303  // 	// for standard input and outputs.
   304  // 	for preopenFd := int32(3); ; preopenFd++ {
   305  // 		var prestat prestat
   306  //
   307  // 		errno := fd_prestat_get(preopenFd, unsafe.Pointer(&prestat))
   308  // 		if errno == EBADF {
   309  // 			break
   310  // 		}
   311  // 		if errno == ENOTDIR || prestat.typ != preopentypeDir {
   312  // 			continue
   313  // 		}
   314  // 		if errno != 0 {
   315  // 			panic("fd_prestat: " + errno.Error())
   316  // 		}
   317  // 		if int(prestat.dir.prNameLen) > len(dirNameBuf) {
   318  // 			dirNameBuf = make([]byte, prestat.dir.prNameLen)
   319  // 		}
   320  //
   321  // 		errno = fd_prestat_dir_name(preopenFd, unsafe.Pointer(&dirNameBuf[0]), prestat.dir.prNameLen)
   322  // 		if errno != 0 {
   323  // 			panic("fd_prestat_dir_name: " + errno.Error())
   324  // 		}
   325  //
   326  // 		preopens = append(preopens, opendir{
   327  // 			fd:   preopenFd,
   328  // 			name: string(dirNameBuf[:prestat.dir.prNameLen]),
   329  // 		})
   330  // 	}
   331  //
   332  // 	if cwd, _ = Getenv("PWD"); cwd != "" {
   333  // 		cwd = joinPath("/", cwd)
   334  // 	} else if len(preopens) > 0 {
   335  // 		cwd = preopens[0].name
   336  // 	}
   337  // }
   338  //
   339  // //go:nosplit
   340  // func appendCleanPath(buf []byte, path string, lookupParent bool) ([]byte, bool) {
   341  // 	i := 0
   342  // 	for i < len(path) {
   343  // 		for i < len(path) && path[i] == '/' {
   344  // 			i++
   345  // 		}
   346  //
   347  // 		j := i
   348  // 		for j < len(path) && path[j] != '/' {
   349  // 			j++
   350  // 		}
   351  //
   352  // 		s := path[i:j]
   353  // 		i = j
   354  //
   355  // 		switch s {
   356  // 		case "":
   357  // 			continue
   358  // 		case ".":
   359  // 			continue
   360  // 		case "..":
   361  // 			if !lookupParent {
   362  // 				k := len(buf)
   363  // 				for k > 0 && buf[k-1] != '/' {
   364  // 					k--
   365  // 				}
   366  // 				for k > 1 && buf[k-1] == '/' {
   367  // 					k--
   368  // 				}
   369  // 				buf = buf[:k]
   370  // 				if k == 0 {
   371  // 					lookupParent = true
   372  // 				} else {
   373  // 					s = ""
   374  // 					continue
   375  // 				}
   376  // 			}
   377  // 		default:
   378  // 			lookupParent = false
   379  // 		}
   380  //
   381  // 		if len(buf) > 0 && buf[len(buf)-1] != '/' {
   382  // 			buf = append(buf, '/')
   383  // 		}
   384  // 		buf = append(buf, s...)
   385  // 	}
   386  // 	return buf, lookupParent
   387  // }
   388  //
   389  
   390  // // preparePath returns the preopen file descriptor of the directory to perform
   391  // // path resolution from, along with the pair of pointer and length for the
   392  // // relative expression of path from the directory.
   393  // //
   394  // // If the path argument is not absolute, it is first appended to the current
   395  // // working directory before resolution.
   396  // func preparePath(path string) (int32, unsafe.Pointer, Size) {
   397  // 	var dirFd = int32(-1)
   398  // 	var dirName string
   399  //
   400  // 	dir := "/"
   401  // 	if !isAbs(path) {
   402  // 		dir = cwd
   403  // 	}
   404  // 	path = joinPath(dir, path)
   405  //
   406  // 	for _, p := range preopens {
   407  // 		if len(p.name) > len(dirName) && hasPrefix(path, p.name) {
   408  // 			dirFd, dirName = p.fd, p.name
   409  // 		}
   410  // 	}
   411  //
   412  // 	path = path[len(dirName):]
   413  // 	for isAbs(path) {
   414  // 		path = path[1:]
   415  // 	}
   416  // 	if len(path) == 0 {
   417  // 		path = "."
   418  // 	}
   419  //
   420  // 	return dirFd, stringPointer(path), Size(len(path))
   421  // }