在 Linux 中,Golang 可以通过 syscall 包来进行系统调用。syscall 包提供了一系列底层系统调用的实现,这些调用允许你直接与操作系统交互。以下是一些使用 syscall 包进行系统调用的示例:
package main
import (
"fmt"
"os"
"syscall"
)
func main() {
// 打开文件
fd, err := syscall.Open("test.txt", syscall.O_RDONLY, 0)
if err != nil {
fmt.Println("Error opening file:", err)
os.Exit(1)
}
defer syscall.Close(fd)
// 读取文件内容
buf := make([]byte, 1024)
n, err := syscall.Read(fd, buf)
if err != nil {
fmt.Println("Error reading file:", err)
os.Exit(1)
}
// 输出文件内容
fmt.Print(string(buf[:n]))
}
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
)
func main() {
// 创建一个子进程
cmd := exec.Command("ls", "-l")
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} // 设置进程组 ID
err := cmd.Start()
if err != nil {
fmt.Println("Error starting command:", err)
os.Exit(1)
}
fmt.Printf("Child process ID: %d\n", cmd.Process.Pid)
// 等待子进程结束
err = cmd.Wait()
if err != nil {
fmt.Println("Error waiting for command:", err)
os.Exit(1)
}
}
package main
import (
"fmt"
"net"
"syscall"
)
func main() {
// 创建一个 TCP 监听器
listener, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("Error creating listener:", err)
os.Exit(1)
}
defer listener.Close()
fmt.Println("Listening on :8080")
for {
// 接受连接
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting connection:", err)
continue
}
// 处理连接
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
// 获取底层文件描述符
file, err := conn.File()
if err != nil {
fmt.Println("Error getting file descriptor:", err)
return
}
defer file.Close()
// 获取文件状态信息
var stat syscall.Stat_t
err = syscall.Fstat(int(file.Fd()), &stat)
if err != nil {
fmt.Println("Error getting file status:", err)
return
}
fmt.Printf("Connected by %s\n", conn.RemoteAddr())
fmt.Printf("PID: %d, UID: %d\n", stat.Uid, stat.Gid)
}
请注意,直接使用 syscall 包可能会导致代码的可移植性降低,因为它依赖于底层操作系统。在许多情况下,使用 Go 标准库中的高级函数(如 os.Open、os.Create 等)是更好的选择,因为它们会自动处理跨平台的差异。只有在需要访问特定于操作系统的功能时,才考虑使用 syscall 包。