void errtfs(int line, int tfserrno) { mon_printf("TFSERROR_%d (line %d): %s\n",(int)tfserrno, line,(char *)mon_tfsctrl(TFS_ERRMSG,tfserrno,0)); mon_appexit(-1); }
/* ls(): * Just list current set of files in TFS... */ void ls(void) { TFILE *tfp; tfp = (TFILE *)0; while((tfp = mon_tfsnext(tfp))) mon_printf("%s\n",TFS_NAME(tfp)); mon_printf("There are currently %d files in TFS\n", (int)mon_tfsctrl(TFS_FCOUNT,0,0)); }
static int rtems_tfs_ioctl( rtems_libio_t *iop, uint32_t cmd, void *buf ) { int ret; ret = mon_tfsctrl(cmd,(long)buf,0); if (ret != TFS_OKAY) return(-1); return(0); }
int main(int argc,char *argv[]) { int i, tfd; char line[80], *fname; /* If argument count is greater than one, then dump out the * set of CLI arguments... */ if (argc > 1) { mon_printf("Argument list...\n"); for(i=0; i<argc; i++) mon_printf(" arg[%d]: %s\n",i,argv[i]); } /* If the shell variable "USE_THIS_FILE" exists, then use the * content of that shell variable as a filename; else use "monrc"... */ fname = mon_getenv("USE_THIS_FILE"); if (!fname) fname = "monrc"; /* If the file exists, the assume it is ASCII and dump it * line by line... */ if (mon_tfsstat(fname)) { mon_printf("Dumping content of '%s'...\n",fname); tfd = mon_tfsopen(fname,TFS_RDONLY,0); if (tfd >= 0) { while(mon_tfsgetline(tfd,line,sizeof(line))) mon_printf("%s",line); mon_tfsclose(tfd,0); } else { mon_printf("TFS error: %s\n", (char *)mon_tfsctrl(TFS_ERRMSG,tfd,0)); } } return(0); }
/* * ctrltest(): * Test various aspects of the tfsctrl() function. */ void ctrltest(char *fname, char *data) { int tfd, ret; char flags[16]; /* Copy fname to TMPFILE... */ cp (TMPFILE,fname); /* Verify TFS_UNOPEN... * Open a file, modify it, then prior to calling tfsclose(), call * tfsctrl(TFS_UNOPEN) on that file descriptor and make sure the * file is in its original state and the file descriptor has been * closed... */ tfd = mon_tfsopen(fname,TFS_APPEND,buffer1); if (tfd < 0) tfsdie(tfd); ret = mon_tfswrite(tfd,"abcdefg",7); if (ret != TFS_OKAY) tfsdie(ret); ret = mon_tfsctrl(TFS_UNOPEN,tfd,0); if (ret != TFS_OKAY) tfsdie(ret); ret = mon_tfsclose(tfd,0); if (ret != TFSERR_BADFD) tfsdie(ret); if (cmp(TMPFILE,fname)) die(); /* Verify TFS_TELL... * Open a file, seek to a known point, then make sure that * tfsctrl(TFS_TELL) returns the expected offset. */ tfd = mon_tfsopen(fname,TFS_RDONLY,0); if (tfd < 0) tfsdie(tfd); ret = mon_tfsseek(tfd,5,TFS_BEGIN); if (ret != 5) tfsdie(ret); ret = mon_tfsctrl(TFS_TELL,tfd,0); if (ret != 5) tfsdie(ret); ret = mon_tfsread(tfd,buffer1,3); if (ret != 3) tfsdie(ret); ret = mon_tfsctrl(TFS_TELL,tfd,0); if (ret != 5+3) tfsdie(ret); ret = mon_tfsclose(tfd,0); if (ret != TFS_OKAY) tfsdie(ret); /* Test all "flag-ascii-to-binary" conversions... */ if ((ret = mon_tfsctrl(TFS_FATOB,(long)"e",0)) != TFS_EXEC) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"b",0)) != TFS_BRUN) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"B",0)) != TFS_QRYBRUN) tfsdie(ret); #if 0 if ((ret = mon_tfsctrl(TFS_FATOB,(long)"C",0)) != TFS_COFF) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"E",0)) != TFS_ELF) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"A",0)) != TFS_AOUT) tfsdie(ret); #else if ((ret = mon_tfsctrl(TFS_FATOB,(long)"E",0)) != TFS_EBIN) tfsdie(ret); #endif if ((ret = mon_tfsctrl(TFS_FATOB,(long)"c",0)) != TFS_CPRS) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"i",0)) != TFS_IPMOD) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"u",0)) != TFS_UNREAD) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"1",0)) != TFS_ULVL1) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"2",0)) != TFS_ULVL2) tfsdie(ret); if ((ret = mon_tfsctrl(TFS_FATOB,(long)"3",0)) != TFS_ULVL3) tfsdie(ret); /* Test all "flag-binary-to-ascii" conversions... */ ret = mon_tfsctrl(TFS_FBTOA,TFS_EXEC,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"e"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_BRUN,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"b"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_QRYBRUN,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"B"))) tfsdie(ret); #if 0 ret = mon_tfsctrl(TFS_FBTOA,TFS_COFF,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"C"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_ELF,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"E"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_AOUT,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"A"))) tfsdie(ret); #else ret = mon_tfsctrl(TFS_FBTOA,TFS_EBIN,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"E"))) tfsdie(ret); #endif ret = mon_tfsctrl(TFS_FBTOA,TFS_CPRS,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"c"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_IPMOD,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"i"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_UNREAD,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"u"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_ULVL1,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"1"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_ULVL2,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"2"))) tfsdie(ret); ret = mon_tfsctrl(TFS_FBTOA,TFS_ULVL3,(long)flags); if ((ret == TFSERR_BADARG) || (strcmp(flags,"3"))) tfsdie(ret); ret = mon_tfsunlink(TMPFILE); if (ret != TFS_OKAY) tfsdie(ret); }
/* writetest(): * Open the specified file in APPEND (modify) mode. Seek into the file * and read 1 byte. Increment that byte by one and then write it back * to the same location from which it was read. Then, close the file. * Build a new file that is what "should" be the content of the file we * just modified and compare the two files. They better match. * This function also verifies TFS_HEADROOM. */ int writetest(char *fname, char *newdata) { TFILE *tfp; char c; long headroom; int size, tfd, err; /* Open the source file: */ tfp = mon_tfsstat(fname); if (!tfp) die(); size = TFS_SIZE(tfp); tfd = mon_tfsopen(fname,TFS_APPEND,buffer1); if (tfd < 0) tfsdie(tfd); headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0); if (headroom != 0) die(); err = mon_tfsseek(tfd,3,TFS_BEGIN); if (err != 3) tfsdie(err); headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0); if (headroom != (size-3)) die(); err = mon_tfsread(tfd,&c,1); if (err != 1) tfsdie(err); headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0); if (headroom != (size-4)) die(); c++; err = mon_tfsseek(tfd,-1,TFS_CURRENT); if (err != 3) tfsdie(err); headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0); if (headroom != (size-3)) die(); err = mon_tfswrite(tfd,&c,1); if (err != TFS_OKAY) tfsdie(err); headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0); if (headroom != (size-4)) die(); mon_tfsclose(tfd,0); /* Add a new file that "should" be identical to the modified file; * then compare them and delete the newfile... */ err = mon_tfsadd(TMPFILE,"newdata1","2",newdata,strlen(newdata)); if (err != TFS_OKAY) tfsdie(err); if (cmp(fname,TMPFILE) != 0) die(); err = mon_tfsunlink(TMPFILE); if (err != TFS_OKAY) tfsdie(err); return(0); }
/* * The routine which does most of the work for the IMFS open handler * The full_path_name here is all text AFTER the TFS_PATHNAME_PREFIX * string, so if the filename is "/TFS/abc", the full_path_name string * is "abc"... * * Attempts to remap the incoming flags to TFS equivalent. * Its not a perfect mapping, but gets pretty close. * A comma-delimited path is supported to allow the user * to specify TFS-stuff (flag string, info string, and a buffer). * For example: * abc,e,script,0x400000 * This is a file called "abc" that will have the TFS 'e' flag * and the TFS info field of "script". The storage buffer is * supplied by the user at 0x400000. */ static int rtems_tfs_open_worker( rtems_libio_t *iop, char *path, int oflag, mode_t mode ) { static int beenhere = 0; long flagmode; int tfdidx, tfd; struct tfdinfo *tip; char *buf, *fstr, *istr, *bstr, pathcopy[TFSNAMESIZE*3+1]; if (RTEMS_TFS_DEBUG) printk("_open_r(%s,0x%" PRIx32 ",0x%" PRIx32 ")\n",path,oflag,mode); if (!beenhere) { newlib_tfdlock(); for(tfdidx=0; tfdidx<MAXTFDS; tfdidx++) tfdtable[tfdidx].inuse = 0; tfdtable[0].inuse = 1; /* fake entry for stdin */ tfdtable[1].inuse = 1; /* fake entry for stdout */ tfdtable[2].inuse = 1; /* fake entry for stderr */ newlib_tfdunlock(); beenhere = 1; } istr = fstr = bstr = buf = (char *)0; /* Copy the incoming path to a local array so that we can safely * modify the string... */ if (strlen(path) > TFSNAMESIZE*3) { return(ENAMETOOLONG); } strcpy(pathcopy,path); /* The incoming string may have commas that are used to delimit the * name from the TFS flag string, TFS info string and buffer. * Check for the commas and test for maximum string length... */ fstr = strchr(pathcopy,','); if (fstr) { *fstr++ = 0; istr = strchr(fstr,','); if (istr) { *istr++ = 0; bstr = strchr(istr,','); if (bstr) *bstr++ = 0; } } if (strlen(pathcopy) > TFSNAMESIZE) { return(ENAMETOOLONG); } if (istr) { if (strlen(istr) > TFSNAMESIZE) { return(ENAMETOOLONG); } } /* If O_EXCL and O_CREAT are set, then fail if the file exists... */ if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { if (mon_tfsstat((char *)pathcopy)) { return(EEXIST); } } /* Only a few flag combinations are supported... * O_RDONLY Simple read-only * O_WRONLY | O_APPEND Each write starts at end of file * O_WRONLY | O_TRUNC If file exists, truncate it * O_WRONLY | O_CREAT Create if it doesn't exist * O_WRONLY | O_CREAT | O_EXCL Fail if file exists */ switch(oflag & O_ACCMODE) { case O_RDONLY: flagmode = TFS_RDONLY; break; case O_WRONLY|O_APPEND: flagmode = TFS_APPEND; break; case O_WRONLY|O_TRUNC: case O_WRONLY|O_CREAT|O_TRUNC: mon_tfsunlink((char *)pathcopy); flagmode = TFS_CREATE|TFS_APPEND; break; case O_WRONLY|O_CREAT: case O_WRONLY|O_CREAT|O_APPEND: flagmode = TFS_CREATE|TFS_APPEND; break; case O_RDWR: case O_WRONLY|O_CREAT|O_EXCL: flagmode = TFS_CREATE|TFS_APPEND; break; default: printk("_open_r(): flag 0x%i not supported\n",oflag); return(ENOTSUP); } /* Find an open slot in our tfd table: */ newlib_tfdlock(); for(tfdidx=0; tfdidx<MAXTFDS; tfdidx++) { if (tfdtable[tfdidx].inuse == 0) break; } if (tfdidx == MAXTFDS) { newlib_tfdunlock(); return(EMFILE); } tip = &tfdtable[tfdidx]; tip->inuse = 1; newlib_tfdunlock(); /* If file is opened for something other than O_RDONLY, then * we need to allocate a buffer for the file.. * WARNING: It is the user's responsibility to make sure that * the file size does not exceed this buffer. Note that the * buffer may be specified as part of the comma-delimited path. */ if (flagmode == TFS_RDONLY) { buf = (char *)0; } else { if (bstr) buf = (char *)strtol(bstr,0,0); else buf = malloc(MAXFILESIZE); if (!buf) { newlib_tfdlock(); tip->inuse = 0; newlib_tfdunlock(); return(ENOMEM); } } /* Deal with tfs flags and tfs info fields if necessary: */ if (fstr) { long bflag; bflag = mon_tfsctrl(TFS_FATOB,(long)fstr,0); if (bflag == -1) { return(EINVAL); } flagmode |= bflag; } if (istr) strcpy(tip->info,istr); else tip->info[0] = 0; tfd = mon_tfsopen((char *)pathcopy,flagmode,buf); if (tfd >= 0) { tip->tfd = tfd; tip->buf = buf; strcpy(tip->name,pathcopy); iop->data0 = (uint32_t)tfdidx; return(0); } else { printk("%s: %s\n",pathcopy, (char *)mon_tfsctrl(TFS_ERRMSG,tfd,0)); } if (buf) free(buf); newlib_tfdlock(); tip->inuse = 0; newlib_tfdunlock(); return(EINVAL); }