int socket( int family, int type, int,protocol)

[net/socket.c]

SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
	int retval;
	struct socket *sock;
	int flags;

	flags = type & ~SOCK_TYPE_MASK;
	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
		return -EINVAL;
	type &= SOCK_TYPE_MASK;

	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;

	/* 分配一个socket
	 * 同时分配了一个inode
	 */
	retval = __sock_create(current->nsproxy->net_ns, family, type, protocol, &sock, 0);
SOCK_TYPE_MASK值为0xf;SOCK_CLOEXEC表示当fork子进程后,在子进程中调用exec时会自动把从父进程继承过来的socket句柄关闭;SOCK_NONBLOCK表示创建的文件句柄是非阻塞的。flags的值是取type的高位,只充许设置刚提到的两个值。然后将type设置为它的低4位。当flags设置了SOCK_NONBLOCK,将其调整为O_NONBLOCK。
然后就是分配socket,第一个参数为当前进程的网络名字空间:
[socket->__sock_create]
int __sock_create(struct net *net, int family, int type, int protocol, struct socket **res, int kern)
{
	struct socket *sock;
	sock = sock_alloc();
先对family和type的范围进行了检查,然后就分配socket:
[socket->__sock_create->sock_alloc]
static struct socket *sock_alloc(void)
{
	struct inode *inode;

	/* 从sockfs创建一个inode
	  * 实际的分配工作由sock_alloc_inode(通过sockfs_ops->alloc_inode调用)完成
	  */
	 inode = new_inode_pseudo(sock_mnt->mnt_sb);
[socket->__sock_create->sock_alloc->new_inode_pseudo]
struct inode *new_inode_pseudo(struct super_block *sb)
{
	struct inode *inode = alloc_inode(sb);

	if (inode) {
		spin_lock(&inode->i_lock);
		inode->i_state = 0;
		spin_unlock(&inode->i_lock);
		INIT_LIST_HEAD(&inode->i_sb_list);
	}
	return inode;
}
aloc_inode分配了一个inode-socket对,返回当中的inode
[socket->__sock_create->sock_alloc]
	/* 通过inode得到socket
	 * 上面通过sock_alloc_inode得到的是一个socket_alloc结构 
	 */
	sock = SOCKET_I(inode);

	kmemcheck_annotate_bitfield(sock, type);
	inode->i_ino = get_next_ino();
	inode->i_mode = S_IFSOCK | S_IRWXUGO;
	inode->i_uid = current_fsuid(); 	// UID for VFS ops 
	inode->i_gid = current_fsgid(); 	// GID for VFS ops 
	inode->i_op = &sockfs_inode_ops;

	/*sockets_in_use为全局变量,现在socket的数量加1
	 */
	this_cpu_add(sockets_in_use, 1);
	return sock;
}
设置inode的节点号;是一个socket文件,所有人可读写,可执行;设置用户ID,组ID;设置对inode的操作为sockfs_inode_ops。
[socket->__sock_create]
	sock->type = type;

#ifdef CONFIG_MODULES
	/* Attempt to load a protocol module if the find failed.
	 *
	 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
	 * requested real, full-featured networking support upon configuration.
	 * Otherwise module support will break!
	 */
	if (rcu_access_pointer(net_families[family]) == NULL)
		request_module("net-pf-%d", family);
#endif	
设置sock的类型,如果net_families数组中下标为family的值为空,加载相应的模块。
static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
是一个数组,大小为41,每种支持socket的family都注册自己的net_proto_family结构指针到此数组中。后面以IP为例,它的family为PF_INET:
static const struct net_proto_family inet_family_ops = {
	.fam
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值