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")
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')
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()
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)
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)
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)
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)
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
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 ('\\', '/', ':'):