gonzui


Format: Advanced Search

t2ex/t2ex_source/t2ex/network/net/src/netmain/tkn_subr.cbare sourcepermlink (0.03 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T2EX Software Package
    4:  *
    5:  *    Copyright 2012 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2012/12/12.
   10:  *    Modified by T-Engine Forum at 2014/07/14.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: /*
   16:  * This software package is available for use, modification, 
   17:  * and redistribution in accordance with the terms of the attached 
   18:  * T-License 2.x.
   19:  * If you want to redistribute the source code, you need to attach 
   20:  * the T-License 2.x document.
   21:  * There's no obligation to publish the content, and no obligation 
   22:  * to disclose it to the TRON Forum if you have modified the 
   23:  * software package.
   24:  * You can also distribute the modified source code. In this case, 
   25:  * please register the modification to T-Kernel traceability service.
   26:  * People can know the history of modifications by the service, 
   27:  * and can be sure that the version you have inherited some 
   28:  * modification of a particular version or not.
   29:  *
   30:  *    http://trace.tron.org/tk/?lang=en
   31:  *    http://trace.tron.org/tk/?lang=ja
   32:  *
   33:  * As per the provisions of the T-License 2.x, TRON Forum ensures that 
   34:  * the portion of the software that is copyrighted by Ken Sakamura or 
   35:  * the TRON Forum does not infringe the copyrights of a third party.
   36:  * However, it does not make any warranty other than this.
   37:  * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
   38:  * responsible for any consequences or damages caused directly or
   39:  * indirectly by the use of this software package.
   40:  *
   41:  * The source codes in bsd_source.tar.gz in this software package are 
   42:  * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
   43:  * They need to be changed or redistributed according to the 
   44:  * representation of each source header.
   45:  */
   46: 
   47: /*
   48:  *      @(#)tkn_subr.c
   49:  *
   50:  */
   51: 
   52: /* BSD general subroutines */
   53: 
   54: #include <tk/tkernel.h>
   55: 
   56: #include <sys/param.h>
   57: #ifndef T2EX
   58: #include <sys/ucred.h>
   59: #endif
   60: #include <sys/systm.h>
   61: #include <sys/sysctl.h>
   62: #include <sys/malloc.h>
   63: #include <sys/sleepq.h>
   64: #include <sys/filedesc.h>
   65: #include <sys/syscallargs.h>
   66: 
   67: #include <net/if.h>
   68: #include <net/route.h>
   69: #include <netmain/if_tkn.h>
   70: #include "tkn.h"
   71: 
   72: #include <ifaddrs.h>
   73: 
   74: lwp_t lwp0;
   75: proc_t proc;
   76: filedesc_t* filedesc0;
   77: 
   78: static lwp_t *tskid_lwp_table;
   79: static int tskid_lwp_table_maxid;
   80: 
   81: kmutex_t spc_lock;
   82: 
   83: EXPORT ER tkn_lwp_init(void)
   84: {
   85:         int i;
   86:         int error;
   87:         ER ercd;
   88: 
   89:         error = mutex_init(&spc_lock, 0, IPL_NONE);
   90:         if ( error != 0 ) {
   91:                 ercd = ERRNOtoER(error);
   92:                 goto err_ret0;
   93:         }
   94: 
   95:         if (tk_get_cfn("TMaxTskId", &tskid_lwp_table_maxid, 1) < 1) {
   96:                 ercd = E_SYS;
   97:                 goto err_ret1;
   98:         }
   99: 
  100:         tskid_lwp_table = (lwp_t *)malloc(sizeof(lwp_t)*tskid_lwp_table_maxid, M_KMEM, M_NOWAIT | M_ZERO);
  101:         if (tskid_lwp_table == NULL) {
  102:                 ercd = E_NOMEM;
  103:                 goto err_ret1;
  104:         }
  105: 
  106:         for(i = 0; i < tskid_lwp_table_maxid; i++) {
  107:                 tskid_lwp_table[i].l_proc = &proc;
  108:                 tskid_lwp_table[i].l_mutex = &spc_lock;
  109: 
  110:                 callout_init(&tskid_lwp_table[i].l_timeout_ch, 0);
  111:                 callout_setfunc(&tskid_lwp_table[i].l_timeout_ch, sleepq_timeout, &tskid_lwp_table[i]);
  112:         }
  113: 
  114:         return E_OK;
  115: 
  116: err_ret1:
  117:         mutex_destroy(&spc_lock);
  118: err_ret0:
  119:         return ercd;
  120: }
  121: 
  122: EXPORT ER tkn_lwp_setfd(void)
  123: {
  124:         int i;
  125: 
  126:         for(i = 0; i < tskid_lwp_table_maxid; i++) {
  127:                 tskid_lwp_table[i].l_fd = filedesc0;
  128:         }
  129: 
  130:         proc.p_fd = filedesc0;
  131: 
  132:         return E_OK;
  133: }
  134: 
  135: EXPORT ER tkn_lwp_finish(void)
  136: {
  137:         int i;
  138: 
  139:         for(i = 0; i < tskid_lwp_table_maxid; i++) {
  140:                 callout_destroy(&tskid_lwp_table[i].l_timeout_ch);
  141:         }
  142: 
  143:         free(tskid_lwp_table, M_KMEM);
  144: 
  145:         mutex_destroy(&spc_lock);
  146: 
  147:         return E_OK;
  148: }
  149: 
  150: static lwp_t*
  151: get_lwp(ID tskid)
  152: {
  153:         return &tskid_lwp_table[tskid - 1];
  154: }
  155: 
  156: lwp_t*
  157: tkn_curlwp(void)
  158: {
  159:         ID tskid = tk_get_tid();
  160: 
  161:         lwp_t* re = get_lwp(tskid);
  162: 
  163:         return re;
  164: }
  165: 
  166: /*
  167:  * Move data described by a struct uio.
  168:  *   The uiomove function copies up to n bytes between the kernel-space
  169:  *   address pointed to by buf and the addresses described by uio, which may
  170:  *   be in user-space or kernel-space.
  171:  */
  172: int
  173: uiomove(void *buf, size_t n, struct uio *uio)
  174: {
  175: #ifndef T2EX
  176:         struct vmspace *vm = uio->uio_vmspace;
  177: #endif
  178:         struct iovec *iov;
  179:         size_t cnt;
  180:         int error = 0;
  181:         char *cp = buf;
  182: 
  183:         ASSERT_SLEEPABLE();
  184: 
  185: #ifdef DIAGNOSTIC
  186:         if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
  187:                 panic("uiomove: mode");
  188: #endif
  189:         while (n > 0 && uio->uio_resid) {
  190:                 iov = uio->uio_iov;
  191:                 cnt = iov->iov_len;
  192:                 if (cnt == 0) {
  193:                         KASSERT(uio->uio_iovcnt > 0);
  194:                         uio->uio_iov++;
  195:                         uio->uio_iovcnt--;
  196:                         continue;
  197:                 }
  198:                 if (cnt > n)
  199:                         cnt = n;
  200: #ifndef T2EX
  201:                 if (!VMSPACE_IS_KERNEL_P(vm)) {
  202:                         if (curcpu()->ci_schedstate.spc_flags &
  203:                             SPCF_SHOULDYIELD)
  204:                                 preempt();
  205:                 }
  206: 
  207:                 if (uio->uio_rw == UIO_READ) {
  208:                         error = copyout_vmspace(vm, cp, iov->iov_base,
  209:                             cnt);
  210:                 } else {
  211:                         error = copyin_vmspace(vm, iov->iov_base, cp,
  212:                             cnt);
  213:                 }
  214: #else
  215:                 if (uio->uio_rw == UIO_READ) {
  216:                         error = copyout(cp, iov->iov_base, cnt);
  217:                 } else {
  218:                         error = copyin(iov->iov_base, cp, cnt);
  219:                 }
  220: #endif
  221:                 if (error) {
  222:                         break;
  223:                 }
  224:                 iov->iov_base = (char *)iov->iov_base + cnt;
  225:                 iov->iov_len -= cnt;
  226:                 uio->uio_resid -= cnt;
  227:                 uio->uio_offset += cnt;
  228:                 cp += cnt;
  229:                 KDASSERT(cnt <= n);
  230:                 n -= cnt;
  231:         }
  232: 
  233:         return (error);
  234: }
  235: 
  236: int
  237: sys_select_us(struct lwp *l, const struct sys_select_us_args *uap, register_t *retval)
  238: {
  239:         struct timeval tv;
  240:         struct sys_select_args a = {
  241:                 .a = {
  242:                         .nfds = SCARG(uap, nfds),
  243:                         .readfds = SCARG(uap, readfds),
  244:                         .writefds = SCARG(uap, writefds),
  245:                         .exceptfds = SCARG(uap, exceptfds),
  246:                 }
  247:         };
  248: 
  249:         if (SCARG(uap, tmout_u) == TMO_FEVR) {
  250:                 a.a.tv = NULL;
  251:         }
  252:         else if (SCARG(uap, tmout_u) >= 0) {
  253:                 tv.tv_sec = SCARG(uap, tmout_u) / 1000000;
  254:                 tv.tv_usec = SCARG(uap, tmout_u) % 1000000;
  255:                 a.a.tv = &tv;
  256:         }
  257:         else {
  258:                 return EINVAL;
  259:         }
  260: 
  261:         return sys_select(l, &a, retval);
  262: }
  263: 
  264: int
  265: sys_select_ms(struct lwp *l, const struct sys_select_ms_args *uap, register_t *retval)
  266: {
  267:         struct timeval tv;
  268:         struct sys_select_args a = {
  269:                 .a = {
  270:                         .nfds = SCARG(uap, nfds),
  271:                         .readfds = SCARG(uap, readfds),
  272:                         .writefds = SCARG(uap, writefds),
  273:                         .exceptfds = SCARG(uap, exceptfds),
  274:                 }
  275:         };
  276: 
  277:         if (SCARG(uap, tmout) == TMO_FEVR) {
  278:                 a.a.tv = NULL;
  279:         }
  280:         else if (SCARG(uap, tmout) >= 0) {
  281:                 tv.tv_sec = SCARG(uap, tmout) / 1000;
  282:                 tv.tv_usec = (SCARG(uap, tmout) % 1000) * 1000;
  283:                 a.a.tv = &tv;
  284:         }
  285:         else {
  286:                 return EINVAL;
  287:         }
  288: 
  289:         return sys_select(l, &a, retval);
  290: }
  291: 
  292: static char sys_hostname[MAXHOSTNAMELEN];
  293: 
  294: int
  295: sys_gethostname(struct lwp *l,  const struct sys_gethostname_args *uap, register_t *retval)
  296: {
  297:         ER ercd;
  298: 
  299:         (void)l;
  300: 
  301:         ercd = ChkSpaceRW(SCARG(uap, name), SCARG(uap, len));
  302:         if ( ercd < E_OK ) {
  303:                 return EFAULT;
  304:         }
  305: 
  306:         strlcpy(SCARG(uap, name), sys_hostname, SCARG(uap, len));
  307: 
  308:         *retval = 0;
  309:         return 0;
  310: }
  311: 
  312: int
  313: sys_sethostname(struct lwp *l,  const struct sys_sethostname_args *uap, register_t *retval)
  314: {
  315:         ER ercd;
  316: 
  317:         (void)l;
  318: 
  319:         ercd = ChkSpaceR(SCARG(uap, name), SCARG(uap, len));
  320:         if ( ercd < E_OK ) {
  321:                 return EFAULT;
  322:         }
  323: 
  324:         if ( SCARG(uap, len) > MAXHOSTNAMELEN ) {
  325:                 *retval = -1;
  326:                 return EINVAL;
  327:         }
  328: 
  329:         strlcpy(sys_hostname, SCARG(uap, name), MAXHOSTNAMELEN);
  330: 
  331:         *retval = 0;
  332:         return 0;
  333: }
  334: 
  335: IMPORT int sockatmark(int s);
  336: int
  337: sys_sockatmark(struct lwp *l, const struct sys_sockatmark_args *uap, register_t *retval)
  338: {
  339:         int re;
  340: 
  341:         (void)l;
  342: 
  343:         re = sockatmark(SCARG(uap, sd));
  344:         *retval = re;
  345:         return 0;
  346: }
  347: 
  348: 
  349: 
  350: /*
  351:  * This function is called by so_break().
  352:  *
  353:  * The following pre-condition is always satisfied.
  354:  *    tskid != TSK_ALL
  355:  */
  356: static int do_sys_break_task(ID tskid)
  357: {
  358:         int cnt = 0;
  359: 
  360:         if( get_lwp(tskid)->is_waiting != 0 ) {
  361:                 tk_dis_wai(tskid, TTW_FLG | TTW_CAL | TTW_RDV );
  362:                 cnt = 1;
  363:         }
  364: 
  365:         return cnt;
  366: }
  367: 
  368: int
  369: sys_break(struct lwp *l, const struct sys_break_args *uap, register_t *retval)
  370: {
  371:         /* {
  372:                 syscallarg(ID)                tskid;
  373:          } */
  374:         int tskid = SCARG(uap, tskid);
  375:         int cnt = 0;
  376:         int err = 0;
  377:         int i;
  378:         T_RTSK rtsk;
  379: 
  380:         (void)l;
  381: 
  382:         tk_dis_dsp();
  383: 
  384:         if(tskid == TSK_ALL) {
  385:                 for(i=1; i<=tskid_lwp_table_maxid; i++) {
  386:                         cnt += do_sys_break_task(tskid);
  387:                 }
  388:         }
  389:         else {
  390:                 err = tk_ref_tsk(tskid, &rtsk);
  391:                 if ( err == E_OK ) {
  392:                         cnt = do_sys_break_task(tskid);
  393:                 }
  394:         }
  395: 
  396:         tk_ena_dsp();
  397: 
  398:         *retval = cnt;
  399:         return err;
  400: }
  401: 
  402: int
  403: gettimeofday(struct timeval *tv, struct timezone *tz)
  404: {
  405:         if (tz != NULL)
  406:                 goto err_param;
  407: 
  408:         microtime(tv);
  409: 
  410:         return 0;
  411: 
  412: err_param:
  413:         return EINVAL;
  414: }
  415: 
  416: static struct tkn_nif_info tkn_dev_info[TKN_NIFDEV_MAX];
  417: 
  418: int
  419: sys_ifattach(struct lwp *l, const struct sys_ifattach_args *uap, register_t *retval)
  420: {
  421:         const char* devname = SCARG(uap, devnm);
  422:         int dev_num;
  423:         int error = 0;
  424:         int ret;
  425:         T_RDEV rdev;
  426:         struct tkn_nif_info *nif;
  427: 
  428:         (void)l;
  429: 
  430:         ret = ChkSpaceBstrR(devname, 0);
  431:         if ( ret < 0 ) {
  432:                 return EFAULT;
  433:         }
  434: 
  435:         for (nif = tkn_nif_mng.nifm_list; nif; nif = nif->nif_next) {
  436:                 if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) {
  437:                         break;
  438:                 }
  439:         }
  440:         if( nif != 0 ) {
  441:                 /* Already registered. */
  442:                 error = EBUSY;
  443:                 goto error;
  444:         }
  445: 
  446:         ret = tk_ref_dev((UB*)devname, &rdev);
  447:         if (ret < 0) {
  448:                 error = EINVAL;
  449:                 goto error;
  450:         }
  451: 
  452:         dev_num  = tkn_nif_mng.nifm_nifmax;
  453:         strncpy((char*)tkn_dev_info[dev_num].nif_dev, devname, TKN_NIFNAMESIZE);
  454: 
  455:         ret = tkn_nif_attach(&tkn_dev_info[dev_num]);
  456:         if (ret != 0) {
  457:                 error = EINVAL;
  458:         }
  459: 
  460: error:
  461:         *retval = 0;
  462: 
  463:         return error;
  464: }
  465: 
  466: int
  467: sys_ifdetach(struct lwp *l, const struct sys_ifdetach_args *uap, register_t *retval)
  468: {
  469:         const char* devname = SCARG(uap, devnm);
  470:         int error = 0;
  471:         int ret;
  472:         T_RDEV rdev;
  473:         struct tkn_nif_info *nif;
  474: 
  475:         (void)l;
  476: 
  477:         ret = ChkSpaceBstrR(devname, 0);
  478:         if ( ret < 0 ) {
  479:                 return EFAULT;
  480:         }
  481: 
  482:         ret = tk_ref_dev((UB*)devname, &rdev);
  483:         if (ret < 0) {
  484:                 error = EINVAL;
  485:                 goto error;
  486:         }
  487: 
  488:         for (nif = tkn_nif_mng.nifm_list; nif != NULL; nif = nif->nif_next) {
  489:                 if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) {
  490:                         break;
  491:                 }
  492:         }
  493:         if( nif == 0 ) {
  494:                 /* Not registered. */
  495:                 error = ENOENT;
  496:                 goto error;
  497:         }
  498: 
  499:         ret = tkn_nif_detach(nif);
  500:         if (ret != 0) {
  501:                 error = EINVAL;
  502:         }
  503: 
  504: error:
  505:         *retval = 0;
  506: 
  507:         return error;
  508: }
  509: 
  510: int
  511: sys_rtlist(struct lwp *l, const struct sys_rtlist_args *uap, register_t *retval)
  512: {
  513:         int error;
  514:         size_t len;
  515: 
  516:         (void)l;
  517: 
  518:         if ( SCARG(uap, buf) != NULL ) {
  519:                 error = ChkSpaceRW(SCARG(uap, buf), SCARG(uap, bufsz));
  520:                 if ( error < E_OK ) {
  521:                         return EFAULT;
  522:                 }
  523:         }
  524: 
  525:         len = SCARG(uap, bufsz);
  526:         error = sysctl_rtable(SCARG(uap,af), SCARG(uap,cmd), SCARG(uap,flags),
  527:                               SCARG(uap,buf), &len );
  528: 
  529:         if (error == 0) {
  530:                 *retval = len;
  531:         }
  532: 
  533:         return error;
  534: }
  535: 
  536: int
  537: sys_getifaddrs(struct lwp *l, const struct sys_getifaddrs_args *uap, register_t *retval)
  538: {
  539:         int error;
  540:         size_t asize;
  541: 
  542:         (void)l;
  543: 
  544:         if ( SCARG(uap, buf) != NULL ) {
  545:                 error = ChkSpaceRW(SCARG(uap, buf), SCARG(uap, bufsz));
  546:                 if ( error < E_OK ) {
  547:                         return EFAULT;
  548:                 }
  549:         }
  550: 
  551:         error = getifaddrs(SCARG(uap,ifap), SCARG(uap,buf), SCARG(uap,bufsz),
  552:                            &asize);
  553: 
  554:         if (error == 0) {
  555:                 *retval = asize;
  556:         }
  557: 
  558:         return error;
  559: }
  560: 
  561: int
  562: sys_ifindextoname(struct lwp *l, const struct sys_ifindextoname_args *uap, register_t *retval)
  563: {
  564:         int error;
  565: 
  566:         (void)l;
  567: 
  568:         error = ChkSpaceBstrRW(SCARG(uap, ifname), 0);
  569:         if ( error < 0 ) {
  570:                 return EFAULT;
  571:         }
  572: 
  573:         error = if_indextoname(SCARG(uap,ifindex), SCARG(uap,ifname));
  574:         if (error == 0) {
  575:                 *retval = 0;
  576:         }
  577: 
  578:         return error;
  579: }
  580: 
  581: int
  582: sys_ifnametoindex(struct lwp *l, const struct sys_ifnametoindex_args *uap, register_t *retval)
  583: {
  584:         int error;
  585:         unsigned int ifindex;
  586: 
  587:         (void)l;
  588: 
  589:         error = ChkSpaceBstrR(SCARG(uap, ifname), 0);
  590:         if ( error < 0 ) {
  591:                 return EFAULT;
  592:         }
  593: 
  594:         error = if_nametoindex(SCARG(uap,ifname), &ifindex);
  595:         if (error == 0) {
  596:                 *retval = ifindex;
  597:         }
  598: 
  599:         return error;
  600: }
  601: 
  602: int sys_bpfopen(struct lwp *l, const struct sys_bpfopen_args *uap, register_t *retval)
  603: {
  604:         int error;
  605:         struct file* fp;
  606:         int indx;
  607: 
  608:         error = ChkSpaceBstrR(SCARG(uap, path), 0);
  609:         if ( error < E_OK ) {
  610:                 return EFAULT;
  611:         }
  612: 
  613:         if ((error = fd_allocfile(&fp, &indx)) != 0)
  614:                 return (error);
  615: 
  616:         if ((error = tkn_bpf_open(SCARG(uap, path), SCARG(uap, oflag), fp)) != 0) {
  617:                 fd_abort(l->l_proc, fp, indx);
  618:                 if ((error == EDUPFD || error == EMOVEFD) &&
  619:                     l->l_dupfd >= 0 &&                        /* XXX from fdopen */
  620:                     (error =
  621:                         fd_dupopen(l->l_dupfd, &indx, SCARG(uap, oflag), error)) == 0) {
  622:                         *retval = indx;
  623:                         return (0);
  624:                 }
  625:                 if (error == ERESTART)
  626:                         error = EINTR;
  627:                 return (error);
  628:         }
  629: 
  630:         return ENOTSUP;
  631: }
  632: 
  633: int sys_tunopen(struct lwp *l, const struct sys_tunopen_args *uap, register_t *retval)
  634: {
  635:         int error;
  636:         struct file* fp;
  637:         int indx;
  638: 
  639:         error = ChkSpaceBstrR(SCARG(uap, path), 0);
  640:         if ( error < E_OK ) {
  641:                 return EFAULT;
  642:         }
  643: 
  644:         if ((error = fd_allocfile(&fp, &indx)) != 0)
  645:                 return (error);
  646: 
  647:         if ((error = tkn_tun_open(SCARG(uap, path), SCARG(uap, oflag), fp)) != 0) {
  648:                 fd_abort(l->l_proc, fp, indx);
  649:                 if ((error == EDUPFD || error == EMOVEFD) &&
  650:                     l->l_dupfd >= 0 &&                        /* XXX from fdopen */
  651:                     (error =
  652:                         fd_dupopen(l->l_dupfd, &indx, SCARG(uap, oflag), error)) == 0) {
  653:                         *retval = indx;
  654:                         return (0);
  655:                 }
  656:                 if (error == ERESTART)
  657:                         error = EINTR;
  658:                 return (error);
  659:         }
  660: 
  661:         return ENOTSUP;
  662: }