at_libc.mx raw

   1  // Copyright 2018 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  //go:build aix || solaris
   6  
   7  package unix
   8  
   9  import (
  10  	"syscall"
  11  	"unsafe"
  12  )
  13  
  14  //go:linkname procFstatat libc_fstatat
  15  //go:linkname procOpenat libc_openat
  16  //go:linkname procUnlinkat libc_unlinkat
  17  //go:linkname procReadlinkat libc_readlinkat
  18  //go:linkname procMkdirat libc_mkdirat
  19  //go:linkname procFchmodat libc_fchmodat
  20  //go:linkname procFchownat libc_fchownat
  21  //go:linkname procRenameat libc_renameat
  22  //go:linkname procLinkat libc_linkat
  23  //go:linkname procSymlinkat libc_symlinkat
  24  
  25  var (
  26  	procFstatat,
  27  	procOpenat,
  28  	procUnlinkat,
  29  	procReadlinkat,
  30  	procMkdirat,
  31  	procFchmodat,
  32  	procFchownat,
  33  	procRenameat,
  34  	procLinkat,
  35  	procSymlinkat uintptr
  36  )
  37  
  38  func Unlinkat(dirfd int, path string, flags int) error {
  39  	p, err := syscall.BytePtrFromString(path)
  40  	if err != nil {
  41  		return err
  42  	}
  43  
  44  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procUnlinkat)), 3,
  45  		uintptr(dirfd),
  46  		uintptr(unsafe.Pointer(p)),
  47  		uintptr(flags),
  48  		0, 0, 0)
  49  	if errno != 0 {
  50  		return errno
  51  	}
  52  
  53  	return nil
  54  }
  55  
  56  func Openat(dirfd int, path string, flags int, perm uint32) (int, error) {
  57  	p, err := syscall.BytePtrFromString(path)
  58  	if err != nil {
  59  		return 0, err
  60  	}
  61  
  62  	fd, _, errno := syscall6(uintptr(unsafe.Pointer(&procOpenat)), 4,
  63  		uintptr(dirfd),
  64  		uintptr(unsafe.Pointer(p)),
  65  		uintptr(flags),
  66  		uintptr(perm),
  67  		0, 0)
  68  	if errno != 0 {
  69  		return 0, errno
  70  	}
  71  
  72  	return int(fd), nil
  73  }
  74  
  75  func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error {
  76  	p, err := syscall.BytePtrFromString(path)
  77  	if err != nil {
  78  		return err
  79  	}
  80  
  81  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procFstatat)), 4,
  82  		uintptr(dirfd),
  83  		uintptr(unsafe.Pointer(p)),
  84  		uintptr(unsafe.Pointer(stat)),
  85  		uintptr(flags),
  86  		0, 0)
  87  	if errno != 0 {
  88  		return errno
  89  	}
  90  
  91  	return nil
  92  }
  93  
  94  func Readlinkat(dirfd int, path string, buf []byte) (int, error) {
  95  	p0, err := syscall.BytePtrFromString(path)
  96  	if err != nil {
  97  		return 0, err
  98  	}
  99  	var p1 unsafe.Pointer
 100  	if len(buf) > 0 {
 101  		p1 = unsafe.Pointer(&buf[0])
 102  	} else {
 103  		p1 = unsafe.Pointer(&_zero)
 104  	}
 105  	n, _, errno := syscall6(uintptr(unsafe.Pointer(&procReadlinkat)), 4,
 106  		uintptr(dirfd),
 107  		uintptr(unsafe.Pointer(p0)),
 108  		uintptr(p1),
 109  		uintptr(len(buf)),
 110  		0, 0)
 111  	if errno != 0 {
 112  		return 0, errno
 113  	}
 114  
 115  	return int(n), nil
 116  }
 117  
 118  func Mkdirat(dirfd int, path string, mode uint32) error {
 119  	p, err := syscall.BytePtrFromString(path)
 120  	if err != nil {
 121  		return err
 122  	}
 123  
 124  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procMkdirat)), 3,
 125  		uintptr(dirfd),
 126  		uintptr(unsafe.Pointer(p)),
 127  		uintptr(mode),
 128  		0, 0, 0)
 129  	if errno != 0 {
 130  		return errno
 131  	}
 132  	return nil
 133  }
 134  
 135  func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
 136  	p, err := syscall.BytePtrFromString(path)
 137  	if err != nil {
 138  		return err
 139  	}
 140  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procFchmodat)), 4,
 141  		uintptr(dirfd),
 142  		uintptr(unsafe.Pointer(p)),
 143  		uintptr(mode),
 144  		uintptr(flags),
 145  		0, 0)
 146  	if errno != 0 {
 147  		return errno
 148  	}
 149  	return nil
 150  }
 151  
 152  func Fchownat(dirfd int, path string, uid, gid int, flags int) error {
 153  	p, err := syscall.BytePtrFromString(path)
 154  	if err != nil {
 155  		return err
 156  	}
 157  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procFchownat)), 5,
 158  		uintptr(dirfd),
 159  		uintptr(unsafe.Pointer(p)),
 160  		uintptr(uid),
 161  		uintptr(gid),
 162  		uintptr(flags),
 163  		0)
 164  	if errno != 0 {
 165  		return errno
 166  	}
 167  	return nil
 168  }
 169  
 170  func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) error {
 171  	oldp, err := syscall.BytePtrFromString(oldpath)
 172  	if err != nil {
 173  		return err
 174  	}
 175  	newp, err := syscall.BytePtrFromString(newpath)
 176  	if err != nil {
 177  		return err
 178  	}
 179  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procRenameat)), 4,
 180  		uintptr(olddirfd),
 181  		uintptr(unsafe.Pointer(oldp)),
 182  		uintptr(newdirfd),
 183  		uintptr(unsafe.Pointer(newp)),
 184  		0,
 185  		0)
 186  	if errno != 0 {
 187  		return errno
 188  	}
 189  	return nil
 190  }
 191  
 192  func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flag int) error {
 193  	oldp, err := syscall.BytePtrFromString(oldpath)
 194  	if err != nil {
 195  		return err
 196  	}
 197  	newp, err := syscall.BytePtrFromString(newpath)
 198  	if err != nil {
 199  		return err
 200  	}
 201  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procLinkat)), 5,
 202  		uintptr(olddirfd),
 203  		uintptr(unsafe.Pointer(oldp)),
 204  		uintptr(newdirfd),
 205  		uintptr(unsafe.Pointer(newp)),
 206  		uintptr(flag),
 207  		0)
 208  	if errno != 0 {
 209  		return errno
 210  	}
 211  	return nil
 212  }
 213  
 214  func Symlinkat(oldpath string, newdirfd int, newpath string) error {
 215  	oldp, err := syscall.BytePtrFromString(oldpath)
 216  	if err != nil {
 217  		return err
 218  	}
 219  	newp, err := syscall.BytePtrFromString(newpath)
 220  	if err != nil {
 221  		return err
 222  	}
 223  	_, _, errno := syscall6(uintptr(unsafe.Pointer(&procSymlinkat)), 3,
 224  		uintptr(unsafe.Pointer(oldp)),
 225  		uintptr(newdirfd),
 226  		uintptr(unsafe.Pointer(newp)),
 227  		0, 0, 0)
 228  	if errno != 0 {
 229  		return errno
 230  	}
 231  	return nil
 232  }
 233