Usage Example 1

Accessing HTTPFS (MCHFS server) via a POSIX File API

I must ask indulgence of the audience: to set up the context I need to present a few bits of rather boring code, hopefully with a bit of excitement at the very end. The code is sort of a set of test cases for file system API:
 
static const char pattern [] = "1234\n467\r\n\007A!\177";
static const char pattern1 [] = "Yet another pattern";

static void do_test(const char filename[])
{
  printf("\nTesting File API using file name >%s<\n", filename);
  {
    int fd;
    printf("\n\tWriting a pattern to the file...");
    do_well( fd = 
	open(filename,O_WRONLY|O_CREAT|O_TRUNC,0777) );
    assert( write(fd,pattern,sizeof(pattern)) 
	== sizeof(pattern) );
    do_well( close(fd) );
  }
  ...

Given the file name, the first test cases opens the file, and writes a pattern to it.
 

The second test case makes sure the file indeed exists and has the right size:
 
 {
    printf("\n\tMaking sure the file we created exists 
		and has size %d...",sizeof(pattern));
    do_well( lstat(filename,&buf) );
    assert( buf.st_size == sizeof(pattern) );
    assert( S_ISREG(buf.st_mode) );
	/* ... the same with stat() ... */
 }

 

The third case reads the file back and verifies what was written. The code continues in the same boring way, so I will show just the outline of the test cases rather than the code itself:
 
 {
   open(filename,O_WRONLY|O_CREAT|O_EXCL,0777)
	must fail
 }
 
 {
		Appending to the FILE
    assert( (fp = fopen(filename,"ab")) != (FILE*)0 );
    fprintf(fp, "%s", pattern1); do_well( fclose(fp) );
 }

 { ... reading back and verifying... }

 {
		Truncating the FILE to pattern1
   assert( (fp = fopen(filename,"wb")) != (FILE*)0 );
   fprintf(fp, "%s", pattern1); do_well( fclose(fp) );
 }

Note the use of fopen() and the variety of opening modes in these cases.
 

 
 {
		Update: over-writing the second byte
   assert( (fp = fopen(filename,"r+b")) != (FILE*)0 );
   for(i=0; i<strlen(pattern1); i++)
       assert( getc(fp) == pattern1[i] );
   do_well( fseek(fp,1,SEEK_SET) );
   fputc('\275',fp);
   do_well( fclose(fp) );
 }
 { 	... reading back and verifying... }
Again, note opening modes as well as fseek().
 

Here's the main() function that calls the test driver above given a file name:
 
int main(void)
{
  do_test("/tmp/x1");
  ...
This was a regular, plain and boring C code. There was no catch. It's quite obvious therefore that all the test cases above pass. It's not that obvious that the second statement finishes just as successfully:

 
int main(void)
{
  do_test("/tmp/x1");
  do_test("http://sun-server/cgi-bin/admin/
          MCHFS-server.pl/DeepestRoot/tmp/x2");
  ...

This invocation of the test driver creates, reads, writes, truncates, modifies and obtains the status of a file /tmp/x2 on a remote Sun/Solaris computer (running an Apache web server). Only the hostname is changed to protect the innocents.
 

The next call to the test driver
 
  ...
 do_test("http://winnt-server/cgi-bin/admin/
         MCHFS-server.pl/wwwroot/x2");

 printf("\nAll Done\n");
 return 0;
}

finishes successfully as well, accessing and modifying a file on a remote WinNT computer.

This main function itself ran on a Sun/Solaris and Linux/i686 computers. The entire code of this example -- file vhttpfs.c -- is a part of the testing suite in a HTTPFS distribution.
 
Back to the Paper Next example

 


Last updated June 25, 1999