diff --git a/examples/Makefile b/examples/Makefile index 67d8826..79684d6 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,23 +1,27 @@ SRC = console-read.c drums3.c echo.c helloworld.c logring.c pager.c\ drums2.c drums.c ioctl.c uid-filter.c OBJ = console-read.o drums3.o echo.o helloworld.o logring.o pager.o\ - drums2.o drums.o ioctl.o uid-filter.o + drums2.o drums.o ioctl.o uid-filter.o mmap-test.o TARGETS = console-read drums3 echo helloworld logring pager\ - drums2 drums ioctl uid-filter + drums2 drums ioctl uid-filter mmap-test -default: $(TARGETS) +default: $(TARGETS) mmap-read install: $(TARGETS) clean: rm -f *.o *.d $(TARGETS) gmon.out *~ -$(TARGETS): %: %.c - $(CC) $(GCF) $< -o $@ ../libfusd/libfusd.a +mmap-read: mmap-read.c + $(CC) $< -o $@ + +$(TARGETS): %: %.c ../libfusd/libfusd.a + $(CC) $(GCF) $< -o $@ ../libfusd/libfusd.a %.d: %.c $(CC) -M $(CFLAGS) $< > $@.$$$$; sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$ + ifeq ($(MAKECMDGOALS),target) include $(SRC:.c=.d) endif diff --git a/examples/mmap-read.c b/examples/mmap-read.c new file mode 100644 index 0000000..9dbb25c --- /dev/null +++ b/examples/mmap-read.c @@ -0,0 +1,110 @@ +/* + * + * Copyright (c) 2003 The Regents of the University of California. All + * rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +/* + * FUSD - The Framework for UserSpace Devices - Example program + * + * This mmap a file/device and change it a bit. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void hexdump(void *ptr_r, int size) +{ + int J, I; + unsigned char *ptr = ptr_r; + unsigned long Addr = 0; + if (ptr == NULL) { + puts("NULL POINTER"); + puts("-------------------------------------------------------------------------------------"); + return; + } + while (Addr <= size) { + for (J = 0; J < 2; J++) { + printf("%08p: ", Addr + ptr); + for (I = 0; I < 16; I++, Addr++) { if (Addr <= size) { printf("%02lX ", (unsigned char) ptr[Addr]); } else { printf(" "); } } + printf(" | "); Addr -= 16; + for (I = 0; I < 16; I++, Addr++) { if (Addr <= size) { putchar(isprint(ptr[Addr]) ? ptr[Addr] : '.'); } else { putchar(' '); } } + puts(""); + } + } + puts("-------------------------------------------------------------------------------------"); +} + +int main(int argc, char *argv[]) +{ + int fd, i; + char *ptr; + int size = 0; + struct stat FileStat; + + srand((unsigned int) time(NULL)); + + if (argc != 3) { + printf("Usage: %s file size"); + } + + fd = open(argv[1], O_RDWR); + size = atoi(argv[2]); + + ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + printf("ptr = %p\n", ptr); + + if ((ptr != NULL) && (ptr != MAP_FAILED)) { + + hexdump(ptr, size); + + /* Let's do some changes */ + for (i = 0; i < 128; i++) { + ptr[i] ^= rand() % 0x100; + } + + msync(ptr, size, MS_SYNC|MS_INVALIDATE); + + hexdump(ptr, size); + } + + close(fd); + + return 0; +} diff --git a/examples/mmap-test.c b/examples/mmap-test.c new file mode 100644 index 0000000..6466976 --- /dev/null +++ b/examples/mmap-test.c @@ -0,0 +1,146 @@ +/* + * + * Copyright (c) 2003 The Regents of the University of California. All + * rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +/* + * FUSD - The Framework for UserSpace Devices - Example program + * + * This example creates a a mmap-able buffer. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "fusd.h" + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define BUFFER_SIZE 1024 + +static char *mmap_buffer; + +static void hexdump(void *ptr_r, int size) +{ + int J, I; + unsigned char *ptr = ptr_r; + unsigned long Addr = 0; + if (ptr == NULL) { + puts("NULL POINTER"); + puts("-------------------------------------------------------------------------------------"); + return; + } + while (Addr <= size) { + for (J = 0; J < 2; J++) { + printf("%08p: ", Addr + ptr); + for (I = 0; I < 16; I++, Addr++) { if (Addr <= size) { printf("%02lX ", (unsigned char) ptr[Addr]); } else { printf(" "); } } + printf(" | "); Addr -= 16; + for (I = 0; I < 16; I++, Addr++) { if (Addr <= size) { putchar(isprint(ptr[Addr]) ? ptr[Addr] : '.'); } else { putchar(' '); } } + puts(""); + } + } + puts("-------------------------------------------------------------------------------------"); +} + +ssize_t mmaptest_read(struct fusd_file_info *file, char *user_buffer, + size_t user_length, loff_t *offset) +{ + int len; + + if (*offset > BUFFER_SIZE) { + return 0; + } + + len = MIN(user_length + (*offset), BUFFER_SIZE); + memcpy(user_buffer, mmap_buffer + (*offset), len); + *offset += len; + return len; +} + + +int tester_mmap(struct fusd_file_info *file, int offset, size_t length, int prot, int flags, + void **addr, size_t *out_length) +{ + + printf("Got a mmap request from PID:%d [offset=%d, size=%d, prot=%X, flags=%X, addr=%p]\n", + file->pid, offset, length, prot, flags, *addr); + + if (length <= BUFFER_SIZE) { + + *addr = mmap_buffer; + *out_length = BUFFER_SIZE; + return 0; + } + + return -1; +} + +int do_open(struct fusd_file_info *file) +{ + /* opens and closes always succeed */ + return 0; +} + +int do_close(struct fusd_file_info *file) +{ + /* Show content of the buffer */ + hexdump(mmap_buffer, 512); + return 0; +} + + +struct fusd_file_operations drums_fops = { + open: do_open, + read: mmaptest_read, + mmap: tester_mmap, + close: do_close +}; + +int main(int argc, char *argv[]) +{ + int i; + + mmap_buffer = (char *)mmap(NULL, BUFFER_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); + + if (fusd_register("mmap-tester", "mmaptest", "mmap-tester", 0666, NULL, &drums_fops) < 0) { + fprintf(stderr, "mmap-tester register failed: %m\n"); + return -1; + } + + memset(mmap_buffer, 0xAA, BUFFER_SIZE); + + fprintf(stderr, "calling fusd_run...\n"); + fusd_run(); + return 0; +}