def test_get_osfhandle(): fid = open(str(udir.join('validate_test.txt')), 'w') fd = fid.fileno() rwin32.get_osfhandle(fd) fid.close() raises(OSError, rwin32.get_osfhandle, fd) rwin32.get_osfhandle(0)
def win32_fstat_llimpl(fd): handle = rwin32.get_osfhandle(fd) filetype = win32traits.GetFileType(handle) if filetype == win32traits.FILE_TYPE_CHAR: # console or LPT device return make_stat_result( (win32traits._S_IFCHR, 0, 0, 0, 0, 0, 0, 0, 0, 0)) elif filetype == win32traits.FILE_TYPE_PIPE: # socket or named pipe return make_stat_result( (win32traits._S_IFIFO, 0, 0, 0, 0, 0, 0, 0, 0, 0)) elif filetype == win32traits.FILE_TYPE_UNKNOWN: error = rwin32.GetLastError() if error != 0: raise WindowsError(error, "os_fstat failed") # else: unknown but valid file # normal disk file (FILE_TYPE_DISK) info = lltype.malloc(win32traits.BY_HANDLE_FILE_INFORMATION, flavor='raw', zero=True) try: res = win32traits.GetFileInformationByHandle(handle, info) if res == 0: raise WindowsError(rwin32.GetLastError(), "os_fstat failed") return by_handle_info_to_stat(info) finally: lltype.free(info, flavor='raw')
def win32_fstat_llimpl(fd): handle = rwin32.get_osfhandle(fd) filetype = win32traits.GetFileType(handle) if filetype == win32traits.FILE_TYPE_CHAR: # console or LPT device return make_stat_result((win32traits._S_IFCHR, 0, 0, 0, 0, 0, 0, 0, 0, 0)) elif filetype == win32traits.FILE_TYPE_PIPE: # socket or named pipe return make_stat_result((win32traits._S_IFIFO, 0, 0, 0, 0, 0, 0, 0, 0, 0)) elif filetype == win32traits.FILE_TYPE_UNKNOWN: error = rwin32.GetLastError() if error != 0: raise WindowsError(error, "os_fstat failed") # else: unknown but valid file # normal disk file (FILE_TYPE_DISK) info = lltype.malloc(win32traits.BY_HANDLE_FILE_INFORMATION, flavor='raw', zero=True) try: res = win32traits.GetFileInformationByHandle(handle, info) if res == 0: raise WindowsError(rwin32.GetLastError(), "os_fstat failed") return by_handle_info_to_stat(info) finally: lltype.free(info, flavor='raw')
def ftruncate_win32(fd, size): curpos = os.lseek(fd, 0, 1) try: # move to the position to be truncated os.lseek(fd, size, 0) # Truncate. Note that this may grow the file! handle = get_osfhandle(fd) if not SetEndOfFile(handle): raise WindowsError(GetLastError(), "Could not truncate file") finally: # we restore the file pointer position in any case os.lseek(fd, curpos, 0)
def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0): # XXX flags is or-ed into access by now. flags = 0 # check size boundaries _check_map_size(length) map_size = length if offset < 0: raise RValueError("negative offset") flProtect = 0 dwDesiredAccess = 0 fh = NULL_HANDLE if access == ACCESS_READ: flProtect = PAGE_READONLY dwDesiredAccess = FILE_MAP_READ elif access == _ACCESS_DEFAULT or access == ACCESS_WRITE: flProtect = PAGE_READWRITE dwDesiredAccess = FILE_MAP_WRITE elif access == ACCESS_COPY: flProtect = PAGE_WRITECOPY dwDesiredAccess = FILE_MAP_COPY else: raise RValueError("mmap invalid access parameter.") # assume -1 and 0 both mean invalid file descriptor # to 'anonymously' map memory. if fileno != -1 and fileno != 0: fh = rwin32.get_osfhandle(fileno) # Win9x appears to need us seeked to zero # SEEK_SET = 0 # libc._lseek(fileno, 0, SEEK_SET) # check file size try: low, high = _get_file_size(fh) except OSError: pass # ignore non-seeking files and errors and trust map_size else: if not high and low <= sys.maxint: size = low else: # not so sure if the signed/unsigned strictness is a good idea: high = rffi.cast(lltype.Unsigned, high) low = rffi.cast(lltype.Unsigned, low) size = (high << 32) + low size = rffi.cast(lltype.Signed, size) if map_size == 0: if offset > size: raise RValueError( "mmap offset is greater than file size") map_size = int(size - offset) if map_size != size - offset: raise RValueError("mmap length is too large") elif offset + map_size > size: raise RValueError("mmap length is greater than file size") m = MMap(access, offset) m.file_handle = INVALID_HANDLE m.map_handle = INVALID_HANDLE if fh: # it is necessary to duplicate the handle, so the # Python code can close it on us handle_ref = lltype.malloc(LPHANDLE.TO, 1, flavor='raw') handle_ref[0] = m.file_handle try: res = DuplicateHandle( GetCurrentProcess(), # source process handle fh, # handle to be duplicated GetCurrentProcess(), # target process handle handle_ref, # result 0, # access - ignored due to options value False, # inherited by child procs? DUPLICATE_SAME_ACCESS) # options if not res: raise rwin32.lastWindowsError() m.file_handle = handle_ref[0] finally: lltype.free(handle_ref, flavor='raw') if not map_size: low, high = _get_file_size(fh) if _64BIT: map_size = (low << 32) + 1 else: if high: # file is too large to map completely map_size = -1 else: map_size = low if tagname: m.tagname = tagname # DWORD is a 4-byte int. If int > 4-byte it must be divided if _64BIT: size_hi = (map_size + offset) >> 32 size_lo = (map_size + offset) & 0xFFFFFFFF offset_hi = offset >> 32 offset_lo = offset & 0xFFFFFFFF else: size_hi = 0 size_lo = map_size + offset offset_hi = 0 offset_lo = offset flProtect |= flags m.map_handle = CreateFileMapping(m.file_handle, NULL, flProtect, size_hi, size_lo, m.tagname) if m.map_handle: data = MapViewOfFile(m.map_handle, dwDesiredAccess, offset_hi, offset_lo, length) if data: # XXX we should have a real LPVOID which must always be casted charp = rffi.cast(LPCSTR, data) m.setdata(charp, map_size) return m winerror = rwin32.lastWindowsError() if m.map_handle: rwin32.CloseHandle(m.map_handle) m.map_handle = INVALID_HANDLE raise winerror
def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0): # XXX flags is or-ed into access by now. flags = 0 # check size boundaries _check_map_size(length) map_size = length if offset < 0: raise RValueError("negative offset") flProtect = 0 dwDesiredAccess = 0 fh = NULL_HANDLE if access == ACCESS_READ: flProtect = PAGE_READONLY dwDesiredAccess = FILE_MAP_READ elif access == _ACCESS_DEFAULT or access == ACCESS_WRITE: flProtect = PAGE_READWRITE dwDesiredAccess = FILE_MAP_WRITE elif access == ACCESS_COPY: flProtect = PAGE_WRITECOPY dwDesiredAccess = FILE_MAP_COPY else: raise RValueError("mmap invalid access parameter.") # assume -1 and 0 both mean invalid file descriptor # to 'anonymously' map memory. if fileno != -1 and fileno != 0: fh = rwin32.get_osfhandle(fileno) # Win9x appears to need us seeked to zero # SEEK_SET = 0 # libc._lseek(fileno, 0, SEEK_SET) # check file size try: low, high = _get_file_size(fh) except OSError: pass # ignore non-seeking files and errors and trust map_size else: if not high and low <= sys.maxint: size = low else: # not so sure if the signed/unsigned strictness is a good idea: high = rffi.cast(lltype.Unsigned, high) low = rffi.cast(lltype.Unsigned, low) size = (high << 32) + low size = rffi.cast(lltype.Signed, size) if map_size == 0: if offset > size: raise RValueError( "mmap offset is greater than file size") map_size = int(size - offset) if map_size != size - offset: raise RValueError("mmap length is too large") elif offset + map_size > size: raise RValueError("mmap length is greater than file size") m = MMap(access, offset) m.file_handle = INVALID_HANDLE m.map_handle = INVALID_HANDLE if fh: # it is necessary to duplicate the handle, so the # Python code can close it on us handle_ref = lltype.malloc(LPHANDLE.TO, 1, flavor='raw') handle_ref[0] = m.file_handle try: res = DuplicateHandle(GetCurrentProcess(), # source process handle fh, # handle to be duplicated GetCurrentProcess(), # target process handle handle_ref, # result 0, # access - ignored due to options value False, # inherited by child procs? DUPLICATE_SAME_ACCESS) # options if not res: raise rwin32.lastWindowsError() m.file_handle = handle_ref[0] finally: lltype.free(handle_ref, flavor='raw') if not map_size: low, high = _get_file_size(fh) if _64BIT: map_size = (low << 32) + 1 else: if high: # file is too large to map completely map_size = -1 else: map_size = low if tagname: m.tagname = tagname # DWORD is a 4-byte int. If int > 4-byte it must be divided if _64BIT: size_hi = (map_size + offset) >> 32 size_lo = (map_size + offset) & 0xFFFFFFFF offset_hi = offset >> 32 offset_lo = offset & 0xFFFFFFFF else: size_hi = 0 size_lo = map_size + offset offset_hi = 0 offset_lo = offset flProtect |= flags m.map_handle = CreateFileMapping(m.file_handle, NULL, flProtect, size_hi, size_lo, m.tagname) if m.map_handle: data = MapViewOfFile(m.map_handle, dwDesiredAccess, offset_hi, offset_lo, length) if data: # XXX we should have a real LPVOID which must always be casted charp = rffi.cast(LPCSTR, data) m.setdata(charp, map_size) return m winerror = rwin32.lastWindowsError() if m.map_handle: rwin32.CloseHandle(m.map_handle) m.map_handle = INVALID_HANDLE raise winerror