gonzui


Format: Advanced Search

t2ex/t2ex_source/t2ex/fs/fimp/src/fimp_console.cbare sourcepermlink (0.02 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 TRON Forum(http://www.tron.org/) at 2015/06/04.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: /*
   15:  * This software package is available for use, modification, 
   16:  * and redistribution in accordance with the terms of the attached 
   17:  * T-License 2.x.
   18:  * If you want to redistribute the source code, you need to attach 
   19:  * the T-License 2.x document.
   20:  * There's no obligation to publish the content, and no obligation 
   21:  * to disclose it to the TRON Forum if you have modified the 
   22:  * software package.
   23:  * You can also distribute the modified source code. In this case, 
   24:  * please register the modification to T-Kernel traceability service.
   25:  * People can know the history of modifications by the service, 
   26:  * and can be sure that the version you have inherited some 
   27:  * modification of a particular version or not.
   28:  *
   29:  *    http://trace.tron.org/tk/?lang=en
   30:  *    http://trace.tron.org/tk/?lang=ja
   31:  *
   32:  * As per the provisions of the T-License 2.x, TRON Forum ensures that 
   33:  * the portion of the software that is copyrighted by Ken Sakamura or 
   34:  * the TRON Forum does not infringe the copyrights of a third party.
   35:  * However, it does not make any warranty other than this.
   36:  * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
   37:  * responsible for any consequences or damages caused directly or
   38:  * indirectly by the use of this software package.
   39:  *
   40:  * The source codes in bsd_source.tar.gz in this software package are 
   41:  * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
   42:  * They need to be changed or redistributed according to the 
   43:  * representation of each source header.
   44:  */
   45: 
   46: /*
   47:  *      @(#)fimp_console.c
   48:  *
   49:  */
   50: 
   51: #include "fimp_console.h"
   52: #include <sys/consio.h>
   53: #include <string.h>
   54: 
   55: /*
   56:  *  FIMP entry for "console" file system
   57:  */
   58: LOCAL   ER        console_service(fimp_t *req);
   59: LOCAL   ER        console_registfn(fimpinf_t *fimpinf, void *info);
   60: LOCAL   ER        console_unregistfn(fimpinf_t *fimpinf);
   61: LOCAL   ER        console_attachfn(coninf_t *coninf, void *info);
   62: LOCAL   ER        console_detachfn(coninf_t *coninf);
   63: 
   64: EXPORT  const    fs_fimp_t  fimp_consolefs_entry = {
   65:         console_service,       /* reqfn      */
   66:         console_registfn,      /* registfn  */
   67:         console_unregistfn,    /* unregistfn      */
   68:         console_attachfn,      /* attachfn  */
   69:         console_detachfn,      /* detachfn  */
   70:         0,                     /* startupfn      */
   71:         0,                     /* cleanupfn      */
   72:         0,                     /* breakfn        */
   73:         FIMP_FLAG_PRIVILEGE,   /* flags  */
   74:         0,                     /* priority       */
   75: };
   76: 
   77: /* Console file descriptors */
   78: #define ROOT_FID                (0)
   79: #define STDIN_FID               (1)
   80: #define STDOUT_FID              (2)
   81: #define STDERR_FID              (3)
   82: #define STDIN_FN                "stdin"
   83: #define STDOUT_FN               "stdout"
   84: #define STDERR_FN               "stderr"
   85: 
   86: /* Macros for flag check */
   87: #define CHK_AND(flags, value)           (((flags) & (value)) == (value))
   88: #define CHK_OR(flags, value)            (((flags) & (value)) != 0)
   89: 
   90: /* Console I/O driver entry */
   91: IMPORT  ER       ConsoleIO(INT ac, UB *av[]);
   92: 
   93: /*
   94:  *  Get console file id
   95:  */
   96: LOCAL   INT       get_con_fid(const coninf_t *coninf, const B *name)
   97: {
   98:         INT    len;
   99: 
  100:         len = strlen(coninf->connm);
  101:         if (*name++ == '/' && strncmp(coninf->connm, name, len) == 0) {
  102:                 /* connm is matched */
  103:                 if (strlen(name) == len) return ROOT_FID;
  104:                 if (name[len] == '/') {
  105:                         name += len + 1;
  106:                         if (strcmp(name, STDIN_FN) == 0)  return STDIN_FID;
  107:                         if (strcmp(name, STDOUT_FN) == 0) return STDOUT_FID;
  108:                         if (strcmp(name, STDERR_FN) == 0) return STDERR_FID;
  109:                 }
  110:         }
  111:         return -1;
  112: }
  113: 
  114: /*
  115:  *  FIMP_OPEN service
  116:  */
  117: LOCAL   ER        console_open(struct fimp_open *req)
  118: {
  119:         ER     er;
  120:         INT    fid;
  121: 
  122:         er = E_OK;
  123:         switch (fid = get_con_fid(req->coninf, req->path)) {
  124:         case ROOT_FID:
  125:                 if (CHK_OR(req->oflags, O_CREAT))             er = EX_ACCES;
  126:                 else if (CHK_OR(req->oflags, O_WRONLY))       er = EX_ISDIR;
  127:                 break;
  128:         case STDIN_FID:
  129:                 if (CHK_OR(req->oflags, O_CREAT | O_WRONLY))  er = EX_ACCES;
  130:                 else if (CHK_OR(req->oflags, O_DIRECTORY))    er = EX_NOTDIR;
  131:                 break;
  132:         case STDOUT_FID:
  133:         case STDERR_FID:
  134:                 if (CHK_OR(req->oflags, O_CREAT | O_RDONLY))  er = EX_ACCES;
  135:                 else if (CHK_OR(req->oflags, O_DIRECTORY))    er = EX_NOTDIR;
  136:                 break;
  137:         default:
  138:                 if (CHK_OR(req->oflags, O_CREAT))             er = EX_ACCES;
  139:                 else                                          er = EX_NOENT;
  140:         }
  141: 
  142:         if (er == E_OK) {
  143:                 if (CHK_AND(req->oflags, O_CREAT | O_EXCL)) {
  144:                         er = EX_EXIST;
  145:                 } else {
  146:                         *req->fid = fid;
  147:                 }
  148:         }
  149:         return er;
  150: }
  151: 
  152: /*
  153:  *  FIMP_CLOSE service
  154:  */
  155: LOCAL   ER        console_close(struct fimp_close *req)
  156: {
  157:         switch (req->fid) {
  158:         case ROOT_FID:
  159:         case STDIN_FID:
  160:         case STDOUT_FID:
  161:         case STDERR_FID:
  162:                 break;
  163:         default:
  164:                 return EX_BADF;
  165:         }
  166:         return E_OK;
  167: }
  168: 
  169: /*
  170:  *  FIMP_READ64 service
  171:  */
  172: LOCAL   ER        console_read64(struct fimp_read64 *req)
  173: {
  174:         ER     er;
  175:         INT    len;
  176: 
  177:         er = EX_BADF;
  178:         if (req->fid == STDIN_FID) {
  179:                 /* Input from "console" */
  180:                 len = console_in((UW)req->coninf->consd, req->buf, *req->len);
  181:                 if (len >= 0) {
  182:                         *req->len = len;
  183:                         er = E_OK;
  184:                 } else {
  185:                         *req->len = 0;
  186:                         er = EX_INTR;
  187:                 }
  188:                 *req->retoff = 0;
  189:         }
  190:         return er;
  191: }
  192: 
  193: /*
  194:  *  FIMP_WRITE64 service
  195:  */
  196: LOCAL   ER        console_write64(struct fimp_write64 *req)
  197: {
  198:         ER     er;
  199:         W      len;
  200: 
  201:         er = EX_BADF;
  202:         if (req->fid == STDOUT_FID || req->fid == STDERR_FID) {
  203:                 /* Output to "console" */
  204:                 len = console_out((UW)req->coninf->consd, req->buf, *req->len);
  205:                 *req->len = len;
  206:                 *req->retoff = 0;
  207:                 er = E_OK;
  208:         }
  209:         return er;
  210: }
  211: 
  212: /*
  213:  *  Get stat64_us
  214:  */
  215: LOCAL   ER        set_stat64_us(struct stat64_us *stat, W fid)
  216: {
  217:         INT    size;
  218:         mode_t mode;
  219: 
  220:         switch(fid) {
  221:         case ROOT_FID:
  222:                 size = 3;
  223:                 mode = S_IFDIR | S_IRUSR | S_IXUSR;
  224:                 break;
  225:         case STDIN_FID:
  226:                 size = 0;
  227:                 mode = S_IFCHR | S_IRUSR;
  228:                 break;
  229:         case STDOUT_FID:
  230:         case STDERR_FID:
  231:                 size = 0;
  232:                 mode = S_IFCHR | S_IWUSR;
  233:                 break;
  234:         default:
  235:                 return EX_BADF;
  236:         }
  237:         memset(stat, 0, sizeof(struct stat64_us));
  238:         stat->st_ino = fid;
  239:         stat->st_size = size * sizeof(struct dirent);
  240:         stat->st_mode = mode;
  241:         return E_OK;
  242: }
  243: 
  244: /*
  245:  *  FIMP_STAT64_US service
  246:  */
  247: LOCAL   ER        console_stat64_us(struct fimp_stat64_us *req)
  248: {
  249:         return set_stat64_us(req->buf, get_con_fid(req->coninf, req->path));
  250: }
  251: 
  252: /*
  253:  *  FIMP_FSTAT64_US service
  254:  */
  255: LOCAL   ER        console_fstat64_us(struct fimp_fstat64_us *req)
  256: {
  257:         return set_stat64_us(req->buf, req->fid);
  258: }
  259: 
  260: /*
  261:  *  FIMP_CHDIR service
  262:  */
  263: LOCAL   ER        console_chdir(struct fimp_chdir *req)
  264: {
  265:         return (get_con_fid(req->coninf, req->path) == ROOT_FID) ?
  266:                                                         E_OK : EX_NOENT;
  267: }
  268: 
  269: /*
  270:  *  FIMP_FCHDIR service
  271:  */
  272: LOCAL   ER        console_fchdir(struct fimp_fchdir *req)
  273: {
  274:         if (req->fid != ROOT_FID) return EX_BADF;
  275: 
  276:         req->buf[0] = '/';
  277:         strcpy(&req->buf[1], req->coninf->connm);
  278:         return E_OK;
  279: }
  280: 
  281: /*
  282:  *  FIMP_GETDENTS service
  283:  */
  284: LOCAL   ER        console_getdents(struct fimp_getdents *req)
  285: {
  286:         ino_t          ino;
  287:         const  B        *fname;
  288:         struct dirent  *dir;
  289:         off64_t                off;
  290:         INT            rlen, len, nlen, reclen;
  291:         ER             er;
  292: 
  293:         if (req->fid != ROOT_FID) return EX_BADF;
  294: 
  295:         off = *req->off;
  296:         if ((off % sizeof(struct dirent)) != 0) return EX_NOENT;
  297: 
  298:         er = E_OK;
  299:         rlen = *req->len;
  300:         for (dir = req->buf, len = 0; len + RECLEN_DIRENT(1) <= rlen; ) {
  301:                 switch (off / sizeof(struct dirent)) {
  302:                 case 0:
  303:                         ino = STDIN_FID;
  304:                         fname = STDIN_FN;
  305:                         break;
  306:                 case 1:
  307:                         ino = STDOUT_FID;
  308:                         fname = STDOUT_FN;
  309:                         break;
  310:                 case 2:
  311:                         ino = STDERR_FID;
  312:                         fname = STDERR_FN;
  313:                         break;
  314:                 default:
  315:                         fname = NULL;
  316:                         break;
  317:                 }
  318:                 if (fname == NULL) break;             /* End of entry */
  319: 
  320:                 /* Calcurate actual entry length and check buffer space */
  321:                 if ((nlen = strlen(fname)) > NAME_MAX) nlen = NAME_MAX;
  322:                 reclen = RECLEN_DIRENT(nlen);
  323:                 if (len + reclen > rlen) {
  324:                         if (len == 0) er = EX_INVAL;
  325:                         break;       /* No more space */
  326:                 }
  327: 
  328:                 /* Set one entry to dir buffer */
  329:                 strncpy(dir->d_name, fname, nlen);
  330:                 dir->d_name[nlen] = '\0';
  331:                 dir->d_ino = ino;
  332:                 dir->d_reclen = reclen;
  333:                 len += reclen;
  334: 
  335:                 /* Setup for next entry */
  336:                 off += sizeof(struct dirent);
  337:                 dir = (struct dirent *)((UB*)dir + reclen);
  338: 
  339:                 /* Special case, get only one entry */
  340:                 if (rlen == sizeof(struct dirent)) break;
  341:         }
  342:         *req->retoff = off;
  343:         *req->len = len;
  344:         return er;
  345: }
  346: 
  347: /*
  348:  *  Console FIMP service function
  349:  */
  350: LOCAL   ER        console_service(fimp_t *req)
  351: {
  352:         ER     er;
  353: 
  354:         switch (req->com.r_code) {
  355:         case FIMP_OPEN:
  356:                 er = console_open(&req->r_open);
  357:                 break;
  358:         case FIMP_CLOSE:
  359:                 er = console_close(&req->r_close);
  360:                 break;
  361:         case FIMP_READ64:
  362:                 er = console_read64(&req->r_read64);
  363:                 break;
  364:         case FIMP_WRITE64:
  365:                 er = console_write64(&req->r_write64);
  366:                 break;
  367:         case FIMP_STAT64_US:
  368:                 er = console_stat64_us(&req->r_stat64_us);
  369:                 break;
  370:         case FIMP_FSTAT64_US:
  371:                 er = console_fstat64_us(&req->r_fstat64_us);
  372:                 break;
  373:         case FIMP_GETDENTS:
  374:                 er = console_getdents(&req->r_getdents);
  375:                 break;
  376:         case FIMP_CHDIR:
  377:                 er = console_chdir(&req->r_chdir);
  378:                 break;
  379:         case FIMP_FCHDIR:
  380:                 er = console_fchdir(&req->r_fchdir);
  381:                 break;
  382:         case FIMP_FSYNC:
  383:         case FIMP_SYNC:
  384:                 er = E_OK;
  385:                 break;
  386:         case FIMP_RMDIR:
  387:                 er = EX_BUSY;
  388:                 break;
  389:         default:
  390:                 er = EX_NOTSUP;
  391:         }
  392:         return er;
  393: }
  394: 
  395: /*
  396:  *  Console FIMP initialize function
  397:  */
  398: LOCAL   ER        console_registfn(fimpinf_t *fimpinf, void *info)
  399: {
  400:         /* Nothing to do */
  401:         return E_OK;
  402: }
  403: 
  404: /*
  405:  *  Console FIMP finalize function
  406:  */
  407: LOCAL   ER        console_unregistfn(fimpinf_t *fimpinf)
  408: {
  409:         /* Never unregister */
  410:         return E_OK;
  411: }
  412: 
  413: /*
  414:  *  Console FIMP attach function
  415:  */
  416: LOCAL   ER        console_attachfn(coninf_t *coninf, void *info)
  417: {
  418:         ER     er;
  419:         UW     port;
  420: 
  421:         /* Has the console driver initialized ? */
  422:         er = console_conf(CS_GETPORT, &port);
  423:         if (er < E_OK) {
  424:                 if (er == E_RSFN) {
  425:                         /* No, initialize console driver now */
  426:                         if (ConsoleIO(0, NULL) >= E_OK) {
  427:                                 er = console_conf(CS_GETPORT, &port);
  428:                         }
  429:                 }
  430:                 if (er < E_OK) return EX_IO;
  431:         }
  432:         coninf->consd = (void *)port;
  433:         return E_OK;
  434: }
  435: 
  436: /*
  437:  *  Console FIMP detach function
  438:  */
  439: LOCAL   ER        console_detachfn(coninf_t *coninf)
  440: {
  441:         /* Never detach */
  442:         return E_OK;
  443: }
  444: