📄 socket.c
字号:
/* * Roadrunner/pk * Copyright (C) 1989-2002 Cornfed Systems, Inc. * * The Roadrunner/pk operating system is free software; you can * redistribute and/or modify it under the terms of the GNU General * Public License, version 2, as published by the Free Software * Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * More information about the Roadrunner/pk operating system of * which this file is a part is available on the World-Wide Web * at: http://www.cornfed.com. * */#include <errno.h>#include <fs.h>#include <net/ip.h>#include <net/tcp.h>#if _DEBUG#include <stdio.h>#endif#include <stdlib.h>#include <string.h>#include <sys/intr.h>#include <sys/socket.h>struct socket sockettab[SOCKETS];voidsocket_init(){ int s; bzero(sockettab, SOCKETS * sizeof(struct socket)); for (s = 0; s < SOCKETS; s++) sockettab[s].slot = s;}socket_tsocket_alloc(){ int s; for (s = 0; s < SOCKETS; s++) if (sockettab[s].state == SS_FREE) break; if (s == SOCKETS) return NULL; return &(sockettab[s]);}voidsocket_clear(socket_t s){ proc_t proc; buf_t b; disable; /* Restart processes waiting on a connection */ for (;;) { proc = remfirstq(&(s->conn)); if (proc == NULL) break; proc->state = PS_READY; insq(proc, &ready); } /* Empty receive queue */ for (;;) { b = bdeq(&(s->rcvq)); if (b == NULL) break; _bfree(b); } /* Restart waiting receivers */ for (;;) { proc = remfirstq(&(s->rcvr)); if (proc == NULL) break; proc->state = PS_READY; insq(proc, &ready); } /* Empty send queue */ for (;;) { b = bdeq(&(s->sndq)); if (b == NULL) break; _bfree(b); } /* Clear socket table entry */ s->state = SS_FREE; s->pcb = NULL; s->backlog = 0; initq(&(s->conn)); s->src = 0; s->dst = 0; s->sport = 0; s->dport = 0; s->rcv_cc = 0; binitq(&(s->rcvq)); initq(&(s->rcvr)); s->snd_cc = 0; binitq(&(s->sndq)); enable;}intsocket_close(socket_t s){ tcb_t tcb; tcb = (tcb_t) s->pcb; if (tcb == NULL) return ENOPCB; switch (tcb->state) { case TCPS_SYN_RECEIVED: case TCPS_ESTABLISHED: tcb->state = TCPS_FIN_WAIT_1; tcb->socket->state = SS_DISCONNECTING; tcp_send_fin(tcb); break; case TCPS_CLOSE_WAIT: tcb->state = TCPS_LAST_ACK; tcp_send_fin(tcb); break; default: break; } return 0;}intsocket(int domain, int type, int protocol){ file_t file; socket_t s; int fileno; if (domain != PF_INET || type != SOCK_STREAM) return EINVAL; if (protocol != IP_PROTOCOL_TCP) return EPROTONOSUPPORT; /* * Allocate a file table entry */ mutex_lock(&filetabmutex); for (fileno = 0; fileno < FILES && filetab[fileno].fs != NULL; fileno++); if (fileno == FILES) {#if _DEBUG kprintf("socket: file table full\n");#endif mutex_unlock(&filetabmutex); return EAGAIN; } file = &(filetab[fileno]); file->fs = (fs_t) & sockettab; mutex_unlock(&filetabmutex); file->type = FT_SOCKET; file->path = NULL; file->refcnt = 1; file->flags = 0; file->filesize = 0; file->pos = 0; file->bufsize = 0; file->buf = NULL; /* * Socket specific elements */ disable; s = socket_alloc(); if (s == NULL) { enable; return EAGAIN; } file->data = s; s->state = SS_INUSE; enable; return fileno;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -