コード例 #1
0
ファイル: text_mmap.c プロジェクト: enukane/netbsd-src
/**
 * Load the contents of a text file.  There are two separate implementations,
 * depending up on whether mmap(3) is available.
 *
 *  If not available, malloc the file length plus one byte.  Read it in
 *  and NUL terminate.
 *
 *  If available, first check to see if the text file size is a multiple of a
 *  page size.  If it is, map the file size plus an extra page from either
 *  anonymous memory or from /dev/zero.  Then map the file text on top of the
 *  first pages of the anonymous/zero pages.  Otherwise, just map the file
 *  because there will be NUL bytes provided at the end.
 *
 * @param mapinfo a structure holding everything we need to know
 *        about the mapping.
 *
 * @param pzFile name of the file, for error reporting.
 */
static void
load_text_file(tmap_info_t * mapinfo, char const * pzFile)
{
#if ! defined(HAVE_MMAP)
    mapinfo->txt_data = AGALOC(mapinfo->txt_size+1, "file text");
    if (mapinfo->txt_data == NULL) {
        mapinfo->txt_errno = ENOMEM;
        return;
    }

    {
        size_t sz = mapinfo->txt_size;
        char*  pz = mapinfo->txt_data;

        while (sz > 0) {
            ssize_t rdct = read(mapinfo->txt_fd, pz, sz);
            if (rdct <= 0) {
                mapinfo->txt_errno = errno;
                fserr_warn("libopts", "read", pzFile);
                free(mapinfo->txt_data);
                return;
            }

            pz += rdct;
            sz -= rdct;
        }

        *pz = NUL;
    }

    mapinfo->txt_errno   = 0;

#else /* HAVE mmap */
    size_t const pgsz = (size_t)GETPAGESIZE();
    void * map_addr   = NULL;

    (void)pzFile;

    mapinfo->txt_full_size = (mapinfo->txt_size + pgsz) & ~(pgsz - 1);
    if (mapinfo->txt_full_size == (mapinfo->txt_size + pgsz)) {
        /*
         * The text is a multiple of a page boundary.  We must map an
         * extra page so the text ends with a NUL.
         */
#if defined(MAP_ANONYMOUS)
        map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE,
                        MAP_ANONYMOUS|MAP_PRIVATE, AO_INVALID_FD, 0);
#else
        mapinfo->txt_zero_fd = open("/dev/zero", O_RDONLY);

        if (mapinfo->txt_zero_fd == AO_INVALID_FD) {
            mapinfo->txt_errno = errno;
            return;
        }
        map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE,
                        MAP_PRIVATE, mapinfo->txt_zero_fd, 0);
#endif
        if (map_addr == MAP_FAILED_PTR) {
            mapinfo->txt_errno = errno;
            return;
        }
        mapinfo->txt_flags |= MAP_FIXED;
    }

    mapinfo->txt_data =
        mmap(map_addr, mapinfo->txt_size, mapinfo->txt_prot,
             mapinfo->txt_flags, mapinfo->txt_fd, 0);

    if (mapinfo->txt_data == MAP_FAILED_PTR)
        mapinfo->txt_errno = errno;
#endif /* HAVE_MMAP */
}
コード例 #2
0
ファイル: makeshell.c プロジェクト: gokzy/netbsd-src
LOCAL noreturn void
fserr_exit(char const * prog, char const * op, char const * fname)
{
    fserr_warn(prog, op, fname);
    option_exits(EXIT_FAILURE);
}