def utime(space, w_path, w_tuple): """ utime(path, (atime, mtime)) utime(path, None) Set the access and modified time of the file to the given values. If the second form is used, set the access and modified times to the current time. """ if space.is_w(w_tuple, space.w_None): try: dispatch_filename(rposix.utime, 1)(space, w_path, None) return except OSError as e: raise wrap_oserror2(space, e, w_path) try: msg = "utime() arg 2 must be a tuple (atime, mtime) or None" args_w = space.fixedview(w_tuple) if len(args_w) != 2: raise oefmt(space.w_TypeError, msg) actime = space.float_w(args_w[0], allow_conversion=False) modtime = space.float_w(args_w[1], allow_conversion=False) dispatch_filename(rposix.utime, 2)(space, w_path, (actime, modtime)) except OSError as e: raise wrap_oserror2(space, e, w_path) except OperationError as e: if not e.match(space, space.w_TypeError): raise raise oefmt(space.w_TypeError, msg)
def open(space, w_fname, flag, mode=0777): """Open a file (for low level IO). Return a file descriptor (a small integer).""" try: fd = dispatch_filename(rposix.open)(space, w_fname, flag, mode) except OSError, e: raise wrap_oserror2(space, e, w_fname)
def listdir(space, w_dirname): """Return a list containing the names of the entries in the directory. \tpath: path of directory to list The list is in arbitrary order. It does not include the special entries '.' and '..' even if they are present in the directory.""" try: if space.isinstance_w(w_dirname, space.w_unicode): dirname = FileEncoder(space, w_dirname) result = rposix.listdir(dirname) len_result = len(result) result_w = [None] * len_result for i in range(len_result): if _WIN32: result_w[i] = space.wrap(result[i]) else: w_bytes = space.wrapbytes(result[i]) result_w[i] = space.fsdecode(w_bytes) return space.newlist(result_w) else: dirname = space.str0_w(w_dirname) result = rposix.listdir(dirname) # The list comprehension is a workaround for an obscure translation # bug. return space.newlist_bytes([x for x in result]) except OSError, e: raise wrap_oserror2(space, e, w_dirname)
def statvfs(space, w_path): try: st = dispatch_filename(rposix_stat.statvfs)(space, w_path) except OSError as e: raise wrap_oserror2(space, e, w_path) else: return build_statvfs_result(space, st)
def lstat(space, w_path): "Like stat(path), but do not follow symbolic links." try: st = dispatch_filename(rposix_stat.lstat)(space, w_path) except OSError as e: raise wrap_oserror2(space, e, w_path) else: return build_stat_result(space, st)
def descr_init(self, space, w_name, mode='r', closefd=True): if space.isinstance_w(w_name, space.w_float): raise oefmt(space.w_TypeError, "integer argument expected, got float") fd = -1 try: fd = space.c_int_w(w_name) except OperationError as e: pass else: if fd < 0: raise oefmt(space.w_ValueError, "negative file descriptor") self.readable, self.writable, self.appending, flags = decode_mode(space, mode) fd_is_own = False try: if fd >= 0: try: os.fstat(fd) except OSError as e: if e.errno == errno.EBADF: raise wrap_oserror(space, e) # else: pass self.fd = fd self.closefd = bool(closefd) else: self.closefd = True if not closefd: raise oefmt(space.w_ValueError, "Cannot use closefd=False with file name") from pypy.module.posix.interp_posix import ( dispatch_filename, rposix) try: self.fd = dispatch_filename(rposix.open)( space, w_name, flags, 0666) except OSError as e: raise wrap_oserror2(space, e, w_name, exception_name='w_IOError') finally: fd_is_own = True self._dircheck(space, w_name) space.setattr(self, space.wrap("name"), w_name) if self.appending: # For consistent behaviour, we explicitly seek to the end of file # (otherwise, it might be done only on the first write()). try: os.lseek(self.fd, 0, os.SEEK_END) except OSError as e: raise wrap_oserror(space, e, exception_name='w_IOError') except: if not fd_is_own: self.fd = -1 raise
def _getfinalpathname(space, w_path): path = space.unicode_w(w_path) try: result = nt._getfinalpathname(path) except nt.LLNotImplemented as e: raise OperationError(space.w_NotImplementedError, space.wrap(e.msg)) except OSError as e: raise wrap_oserror2(space, e, w_path) return space.wrap(result)
def readlink(space, w_path): "Return a string representing the path to which the symbolic link points." is_unicode = space.isinstance_w(w_path, space.w_unicode) if is_unicode: path = space.fsencode_w(w_path) else: path = space.bytes0_w(w_path) try: result = os.readlink(path) except OSError, e: raise wrap_oserror2(space, e, w_path)
def _getfullpathname(space, w_path): """helper for ntpath.abspath """ try: if space.isinstance_w(w_path, space.w_unicode): path = FileEncoder(space, w_path) fullpath = rposix._getfullpathname(path) w_fullpath = space.wrap(fullpath) else: path = space.str_w(w_path) fullpath = rposix._getfullpathname(path) w_fullpath = space.wrap(fullpath) except OSError, e: raise wrap_oserror2(space, e, w_path)
def utime(space, w_path, w_tuple): """ utime(path, (atime, mtime)) utime(path, None) Set the access and modified time of the file to the given values. If the second form is used, set the access and modified times to the current time. """ if space.is_w(w_tuple, space.w_None): try: dispatch_filename(rposix.utime, 1)(space, w_path, None) return except OSError, e: raise wrap_oserror2(space, e, w_path)
def _dircheck(self, space, w_filename): # On Unix, fopen will succeed for directories. # In Python, there should be no file objects referring to # directories, so we need a check. if self.fd < 0: return try: st = os.fstat(self.fd) except OSError: return if stat.S_ISDIR(st.st_mode): raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"), w_filename, exception_name='w_IOError')
def access(space, w_path, mode): """ access(path, mode) -> 1 if granted, 0 otherwise Use the real uid/gid to test for access to a path. Note that most operations will use the effective uid/gid, therefore this routine can be used in a suid/sgid environment to test if the invoking user has the specified access to the path. The mode argument can be F_OK to test existence, or the inclusive-OR of R_OK, W_OK, and X_OK. """ try: ok = dispatch_filename(rposix.access)(space, w_path, mode) except OSError, e: raise wrap_oserror2(space, e, w_path)
def _getfullpathname(space, w_path): """helper for ntpath.abspath """ try: if space.isinstance_w(w_path, space.w_unicode): path = FileEncoder(space, w_path) fullpath = rposix.getfullpathname(path) w_fullpath = u2utf8(space, fullpath) else: path = space.bytes0_w(w_path) fullpath = rposix.getfullpathname(path) w_fullpath = space.newbytes(fullpath) except OSError as e: raise wrap_oserror2(space, e, w_path) else: return w_fullpath
def check_mode(self, follow_symlinks): """Get the stat() or lstat() of the direntry, and return the S_IFMT. If calling stat()/lstat() gives us ENOENT, return -1 instead; it is better to give up and answer "no, not this type" to requests, rather than propagate the error. """ try: st = self.get_stat_or_lstat(follow_symlinks) except OSError as e: if e.errno == ENOENT: # not found return -1 raise wrap_oserror2(self.space, e, self.fget_path(self.space), eintr_retry=False) return stat.S_IFMT(st.st_mode)
def stat(space, w_path): """Perform a stat system call on the given path. Return an object with (at least) the following attributes: st_mode st_ino st_dev st_nlink st_uid st_gid st_size st_atime st_mtime st_ctime """ try: st = dispatch_filename(rposix.stat)(space, w_path) except OSError, e: raise wrap_oserror2(space, e, w_path)
def listdir(space, w_dirname): """Return a list containing the names of the entries in the directory. \tpath: path of directory to list The list is in arbitrary order. It does not include the special entries '.' and '..' even if they are present in the directory.""" try: if space.isinstance_w(w_dirname, space.w_unicode): dirname = FileEncoder(space, w_dirname) result = rposix.listdir(dirname) w_fs_encoding = getfilesystemencoding(space) result_w = [space.call_method(space.wrap(s), "decode", w_fs_encoding) for s in result] else: dirname = space.str_w(w_dirname) result = rposix.listdir(dirname) result_w = [space.wrap(s) for s in result] except OSError, e: raise wrap_oserror2(space, e, w_dirname)
def scandir(space, w_path=None): "scandir(path='.') -> iterator of DirEntry objects for given path" if space.is_none(w_path): w_path = space.newunicode(u".") if not _WIN32: if space.isinstance_w(w_path, space.w_bytes): path = space.bytes0_w(w_path) result_is_bytes = True else: path = space.fsencode_w(w_path) result_is_bytes = False else: if space.isinstance_w(w_path, space.w_bytes): raise oefmt( space.w_TypeError, "os.scandir() doesn't support bytes path" " on Windows, use Unicode instead") path = space.unicode_w(w_path) result_is_bytes = False # 'path' is always bytes on posix and always unicode on windows try: dirp = rposix_scandir.opendir(path) except OSError as e: raise wrap_oserror2(space, e, w_path, eintr_retry=False) path_prefix = path if not _WIN32: if len(path_prefix) > 0 and path_prefix[-1] != '/': path_prefix += '/' w_path_prefix = space.newbytes(path_prefix) if not result_is_bytes: w_path_prefix = space.fsdecode(w_path_prefix) else: if len(path_prefix) > 0 and path_prefix[-1] not in (u'\\', u'/', u':'): path_prefix += u'\\' w_path_prefix = space.newunicode(path_prefix) if rposix.HAVE_FSTATAT: dirfd = rposix.c_dirfd(dirp) else: dirfd = -1 return W_ScandirIterator(space, dirp, dirfd, w_path_prefix, result_is_bytes)
def listdir(space, w_dirname): """Return a list containing the names of the entries in the directory. \tpath: path of directory to list The list is in arbitrary order. It does not include the special entries '.' and '..' even if they are present in the directory.""" try: if space.isinstance_w(w_dirname, space.w_unicode): dirname = FileEncoder(space, w_dirname) result = rposix.listdir(dirname) w_fs_encoding = getfilesystemencoding(space) result_w = [ space.call_method(space.wrap(s), "decode", w_fs_encoding) for s in result ] else: dirname = space.str_w(w_dirname) result = rposix.listdir(dirname) result_w = [space.wrap(s) for s in result] except OSError, e: raise wrap_oserror2(space, e, w_dirname)
def next_w(self): if not self.dirp: raise self.fail() if self._in_next: raise self.fail( oefmt( self.space.w_RuntimeError, "cannot use ScandirIterator from multiple threads concurrently" )) self._in_next = True try: # space = self.space while True: try: entry = rposix_scandir.nextentry(self.dirp) except OSError as e: raise self.fail( wrap_oserror2(space, e, self.w_path_prefix, eintr_retry=False)) if not entry: raise self.fail() if not _WIN32: name = rposix_scandir.get_name_bytes(entry) if name != '.' and name != '..': break else: name = rposix_scandir.get_name_unicode(entry) if name != u'.' and name != u'..': break # known_type = rposix_scandir.get_known_type(entry) inode = rposix_scandir.get_inode(entry) finally: self._in_next = False direntry = W_DirEntry(self, name, known_type, inode) return direntry
def chmod(space, w_path, mode): "Change the access permissions of a file." try: dispatch_filename(rposix.chmod)(space, w_path, mode) except OSError, e: raise wrap_oserror2(space, e, w_path)
def remove(space, w_path): """Remove a file (same as unlink(path)).""" try: dispatch_filename(rposix.unlink)(space, w_path) except OSError, e: raise wrap_oserror2(space, e, w_path)
result_w[i] = space.call_method(w_bytes, "decode", w_fs_encoding) except OperationError as e: # fall back to the original byte string if e.async(space): raise result_w[i] = w_bytes return space.newlist(result_w) else: dirname = space.str0_w(w_dirname) result = rposix.listdir(dirname) # The list comprehension is a workaround for an obscure translation # bug. return space.newlist_bytes([x for x in result]) except OSError as e: raise wrap_oserror2(space, e, w_dirname) def pipe(space): "Create a pipe. Returns (read_end, write_end)." try: fd1, fd2 = os.pipe() except OSError as e: raise wrap_oserror(space, e) return space.newtuple([space.wrap(fd1), space.wrap(fd2)]) @unwrap_spec(mode=c_int) def chmod(space, w_path, mode): "Change the access permissions of a file." try: dispatch_filename(rposix.chmod)(space, w_path, mode) except OSError as e:
def lstat(space, w_path): "Like stat(path), but do no follow symbolic links." try: st = dispatch_filename(rposix.lstat)(space, w_path) except OSError, e: raise wrap_oserror2(space, e, w_path)
except OSError, e: raise wrap_oserror2(space, e, w_filename) @unwrap_spec(mode=c_int, device=c_int) def mknod(space, w_filename, mode=0600, device=0): """Create a filesystem node (file, device special file or named pipe) named filename. mode specifies both the permissions to use and the type of node to be created, being combined (bitwise OR) with one of S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK, device defines the newly created device special file (probably using os.makedev()), otherwise it is ignored.""" try: dispatch_filename(rposix.mknod)(space, w_filename, mode, device) except OSError, e: raise wrap_oserror2(space, e, w_filename) @unwrap_spec(mask=c_int) def umask(space, mask): "Set the current numeric umask and return the previous umask." prevmask = os.umask(mask) return space.wrap(prevmask) def getpid(space): "Return the current process id." try: pid = os.getpid() except OSError, e: raise wrap_oserror(space, e)
# else: pass self.fd = fd self.closefd = bool(closefd) else: self.closefd = True if not closefd: raise OperationError(space.w_ValueError, space.wrap( "Cannot use closefd=False with file name")) from pypy.module.posix.interp_posix import ( dispatch_filename, rposix) try: self.fd = dispatch_filename(rposix.open)( space, w_name, flags, 0666) except OSError, e: raise wrap_oserror2(space, e, w_name, exception_name='w_IOError') finally: fd_is_own = True self._dircheck(space, w_name) space.setattr(self, space.wrap("name"), w_name) if self.appending: # For consistent behaviour, we explicitly seek to the end of file # (otherwise, it might be done only on the first write()). try: os.lseek(self.fd, 0, os.SEEK_END) except OSError, e: raise wrap_oserror(space, e, exception_name='w_IOError') except: if not fd_is_own:
def mkfifo(space, w_filename, mode=0666): """Create a FIFO (a POSIX named pipe).""" try: dispatch_filename(rposix.mkfifo)(space, w_filename, mode) except OSError, e: raise wrap_oserror2(space, e, w_filename)
def rmdir(space, w_path): """Remove a directory.""" try: dispatch_filename(rposix.rmdir)(space, w_path) except OSError, e: raise wrap_oserror2(space, e, w_path)
def chdir(space, w_path): """Change the current working directory to the specified path.""" try: dispatch_filename(rposix.chdir)(space, w_path) except OSError, e: raise wrap_oserror2(space, e, w_path)
def wrap_oserror_as_ioerror(space, e, w_filename=None): return wrap_oserror2(space, e, w_filename, w_exception_class=space.w_IOError)
def mkdir(space, w_path, mode=0777): """Create a directory.""" try: dispatch_filename(rposix.mkdir)(space, w_path, mode) except OSError, e: raise wrap_oserror2(space, e, w_path)
def scandir(space, path=None): "scandir(path='.') -> iterator of DirEntry objects for given path" try: space._try_buffer_w(path.w_path, space.BUF_FULL_RO) except BufferInterfaceNotFound: as_bytes = (path.as_unicode is None) result_is_bytes = False else: as_bytes = True result_is_bytes = True if path.as_fd != -1: if not rposix.HAVE_FDOPENDIR: # needed for translation, in practice this is dead code raise oefmt(space.w_TypeError, "scandir: illegal type for path argument") try: dirfd = rposix.dup(path.as_fd, inheritable=False) except OSError as e: raise wrap_oserror(space, e, eintr_retry=False) dirp = rposix.c_fdopendir(dirfd) if not dirp: rposix.c_close(dirfd) e = rposix.get_saved_errno() if e == ENOTDIR: w_type = space.w_NotADirectoryError else: w_type = space.w_ValueError raise oefmt(w_type, "invalid fd %d", path.as_fd) path_prefix = '' elif as_bytes: path_prefix = path.as_bytes try: name = path.as_bytes dirp = rposix_scandir.opendir(name, len(name)) except OSError as e: raise wrap_oserror2(space, e, space.newbytes(path.as_bytes), eintr_retry=False) else: w_path = path.w_path path_prefix = space.utf8_w(w_path) lgt = len(path_prefix) try: dirp = rposix_scandir.opendir(path_prefix, lgt) except OSError as e: raise wrap_oserror2(space, e, w_path, eintr_retry=False) if not _WIN32: if len(path_prefix) > 0 and path_prefix[-1] != '/': path_prefix += '/' w_path_prefix = space.newbytes(path_prefix) if not result_is_bytes: w_path_prefix = space.fsdecode(w_path_prefix) else: if len(path_prefix) > 0 and path_prefix[-1] not in ('\\', '/', ':'): path_prefix += '\\' if result_is_bytes: w_path_prefix = space.newbytes(path_prefix) else: w_path_prefix = space.newtext(path_prefix) if rposix.HAVE_FSTATAT: dirfd = rposix.c_dirfd(dirp) else: dirfd = -1 return W_ScandirIterator(space, dirp, dirfd, w_path_prefix, result_is_bytes, path.as_fd)
self.closefd = bool(closefd) else: self.closefd = True if not closefd: raise OperationError( space.w_ValueError, space.wrap("Cannot use closefd=False with file name")) from pypy.module.posix.interp_posix import (dispatch_filename, rposix) try: self.fd = dispatch_filename(rposix.open)(space, w_name, flags, 0666) except OSError, e: raise wrap_oserror2(space, e, w_name, exception_name='w_IOError') finally: fd_is_own = True self._dircheck(space, w_name) space.setattr(self, space.wrap("name"), w_name) if self.appending: # For consistent behaviour, we explicitly seek to the end of file # (otherwise, it might be done only on the first write()). try: os.lseek(self.fd, 0, os.SEEK_END) except OSError, e: raise wrap_oserror(space, e, exception_name='w_IOError') except:
def descr_init(self, space, w_name, mode='r', closefd=True): if space.isinstance_w(w_name, space.w_float): raise oefmt(space.w_TypeError, "integer argument expected, got float") fd = -1 try: fd = space.c_int_w(w_name) except OperationError as e: pass else: if fd < 0: raise oefmt(space.w_ValueError, "negative file descriptor") self.readable, self.writable, self.appending, flags = decode_mode( space, mode) fd_is_own = False try: if fd >= 0: try: os.fstat(fd) except OSError as e: if e.errno == errno.EBADF: raise wrap_oserror(space, e) # else: pass self.fd = fd self.closefd = bool(closefd) else: self.closefd = True if not closefd: raise oefmt(space.w_ValueError, "Cannot use closefd=False with file name") from pypy.module.posix.interp_posix import (dispatch_filename, rposix) try: self.fd = dispatch_filename(rposix.open)(space, w_name, flags, 0666) except OSError as e: raise wrap_oserror2(space, e, w_name, w_exception_class=space.w_IOError) finally: fd_is_own = True self._dircheck(space, w_name) space.setattr(self, space.newtext("name"), w_name) if self.appending: # For consistent behaviour, we explicitly seek to the end of file # (otherwise, it might be done only on the first write()). try: os.lseek(self.fd, 0, os.SEEK_END) except OSError as e: raise wrap_oserror(space, e, w_exception_class=space.w_IOError) except: if not fd_is_own: self.fd = -1 raise
dispatch_filename(rposix.mkfifo)(space, w_filename, mode) except OSError, e: raise wrap_oserror2(space, e, w_filename) @unwrap_spec(mode=c_int, device=c_int) def mknod(space, w_filename, mode=0600, device=0): """Create a filesystem node (file, device special file or named pipe) named filename. mode specifies both the permissions to use and the type of node to be created, being combined (bitwise OR) with one of S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK, device defines the newly created device special file (probably using os.makedev()), otherwise it is ignored.""" try: dispatch_filename(rposix.mknod)(space, w_filename, mode, device) except OSError, e: raise wrap_oserror2(space, e, w_filename) @unwrap_spec(mask=c_int) def umask(space, mask): "Set the current numeric umask and return the previous umask." prevmask = os.umask(mask) return space.wrap(prevmask) def getpid(space): "Return the current process id." try: pid = os.getpid() except OSError, e: raise wrap_oserror(space, e) return space.wrap(pid)
raise w_res = w_bytes elif isinstance(res, unicode): w_res = u2utf8(space, res) else: assert False result_w[i] = w_res return space.newlist(result_w) else: dirname = space.bytes0_w(w_dirname) result = rposix.listdir(dirname) # The list comprehension is a workaround for an obscure translation # bug. return space.newlist_bytes([x for x in result]) except OSError as e: raise wrap_oserror2(space, e, w_dirname) def pipe(space): "Create a pipe. Returns (read_end, write_end)." try: fd1, fd2 = os.pipe() except OSError as e: raise wrap_oserror(space, e) return space.newtuple([space.newint(fd1), space.newint(fd2)]) @unwrap_spec(mode=c_int) def chmod(space, w_path, mode): "Change the access permissions of a file." try:
def descr_init(self, space, w_name, mode='r', closefd=True, w_opener=None): if self.fd >= 0: if self.closefd: self._close(space) else: self.fd = -1 if space.isinstance_w(w_name, space.w_float): raise oefmt(space.w_TypeError, "integer argument expected, got float") fd = -1 try: fd = space.c_int_w(w_name) except OperationError as e: pass else: if fd < 0: raise oefmt(space.w_ValueError, "negative file descriptor") self.readable, self.writable, self.created, self.appending, flags = decode_mode(space, mode) if rposix.O_CLOEXEC is not None: flags |= rposix.O_CLOEXEC fd_is_own = False try: if fd >= 0: self.fd = fd self.closefd = bool(closefd) else: self.closefd = True if not closefd: raise oefmt(space.w_ValueError, "Cannot use closefd=False with file name") if space.is_none(w_opener): from pypy.module.posix.interp_posix import dispatch_filename, fspath w_path = fspath(space, w_name) while True: try: self.fd = dispatch_filename(rposix.open)( space, w_path, flags, 0666) fd_is_own = True break except OSError as e: wrap_oserror2(space, e, w_name, w_exception_class=space.w_IOError, eintr_retry=True) try: _open_inhcache.set_non_inheritable(self.fd) except OSError as e: raise wrap_oserror2(space, e, w_name, eintr_retry=False) else: w_fd = space.call_function(w_opener, w_name, space.newint(flags)) try: self.fd = space.int_w(w_fd) if self.fd < 0: # The opener returned a negative result instead # of raising an exception raise oefmt(space.w_ValueError, "opener returned %d", self.fd) fd_is_own = True except OperationError as e: if not e.match(space, space.w_TypeError): raise raise oefmt(space.w_TypeError, "expected integer from opener") if not rposix._WIN32: try: rposix.set_inheritable(self.fd, False) except OSError as e: raise wrap_oserror2(space, e, w_name, eintr_retry=False) try: st = os.fstat(self.fd) except OSError as e: raise wrap_oserror(space, e, eintr_retry=False) # On Unix, fopen will succeed for directories. # In Python, there should be no file objects referring to # directories, so we need a check. if stat.S_ISDIR(st.st_mode): raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"), w_name, w_exception_class=space.w_IOError, eintr_retry=False) self.blksize = DEFAULT_BUFFER_SIZE if HAS_BLKSIZE and st.st_blksize > 1: self.blksize = st.st_blksize _setfd_binary(self.fd) space.setattr(self, space.newtext("name"), w_name) if self.appending: # For consistent behaviour, we explicitly seek to the end of file # (otherwise, it might be done only on the first write()). try: os.lseek(self.fd, 0, os.SEEK_END) except OSError as e: raise wrap_oserror(space, e, w_exception_class=space.w_IOError, eintr_retry=False) except: if not fd_is_own: self.fd = -1 self._close(space) raise