xref: /freebsd/contrib/expat/xmlwf/unixfilemap.c (revision 220ed979dec58fe7c868d7b64de3cd46b27312e9)
15bb6a25fSPoul-Henning Kamp /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
25bb6a25fSPoul-Henning Kamp    See the file COPYING for copying permission.
35bb6a25fSPoul-Henning Kamp */
45bb6a25fSPoul-Henning Kamp 
55bb6a25fSPoul-Henning Kamp #include <sys/types.h>
65bb6a25fSPoul-Henning Kamp #include <sys/mman.h>
75bb6a25fSPoul-Henning Kamp #include <sys/stat.h>
85bb6a25fSPoul-Henning Kamp #include <fcntl.h>
95bb6a25fSPoul-Henning Kamp #include <errno.h>
105bb6a25fSPoul-Henning Kamp #include <string.h>
115bb6a25fSPoul-Henning Kamp #include <stdio.h>
125bb6a25fSPoul-Henning Kamp #include <unistd.h>
135bb6a25fSPoul-Henning Kamp 
145bb6a25fSPoul-Henning Kamp #ifndef MAP_FILE
155bb6a25fSPoul-Henning Kamp #define MAP_FILE 0
165bb6a25fSPoul-Henning Kamp #endif
175bb6a25fSPoul-Henning Kamp 
185bb6a25fSPoul-Henning Kamp #include "filemap.h"
195bb6a25fSPoul-Henning Kamp 
205bb6a25fSPoul-Henning Kamp int
215bb6a25fSPoul-Henning Kamp filemap(const char *name,
225bb6a25fSPoul-Henning Kamp         void (*processor)(const void *, size_t, const char *, void *arg),
235bb6a25fSPoul-Henning Kamp         void *arg)
245bb6a25fSPoul-Henning Kamp {
255bb6a25fSPoul-Henning Kamp   int fd;
265bb6a25fSPoul-Henning Kamp   size_t nbytes;
275bb6a25fSPoul-Henning Kamp   struct stat sb;
285bb6a25fSPoul-Henning Kamp   void *p;
295bb6a25fSPoul-Henning Kamp 
305bb6a25fSPoul-Henning Kamp   fd = open(name, O_RDONLY);
315bb6a25fSPoul-Henning Kamp   if (fd < 0) {
325bb6a25fSPoul-Henning Kamp     perror(name);
335bb6a25fSPoul-Henning Kamp     return 0;
345bb6a25fSPoul-Henning Kamp   }
355bb6a25fSPoul-Henning Kamp   if (fstat(fd, &sb) < 0) {
365bb6a25fSPoul-Henning Kamp     perror(name);
375bb6a25fSPoul-Henning Kamp     close(fd);
385bb6a25fSPoul-Henning Kamp     return 0;
395bb6a25fSPoul-Henning Kamp   }
405bb6a25fSPoul-Henning Kamp   if (!S_ISREG(sb.st_mode)) {
415bb6a25fSPoul-Henning Kamp     close(fd);
425bb6a25fSPoul-Henning Kamp     fprintf(stderr, "%s: not a regular file\n", name);
435bb6a25fSPoul-Henning Kamp     return 0;
445bb6a25fSPoul-Henning Kamp   }
455bb6a25fSPoul-Henning Kamp 
465bb6a25fSPoul-Henning Kamp   nbytes = sb.st_size;
47220ed979SColeman Kane   /* mmap fails for zero length files */
48220ed979SColeman Kane   if (nbytes == 0) {
49220ed979SColeman Kane     static const char c = '\0';
50220ed979SColeman Kane     processor(&c, 0, name, arg);
51220ed979SColeman Kane     close(fd);
52220ed979SColeman Kane     return 1;
53220ed979SColeman Kane   }
545bb6a25fSPoul-Henning Kamp   p = (void *)mmap((caddr_t)0, (size_t)nbytes, PROT_READ,
555bb6a25fSPoul-Henning Kamp                    MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
565bb6a25fSPoul-Henning Kamp   if (p == (void *)-1) {
575bb6a25fSPoul-Henning Kamp     perror(name);
585bb6a25fSPoul-Henning Kamp     close(fd);
595bb6a25fSPoul-Henning Kamp     return 0;
605bb6a25fSPoul-Henning Kamp   }
615bb6a25fSPoul-Henning Kamp   processor(p, nbytes, name, arg);
625bb6a25fSPoul-Henning Kamp   munmap((caddr_t)p, nbytes);
635bb6a25fSPoul-Henning Kamp   close(fd);
645bb6a25fSPoul-Henning Kamp   return 1;
655bb6a25fSPoul-Henning Kamp }
66