Example #1
0
static DWORD
TransmitFileMap (SOCKET sd, HANDLE fd, DWORD n)
{
    HANDLE hmap = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL);
    DWORD res = 0;

    if (hmap) {
	DWORD size_hi, size_lo;
	char *base = NULL;

	size_lo = GetFileSize(fd, &size_hi);
	if (size_lo != -1L || SYS_ERRNO == NO_ERROR) {
	    LONG off_hi = 0L, off_lo;
	    int64_t size;
	    DWORD len;

	    off_lo = SetFilePointer(fd, 0, &off_hi, SEEK_CUR);
	    size = INT64_MAKE(size_lo, size_hi) - INT64_MAKE(off_lo, off_hi);
	    len = (size < (int64_t) ~((DWORD) 0))
	     ? (DWORD) size : ~((DWORD) 0);

	    if (n <= 0 || n > len) n = len;
	    size_lo = (off_lo & SYS_GRAN_MASK);
	    base = MapViewOfFile(hmap, FILE_MAP_READ,
	     off_hi, (off_lo & ~SYS_GRAN_MASK), 0);
	}
	CloseHandle(hmap);

	if (base) {
	    WSABUF buf = {n, base + size_lo};

	    if (!WSASend(sd, &buf, 1, &res, 0, NULL, NULL)) {
		LONG off_hi = 0L;
		SetFilePointer(fd, res, &off_hi, SEEK_CUR);
	    }
	    UnmapViewOfFile(base);
	}
    }
    return res;
}
Example #2
0
/*
 * Arguments: membuf_udata, fd_udata, [protection (string: "rw"),
 *	offset (number), num_bytes (number), private/shared (boolean)]
 * Returns: [membuf_udata]
 */
static int
mem_map (lua_State *L)
{
    struct membuf *mb = checkudata(L, 1, MEM_TYPENAME);
    const fd_t *fdp = checkudata(L, 2, FD_TYPENAME);
    fd_t fd = fdp ? (fd_t) *fdp : (fd_t) -1;  /* named or anonymous mapping */
    const char *protstr = lua_tostring(L, 3);
    const lua_Number offset = lua_tonumber(L, 4);
    const int64_t off = (int64_t) offset;  /* to avoid warning */
    size_t len = (size_t) lua_tointeger(L, 5);
    const int is_private = lua_isboolean(L, -1) && lua_toboolean(L, -1);
    int prot = 0, flags;
    void *ptr;

#ifndef _WIN32
#ifndef MAP_ANON
    int is_anon = 0;
#endif

    sys_vm_leave();
    /* length */
    if (!len) {
	struct stat sb;
	if (fd == -1 || fstat(fd, &sb) == -1)
	    goto err;
	sb.st_size -= off;
	len = ((uint64_t) sb.st_size < (uint64_t) ~((size_t) 0))
	 ? (size_t) sb.st_size : ~((size_t) 0);
    }
    /* protection and flags */
    prot = PROT_READ;
    if (protstr) {
	if (protstr[0] == 'w')
	    prot = PROT_WRITE;
	else if (protstr[1] == 'w')
	    prot |= PROT_WRITE;
    }
    flags = is_private ? MAP_PRIVATE : MAP_SHARED;
    /* anonymous shared memory? */
    if (fd == -1) {
#ifdef MAP_ANON
	flags |= MAP_ANON;
#else
	if ((fd = open("/dev/zero", O_RDWR)) == -1)
	    goto err;
	is_anon = 1;
#endif
    }
    /* map file to memory */
    ptr = mmap(0, len, prot, flags, (int) fd, off);
#ifndef MAP_ANON
    if (is_anon) close(fd);
#endif
    if (ptr == MAP_FAILED) goto err;

#else
    sys_vm_leave();
    /* length */
    if (!len) {
	DWORD size_hi, size_lo;
	int64_t size;

	if (fd == (fd_t) -1) goto err;
	size_lo = GetFileSize(fd, &size_hi);
	if (size_lo == (DWORD) -1L && SYS_ERRNO != NO_ERROR)
	    goto err;
	size = INT64_MAKE(size_lo, size_hi) - off;
	len = ((uint64_t) size < (uint64_t) ~((DWORD) 0))
	 ? (DWORD) size : ~((DWORD) 0);
    }
    /* protection and flags */
    if (protstr && (protstr[0] == 'w' || protstr[1] == 'w')) {
	prot = PAGE_READWRITE;
	flags = FILE_MAP_WRITE;
    } else {
	prot = PAGE_READONLY;
	flags = FILE_MAP_READ;
    }
    if (is_private) {
	prot = PAGE_WRITECOPY;
	flags = FILE_MAP_COPY;
    }
    /* map file to memory */
    {
	const DWORD off_hi = INT64_HIGH(off);
	const DWORD off_lo = INT64_LOW(off);
	HANDLE hmap = CreateFileMapping(fd, NULL, prot, 0, len, NULL);

	if (!hmap) goto err;
	ptr = MapViewOfFile(hmap, flags, off_hi, off_lo, len);
	CloseHandle(hmap);
	if (!ptr) goto err;
    }
#endif /* !Win32 */
    sys_vm_enter();

    mb->flags |= MEM_MAP;
    mb->len = len;
    mb->data = ptr;
    lua_settop(L, 1);
    return 1;
 err:
    sys_vm_enter();
    return sys_seterror(L, 0);
}