static void jump_linenum (int linenum)
{
  FILE *original;
  int   finished;

  /* Not only does this verify whether the scanner finished,
     if it has finished, it additionally closes the stream. */
  finished = tokenizer_finished();
  /* We save this copy in case the scanner wasn't finished. */
  original = io_handle();

  /* Start a new scanner from the beginning of the file. */
  tokenizer_init(io_file());
  reset(T_ERROR);
  io_reset();

  /* Search for linenum. */
  find_linenum(linenum);

  /* If the search ended at EOF, linenum could not be found! */
  if (tokenizer_finished())
  {
    dprintf(
      "*warning: could not jump to `%d'\n",
      E_WARNING, linenum);
    /* Set back to original stream */
    io_set(io_file(), original);
    /* Prepare scanner to continue. */
    if (!finished)
    {
      reset(T_NUMBER);
      io_reset();
      io_next();
    }
  }
}
Example #2
0
int main(int argc, char **argv) {
   struct sigaction act;
   io_handle_t serv1, serv2, serv3, servr, watcher;
   sdp_session_t *session;

   memset(&act, 0, sizeof(act));
   act.sa_handler = sigint_handler;
   
   DIE_IF_ERR(storage_segregate(&storage, 12, 512));

   DIE_IF_ERR(io_loop_init(&loop));
   DIE_IF_ERR(io_file(&loop, &backup, "backup.txt", O_RDWR));
   DIE_IF_ERR(io_inotify(&loop, &watcher));
   DIE_IF_ERR(io_tcp_server(&loop, &serv1, "0.0.0.0", "3000"));
   DIE_IF_ERR(io_tcp_server(&loop, &serv2, "0.0.0.0", "4000"));
   DIE_IF_ERR(io_tcp_server(&loop, &serv3, "0.0.0.0", "5000"));
   DIE_IF_ERR(io_rfcomm_server(&loop, &servr, BDADDR_ANY, 4));
   
   lseek(backup.fd, 0, SEEK_END);

   DIE_IF_ERR(io_watch_start(&watcher, "/dev", IN_CREATE | IN_DELETE, file_changed));
   DIE_IF_ERR(io_channel(&channel));
   DIE_IF_ERR(io_channel_join(&channel, &backup, backup_updated));
   DIE_IF_ERR(io_channel_join(&channel, &tcp1, serl_updated));

   if(try_serial(&loop, &serl) == -1) puts("warning: arduino not connected.");
   else DIE_IF_ERR(io_publish_start(&serl, &channel, data_published));

   DIE_IF_ERR(io_listen_start(&serv1, new_tcp1_conn));
   DIE_IF_ERR(io_listen_start(&serv2, new_tcp2_conn));
   DIE_IF_ERR(io_listen_start(&serv3, new_tcp3_conn));
   DIE_IF_ERR(io_listen_start(&servr, new_rfcm_conn));

   session = io_rfcomm_advertise(4, name, desc, uuid128);
   DIE_IF_ERR(sigaction(SIGINT, &act, NULL));
   puts("pi server is up...");
   DIE_IF_ERR(io_loop_run(&loop));

   io_channel_close(&channel);
   storage_collapse(&storage);
   io_rfcomm_unadvertise(session);
   return 0;
}
Example #3
0
static int test_rwpartial(directory_t* tmpdir)
{
   iothread_t  iothr = iothread_FREE;
   file_t      file = file_FREE;
   memblock_t  writebuf = memblock_FREE;
   memblock_t  readbuf  = memblock_FREE;
   iotask_t    iotask_buffer;
   iotask_t*   iotask = &iotask_buffer;
   eventcount_t counter = eventcount_INIT;

   // prepare0
   TEST(0 == init_iothread(&iothr));
   // alloc buffer
   TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &readbuf));
   TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &writebuf));
   for (size_t val = 0; val < writebuf.size/sizeof(uint32_t); ++val) {
      ((uint32_t*)writebuf.addr)[val] = (uint32_t) val;
   }
   memset(readbuf.addr, 0, readbuf.size);

   for (int ispos = 0; ispos <= 1; ++ispos) {

      // TEST insertiotask_iothread: (writep,write) && syscall writes less than writebuf.size
      TEST(0 == initcreate_file(&file, "testpartial", tmpdir))
      if (ispos) {
         initwritep_iotask(iotask, io_file(file), writebuf.size, writebuf.addr, 0, &counter);
      } else {
         initwrite_iotask(iotask, io_file(file), writebuf.size, writebuf.addr, &counter);
      }
      // test
      s_iothread_errtimer_count = 0;
      init_testerrortimer(&s_iothread_errtimer, 2/*trigger partial io*/, 1);
      insertiotask_iothread(&iothr, 1, &iotask);
      // wait for writer ready
      wait_eventcount(&counter,0);
      // check iotask
      TEST(iotask->iolist_next == 0);
      TEST(iotask->bytesrw    == writebuf.size);
      TEST(iotask->state      == iostate_OK);
      TEST(iotask->op         == ioop_WRITE);
      TEST(iotask->ioc        == io_file(file));
      TEST(iotask->offset     == (ispos ? 0 : -1));
      TEST(iotask->bufaddr    == writebuf.addr);
      TEST(iotask->bufsize    == writebuf.size);
      TEST(iotask->readycount == &counter);
      // check 32 partial writes (1+32)
      TEST(32 == s_iothread_errtimer_count);
      // reset
      TEST(0 == free_file(&file));
      free_testerrortimer(&s_iothread_errtimer);

      // TEST insertiotask_iothread: (readp, read) && syscall reads less than writebuf.size
      TEST(0 == init_file(&file, "testpartial", accessmode_READ, tmpdir));
      if (ispos) {
         initreadp_iotask(iotask, io_file(file), readbuf.size, readbuf.addr, 0, &counter);
      } else {
         initread_iotask(iotask, io_file(file), readbuf.size, readbuf.addr, &counter);
      }
      // test
      s_iothread_errtimer_count = 0;
      init_testerrortimer(&s_iothread_errtimer, 2/*trigger partial io*/, 1);
      insertiotask_iothread(&iothr, 1, &iotask);
      // wait for reader ready
      wait_eventcount(&counter,0);
      // check iotask.ioop[0]
      TEST(iotask->iolist_next == 0);
      TEST(iotask->bytesrw    == writebuf.size);
      TEST(iotask->state      == iostate_OK);
      TEST(iotask->op         == ioop_READ);
      TEST(iotask->ioc        == io_file(file));
      TEST(iotask->offset     == (ispos ? 0 : -1));
      TEST(iotask->bufaddr    == readbuf.addr);
      TEST(iotask->bufsize    == readbuf.size);
      TEST(iotask->readycount == &counter);
      // check content of readbuf
      for (size_t val = 0; val < readbuf.size/sizeof(uint32_t); ++val) {
         TEST(val == ((uint32_t*)readbuf.addr)[val]);
      }
      // check 32 partial writes (1+32)
      TEST(32 == s_iothread_errtimer_count);
      // reset
      memset(readbuf.addr, 0, readbuf.size);
      TEST(0 == free_file(&file));
      TEST(0 == removefile_directory(tmpdir, "testpartial"));
      free_testerrortimer(&s_iothread_errtimer);
   }

   // reset
   TEST(0 == free_iothread(&iothr));
   TEST(0 == free_eventcount(&counter));
   TEST(0 == free_iochannel(&file));
   TEST(0 == RELEASE_PAGECACHE(&writebuf));
   TEST(0 == RELEASE_PAGECACHE(&readbuf));

   return 0;
ONERR:
   free_iothread(&iothr);
   free_eventcount(&counter);
   free_iochannel(&file);
   RELEASE_PAGECACHE(&writebuf);
   RELEASE_PAGECACHE(&readbuf);
   removefile_directory(tmpdir, "testpartial");
   return EINVAL;
}
Example #4
0
static int test_write(directory_t* tmpdir)
{
   iothread_t  iothr = iothread_FREE;
   file_t      file = file_FREE;
   memblock_t  mblock[10] = { memblock_FREE };
   memblock_t  readbuf = memblock_FREE;
   iotask_t    iotask_buffer[lengthof(mblock)];
   iotask_t*   iotask[lengthof(mblock)];
   eventcount_t counter = eventcount_INIT;

   // prepare0
   TEST(0 == init_iothread(&iothr));
   memset(iotask_buffer, 0, sizeof(iotask_buffer));
   for (unsigned i = 0; i < lengthof(iotask); ++i) {
      iotask[i] = &iotask_buffer[i];
   }
   // fill write buffer
   for (size_t i = 0, val = 0; i < lengthof(mblock); ++i) {
      TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &mblock[i]));
      for (size_t off = 0; off < mblock[i].size/sizeof(uint32_t); ++off, ++val) {
         ((uint32_t*)mblock[i].addr)[off] = (uint32_t) val;
      }
   }
   // alloc read buffer
   TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &readbuf));
   memset(readbuf.addr, 0, readbuf.size);

   // TEST insertiotask_iothread: writep (forward)
   static_assert((lengthof(iotask)-1) % 3 == 0, "full range 1..lengthof(iotask)");
   for (unsigned nrio = 1; nrio <= lengthof(iotask); nrio += 3) {
      // prepare
      TEST(0 == initcreate_file(&file, "testwrite", tmpdir));
      for (size_t i = 0; i < nrio; ++i) {
         initwritep_iotask(iotask[i], io_file(file), mblock[i].size, mblock[i].addr, (off_t) (i*mblock[0].size), &counter);
      }
      // test
      insertiotask_iothread(&iothr, (uint8_t) nrio, &iotask[0]);
      // check
      for (unsigned i = 0; i < nrio; ++i) {
         // wait for ready counter
         while (iostate_QUEUED == read_atomicint(&iotask[i]->state)) {
            wait_eventcount(&counter,0);
         }
         // check iotask
         TEST(0 == compare_iotask(iotask[i], 0, mblock[i].size, iostate_OK, ioop_WRITE, io_file(file),
                     (off_t) (i*mblock[0].size), mblock[i].addr, mblock[i].size, &counter));
         // check written bytes
         TEST((int)readbuf.size == pread(io_file(file), readbuf.addr, readbuf.size, iotask[i]->offset));
         for (size_t vi = 0, val = (size_t)iotask[i]->offset/sizeof(uint32_t); vi < readbuf.size/sizeof(uint32_t); ++vi, ++val) {
            TEST(val == ((uint32_t*)readbuf.addr)[vi]);
         }
         // reset
         iotask[i]->bytesrw = 0;
      }
      // check file position (offset) not changed
      TEST(0 == lseek(io_file(file), 0, SEEK_CUR));
      // reset
      TEST(0 == free_iochannel(&file));
      TEST(0 == removefile_directory(tmpdir, "testwrite"));
      counter.nrevents = 0;
   }

   // TEST insertiotask_iothread: writep (backward)
   static_assert((lengthof(iotask)-1) % 3 == 0, "full range 1..lengthof(iotask)");
   for (unsigned nrio = 1; nrio <= lengthof(iotask); nrio += 3) {
      // prepare
      TEST(0 == initcreate_file(&file, "testwrite", tmpdir));
      for (unsigned i = 0; i < nrio; ++i) {
         initwritep_iotask(iotask[i], io_file(file), mblock[i].size, mblock[i].addr, (off_t)((nrio-1-i)*mblock[0].size), &counter);
      }
      // test
      insertiotask_iothread(&iothr, (uint8_t) nrio, &iotask[0]);
      // check
      for (unsigned i = 0; i < nrio; ++i) {
         // wait for ready counter
         while (iostate_QUEUED == read_atomicint(&iotask[i]->state)) {
            wait_eventcount(&counter,0);
         }
         // check iotask
         TEST(0 == compare_iotask(iotask[i], 0, mblock[i].size, iostate_OK, ioop_WRITE, io_file(file),
                     (off_t) ((nrio-1-i)*mblock[0].size), mblock[i].addr, mblock[i].size, &counter));
         // check written bytes
         TEST((int)readbuf.size == pread(io_file(file), readbuf.addr, readbuf.size, iotask[i]->offset));
         for (size_t vi = 0, val = i*mblock[0].size/sizeof(uint32_t); vi < readbuf.size/sizeof(uint32_t); ++vi, ++val) {
            TEST(val == ((uint32_t*)readbuf.addr)[vi]);
         }
         // reset
         iotask[i]->bytesrw = 0;
      }
      // check file position (offset) not changed
      TEST(0 == lseek(io_file(file), 0, SEEK_CUR));
      // reset
      TEST(0 == free_iochannel(&file));
      TEST(0 == removefile_directory(tmpdir, "testwrite"));
      counter.nrevents = 0;
   }

   // TEST insertiotask_iothread: write
   // prepare
   TEST(0 == initcreate_file(&file, "testwrite", tmpdir));
   for (unsigned i = 0; i < lengthof(iotask); ++i) {
      initwrite_iotask(iotask[i], io_file(file), mblock[i].size, mblock[i].addr, 0);
   }
   // test
   insertiotask_iothread(&iothr, lengthof(iotask), &iotask[0]);
   // check
   for (unsigned i = 0; i < lengthof(iotask); ++i) {
      // wait for ready counter
      for (int w = 0; w < 500000; ++w) {
         if (iostate_QUEUED != read_atomicint(&iotask[i]->state)) break;
         yield_thread();
      }
      // check iotask
      TEST(0 == compare_iotask(iotask[i], 0, mblock[i].size, iostate_OK, ioop_WRITE, io_file(file),
                  -1, mblock[i].addr, mblock[i].size, 0));
      // check written bytes
      TEST((int)readbuf.size == pread(io_file(file), readbuf.addr, readbuf.size, (off_t)(i*mblock[0].size)));
      for (size_t vi = 0, val = (i*mblock[0].size)/sizeof(uint32_t); vi < readbuf.size/sizeof(uint32_t); ++vi, ++val) {
         TEST(val == ((uint32_t*)readbuf.addr)[vi]);
      }
      // reset
      iotask[i]->bytesrw = 0;
   }
   // check file position (offset) changed
   TEST((off_t)(lengthof(mblock)*mblock[0].size) == lseek(io_file(file), 0, SEEK_CUR));

   // reset
   TEST(0 == free_iochannel(&file));
   TEST(0 == removefile_directory(tmpdir, "testwrite"));

   // reset0
   TEST(0 == free_iothread(&iothr));
   TEST(0 == free_eventcount(&counter));
   for (unsigned i = 0; i < lengthof(mblock); ++i) {
      TEST(0 == RELEASE_PAGECACHE(&mblock[i]));
   }
   TEST(0 == RELEASE_PAGECACHE(&readbuf));

   return 0;
ONERR:
   free_iothread(&iothr);
   free_eventcount(&counter);
   free_iochannel(&file);
   for (unsigned i = 0; i < lengthof(mblock); ++i) {
      RELEASE_PAGECACHE(&mblock[i]);
   }
   RELEASE_PAGECACHE(&readbuf);
   removefile_directory(tmpdir, "testwrite");
   return EINVAL;
}