xref: /freebsd/contrib/expat/xmlwf/unixfilemap.c (revision 6b2c1e49da284f28ec7b52f7c031474087e37104)
10a48773fSEric van Gyzen /*
20a48773fSEric van Gyzen                             __  __            _
30a48773fSEric van Gyzen                          ___\ \/ /_ __   __ _| |_
40a48773fSEric van Gyzen                         / _ \\  /| '_ \ / _` | __|
50a48773fSEric van Gyzen                        |  __//  \| |_) | (_| | |_
60a48773fSEric van Gyzen                         \___/_/\_\ .__/ \__,_|\__|
70a48773fSEric van Gyzen                                  |_| XML parser
80a48773fSEric van Gyzen 
90a48773fSEric van Gyzen    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
100a48773fSEric van Gyzen    Copyright (c) 2000-2017 Expat development team
110a48773fSEric van Gyzen    Licensed under the MIT license:
120a48773fSEric van Gyzen 
130a48773fSEric van Gyzen    Permission is  hereby granted,  free of charge,  to any  person obtaining
140a48773fSEric van Gyzen    a  copy  of  this  software   and  associated  documentation  files  (the
150a48773fSEric van Gyzen    "Software"),  to  deal in  the  Software  without restriction,  including
160a48773fSEric van Gyzen    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
170a48773fSEric van Gyzen    distribute, sublicense, and/or sell copies of the Software, and to permit
180a48773fSEric van Gyzen    persons  to whom  the Software  is  furnished to  do so,  subject to  the
190a48773fSEric van Gyzen    following conditions:
200a48773fSEric van Gyzen 
210a48773fSEric van Gyzen    The above copyright  notice and this permission notice  shall be included
220a48773fSEric van Gyzen    in all copies or substantial portions of the Software.
230a48773fSEric van Gyzen 
240a48773fSEric van Gyzen    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
250a48773fSEric van Gyzen    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
260a48773fSEric van Gyzen    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
270a48773fSEric van Gyzen    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
280a48773fSEric van Gyzen    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
290a48773fSEric van Gyzen    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
300a48773fSEric van Gyzen    USE OR OTHER DEALINGS IN THE SOFTWARE.
315bb6a25fSPoul-Henning Kamp */
325bb6a25fSPoul-Henning Kamp 
335bb6a25fSPoul-Henning Kamp #include <sys/types.h>
345bb6a25fSPoul-Henning Kamp #include <sys/mman.h>
355bb6a25fSPoul-Henning Kamp #include <sys/stat.h>
365bb6a25fSPoul-Henning Kamp #include <fcntl.h>
375bb6a25fSPoul-Henning Kamp #include <errno.h>
385bb6a25fSPoul-Henning Kamp #include <string.h>
395bb6a25fSPoul-Henning Kamp #include <stdio.h>
405bb6a25fSPoul-Henning Kamp #include <unistd.h>
415bb6a25fSPoul-Henning Kamp 
425bb6a25fSPoul-Henning Kamp #ifndef MAP_FILE
435bb6a25fSPoul-Henning Kamp #  define MAP_FILE 0
445bb6a25fSPoul-Henning Kamp #endif
455bb6a25fSPoul-Henning Kamp 
460a48773fSEric van Gyzen #include "xmltchar.h"
475bb6a25fSPoul-Henning Kamp #include "filemap.h"
485bb6a25fSPoul-Henning Kamp 
490a48773fSEric van Gyzen #ifdef XML_UNICODE_WCHAR_T
500a48773fSEric van Gyzen #  define XML_FMT_STR "ls"
510a48773fSEric van Gyzen #else
520a48773fSEric van Gyzen #  define XML_FMT_STR "s"
530a48773fSEric van Gyzen #endif
540a48773fSEric van Gyzen 
555bb6a25fSPoul-Henning Kamp int
560a48773fSEric van Gyzen filemap(const tchar *name,
570a48773fSEric van Gyzen         void (*processor)(const void *, size_t, const tchar *, void *arg),
58*6b2c1e49SXin LI         void *arg) {
595bb6a25fSPoul-Henning Kamp   int fd;
605bb6a25fSPoul-Henning Kamp   size_t nbytes;
615bb6a25fSPoul-Henning Kamp   struct stat sb;
625bb6a25fSPoul-Henning Kamp   void *p;
635bb6a25fSPoul-Henning Kamp 
640a48773fSEric van Gyzen   fd = topen(name, O_RDONLY);
655bb6a25fSPoul-Henning Kamp   if (fd < 0) {
660a48773fSEric van Gyzen     tperror(name);
675bb6a25fSPoul-Henning Kamp     return 0;
685bb6a25fSPoul-Henning Kamp   }
695bb6a25fSPoul-Henning Kamp   if (fstat(fd, &sb) < 0) {
700a48773fSEric van Gyzen     tperror(name);
715bb6a25fSPoul-Henning Kamp     close(fd);
725bb6a25fSPoul-Henning Kamp     return 0;
735bb6a25fSPoul-Henning Kamp   }
745bb6a25fSPoul-Henning Kamp   if (! S_ISREG(sb.st_mode)) {
755bb6a25fSPoul-Henning Kamp     close(fd);
760a48773fSEric van Gyzen     fprintf(stderr, "%" XML_FMT_STR ": not a regular file\n", name);
775bb6a25fSPoul-Henning Kamp     return 0;
785bb6a25fSPoul-Henning Kamp   }
790a48773fSEric van Gyzen   if (sb.st_size > XML_MAX_CHUNK_LEN) {
800a48773fSEric van Gyzen     close(fd);
810a48773fSEric van Gyzen     return 2; /* Cannot be passed to XML_Parse in one go */
820a48773fSEric van Gyzen   }
835bb6a25fSPoul-Henning Kamp 
845bb6a25fSPoul-Henning Kamp   nbytes = sb.st_size;
85220ed979SColeman Kane   /* mmap fails for zero length files */
86220ed979SColeman Kane   if (nbytes == 0) {
87220ed979SColeman Kane     static const char c = '\0';
88220ed979SColeman Kane     processor(&c, 0, name, arg);
89220ed979SColeman Kane     close(fd);
90220ed979SColeman Kane     return 1;
91220ed979SColeman Kane   }
92*6b2c1e49SXin LI   p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE,
93*6b2c1e49SXin LI                    fd, (off_t)0);
945bb6a25fSPoul-Henning Kamp   if (p == (void *)-1) {
950a48773fSEric van Gyzen     tperror(name);
965bb6a25fSPoul-Henning Kamp     close(fd);
975bb6a25fSPoul-Henning Kamp     return 0;
985bb6a25fSPoul-Henning Kamp   }
995bb6a25fSPoul-Henning Kamp   processor(p, nbytes, name, arg);
100be8aff81SXin LI   munmap((void *)p, nbytes);
1015bb6a25fSPoul-Henning Kamp   close(fd);
1025bb6a25fSPoul-Henning Kamp   return 1;
1035bb6a25fSPoul-Henning Kamp }
104