1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
//go:build linux && cgo
package linux
/*
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <limits.h>
#include <poll.h>
#include <pty.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include "../../shared/cgo/process_utils.h"
#include "../../shared/cgo/syscall_wrappers.h"
#define ABSTRACT_UNIX_SOCK_LEN sizeof(((struct sockaddr_un *)0)->sun_path)
static int read_pid(int fd)
{
ssize_t ret;
pid_t n = -1;
again:
ret = read(fd, &n, sizeof(n));
if (ret < 0 && errno == EINTR)
goto again;
if (ret < 0)
return -1;
return n;
}
*/
import "C"
import (
"fmt"
"os"
"golang.org/x/sys/unix"
_ "github.com/lxc/incus/v6/shared/cgo" // Used by cgo
)
const ABSTRACT_UNIX_SOCK_LEN int = C.ABSTRACT_UNIX_SOCK_LEN
func ReadPid(r *os.File) int {
return int(C.read_pid(C.int(r.Fd())))
}
func unCloexec(fd int) error {
var err error = nil
flags, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(fd), unix.F_GETFD, 0)
if errno != 0 {
err = errno
return err
}
flags &^= unix.FD_CLOEXEC
_, _, errno = unix.Syscall(unix.SYS_FCNTL, uintptr(fd), unix.F_SETFD, flags)
if errno != 0 {
err = errno
}
return err
}
func PidFdOpen(Pid int, Flags uint32) (*os.File, error) {
pidFd, errno := C.incus_pidfd_open(C.int(Pid), C.uint32_t(Flags))
if errno != nil {
return nil, errno
}
errno = unCloexec(int(pidFd))
if errno != nil {
return nil, errno
}
return os.NewFile(uintptr(pidFd), fmt.Sprintf("%d", Pid)), nil
}
func PidfdSendSignal(Pidfd int, Signal int, Flags uint32) error {
ret, errno := C.incus_pidfd_send_signal(C.int(Pidfd), C.int(Signal), nil, C.uint32_t(Flags))
if ret != 0 {
return errno
}
return nil
}
const (
// CLOSE_RANGE_UNSHARE matches CLOSE_RANGE_UNSHARE flag.
CLOSE_RANGE_UNSHARE uint32 = C.CLOSE_RANGE_UNSHARE
// CLOSE_RANGE_CLOEXEC matches CLOSE_RANGE_CLOEXEC flag.
CLOSE_RANGE_CLOEXEC uint32 = C.CLOSE_RANGE_CLOEXEC
)
func CloseRange(FirstFd uint32, LastFd uint32, Flags uint32) error {
ret, errno := C.incus_close_range(C.uint32_t(FirstFd), C.uint32_t(LastFd), C.uint32_t(Flags))
if ret != 0 {
if errno != unix.ENOSYS && errno != unix.EINVAL {
return errno
}
}
return nil
}
|