android_get_control_socket 获取 UNIX 域套接字 FD
Netd 中的 “netd” 套接字
SocketListener::startListener 在启动监听的过程中需要查询到套接字,调用了 android_get_control_socket,传入了参数 “netd”,其查询细节如下面讲解分析。
startListener 的调用发生在 main.cpp 中 main 函数里面的 CommandListener 的启动:
/** Now that we're up, we can respond to commands. Starting the listener also tells* NetworkManagementService that we are up and that our binder interface is ready.*/if (cl.startListener()) {ALOGE("Unable to start CommandListener (%s)", strerror(errno));exit(1);}
而其域套接字何时创建的呢?
猜测是在 service 创建的时候,后面在分析
Android get control socket
/hardware/ril/libril/ril.cpp下有如下代码:
s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
if (s_fdListen < 0) {LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");exit(-1);
}if (listen(s_fdListen, 4)) {exit(1);
}
s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
这个android_get_control_socket函数有什么作用呢? android_get_control_socket函数定义在/system/core/include/cutils/sockets.h:
#define ANDROID_SOCKET_ENV_PREFIX "ANDROID_SOCKET_"
#define ANDROID_SOCKET_DIR "/dev/socket"#ifdef __cplusplus
extern "C" {
#endif/** android_get_control_socket - simple helper function to get the file* descriptor of our init-managed Unix domain socket. `name' is the name of the* socket, as given in init.rc. Returns -1 on error.** This is inline and not in libcutils proper because we want to use this in* third-party daemons with minimal modification.*/
static inline int android_get_control_socket(const char *name)
{char key[64] = ANDROID_SOCKET_ENV_PREFIX;const char *val;int fd;/* build our environment variable, counting cycles like a wolf ... */
#if HAVE_STRLCPYstrlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,name,sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
#else /* for the host, which may lack the almightly strncpy ... */strncpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,name,sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));key[sizeof(key)-1] = '\0';
#endifval = getenv(key); // socket名字和对应的socket文件的文件描述符以键值对的形式存储在环境变量中, if (!val)return -1;errno = 0;fd = strtol(val, NULL, 10);if (errno)return -1;return fd;
}
init.rc /system/core/init/readme.txt
/system/core/init/util.c
/** create_socket - creates a Unix domain socket in ANDROID_SOCKET_DIR* ("/dev/socket") as dictated in init.rc. This socket is inherited by the* daemon. We communicate the file descriptor's value via the environment* variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo").*/
int create_socket(const char *name, int type, mode_t perm, uid_t uid, gid_t gid)
{struct sockaddr_un addr;int fd, ret;fd = socket(PF_UNIX, type, 0);if (fd < 0) {ERROR("Failed to open socket '%s': %s\n", name, strerror(errno));return -1;}memset(&addr, 0 , sizeof(addr));addr.sun_family = AF_UNIX;snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s",name);ret = unlink(addr.sun_path);if (ret != 0 && errno != ENOENT) {ERROR("Failed to unlink old socket '%s': %s\n", name, strerror(errno));goto out_close;}ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr));if (ret) {ERROR("Failed to bind socket '%s': %s\n", name, strerror(errno));goto out_unlink;}chown(addr.sun_path, uid, gid);chmod(addr.sun_path, perm);INFO("Created socket '%s' with mode '%o', user '%d', group '%d'\n",addr.sun_path, perm, uid, gid);return fd;out_unlink:unlink(addr.sun_path);
out_close:close(fd);return -1;
}
/system/core/init/init.c
static void publish_socket(const char *name, int fd)
{char key[64] = ANDROID_SOCKET_ENV_PREFIX;char val[64];strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,name,sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));snprintf(val, sizeof(val), "%d", fd);add_environment(key, val); //添加到环境变量中/* make sure we don't close-on-exec */fcntl(fd, F_SETFD, 0);
}
参考:http://calvinlee.github.io/blog/2012/04/26/android-init-socket/
android_get_control_socket 获取 UNIX 域套接字 FD相关推荐
- 学习Unix域套接字总结
开门见山,哲学三问!Unix域套接字是什么?为什么会存在Unix域套接字?如何用Unix域套接字? Unix域套接字是什么,为什么会有Unix用于套接字? Linux系统中不同进程进行通信的手段很多, ...
- 域服务器广播消息,广播,组播和UNIX域套接字
1.广播 1.特点 一对多 仅能使用UDP 2.概念 发送方只有一个接收方则称单播 如果同时发给局域网中的所有主机,成为广播 只有用户数据包(使用UDP协议)套接字才能广播 广播地址 1.以192.1 ...
- linux 套接字 文件 路径,linux – 识别unix域套接字连接的另一端
我正在试图找出一个持有unix域套接字另一端的进程.在某些strace输出中,我已经确定了一个给定的文件描述符,这个文件描述符涉及到我目前正在调试的问题,我想知道哪一个进程在另一端.由于存在与该套接字 ...
- unix 域套接字实现进程间通信
目录 1.认识域套接字 2.unix域套接字相关API及地址结构介绍 (1) 创建unix域套接字 (2) 填充地址结构 sockaddr_un 3.unix域套接字实现进程间通信( ...
- 【socket】 unix域套接字(socketpair )通信|socketpair和pipe的区别|进程间通信-Unix domain socket
目录 unix域套接字(socketpair )通信|socketpair和pipe的区别 socketpair机制 描述 原理 socketpair和pipe的区别 进程间通信-Unix domai ...
- UNIX域套接字编程和socketpair 函数
一.UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络soc ...
- Beats:将 Unix 域套接字中的数据索引到 Elastic Stack
这篇博文将解释什么是 UNIX 域套接字,以及如何将发送到 UNIX 域套接字的索引编入 Elastic Stack - 以及为此存在哪些不同的用例. UNIX 域套接字 - 简短的历史 如果你想让进 ...
- 【技术应用】java基于UNIX域套接字(unix domain socket)连接mysql数据库
前言 Unix domain socket 又叫 IPC(inter-process communication 进程间通信)socket,用于实现同一主机上的进程间通信. socket 原本是为网络 ...
- 网络编程_5(超时检测+UNIX域套接字+抓包工具+包头分析)
一二章请点击:网络编程_1(网络基础+跨主机传输) 三四章请点击:网络编程_2(网络属性+UDP(UDP模型+广播组播)) 第五章请点击:网络编程_3(TCP) 第六章请点击:网络编程_4(IO模型) ...
- 经由unix域套接字传送文件描述符
sendmsg 和recvmsg 该两个函数都指向msghdr指针:该结构包含了所有有关收发内容的信息 两个元素处理控制信息的传送与接收
最新文章
- [C++再学习系列] 前置++与后置++
- Leetcode: Binary Tree Maximum Path Sum
- 2017/Province_Java_B/2、纸牌三角形
- 您不知道Bash:Bash阵列简介
- 搜索,贪心,DP,三者的区别和联系
- html 星空效果,html5 canvas炫酷旋转银河系星空背景特效
- 【基础处理】基于matlab GUI语音信号播放【含Matlab源码 946期】
- 软件工程--可行性研究过程详解
- oracle获取两个月前的时间
- 计算机卡住了怎样恢复,电脑频繁假死怎么办 电脑死机数据恢复
- 计算机电源德国产,德国原装崇拜者来一发?BeQuiet! Straight Power 11全模电源
- left join 多表关联查询
- 计算机课里的余数是什么,余数
- WebGL实践篇(九)—— 光照:点光源
- 浏览器打开html文件特别慢,打开浏览器速度缓慢的原因及解决方法
- Win10笔记本触摸板在按键时或刚按完键后无法正常使用的问题
- python时间日历(超详细)
- matlab网页运行
- 几个FFmpeg 视频参数 fps、tbr、tbn、tbc
- 梅特卡夫法则(Metcalfe's law)