/* * Perform the socket system call. we locate the appropriate * family, then create a fresh socket. */ static int sock_socket(int family, int type, int protocol) { int i, fd; struct socket *sock; struct proto_ops *ops; /* Locate the correct protocol family. */ for (i = 0; i < NPROTO; ++i) //查找对应的协议族 { if (pops[i] == NULL) continue; if (pops[i]->family == family) break; } if (i == NPROTO) //查找未果,返回错误 { return -EINVAL; } ops = pops[i];//指针指向该协议族的原型操作函数集 /* * Check that this is a type that we know how to manipulate and * the protocol makes sense here. The family can still reject the * protocol later. */ if ((type != SOCK_STREAM && type != SOCK_DGRAM && type != SOCK_SEQPACKET && type != SOCK_RAW && type != SOCK_PACKET) || protocol < 0) return(-EINVAL); /* * Allocate the socket and allow the family to set things up. if * the protocol is 0, the family is instructed to select an appropriate * default. */ if (!(sock = sock_alloc())) //获取一个socket,已经完成了socket部分初始化设置 { printk("NET: sock_socket: no more sockets\n"); return(-ENOSR); /* Was: EAGAIN, but we are out of system resources! */ } sock->type = type; sock->ops = ops; if ((i = sock->ops->create(sock, protocol)) < 0) //调用INET层函数,inet_create()函数,创建inet层的socket,即sock结构 { sock_release(sock); return(i); } if ((fd = get_fd(SOCK_INODE(sock))) < 0) //根据sock结构中的inode,分配文件描述符 { sock_release(sock); return(-EINVAL); } return(fd); } |