/* * trunctest(): * Test file truncation. Verify that file truncates to expected size * and that the data in the file is as expected. */ int trunctest(char *fname, char *data) { int tfd, err, size; TFILE *tfp; /* Copy incoming file name to a tempoary file... */ cp(TMPFILE,fname); /* Open the temporary file and truncate it. * First verify that a truncation size too big will fail, then * do a real truncation. Close the file then verify that the * file has been trunated. */ tfd = mon_tfsopen(TMPFILE,TFS_APPEND,buffer1); if (tfd < 0) tfsdie(tfd); err = mon_tfstruncate(tfd,9999999); if (err != TFSERR_BADARG) tfsdie(err); err = mon_tfstruncate(tfd,TRUNCATE_SIZE); if (err != TFS_OKAY) tfsdie(err); err = mon_tfsclose(tfd,0); if (err < 0) tfsdie(err); /* Make sure that the file was truncated to the proper size. */ tfp = mon_tfsstat(TMPFILE); if (!tfp) die(); if (TFS_SIZE(tfp) != TRUNCATE_SIZE) die(); /* Now reopen the file and verify that the data is correct... */ tfd = mon_tfsopen(TMPFILE,TFS_RDONLY,0); if (tfd < 0) tfsdie(tfd); size = mon_tfsread(tfd,buffer1,TFS_SIZE(tfp)); if (size != TFS_SIZE(tfp)) tfsdie(size); if (memcmp(buffer1,data,TRUNCATE_SIZE)) die(); /* Close and remove the temporary file. */ mon_tfsclose(tfd,0); err = mon_tfsunlink(TMPFILE); if (err != TFS_OKAY) tfsdie(err); 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); }
int fs_open(char *name, struct fs_file *file) { TFILE *tfp; char *prefix, namebuf[TFSNAMESIZE+1]; char *origname; /* Look for the specified file in TFS. If found, then * return it; else return the nofile string above. */ origname = name; prefix = mon_getenv(HTTP_PREFIX_VARNAME); if (prefix) { if ((strlen(name) + strlen(prefix) + 1) < sizeof(namebuf)) { mon_sprintf(namebuf,"%s%s",prefix,name); name = namebuf; } } tfp = mon_tfsstat(name); if (!tfp) { file->data = (char *)nofile; file->len = strlen(nofile); } else { /* If the file ends with ".html", then parse it for ${XXX} tokens. * and whenver XXX is a valid shell variable in uMon, replace the * ${XXX} with the content of the variable (see convert_vars() above). */ if (strstr(name,".html")) { file->len = convert_vars(TFS_BASE(tfp),TFS_SIZE(tfp)); file->data = filebuf; } else { file->data = TFS_BASE(tfp); file->len = TFS_SIZE(tfp); } } return(1); }
int main(int argc,char *argv[]) { int err, opt, removefiles, list; char *file1, *file2; verbose = 0; list = 0; removefiles = 1; getoptinit(); while((opt=getopt(argc,argv,"lrv")) != -1) { switch(opt) { case 'l': list = 1; break; case 'r': removefiles = 0; break; case 'v': verbose++; break; default: usage(0); } } if (argc != optind+2) usage("Bad arg count"); /* Test all aspects of TFS API calls: */ file1 = argv[optind]; file2 = argv[optind+1]; if ((!strcmp(file1,TMPFILE)) || (!strcmp(file2,TMPFILE))) usage(TMPFILE); if (verbose) mon_printf("tfstest %s %s...\n",file1,file2); /* * Start by removing files to be created later... */ if (mon_tfsstat(TMPFILE)) { if (verbose) mon_printf("Removing %s...\n",TMPFILE); err = mon_tfsunlink(TMPFILE); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(file1)) { if (verbose) mon_printf("Removing %s...\n",file1); err = mon_tfsunlink(file1); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(file2)) { if (verbose) mon_printf("Removing %s...\n",file2); err = mon_tfsunlink(file2); if (err != TFS_OKAY) tfsdie(err); } /* * Create a file... */ if (verbose) mon_printf("Creating %s...\n",file1); err = mon_tfsadd(file1,"data1","2",data1,strlen(data1)); if (err != TFS_OKAY) tfsdie(err); /* * Basic getline test... */ if (verbose) mon_printf("Checking 'getline'...\n"); getlinetest(file1,data1); /* * Now copy the file... */ if (verbose) mon_printf("Copying %s to %s...\n",file1,file2); cp(file2,file1); /* * Now compare the two... * (they should be identical) */ if (verbose) mon_printf("Comparing %s to %s...\n",file1,file2); if (cmp(file1,file2) != 0) die(); /* * Seek test... * Verify that data at a specified offset is as expected based on the * file (file1) initially created from the data1 array... */ if (verbose) mon_printf("Running seek test on %s...\n",file1); seektest(file1,38,data1[38]); /* * Truncateion test... * Truncate a file and verify. */ if (verbose) mon_printf("Running truncation test on %s...\n",file1); trunctest(file1,data1); /* * Tfsctrl() function test... */ if (verbose) mon_printf("Running tfsctrl test...\n"); ctrltest(file1,data1); /* * Write test... * Modify a file in a few different ways and verify the modification... * Note that after this point, file1 and data1 are not the same. * The content of file1 will be the same as the new_data1 array. */ if (verbose) mon_printf("Running write test on %s...\n",file1); writetest(file1,new_data1); /* * File in-use test... * Verify that if a file is in-use, it cannot be removed. */ if (verbose) mon_printf("Running in-use test on %s...\n",file1); inusetest(file1); /* * Append test... * Verify that a file can be properly appended to. */ if (verbose) mon_printf("Running append test on %s...\n",file1); appendtest(file1,"this_is_some_data","this_is_the_appended_data"); /* * If the -r option is not set, then remove the files... */ if (removefiles) { if (mon_tfsstat(file1)) { err = mon_tfsunlink(file1); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(file2)) { err = mon_tfsunlink(file2); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(TMPFILE)) { err = mon_tfsunlink(TMPFILE); if (err != TFS_OKAY) tfsdie(err); } } if (list) ls(); /* All error cases checked above would have resulted in an exit * of this application, so if we got here, the testing must * have succeeded... */ mon_printf("TFS test on %s & %s PASSED\n",file1,file2); mon_appexit(0); return(0); }
/* 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); }
/* seektest(): * Run some tests on tfsseek(). * Verify that the character in the file specified at the incoming offset * is as expected. Seek to beyond the end of file and verify error, etc... */ int seektest(char *fname, int offset, char value) { char c, buf1[16], buf2[16]; TFILE *tfp; int tfd, end, err; /* Open the source file: */ tfd = mon_tfsopen(fname,TFS_RDONLY,0); if (tfd < 0) tfsdie(tfd); if (mon_tfsseek(tfd,offset,TFS_BEGIN) != offset) tfsdie(tfd); if (mon_tfsread(tfd,&c,1) != 1) tfsdie(tfd); if (c != value) die(); tfp = mon_tfsstat(fname); if (!tfp) die(); end = TFS_SIZE(tfp); /* * Seek to various limits in the file and verify proper return * value... */ err = mon_tfsseek(tfd,0,TFS_BEGIN); if (err != 0) tfsdie(err); err = mon_tfsseek(tfd,end,TFS_CURRENT); if (err != end) tfsdie(err); err = mon_tfsseek(tfd,1,TFS_CURRENT); if (err != TFSERR_EOF) tfsdie(err); err = mon_tfsseek(tfd,end,TFS_BEGIN); if (err != end) tfsdie(err); err = mon_tfsseek(tfd,end+1,TFS_BEGIN); if (err != TFSERR_EOF) tfsdie(err); err = mon_tfsseek(tfd,0,TFS_BEGIN); if (err != 0) tfsdie(err); err = mon_tfsseek(tfd,-1,TFS_CURRENT); if (err != TFSERR_EOF) tfsdie(err); err = mon_tfsseek(tfd,end,TFS_BEGIN); if (err != end) tfsdie(err); err = mon_tfsseek(tfd,-1,TFS_CURRENT); if (err != end-1) tfsdie(err); err = mon_tfsseek(tfd,2,TFS_CURRENT); if (err != TFSERR_EOF) tfsdie(err); /* Seek to beginning, read 10, seek to beginning again read 10 again. * Verify that both reads have same data. */ err = mon_tfsseek(tfd,0,TFS_BEGIN); if (err != 0) tfsdie(err); err = mon_tfsread(tfd,buf1,10); if (err != 10) tfsdie(err); err = mon_tfsseek(tfd,0,TFS_BEGIN); if (err != 0) tfsdie(err); err = mon_tfsread(tfd,buf2,10); if (err != 10) tfsdie(err); if (memcmp(buf1,buf2,10)) die(); /* * Seek to end, then verify that read() returns EOF and tfs_eof() * returns true. */ err = mon_tfsseek(tfd,end,TFS_BEGIN); if (err != end) tfsdie(err); err = mon_tfsread(tfd,buf1,1); if (err != TFSERR_EOF) tfsdie(err); if (mon_tfseof(tfd) != 1) die(); mon_tfsclose(tfd,0); 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); }