Golang 系统调用Syscall

Go语言系统调用详解
本文深入探讨了Go语言中的系统调用实现细节,特别是Syscall与RawSyscall的区别及应用场景,并通过实例展示了如何利用这些函数来创建socket并进行ioctl系统调用。

最近在研究go语言,发现go语言系统调用源码只有调用函数的定义,没有指导文档,网上也没有相关文档的说明,自己稍微研究了一下,不对的地方欢迎指教
go源码中关于系统调用的定义如下:

func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)

其中Syscall和RawSyscall区别在于Syscall开始和结束,分别调用了 runtime 中的进入系统调用和退出系统调用的函数,说明Syscall函数受调度器控制,不会造成系统堵塞,而RawSyscall函数没有调用runtime,因此可能会造成堵塞,一般我们使用Syscall就可以了,RawSyscall最好用在不会堵塞的情况下。

func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)

Syscall 的定义位于 src/syscall/asm_linux_amd64.s, 是用汇编写成的,封装了对linux底层的调用。接收4个参数,其中trap为中断信号,a1,a2,a3为底层调用函数对应的参数

举例说明:Go调用底层ioctl函数

trap中断类型传入syscall.SYS_IOCTL,SYS_IOCTL中断号表示调用linux底层ioctl函数
Syscall函数中剩下三个参数a1,a2,a3分别对应ioctl的三个参数。可以man命令查看linux ioctl函数参数,如下

int ioctl(int d, int request, ...);

第一个参数d指定一个由open/socket创建的文件描述符,即socket套接字
第二个参数request指定操作的类型,即对该文件描述符执行何种操作,设备相关的请求的代码
第三个参数为一块内存区域,通常依赖于request指定的操作类型

具体过程如下:
1 通过socket创建套接字
2 初始化struct ifconf与/或struct ifreq结构
3 调用ioctl函数,执行相应类型的SIO操作
4 获取返回至truct ifconf与/或struct ifreq结构中的相关信息

调用底层socket函数创建socket套接字,linux下用man命令查看socket函数用法

int socket(int domain, int type, int protocol);

其中domain为协议类型,type为套接字类型,protocol指定某个协议类型常值
domain的值有:

AF_INET IPv4协议
AF_INET6 Ipv6协议
AF_ROUTE 路由套接字
...

type的值有:

SOCK_STREAM 字节流套接字
SOCK_DGRAM 数据报套接字
SOCK_RAW 原始套接字
...

protocol的值有:

IPPROTO_IP IP传输协议
IPPROTO_TCP TCP传输协议
IPPROTO_UDP UDP传输协议
...

因此linux下调用socket生成套接字写法:

fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

综上,转换成go语言中系统调用写法

fd, _, err := syscall.RawSyscall(syscall.SYS_SOCKET, syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_IP)

此时即生成了的socket套接字fd
我们传给int ioctl(int d, int request, …);函数作为第一个参数,第二个参数request操作的类型我们传入SIOCETHTOOL,获取ethtool信息
SIOCETHTOOL 在源码中宏定义为

#define SIOCETHTOOL     0x8946

第三个参数为struct ifreq结构内存地址
Struct ifreq结构如下:

Struct ifreq{
Char ifr_name[IFNAMSIZ];
Union{
    Struct  sockaddr  ifru_addr;
    Struct  sockaddr  ifru_dstaddr;
    Struct  sockaddr  ifru_broadaddr;
    Struct  sockaddr  ifru_netmask;
    Struct  sockaddr  ifru_hwaddr;
    Short  ifru_flags;
    Int     ifru_metric;
    Caddr_t ifru_data;
}ifr_ifru;
};
#define ifr_addr        ifr_ifru.ifru_addr
#define ifr_broadaddr   ifr_ifru.ifru_broadadd
#define ifr_hwaddr      ifr_ifru_hwaddr

综上,linux调用ioctl函数如下:

fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
ioctl(fd, SIOCETHTOOL, &ifreq);

go语言:

fd, _, err := syscall.RawSyscall(syscall.SYS_SOCKET, syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_IP)
if err != 0 {
        return syscall.Errno(err)
    }

_, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifreq)))
if ep != 0 {
        return syscall.Errno(ep)
    }
在Shubham Bhatt的搜索结果中增强了自定义设置的字段搜索和工具提示。感谢Sameer N Miraj。 通过使用级快速查找,您可以缩短代码几次单击的时间。 另外,您可以搜索代码的任何字符串使用此扩展名,您可以搜索您的salesforce实例的代码组件:1)顶点类2)Apex触发器3)visualforce页面4)Visualforce组件5)自定义设置及其字段搜索6)用户搜索按名称7)按配置文件名称搜索配置文件8)权限集9)队列10)自定义标签除上述内容外,您还可以使用此扩展名从左侧的级快速查找部分跳转到类/页面/触发器。 在悬停时,需要更多信息,我们提供了工具提示。 在firefox上可以找到类似的插件,可以在这里下载:https://addons.mozilla.org/en-US/firefox/addon/salesforce-quick-search/使用方法:以下两个部分都添加到了设置页面,因此这仅对开发员和管理员有用,此工具对Salesforce用户没有任何意义。 1)“级快速查找”部分:在所有设置页面的侧面导航栏中添加了此部分。 选择要转到的代码组件,然后开始输入代码名称,将弹出一个自动完成建议,然后选择要转到的代码。 2)开发员实用工具:2.1)仅在force.com主页中添加了此组件。 假设您想知道自己在代码中将配置文件名称硬编码的位置,例如if(profile.name =='sys Admin'){//您正在做某事}。 现在要找到答案,您必须单独浏览所有代码,或者在eclipse中创建一个force.com项目,然后在其中进行搜索。 我们无法直接在Salesforce中做到这一点。 此字符串搜索将帮助您做到这一点。 您必须检查要在其中搜索代码的代码组件,在输入文本字段中输入字符串,然后按Enter。 您将看到一个使用该字符串的代码组件列表。 2.2)代码覆盖率摘录:您可以在组织中查看和下载代码覆盖率。 1.1.1版更新将快速搜索范围扩展到电子邮件模板,验证规则,工作流规则,添加的自定义对象版本检查。 Update 1.2更新了UI,使其与Lightning Update 1.3更加同步,增加了Code Coverage提取部分,允许用户查看和下载Code Coverage。 更新1.3.3:更新了cookie问题。 注意:1)Salesforce的REST API用于完成上述功能。更新1.3.5 1)添加了对删除所有调试日志的支持2)在traceflag上添加了一个按钮以更新startDate /到期日期。 更新2.0.0 1)添加了对工具提示的支持2)添加了自定义设置及其字段搜索Update 2.1 1)修复了工具查询的自定义设置限制的错误Update 2.2 1)添加了用户和配置文件搜索Update 2.3 1)修复了该错误工具查询更新2.3的自定义设置限制1)添加了对权限集,队列和自定义标签的搜索 支持语言:English
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值