------------------ port 篇 -------------
open_port/2这个是由bif实现, 源文件在erl_bif_port.c中, 函数是BIF_RETTYPE open_port_2(BIF_ALIST_2)
其中:
#define BIF_RETTYPE Eterm
#define BIF_ALIST_2 Process* A__p, Eterm A_1, Eterm A_2
此函数调用了同文件中的
static int
open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
函数.
name 对应 open_port/2的第一个参数PortName
setting 对应 open_port/2的第二个参数PortSettings
其中:
PortSettings = [Opt]
Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof
N = 1 | 2 | 4
L = int()
Dir = string()
Env = [{Name, Val}]
Name = string()
Val = string() | false
这些port的设置都由open_port函数Parse the settings注释后面的代码解析. erl_bif_port.c: 475行
第一个参数name的解析由open_port函数Parse the first argument and start the appropriate driver注释后面的代码解析. erl_bif_port.c: 590行
此处解析第一个参数name,并开启正确的driver
PortName = {spawn, Command} | {fd, In, Out}
分两种情况: spawn出来的进程, 使用文件描述符
spawn_driver_entry外部定义, spawn_driver_entry是名为spawn的driver的入口结构体. 它在linux平台上的定义在emulator/sys/unix/sys.c下
struct erl_drv_entry spawn_driver_entry = {
spawn_init,
spawn_start,
stop,
output,
ready_input,
ready_output,
"spawn",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
ERL_DRV_EXTENDED_MARKER,
ERL_DRV_EXTENDED_MAJOR_VERSION,
ERL_DRV_EXTENDED_MINOR_VERSION,
ERL_DRV_FLAG_USE_PORT_LOCKING
};
erl_drv_entry这个结构体的定义的emulator/beam/erl_driver.h. 结构体的成员包括port初始化, 开始,停止, 取/出数据的各种函数指针(因为运行的平台不同,所以用指针来指定策略).
真正干活的是io.c下面的
/*
Opens a driver.
Returns the non-negative port number, if successful.
If there is an error, -1 or -2 or -3 is returned. -2 means that
there is valid error information in 'errno'.
Returning -3 means that an error in the given options was detected.
The driver start function must obey the same conventions.
*/
int
erts_open_driver(ErlDrvEntry* driver, /* Pointer to driver entry. */
Eterm pid, /* Current process. */
char* name, /* Driver name. */
SysDriverOpts* opts, /* Options. */
int *error_number_ptr) /* errno in case -2 is returned */
函数. io.c: 505行
步骤:
1. 获取一个free的port,取得一个port_num. 通过 static int get_free_port(void)函数来检查, 如果port的status属性为ERTS_PORT_S_FREE则这个port是free的
2. 检查同名的driver是否已经存在.如果存在,则用已有的driver,如果不存在则用默认的spawn/fd driver
3. drv_data = (*driver->start)((ErlDrvPort)port_num, name, opts); 初始化一些东西而已,比如driver名称,driver的io队列等
4. 用已有的名为spawn的driver启动driver, drv_data = (*driver->start)((ErlDrvPort)port_num, name, opts); (unix/sys.c)
5. clean up the port.
6. 返回port_num.
附:名为efile的driver,它的struct erl_drv_entry结构体定义在emulator/drivers/comm/efile_drv.c中, 如下:
struct erl_drv_entry efile_driver_entry = {
file_init,
file_start,
file_stop,
file_output,
NULL,
NULL,
"efile",
NULL,
NULL,
file_control,
file_timeout,
file_outputv,
file_async_ready,
file_flush,
NULL,
NULL,
ERL_DRV_EXTENDED_MARKER,
ERL_DRV_EXTENDED_MAJOR_VERSION,
ERL_DRV_EXTENDED_MINOR_VERSION,
ERL_DRV_FLAG_USE_PORT_LOCKING,
NULL
};
分享到:
相关推荐
Bot Framework Emulator是一款由微软开发的强大工具,专门用于测试和调试基于Microsoft Bot Framework构建的聊天机器人。这个工具允许开发者在本地环境与他们的bot进行交互,而无需部署到任何服务器。它支持多种消息...
虚拟串口(Virtual Serial Port, VSP)驱动程序,如"vspd.exe",是一种软件解决方案,用于在没有物理串口的情况下模拟串行通信。它允许应用程序通过虚拟接口进行通信,就如同它们连接到真实的RS-232串行端口一样。在...
- **应用场景**:用于日志调试,特别是针对特定组件的日志。 27. **`-no-audio`** 或 **`-noaudio`** - **功能**:禁用音频支持。 - **应用场景**:当不需要音频功能时。 28. **`-audio<backend>`** - **功能*...
首先在设备上启用开发者选项中的“USB调试”,然后连接到电脑并获取设备的IP地址,运行`adb connect <device-ip>:<port>`即可建立连接。 **adb的安装与配置:** 1. 下载Android SDK Platform Tools,解压后将路径...
adb forward tcp:<localPort> tcp:<remotePort> ``` ##### 从模拟器/设备中拷入或拷出文件 利用`adb pull`和`adb push`命令可以在模拟器或设备与电脑之间传输文件: ``` adb push <localPath> adb pull ...
2. **日志记录**:合理利用Logcat功能,可以帮助追踪代码执行流程,尤其是在多线程环境下更容易发现问题。 3. **版本控制**:使用版本控制系统如Git管理源代码,有助于团队协作以及版本回溯。 4. **代码审查**:定期...
Android调试桥(ADB)是Android开发中不可或缺的工具,它提供了多种功能,包括管理设备或模拟器的状态、执行shell命令、端口转发、文件传输以及日志记录等。ADB由客户端、服务器和设备端守护进程三部分组成,为开发者...
adb forward tcp:<hostPort> tcp: ``` 例如,将主机的8080端口转发到设备的8080端口: ```bash adb forward tcp:8080 tcp:8080 ``` #### 从模拟器/设备中拷入或拷出文件 使用`pull`和`push`命令可以实现文件的...
adb forward tcp:<localPort> tcp:<remotePort> ``` 例如,将本地端口 8080 转发到设备的 8080 端口: ```sh adb forward tcp:8080 tcp:8080 ``` #### 从模拟器/设备中拷入或拷出文件 通过 `adb pull` 和 `adb push...
3. 发布端口:`adb forward tcp:<host_port> tcp:<device_port>`,用于主机与设备间的通信。 4. 文件复制:`adb push`和`adb pull`分别用于上传和下载文件。 5. 查看设备列表:`adb devices`,显示所有连接的设备和...
序列号是ADB用来唯一标识每个实例的字符串,格式通常是`emulator-<consolePort>`或实际设备的序列号。连接状态有三种: - `offline`:表示该实例未连接到ADB或无法响应。 - `device`:表示该实例与ADB服务器建立了...
- **开发调试**:开发者可以通过ADB在设备上安装调试版本的应用,并使用日志功能来追踪应用的运行状态。 - **自动化测试**:结合自动化测试框架(如Appium),ADB可以实现对设备的操作控制,方便进行UI自动化测试。 ...
adb forward tcp:<host_port> tcp:<device_port> ``` 例如,将主机的8080端口映射到设备的8080端口: ```bash adb forward tcp:8080 tcp:8080 ``` #### 从模拟器/设备中拷入或拷出文件 ADB提供了强大的文件传输...
11. SerialPort/SocketListener/SSHCommand/SSHDownloader/Syslog/TcpPort:监视器能够监听串行端口和套接字,运行SSH命令、通过SSH进行文件传输,以及通过Syslog记录日志信息。 12. VmwareControl:控制VMware...
- `adblogcat`:打印日志到屏幕,可以帮助开发者调试应用。 - `adb bugreport`:打印`dumpsys`、`dumpstate`和`logcat`数据到屏幕,对于系统级的问题非常有用。 - `adb jdwp`:查看指定设备的JDWP(Java调试线程协议...
- 常见的虚拟串口工具包括:Com0Com(开源)、VSPM(Virtual Serial Port Driver)、Serial Port Splitter、ComPort Emulator等。 - 安装和使用虚拟串口工具一般步骤是:安装软件、创建虚拟串口对、设置串口参数、...