📄 9lstn.c
字号:
#include "stdinc.h"#include "9.h"typedef struct Lstn Lstn;typedef struct Lstn { int afd; int flags; char* address; char dir[NETPATHLEN]; Lstn* next; Lstn* prev;} Lstn;static struct { VtLock* lock; Lstn* head; Lstn* tail;} lbox;static voidlstnFree(Lstn* lstn){ vtLock(lbox.lock); if(lstn->prev != nil) lstn->prev->next = lstn->next; else lbox.head = lstn->next; if(lstn->next != nil) lstn->next->prev = lstn->prev; else lbox.tail = lstn->prev; vtUnlock(lbox.lock); if(lstn->afd != -1) close(lstn->afd); vtMemFree(lstn->address); vtMemFree(lstn);}static voidlstnListen(void* a){ Lstn *lstn; int dfd, lfd; char newdir[NETPATHLEN]; vtThreadSetName("listen"); lstn = a; for(;;){ if((lfd = listen(lstn->dir, newdir)) < 0){ fprint(2, "listen: listen '%s': %r", lstn->dir); break; } if((dfd = accept(lfd, newdir)) >= 0) conAlloc(dfd, newdir, lstn->flags); else fprint(2, "listen: accept %s: %r\n", newdir); close(lfd); } lstnFree(lstn);}static Lstn*lstnAlloc(char* address, int flags){ int afd; Lstn *lstn; char dir[NETPATHLEN]; vtLock(lbox.lock); for(lstn = lbox.head; lstn != nil; lstn = lstn->next){ if(strcmp(lstn->address, address) != 0) continue; vtSetError("listen: already serving '%s'", address); vtUnlock(lbox.lock); return nil; } if((afd = announce(address, dir)) < 0){ vtSetError("listen: announce '%s': %r", address); vtUnlock(lbox.lock); return nil; } lstn = vtMemAllocZ(sizeof(Lstn)); lstn->afd = afd; lstn->address = vtStrDup(address); lstn->flags = flags; memmove(lstn->dir, dir, NETPATHLEN); if(lbox.tail != nil){ lstn->prev = lbox.tail; lbox.tail->next = lstn; } else{ lbox.head = lstn; lstn->prev = nil; } lbox.tail = lstn; vtUnlock(lbox.lock); if(vtThread(lstnListen, lstn) < 0){ vtSetError("listen: thread '%s': %r", lstn->address); lstnFree(lstn); return nil; } return lstn;}static intcmdLstn(int argc, char* argv[]){ int dflag, flags; Lstn *lstn; char *usage = "usage: listen [-dIN] [address]"; dflag = 0; flags = 0; ARGBEGIN{ default: return cliError(usage); case 'd': dflag = 1; break; case 'I': flags |= ConIPCheck; break; case 'N': flags |= ConNoneAllow; break; }ARGEND switch(argc){ default: return cliError(usage); case 0: vtRLock(lbox.lock); for(lstn = lbox.head; lstn != nil; lstn = lstn->next) consPrint("\t%s\t%s\n", lstn->address, lstn->dir); vtRUnlock(lbox.lock); break; case 1: if(!dflag){ if(lstnAlloc(argv[0], flags) == nil) return 0; break; } vtLock(lbox.lock); for(lstn = lbox.head; lstn != nil; lstn = lstn->next){ if(strcmp(lstn->address, argv[0]) != 0) continue; if(lstn->afd != -1){ close(lstn->afd); lstn->afd = -1; } break; } vtUnlock(lbox.lock); if(lstn == nil){ vtSetError("listen: '%s' not found", argv[0]); return 0; } break; } return 1;}intlstnInit(void){ lbox.lock = vtLockAlloc(); cliAddCmd("listen", cmdLstn); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -