int sys_tunopen(struct lwp *l, const struct sys_tunopen_args *uap, register_t *retval) { int error; struct file* fp; int indx; error = ChkSpaceBstrR(SCARG(uap, path), 0); if ( error < E_OK ) { return EFAULT; } if ((error = fd_allocfile(&fp, &indx)) != 0) return (error); if ((error = tkn_tun_open(SCARG(uap, path), SCARG(uap, oflag), fp)) != 0) { fd_abort(l->l_proc, fp, indx); if ((error == EDUPFD || error == EMOVEFD) && l->l_dupfd >= 0 && /* XXX from fdopen */ (error = fd_dupopen(l->l_dupfd, &indx, SCARG(uap, oflag), error)) == 0) { *retval = indx; return (0); } if (error == ERESTART) error = EINTR; return (error); } return ENOTSUP; }
/* * Device registration */ RAW_U32 _tk_def_dev( CONST UB *devnm, CONST T_DDEV *ddev, void *caller_gp ) { DevCB *devcb; INT len, evttyp; ER ercd; len = ChkSpaceBstrR(devnm, 0); if ( len <= 0 || len > MaxRegDev ) { RAW_ASSERT(0); } /* Search whether 'devnm' device is registered */ devcb = searchDevCB(devnm); if ( devcb == 0 ) { if ( ddev == 0 ) { ercd = E_NOEXS; goto err_ret2; } /* Get 'devcb' for new registration because it is not registered */ devcb = newDevCB(devnm); if ( devcb == NULL ) { ercd = E_LIMIT; goto err_ret2; } } if ( ddev != NULL ) { /* Set/update device registration information */ devcb->ddev = *ddev; evttyp = TSEVT_DEVICE_REGIST; } else { if ( !isQueEmpty(&devcb->openq) ) { /* In use (open) */ ercd = E_BUSY; goto err_ret2; } /* Device unregistration */ delDevCB(devcb); evttyp = TSEVT_DEVICE_DELETE; } return DID(devcb); }
int sys_ifattach(struct lwp *l, const struct sys_ifattach_args *uap, register_t *retval) { const char* devname = SCARG(uap, devnm); int dev_num; int error = 0; int ret; T_RDEV rdev; struct tkn_nif_info *nif; (void)l; ret = ChkSpaceBstrR(devname, 0); if ( ret < 0 ) { return EFAULT; } for (nif = tkn_nif_mng.nifm_list; nif; nif = nif->nif_next) { if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) { break; } } if( nif != 0 ) { /* Already registered. */ error = EBUSY; goto error; } ret = tk_ref_dev((UB*)devname, &rdev); if (ret < 0) { error = EINVAL; goto error; } dev_num = tkn_nif_mng.nifm_nifmax; strncpy((char*)tkn_dev_info[dev_num].nif_dev, devname, TKN_NIFNAMESIZE); ret = tkn_nif_attach(&tkn_dev_info[dev_num]); if (ret != 0) { error = EINVAL; } error: *retval = 0; return error; }
int sys_ifdetach(struct lwp *l, const struct sys_ifdetach_args *uap, register_t *retval) { const char* devname = SCARG(uap, devnm); int error = 0; int ret; T_RDEV rdev; struct tkn_nif_info *nif; (void)l; ret = ChkSpaceBstrR(devname, 0); if ( ret < 0 ) { return EFAULT; } ret = tk_ref_dev((UB*)devname, &rdev); if (ret < 0) { error = EINVAL; goto error; } for (nif = tkn_nif_mng.nifm_list; nif != NULL; nif = nif->nif_next) { if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) { break; } } if( nif == 0 ) { /* Not registered. */ error = ENOENT; goto error; } ret = tkn_nif_detach(nif); if (ret != 0) { error = EINVAL; } error: *retval = 0; return error; }
int sys_ifnametoindex(struct lwp *l, const struct sys_ifnametoindex_args *uap, register_t *retval) { int error; unsigned int ifindex; (void)l; error = ChkSpaceBstrR(SCARG(uap, ifname), 0); if ( error < 0 ) { return EFAULT; } error = if_nametoindex(SCARG(uap,ifname), &ifindex); if (error == 0) { *retval = ifindex; } return error; }
/* * Device open */ EXPORT ID _tk_opn_dev( CONST UB *devnm, UINT omode ) { UB pdevnm[L_DEVNM + 1]; INT unitno; ResCB *rescb; DevCB *devcb; OpnCB *opncb; WaitQ waiq; ER ercd; ercd = ChkSpaceBstrR(devnm, 0); if ( ercd < E_OK ) { goto err_ret1; } unitno = phydevnm(pdevnm, devnm); /* Get resource management information */ rescb = GetResCB(DEVICE_SVC, TSK_SELF); if ( rescb == NULL ) { ercd = E_CTX; goto err_ret1; } LockDM(); /* Search device to open */ devcb = searchDevCB(pdevnm); if ( devcb == NULL || unitno > devcb->ddev.nsub ) { ercd = E_NOEXS; goto err_ret2; } /* Check open mode */ ercd = chkopenmode(devcb, unitno, omode); if ( ercd < E_OK ) { goto err_ret2; } /* Get open management block */ opncb = newOpnCB(devcb, unitno, omode, rescb); if ( opncb == NULL ) { ercd = E_LIMIT; goto err_ret2; } /* Multiple tasks can initiate open/close processing, so ensure processing only by one task at a time. */ if ( enterSyncWait(&devcb->syncq, &waiq) ) { /* Wait for synchronization for concurrent open/close */ UnlockDM(); SyncWaitDM(); LockDM(); } /* Is device driver call required? */ if ( ! ( chkopen(devcb, unitno, opncb) && (devcb->ddev.drvatr & TDA_OPENREQ) == 0 ) ) { /* Device driver call */ UnlockDM(); ercd = call_openfn(devcb, DEVID(devcb, unitno), omode); LockDM(); if ( ercd < E_OK ) { goto err_ret3; } } opncb->resid = tk_get_rid(TSK_SELF); /* Indicate that open processing is completed */ /* Wake up task waiting for synchronization for concurrent open/close */ leaveSyncWait(&devcb->syncq, &waiq); UnlockDM(); return DD(opncb); err_ret3: delOpnCB(opncb); leaveSyncWait(&devcb->syncq, &waiq); err_ret2: UnlockDM(); err_ret1: DEBUG_PRINT(("_tk_opn_dev ercd = %d\n", ercd)); return ercd; }