📄 netdevmedium.c
字号:
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "../port/error.h"#include "ip.h"static void netdevbind(Ipifc *ifc, int argc, char **argv);static void netdevunbind(Ipifc *ifc);static void netdevbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);static void netdevread(void *a);typedef struct Netdevrock Netdevrock;struct Netdevrock{ Fs *f; /* file system we belong to */ Proc *readp; /* reading process */ Chan *mchan; /* Data channel */};Medium netdevmedium ={.name= "netdev",.hsize= 0,.mintu= 0,.maxtu= 64000,.maclen= 0,.bind= netdevbind,.unbind= netdevunbind,.bwrite= netdevbwrite,.unbindonclose= 0,};/* * called to bind an IP ifc to a generic network device * called with ifc qlock'd */static voidnetdevbind(Ipifc *ifc, int argc, char **argv){ Chan *mchan; Netdevrock *er; if(argc < 2) error(Ebadarg); mchan = namec(argv[2], Aopen, ORDWR, 0); er = smalloc(sizeof(*er)); er->mchan = mchan; er->f = ifc->conv->p->f; ifc->arg = er; kproc("netdevread", netdevread, ifc);}/* * called with ifc wlock'd */static voidnetdevunbind(Ipifc *ifc){ Netdevrock *er = ifc->arg; if(er->readp != nil) postnote(er->readp, 1, "unbind", 0); /* wait for readers to die */ while(er->readp != nil) tsleep(&up->sleep, return0, 0, 300); if(er->mchan != nil) cclose(er->mchan); free(er);}/* * called by ipoput with a single block to write */static voidnetdevbwrite(Ipifc *ifc, Block *bp, int, uchar*){ Netdevrock *er = ifc->arg; if(bp->next) bp = concatblock(bp); if(BLEN(bp) < ifc->mintu) bp = adjustblock(bp, ifc->mintu); devtab[er->mchan->type]->bwrite(er->mchan, bp, 0); ifc->out++;}/* * process to read from the device */static voidnetdevread(void *a){ Ipifc *ifc; Block *bp; Netdevrock *er; char *argv[1]; ifc = a; er = ifc->arg; er->readp = up; /* hide identity under a rock for unbind */ if(waserror()){ er->readp = nil; pexit("hangup", 1); } for(;;){ bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxtu, 0); if(bp == nil){ /* * get here if mchan is a pipe and other side hangs up * clean up this interface & get outZZZ is this a good idea? */ poperror(); er->readp = nil; argv[0] = "unbind"; if(!waserror()) ifc->conv->p->ctl(ifc->conv, argv, 1); pexit("hangup", 1); } if(!canrlock(ifc)){ freeb(bp); continue; } if(waserror()){ runlock(ifc); nexterror(); } ifc->in++; if(ifc->lifc == nil) freeb(bp); else ipiput4(er->f, ifc, bp); runlock(ifc); poperror(); }}voidnetdevmediumlink(void){ addipmedium(&netdevmedium);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -