xref: /netbsd-src/external/mit/expat/dist/xmlwf/unixfilemap.c (revision 0315d311127d32bec5b7d97b2ab4b7dd0718f175)
19fd04a41Smaya /*
29fd04a41Smaya                             __  __            _
39fd04a41Smaya                          ___\ \/ /_ __   __ _| |_
49fd04a41Smaya                         / _ \\  /| '_ \ / _` | __|
59fd04a41Smaya                        |  __//  \| |_) | (_| | |_
69fd04a41Smaya                         \___/_/\_\ .__/ \__,_|\__|
79fd04a41Smaya                                  |_| XML parser
89fd04a41Smaya 
99fd04a41Smaya    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10*0315d311Schristos    Copyright (c) 2000      Clark Cooper <coopercc@users.sourceforge.net>
11*0315d311Schristos    Copyright (c) 2001-2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
12*0315d311Schristos    Copyright (c) 2006      Karl Waclawek <karl@waclawek.net>
13*0315d311Schristos    Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
14*0315d311Schristos    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
159fd04a41Smaya    Licensed under the MIT license:
169fd04a41Smaya 
179fd04a41Smaya    Permission is  hereby granted,  free of charge,  to any  person obtaining
189fd04a41Smaya    a  copy  of  this  software   and  associated  documentation  files  (the
199fd04a41Smaya    "Software"),  to  deal in  the  Software  without restriction,  including
209fd04a41Smaya    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
219fd04a41Smaya    distribute, sublicense, and/or sell copies of the Software, and to permit
229fd04a41Smaya    persons  to whom  the Software  is  furnished to  do so,  subject to  the
239fd04a41Smaya    following conditions:
249fd04a41Smaya 
259fd04a41Smaya    The above copyright  notice and this permission notice  shall be included
269fd04a41Smaya    in all copies or substantial portions of the Software.
279fd04a41Smaya 
289fd04a41Smaya    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
299fd04a41Smaya    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
309fd04a41Smaya    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
319fd04a41Smaya    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
329fd04a41Smaya    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
339fd04a41Smaya    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
349fd04a41Smaya    USE OR OTHER DEALINGS IN THE SOFTWARE.
35d50d1d7fStron */
36d50d1d7fStron 
37d50d1d7fStron #include <sys/types.h>
38d50d1d7fStron #include <sys/mman.h>
39d50d1d7fStron #include <sys/stat.h>
40d50d1d7fStron #include <fcntl.h>
41d50d1d7fStron #include <errno.h>
42d50d1d7fStron #include <string.h>
43d50d1d7fStron #include <stdio.h>
44d50d1d7fStron #include <unistd.h>
45d50d1d7fStron 
46d50d1d7fStron #ifndef MAP_FILE
47d50d1d7fStron #  define MAP_FILE 0
48d50d1d7fStron #endif
49d50d1d7fStron 
509fd04a41Smaya #include "xmltchar.h"
51d50d1d7fStron #include "filemap.h"
52d50d1d7fStron 
539fd04a41Smaya #ifdef XML_UNICODE_WCHAR_T
549fd04a41Smaya #  define XML_FMT_STR "ls"
559fd04a41Smaya #else
569fd04a41Smaya #  define XML_FMT_STR "s"
579fd04a41Smaya #endif
589fd04a41Smaya 
59d50d1d7fStron int
filemap(const tchar * name,void (* processor)(const void *,size_t,const tchar *,void * arg),void * arg)609fd04a41Smaya filemap(const tchar *name,
619fd04a41Smaya         void (*processor)(const void *, size_t, const tchar *, void *arg),
629fd04a41Smaya         void *arg) {
63d50d1d7fStron   int fd;
64d50d1d7fStron   size_t nbytes;
65d50d1d7fStron   struct stat sb;
66d50d1d7fStron   void *p;
67d50d1d7fStron 
689fd04a41Smaya   fd = topen(name, O_RDONLY);
69d50d1d7fStron   if (fd < 0) {
709fd04a41Smaya     tperror(name);
71d50d1d7fStron     return 0;
72d50d1d7fStron   }
73d50d1d7fStron   if (fstat(fd, &sb) < 0) {
749fd04a41Smaya     tperror(name);
75d50d1d7fStron     close(fd);
76d50d1d7fStron     return 0;
77d50d1d7fStron   }
78d50d1d7fStron   if (! S_ISREG(sb.st_mode)) {
79d50d1d7fStron     close(fd);
809fd04a41Smaya     fprintf(stderr, "%" XML_FMT_STR ": not a regular file\n", name);
81d50d1d7fStron     return 0;
82d50d1d7fStron   }
834c74f82dSchristos   if (sb.st_size > XML_MAX_CHUNK_LEN) {
844c74f82dSchristos     close(fd);
854c74f82dSchristos     return 2; /* Cannot be passed to XML_Parse in one go */
864c74f82dSchristos   }
87d50d1d7fStron 
88d50d1d7fStron   nbytes = sb.st_size;
89d50d1d7fStron   /* mmap fails for zero length files */
90d50d1d7fStron   if (nbytes == 0) {
91d50d1d7fStron     static const char c = '\0';
92d50d1d7fStron     processor(&c, 0, name, arg);
93d50d1d7fStron     close(fd);
94d50d1d7fStron     return 1;
95d50d1d7fStron   }
969fd04a41Smaya   p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE,
979fd04a41Smaya                    fd, (off_t)0);
98d50d1d7fStron   if (p == (void *)-1) {
999fd04a41Smaya     tperror(name);
100d50d1d7fStron     close(fd);
101d50d1d7fStron     return 0;
102d50d1d7fStron   }
103d50d1d7fStron   processor(p, nbytes, name, arg);
1048a91d82aSspz   munmap((void *)p, nbytes);
105d50d1d7fStron   close(fd);
106d50d1d7fStron   return 1;
107d50d1d7fStron }
108