首先我们先要创建一个用于通信的结构unix_proto_data ,并初始化某些字段
static int unix_proto_create(struct socket *sock, int protocol)
{
struct unix_proto_data *upd;
/*
* No funny SOCK_RAW stuff
*/
if (protocol != 0)
{
return(-EINVAL);
}
// 分配一个unix_proto_data结构体
if (!(upd = unix_data_alloc()))
{
printk("UNIX: create: can't allocate buffer
");
return(-ENOMEM);
}
// 给unix_proto_data的buf字段分配一个页大小的内存
if (!(upd->buf = (char*) get_free_page(GFP_USER)))
{
printk("UNIX: create: can't get page!
");
unix_data_deref(upd);
return(-ENOMEM);
}
upd->protocol = protocol;
// 关联unix_proto_data对应的socket结构
upd->socket = sock;
// socket的data字段指向unix_proto_data结构
UN_DATA(sock) = upd;
// 标记unix_proto_data已被使用
upd->refcnt = 1; /* Now it's complete - bgm */
return(0);
}
接着给这个结构绑定"地址信息",一个文件路径。bind函数主要是根据传进来的路径创建一个文件,如果已经存在则报错。否则新建成功后把inode节点,路径名等信息存在unix_proto_data 结构
// 把sockaddr的内容存在unix_proto_data中,并创建一个文件
static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
int sockaddr_len)
{
char fname[UNIX_PATH_MAX + 1];
struct unix_proto_data *upd = UN_DATA(sock);
unsigned long old_fs;
int i;
if (sockaddr_len <= UN_PATH_OFFSET ||
sockaddr_len > sizeof(struct sockaddr_un))
{
return(-EINVAL);
}
if (upd->sockaddr_len || upd->inode)
{
/*printk("UNIX: bind: already bound!
");*/
return(-EINVAL);
}
// sockaddr_un兼容sockaddr结构
memcpy(&upd->sockaddr_un, umyaddr, sockaddr_len);
/*
UN_PATH_OFFSET为sun_path在sockaddr_un结构中的偏移,
sockaddr_len-UN_PATH_OFFSET等于sun_path的最后一个字符+1的位置
*/
upd->sockaddr_un.sun_path[sockaddr_len-UN_PATH_OFFSET] = '