Ejemplo n.º 1
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")
Ejemplo n.º 2
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')
Ejemplo n.º 3
0
def make_traits(traits):
    win32traits = make_win32_traits(traits)

    class NTTraits(win32traits):

        GetFinalPathNameByHandle_HANDLE = lltype.nullptr(rffi.VOIDP.TO)

        def check_GetFinalPathNameByHandle(self):
            if (self.GetFinalPathNameByHandle_HANDLE != lltype.nullptr(
                    rffi.VOIDP.TO)):
                return True

            from rpython.rlib.rdynload import GetModuleHandle, dlsym
            hKernel32 = GetModuleHandle("KERNEL32")
            try:
                func = dlsym(hKernel32, 'GetFinalPathNameByHandleW')
            except KeyError:
                return False

            self.GetFinalPathNameByHandle_HANDLE = func
            return True

        def GetFinalPathNameByHandle(self, *args):
            assert (self.GetFinalPathNameByHandle_HANDLE != lltype.nullptr(
                rffi.VOIDP.TO))
            return pypy_GetFinalPathNameByHandle(
                self.GetFinalPathNameByHandle_HANDLE, *args)

    return NTTraits()
Ejemplo n.º 4
0
 def win32_xstat(traits, path, traverse=False):
     win32traits = make_win32_traits(traits)
     with lltype.scoped_alloc(win32traits.WIN32_FILE_ATTRIBUTE_DATA) as data:
         res = win32traits.GetFileAttributesEx(path, win32traits.GetFileExInfoStandard, data)
         if res == 0:
             errcode = rwin32.GetLastError_saved()
             if errcode == win32traits.ERROR_SHARING_VIOLATION:
                 res = win32_attributes_from_dir(win32traits, path, data)
         if res == 0:
             errcode = rwin32.GetLastError_saved()
             raise WindowsError(errcode, "os_stat failed")
         return win32_attribute_data_to_stat(win32traits, data)
Ejemplo n.º 5
0
 def win32_xstat(traits, path, traverse=False):
     win32traits = make_win32_traits(traits)
     with lltype.scoped_alloc(
             win32traits.WIN32_FILE_ATTRIBUTE_DATA) as data:
         res = win32traits.GetFileAttributesEx(
             path, win32traits.GetFileExInfoStandard, data)
         if res == 0:
             errcode = rwin32.GetLastError_saved()
             if errcode == win32traits.ERROR_SHARING_VIOLATION:
                 res = win32_attributes_from_dir(win32traits, path, data)
         if res == 0:
             errcode = rwin32.GetLastError_saved()
             raise WindowsError(errcode, "os_stat failed")
         return win32_attribute_data_to_stat(win32traits, data)
Ejemplo n.º 6
0
 def fileno_w(self, space):
     traits = _preferred_traits(u"")
     win32traits = make_win32_traits(traits)
     if self.fd < 0 and self.handle != rwin32.INVALID_HANDLE_VALUE:
         if self.writable:
             self.fd = rwin32.open_osfhandle(
                 rffi.cast(rffi.INTP, self.handle),
                 win32traits._O_WRONLY | win32traits._O_BINARY)
         else:
             self.fd = rwin32.open_osfhandle(
                 rffi.cast(rffi.INTP, self.handle),
                 win32traits._O_RDONLY | win32traits._O_BINARY)
     if self.fd < 0:
         raise err_mode(space, "fileno")
     return space.newint(self.fd)
Ejemplo n.º 7
0
    def win32_xstat3(traits, path, traverse=False):
        # This is the Python3 version of os.stat() or lstat().
        # XXX 'traverse' is ignored, and everything related to
        # the "reparse points" is missing
        win32traits = make_win32_traits(traits)

        hFile = win32traits.CreateFile(
            path,
            win32traits.FILE_READ_ATTRIBUTES,
            0,
            lltype.nullptr(rwin32.LPSECURITY_ATTRIBUTES.TO),
            win32traits.OPEN_EXISTING,
            win32traits.FILE_ATTRIBUTE_NORMAL
            | win32traits.FILE_FLAG_BACKUP_SEMANTICS
            | 0,  # win32traits.FILE_FLAG_OPEN_REPARSE_POINT,
            rwin32.NULL_HANDLE)

        if hFile == rwin32.INVALID_HANDLE_VALUE:
            errcode = rwin32.GetLastError_saved()
            if (errcode != win32traits.ERROR_ACCESS_DENIED
                    and errcode != win32traits.ERROR_SHARING_VIOLATION):
                raise WindowsError(errcode, "os_stat failed")

            with lltype.scoped_alloc(
                    win32traits.WIN32_FILE_ATTRIBUTE_DATA) as data:
                if win32_attributes_from_dir(win32traits, path, data) == 0:
                    raise WindowsError(rwin32.GetLastError_saved(),
                                       "win32_attributes_from_dir failed")
                return win32_attribute_data_to_stat(win32traits, data)

        with lltype.scoped_alloc(win32traits.BY_HANDLE_FILE_INFORMATION,
                                 zero=True) as data:
            res = win32traits.GetFileInformationByHandle(hFile, data)
            errcode = rwin32.GetLastError_saved()
            rwin32.CloseHandle(hFile)
            if res == 0:
                raise WindowsError(errcode,
                                   "GetFileInformationByHandle failed")
            return win32_by_handle_info_to_stat(win32traits, data)
Ejemplo n.º 8
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
Ejemplo n.º 9
0
    def get_known_type(direntp):
        if rposix.HAVE_D_TYPE:
            return rffi.getintfield(direntp, 'c_d_type')
        return DT_UNKNOWN

    def get_inode(direntp):
        return rffi.getintfield(direntp, 'c_d_ino')

else:
    # ----- Win32 version -----
    import stat
    from rpython.rlib._os_support import unicode_traits, string_traits
    from rpython.rlib.rwin32file import make_win32_traits
    from rpython.rlib import rposix_stat

    win32traits = make_win32_traits(unicode_traits)

    SCANDIRP = lltype.Ptr(
        lltype.Struct(
            'SCANDIRP',
            ('filedata', win32traits.WIN32_FIND_DATA),
            ('hFindFile', rwin32.HANDLE),
            ('first_time', lltype.Bool),
        ))
    NULL_DIRP = lltype.nullptr(SCANDIRP.TO)

    # must only be called with utf-8, codepoints!
    def opendir(path, lgt):
        if lgt == 0:
            path = '.'
        if path[-1] not in ('\\', '/', ':'):