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(); } } }
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; }
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; }
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; }