Beispiel #1
0
def test_get_osfhandle():
    fid = open(str(udir.join("validate_test.txt")), "w")
    fd = fid.fileno()
    rwin32.get_osfhandle(fd)
    fid.close()
    py.test.raises(OSError, rwin32.get_osfhandle, fd)
    rwin32.get_osfhandle(0)
Beispiel #2
0
def test_get_osfhandle():
    fid = open(str(udir.join('validate_test.txt')), 'w')
    fd = fid.fileno()
    rwin32.get_osfhandle(fd)
    fid.close()
    py.test.raises(OSError, rwin32.get_osfhandle, fd)
    rwin32.get_osfhandle(0)
Beispiel #3
0
def test_get_osfhandle():
    fid = open(str(udir.join('validate_test.txt')), 'w')
    fd = fid.fileno()
    rwin32.get_osfhandle(fd)
    fid.close()
    # Somehow the SuppressIPH's c_enter_suppress_iph, which resolves
    # to calling _set_thread_local_invalid_parameter_handler, does not work
    # untranslated. After translation it does work.
    # py.test.raises(OSError, rwin32.get_osfhandle, fd)
    rwin32.get_osfhandle(0)
Beispiel #4
0
def fstat(fd):
    if not _WIN32:
        with lltype.scoped_alloc(STAT_STRUCT.TO) as stresult:
            handle_posix_error("fstat", c_fstat(fd, stresult))
            return build_stat_result(stresult)
    else:
        handle = rwin32.get_osfhandle(fd)
        win32traits = make_win32_traits(string_traits)
        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_saved()
            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_saved(), "os_fstat failed")
            return win32_by_handle_info_to_stat(win32traits, info)
        finally:
            lltype.free(info, flavor="raw")
Beispiel #5
0
def fstat(fd):
    if not _WIN32:
        with lltype.scoped_alloc(STAT_STRUCT.TO) as stresult:
            handle_posix_error('fstat', c_fstat(fd, stresult))
            return build_stat_result(stresult)
    else:
        handle = rwin32.get_osfhandle(fd)
        win32traits = make_win32_traits(string_traits)
        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, 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, 0, 0, 0))
        elif filetype == win32traits.FILE_TYPE_UNKNOWN:
            error = rwin32.GetLastError_saved()
            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_saved(),
                                   "os_fstat failed")
            return win32_by_handle_info_to_stat(win32traits, info)
        finally:
            lltype.free(info, flavor='raw')
Beispiel #6
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')
Beispiel #7
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_saved()
            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_saved(),
                                   "os_fstat failed")
            return by_handle_info_to_stat(info)
        finally:
            lltype.free(info, flavor='raw')
Beispiel #8
0
 def _getfileinformation_llimpl(fd):
     hFile = rwin32.get_osfhandle(fd)
     with lltype.scoped_alloc(
         win32traits.BY_HANDLE_FILE_INFORMATION) as info:
         if win32traits.GetFileInformationByHandle(hFile, info) == 0:
             raise rwin32.lastSavedWindowsError("_getfileinformation")
         return (rffi.cast(lltype.Signed, info.c_dwVolumeSerialNumber),
                 rffi.cast(lltype.Signed, info.c_nFileIndexHigh),
                 rffi.cast(lltype.Signed, info.c_nFileIndexLow))
Beispiel #9
0
def get_osfhandle(space, fd):
    """get_osfhandle()

    Return the handle corresponding to the file descriptor (windows only)
    """
    from rpython.rlib import rwin32  # Windows only
    try:
        ret = rwin32.get_osfhandle(fd)
        return space.newint(rffi.cast(rffi.INT, ret))
    except OSError as e:
        raise wrap_oserror(space, e)
Beispiel #10
0
 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 OSError(GetLastError_saved(), "Could not truncate file")
     finally:
         # we restore the file pointer position in any case
         os.lseek(fd, curpos, 0)
Beispiel #11
0
 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 OSError(GetLastError_saved(), "Could not truncate file")
     finally:
         # we restore the file pointer position in any case
         os.lseek(fd, curpos, 0)
Beispiel #12
0
def _pyio_get_console_type(space, w_path_or_fd):

    # XXX 2020-07-22 Disable WinConsoleIO since it is flaky
    return '\0'

    if space.isinstance_w(w_path_or_fd, space.w_int):
        fd = space.int_w(w_path_or_fd)
        handle = rwin32.get_osfhandle(fd)
        if handle == rwin32.INVALID_HANDLE_VALUE:
            return '\0'
        return _get_console_type(handle)

    decoded = space.fsdecode_w(w_path_or_fd)
    if not decoded:
        return '\0'

    m = '\0'

    # In CPython the _wcsicmp function is used to perform case insensitive comparison
    dlower = decoded.lower()
    if len(dlower) >= 4:
        if dlower[:4] == '\\\\.\\' or dlower[:4] == '\\\\?\\':
            dlower = dlower[4:]
        if dlower[:4] == '//./' or dlower[:4] == '//?/':
            dlower = dlower[4:]
        elif dlower[:3] == 'c:\\':
            dlower = dlower[3:]
    if dlower == 'conin$':
        m = 'r'
    elif dlower == 'conout$':
        m = 'w'
    elif dlower == 'con':
        m = 'x'

    # TODO: call GetFullPathNameW to deal with C:\Program Files\CONOUT$
    return m
Beispiel #13
0
    def descr_init(self,
                   space,
                   w_nameobj,
                   mode='r',
                   closefd=True,
                   w_opener=None):
        name = rffi.cast(rffi.CWCHARP, 0)
        self.fd = -1
        self.handle = rwin32.INVALID_HANDLE_VALUE
        self.readable = False
        self.writable = False
        self.blksize = 0
        rwa = False
        console_type = '\0'
        self.buf = ''

        if space.isinstance_w(w_nameobj, space.w_int):
            self.fd = space.int_w(w_nameobj)
            if self.fd < 0:
                raise oefmt(space.w_ValueError, "negative file descriptor")

        # make the flow analysis happy,otherwise it thinks w_path
        # is undefined later
        w_path = w_nameobj
        if self.fd < 0:
            from pypy.module.posix.interp_posix import fspath
            w_path = fspath(space, w_nameobj)
            console_type = _pyio_get_console_type(space, w_path)
            if not console_type:
                raise oefmt(space.w_ValueError, "Invalid console type")
            if console_type == '\0':
                raise oefmt(space.w_ValueError, "Cannot open non-console file")
        self.mode = 'u'
        for char in mode:
            if char in "+ax":
                # OK do nothing
                pass
            elif char == "b":
                self.mode = 'b'
            elif char == "r":
                if rwa:
                    raise oefmt(space.w_ValueError, "invalid mode: %s", mode)
                rwa = True
                self.readable = True
                if console_type == "x":
                    console_type = "r"
            elif char == "w":
                if rwa:
                    raise oefmt(space.w_ValueError, "invalid mode: %s", mode)
                rwa = True
                self.writable = True
                if console_type == 'x':
                    console_type = 'w'
            else:
                raise oefmt(space.w_ValueError, "invalid mode: %s", mode)
        if not rwa:
            raise oefmt(space.w_ValueError,
                        "Must have exactly one of read or write mode")

        if self.fd >= 0:
            self.handle = rwin32.get_osfhandle(self.fd)
            self.closehandle = False
        else:
            access = rwin32.GENERIC_READ
            self.closehandle = True
            if not closefd:
                raise oefmt(space.w_ValueError,
                            "Cannot use closefd=False with a file name")
            if self.writable:
                access = rwin32.GENERIC_WRITE

            traits = _preferred_traits(space.realunicode_w(w_path))
            if not (traits.str is unicode):
                raise oefmt(space.w_ValueError, "Non-unicode string name %s",
                            traits.str)
            win32traits = make_win32_traits(traits)

            pathlen = space.len_w(w_path)
            name = rffi.utf82wcharp(space.utf8_w(w_path), pathlen)
            self.handle = win32traits.CreateFile(
                name, rwin32.GENERIC_READ | rwin32.GENERIC_WRITE,
                rwin32.FILE_SHARE_READ | rwin32.FILE_SHARE_WRITE, rffi.NULL,
                win32traits.OPEN_EXISTING, 0, rffi.cast(rwin32.HANDLE, 0))
            if self.handle == rwin32.INVALID_HANDLE_VALUE:
                self.handle = win32traits.CreateFile(
                    name, access,
                    rwin32.FILE_SHARE_READ | rwin32.FILE_SHARE_WRITE,
                    rffi.NULL, win32traits.OPEN_EXISTING, 0,
                    rffi.cast(rwin32.HANDLE, 0))
            lltype.free(name, flavor='raw')

            if self.handle == rwin32.INVALID_HANDLE_VALUE:
                raise WindowsError(rwin32.GetLastError_saved(),
                                   "Failed to open handle")

        if console_type == '\0':
            console_type = _get_console_type(self.handle)

        if console_type == '\0':
            raise oefmt(space.w_ValueError, "Cannot open non-console file")

        if self.writable and console_type != 'w':
            raise oefmt(space.w_ValueError,
                        "Cannot open input buffer for writing")

        if self.readable and console_type != 'r':
            raise oefmt(space.w_ValueError,
                        "Cannot open output buffer for reading")

        self.blksize = DEFAULT_BUFFER_SIZE
Beispiel #14
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 size == 0:
                        raise RValueError("cannot mmap an empty file")
                    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.lastSavedWindowsError()
                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.lastSavedWindowsError()
        if m.map_handle:
            rwin32.CloseHandle_no_err(m.map_handle)
        m.map_handle = INVALID_HANDLE
        raise winerror
Beispiel #15
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 size == 0:
                        raise RValueError("cannot mmap an empty file")
                    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.lastSavedWindowsError()
                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.lastSavedWindowsError()
        if m.map_handle:
            rwin32.CloseHandle_no_err(m.map_handle)
        m.map_handle = INVALID_HANDLE
        raise winerror