1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd 2 See the file COPYING for copying permission. 3 */ 4 5 #include <sys/types.h> 6 #include <sys/mman.h> 7 #include <sys/stat.h> 8 #include <fcntl.h> 9 #include <errno.h> 10 #include <string.h> 11 #include <stdio.h> 12 #include <unistd.h> 13 14 #ifndef MAP_FILE 15 #define MAP_FILE 0 16 #endif 17 18 #include "filemap.h" 19 20 int 21 filemap(const char *name, 22 void (*processor)(const void *, size_t, const char *, void *arg), 23 void *arg) 24 { 25 int fd; 26 size_t nbytes; 27 struct stat sb; 28 void *p; 29 30 fd = open(name, O_RDONLY); 31 if (fd < 0) { 32 perror(name); 33 return 0; 34 } 35 if (fstat(fd, &sb) < 0) { 36 perror(name); 37 close(fd); 38 return 0; 39 } 40 if (!S_ISREG(sb.st_mode)) { 41 close(fd); 42 fprintf(stderr, "%s: not a regular file\n", name); 43 return 0; 44 } 45 if (sb.st_size > XML_MAX_CHUNK_LEN) { 46 close(fd); 47 return 2; /* Cannot be passed to XML_Parse in one go */ 48 } 49 50 nbytes = sb.st_size; 51 /* mmap fails for zero length files */ 52 if (nbytes == 0) { 53 static const char c = '\0'; 54 processor(&c, 0, name, arg); 55 close(fd); 56 return 1; 57 } 58 p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, 59 MAP_FILE|MAP_PRIVATE, fd, (off_t)0); 60 if (p == (void *)-1) { 61 perror(name); 62 close(fd); 63 return 0; 64 } 65 processor(p, nbytes, name, arg); 66 munmap((void *)p, nbytes); 67 close(fd); 68 return 1; 69 } 70