def time_sleep_llimpl(secs): void = lltype.nullptr(rffi.VOIDP.TO) t = lltype.malloc(self.TIMEVAL, flavor='raw') try: frac = math.fmod(secs, 1.0) t.c_tv_sec = int(secs) t.c_tv_usec = int(frac*1000000.0) if rffi.cast(rffi.LONG, c_select(0, void, void, void, t)) != 0: errno = rposix.get_errno() if errno != EINTR: raise OSError(rposix.get_errno(), "Select failed") finally: lltype.free(t, flavor='raw')
def tcsetattr_llimpl(fd, when, attributes): c_struct = lltype.malloc(TERMIOSP.TO, flavor='raw') c_struct.c_c_iflag, c_struct.c_c_oflag, c_struct.c_c_cflag, \ c_struct.c_c_lflag, ispeed, ospeed, cc = attributes try: for i in range(NCCS): c_struct.c_c_cc[i] = rffi.r_uchar(ord(cc[i][0])) if c_cfsetispeed(c_struct, ispeed) < 0: raise OSError(rposix.get_errno(), 'tcsetattr failed') if c_cfsetospeed(c_struct, ospeed) < 0: raise OSError(rposix.get_errno(), 'tcsetattr failed') if c_tcsetattr(fd, when, c_struct) < 0: raise OSError(rposix.get_errno(), 'tcsetattr failed') finally: lltype.free(c_struct, flavor='raw')
def startup(self): if not OPROFILE_AVAILABLE: return agent = op_open_agent() if not agent: raise OProfileError(get_errno(), "startup") self.agent = agent
def flush(self, offset=0, size=0): self.check_valid() if size == 0: size = self.size if offset < 0 or size < 0 or offset + size > self.size: raise RValueError("flush values out of range") else: start = self.getptr(offset) if _MS_WINDOWS: res = FlushViewOfFile(start, size) # XXX res == 0 means that an error occurred, but in CPython # this is not checked return res elif _POSIX: ## XXX why is this code here? There is no equivalent in CPython ## if _LINUX: ## # alignment of the address ## value = cast(self.data, c_void_p).value ## aligned_value = value & ~(PAGESIZE - 1) ## # the size should be increased too. otherwise the final ## # part is not "msynced" ## new_size = size + value & (PAGESIZE - 1) res = c_msync(start, size, MS_SYNC) if res == -1: errno = rposix.get_errno() raise OSError(errno, os.strerror(errno)) return 0
def bindtextdomain(space, domain, w_dir): """bindtextdomain(domain, dir) -> string Bind the C library's domain to dir.""" if space.is_w(w_dir, space.w_None): dir = None domain_c = rffi.str2charp(domain) try: dirname = _bindtextdomain(domain_c, dir) finally: rffi.free_charp(domain_c) else: dir = space.str_w(w_dir) domain_c = rffi.str2charp(domain) dir_c = rffi.str2charp(dir) try: dirname = _bindtextdomain(domain_c, dir_c) finally: rffi.free_charp(domain_c) rffi.free_charp(dir_c) if not dirname: errno = rposix.get_errno() raise OperationError(space.w_OSError, space.wrap(errno)) return space.wrap(rffi.charp2str(dirname))
def exception_from_errno(space, w_type): from pypy.rlib.rposix import get_errno errno = get_errno() msg = os.strerror(errno) w_error = space.call_function(w_type, space.wrap(errno), space.wrap(msg)) return OperationError(w_type, w_error)
def _sem_timedwait_save(sem, deadline): delay = 0 void = lltype.nullptr(rffi.VOIDP.TO) with lltype.scoped_alloc(TIMEVALP.TO, 1) as tvdeadline: while True: # poll if _sem_trywait(sem) == 0: return 0 elif rposix.get_errno() != errno.EAGAIN: return -1 now = gettimeofday() c_tv_sec = rffi.getintfield(deadline[0], 'c_tv_sec') c_tv_nsec = rffi.getintfield(deadline[0], 'c_tv_nsec') if (c_tv_sec < now[0] or (c_tv_sec == now[0] and c_tv_nsec <= now[1])): rposix.set_errno(errno.ETIMEDOUT) return -1 # calculate how much time is left difference = ((c_tv_sec - now[0]) * 1000000 + (c_tv_nsec - now[1])) # check delay not too long -- maximum is 20 msecs if delay > 20000: delay = 20000 if delay > difference: delay = difference delay += 1000 # sleep rffi.setintfield(tvdeadline[0], 'c_tv_sec', delay / 1000000) rffi.setintfield(tvdeadline[0], 'c_tv_usec', delay % 1000000) if _select(0, void, void, void, tvdeadline) < 0: return -1
def mkdir_llimpl(pathname, mode): if IGNORE_MODE: res = os_mkdir(pathname) else: res = os_mkdir(pathname, mode) res = rffi.cast(lltype.Signed, res) if res < 0: raise OSError(rposix.get_errno(), "os_mkdir failed")
def spawnv_llimpl(mode, path, args): mode = rffi.cast(rffi.INT, mode) l_args = rffi.liststr2charpp(args) childpid = os_spawnv(mode, path, l_args) rffi.free_charpp(l_args) if childpid == -1: raise OSError(rposix.get_errno(), "os_spawnv failed") return rffi.cast(lltype.Signed, childpid)
def native_code_written(self, name, address, size): assert size > 0 if not OPROFILE_AVAILABLE: return uaddress = rffi.cast(rffi.ULONG, address) success = op_write_native_code(self.agent, name, uaddress, rffi.cast(rffi.VOIDP, 0), size) if success != 0: raise OProfileError(get_errno(), "write")
def ll_math_pow(x, y): # deal directly with IEEE specials, to cope with problems on various # platforms whose semantics don't exactly match C99 if isnan(y): if x == 1.0: return 1.0 # 1**Nan = 1 return y if not isfinite(x): if isnan(x): if y == 0.0: return 1.0 # NaN**0 = 1 return x else: # isinf(x) odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0 if y > 0.0: if odd_y: return x return math_fabs(x) elif y == 0.0: return 1.0 else: # y < 0.0 if odd_y: return math_copysign(0.0, x) return 0.0 if isinf(y): if math_fabs(x) == 1.0: return 1.0 elif y > 0.0 and math_fabs(x) > 1.0: return y elif y < 0.0 and math_fabs(x) < 1.0: if x == 0.0: raise ValueError("0**-inf: divide by zero") return -y # result is +inf else: return 0.0 _error_reset() r = math_pow(x, y) errno = rposix.get_errno() if not isfinite(r): if isnan(r): # a NaN result should arise only from (-ve)**(finite non-integer) errno = EDOM else: # isinf(r) # an infinite result here arises either from: # (A) (+/-0.)**negative (-> divide-by-zero) # (B) overflow of x**y with x and y finite if x == 0.0: errno = EDOM else: errno = ERANGE if errno: _likely_raise(errno, r) return r
def _check_error(x): errno = rposix.get_errno() if errno: if errno == ERANGE: if not x: return # we consider underflow to not be an error, like CPython raise OverflowError("math range error") else: raise ValueError("math domain error")
def sem_getvalue(sem): sval_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') try: res = _sem_getvalue(sem, sval_ptr) if res < 0: raise OSError(rposix.get_errno(), "sem_getvalue failed") return rffi.cast(lltype.Signed, sval_ptr[0]) finally: lltype.free(sval_ptr, flavor='raw')
def lseek_llimpl(fd, pos, how): how = fix_seek_arg(how) res = os_lseek(rffi.cast(rffi.INT, fd), rffi.cast(rffi.LONGLONG, pos), rffi.cast(rffi.INT, how)) res = rffi.cast(lltype.SignedLongLong, res) if res < 0: raise OSError(rposix.get_errno(), "os_lseek failed") return res
def flush(self): if self.buf_count > 0: bytes = self.buf_count * rffi.sizeof(rffi.LONG) count = raw_os_write(self.fd, rffi.cast(llmemory.Address, self.writebuffer), rffi.cast(rffi.SIZE_T, bytes)) if rffi.cast(lltype.Signed, count) != bytes: raise OSError(rposix.get_errno(), "raw_os_write failed") self.buf_count = 0
def gettimeofday(): now = lltype.malloc(TIMEVALP.TO, 1, flavor='raw') try: res = _gettimeofday(now, None) if res < 0: raise OSError(rposix.get_errno(), "gettimeofday failed") return rffi.getintfield(now[0], 'c_tv_sec'), rffi.getintfield(now[0], 'c_tv_usec') finally: lltype.free(now, flavor='raw')
def sh_cmd(vm): (cmd_o,),_ = vm.decode_args("S") assert isinstance(cmd_o, Con_String) r = system(cmd_o.v) if r == -1: vm.raise_helper("Exception", [Con_String(vm, os.strerror(rposix.get_errno()))]) return Con_Int(vm, os.WEXITSTATUS(r))
def PyOS_string_to_double(space, s, endptr, w_overflow_exception): """Convert a string s to a double, raising a Python exception on failure. The set of accepted strings corresponds to the set of strings accepted by Python's float() constructor, except that s must not have leading or trailing whitespace. The conversion is independent of the current locale. If endptr is NULL, convert the whole string. Raise ValueError and return -1.0 if the string is not a valid representation of a floating-point number. If endptr is not NULL, convert as much of the string as possible and set *endptr to point to the first unconverted character. If no initial segment of the string is the valid representation of a floating-point number, set *endptr to point to the beginning of the string, raise ValueError, and return -1.0. If s represents a value that is too large to store in a float (for example, "1e500" is such a string on many platforms) then if overflow_exception is NULL return Py_HUGE_VAL (with an appropriate sign) and don't set any exception. Otherwise, overflow_exception must point to a Python exception object; raise that exception and return -1.0. In both cases, set *endptr to point to the first character after the converted value. If any other error occurs during the conversion (for example an out-of-memory error), set the appropriate Python exception and return -1.0. """ user_endptr = True try: if not endptr: endptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw') user_endptr = False result = rdtoa.dg_strtod(s, endptr) endpos = (rffi.cast(rffi.LONG, endptr[0]) - rffi.cast(rffi.LONG, s)) if endpos == 0 or (not user_endptr and not endptr[0][0] == '\0'): raise OperationError( space.w_ValueError, space.wrap('invalid input at position %s' % endpos)) if rposix.get_errno() == errno.ERANGE: rposix.set_errno(0) if w_overflow_exception is None: if result > 0: return rfloat.INFINITY else: return -rfloat.INFINITY else: raise OperationError(w_overflow_exception, space.wrap('value too large')) return result finally: if not user_endptr: lltype.free(endptr, flavor='raw')
def os_pipe_llimpl(): filedes = lltype.malloc(INT_ARRAY_P.TO, 2, flavor='raw') error = rffi.cast(lltype.Signed, os_pipe(filedes)) read_fd = filedes[0] write_fd = filedes[1] lltype.free(filedes, flavor='raw') if error != 0: raise OSError(rposix.get_errno(), "os_pipe failed") return (rffi.cast(lltype.Signed, read_fd), rffi.cast(lltype.Signed, write_fd))
def os_listdir_llimpl(path): dirp = os_opendir(path) if not dirp: raise OSError(rposix.get_errno(), "os_opendir failed") rposix.set_errno(0) result = [] while True: direntp = os_readdir(dirp) if not direntp: error = rposix.get_errno() break namep = rffi.cast(rffi.CCHARP, direntp.c_d_name) name = rffi.charp2str(namep) if name != '.' and name != '..': result.append(name) os_closedir(dirp) if error: raise OSError(error, "os_readdir failed") return result
def gettimeofday(): now = lltype.malloc(TIMEVALP.TO, 1, flavor='raw') try: res = _gettimeofday(now, None) if res < 0: raise OSError(rposix.get_errno(), "gettimeofday failed") return rffi.getintfield(now[0], 'c_tv_sec'), rffi.getintfield( now[0], 'c_tv_usec') finally: lltype.free(now, flavor='raw')
def epoll_ctl(self, space, ctl, w_fd, eventmask, ignore_ebadf=False): fd = space.c_filedescriptor_w(w_fd) with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, eventmask) rffi.setintfield(ev.c_data, "c_fd", fd) result = epoll_ctl(self.epfd, ctl, fd, ev) if ignore_ebadf and get_errno() == errno.EBADF: result = 0 if result < 0: raise exception_from_errno(space, space.w_IOError)
def tcsetattr_llimpl(fd, when, attributes): c_struct = lltype.malloc(TERMIOSP.TO, flavor='raw') try: c_struct.c_c_iflag = r_uint(attributes[0]) c_struct.c_c_oflag = r_uint(attributes[1]) c_struct.c_c_cflag = r_uint(attributes[2]) c_struct.c_c_lflag = r_uint(attributes[3]) ispeed = r_uint(attributes[4]) ospeed = r_uint(attributes[5]) cc = attributes[6] for i in range(NCCS): c_struct.c_c_cc[i] = rffi.r_uchar(ord(cc[i][0])) if c_cfsetispeed(c_struct, ispeed) < 0: raise OSError(rposix.get_errno(), 'tcsetattr failed') if c_cfsetospeed(c_struct, ospeed) < 0: raise OSError(rposix.get_errno(), 'tcsetattr failed') if c_tcsetattr(fd, when, c_struct) < 0: raise OSError(rposix.get_errno(), 'tcsetattr failed') finally: lltype.free(c_struct, flavor='raw')
def epoll_ctl(self, space, ctl, w_fd, eventmask, ignore_ebadf=False): fd = space.c_filedescriptor_w(w_fd) with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, eventmask) rffi.setintfield(ev.c_data, 'c_fd', fd) result = epoll_ctl(self.epfd, ctl, fd, ev) if ignore_ebadf and get_errno() == errno.EBADF: result = 0 if result < 0: raise exception_from_errno(space, space.w_IOError)
def putenv_llimpl(name, value): l_string = rffi.str2charp('%s=%s' % (name, value)) error = rffi.cast(lltype.Signed, os_putenv(l_string)) if error: rffi.free_charp(l_string) raise OSError(rposix.get_errno(), "os_putenv failed") # keep 'l_string' alive - we know that the C library needs it # until the next call to putenv() with the same 'name'. l_oldstring = envkeepalive.byname.get(name, lltype.nullptr(rffi.CCHARP.TO)) envkeepalive.byname[name] = l_string if l_oldstring: rffi.free_charp(l_oldstring)
def os_utime_llimpl(path, tp): # NB. this function is specialized; we get one version where # tp is known to be None, and one version where it is known # to be a tuple of 2 floats. if tp is None: error = os_utime(path, lltype.nullptr(UTIMBUFP.TO)) else: actime, modtime = tp error = os_utime_platform(path, actime, modtime) error = rffi.cast(lltype.Signed, error) if error == -1: raise OSError(rposix.get_errno(), "os_utime failed")
def unsetenv_llimpl(name): l_name = rffi.str2charp(name) error = os_unsetenv(l_name) # 'error' is None on OS/X rffi.free_charp(l_name) if error: raise OSError(rposix.get_errno(), "os_unsetenv failed") try: l_oldstring = envkeepalive.byname[name] except KeyError: pass else: del envkeepalive.byname[name] rffi.free_charp(l_oldstring)
def posix_stat_llimpl(arg): stresult = lltype.malloc(STAT_STRUCT.TO, flavor='raw') try: if arg_is_path: arg = rffi.str2charp(arg) error = rffi.cast(rffi.LONG, posix_mystat(arg, stresult)) if arg_is_path: rffi.free_charp(arg) if error != 0: raise OSError(rposix.get_errno(), "os_?stat failed") return build_stat_result(stresult) finally: lltype.free(stresult, flavor='raw')
def posix_stat_llimpl(arg): stresult = lltype.malloc(STAT_STRUCT.TO, flavor='raw') try: if arg_is_path: arg = traits.str2charp(arg) error = rffi.cast(rffi.LONG, posix_mystat(arg, stresult)) if arg_is_path: traits.free_charp(arg) if error != 0: raise OSError(rposix.get_errno(), "os_?stat failed") return build_stat_result(stresult) finally: lltype.free(stresult, flavor='raw')
def os_waitpid_llimpl(pid, options): status_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') status_p[0] = rffi.cast(rffi.INT, 0) result = os_waitpid(rffi.cast(rffi.PID_T, pid), status_p, rffi.cast(rffi.INT, options)) result = rffi.cast(lltype.Signed, result) status = status_p[0] lltype.free(status_p, flavor='raw') if result == -1: raise OSError(rposix.get_errno(), "os_waitpid failed") return (rffi.cast(lltype.Signed, result), rffi.cast(lltype.Signed, status))
def times_lltypeimpl(): l_tmsbuf = lltype.malloc(TMSP.TO, flavor='raw') try: result = os_times(l_tmsbuf) if result == rffi.cast(self.CLOCK_T, -1): raise OSError(rposix.get_errno(), "times failed") return ( l_tmsbuf.c_tms_utime / CLOCK_TICKS_PER_SECOND, l_tmsbuf.c_tms_stime / CLOCK_TICKS_PER_SECOND, l_tmsbuf.c_tms_cutime / CLOCK_TICKS_PER_SECOND, l_tmsbuf.c_tms_cstime / CLOCK_TICKS_PER_SECOND, result / CLOCK_TICKS_PER_SECOND) finally: lltype.free(l_tmsbuf, flavor='raw')
def uname_llimpl(): l_utsbuf = lltype.malloc(UTSNAMEP.TO, flavor='raw') result = os_uname(l_utsbuf) if result == -1: raise OSError(rposix.get_errno(), "os_uname failed") retval = ( rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_sysname)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_nodename)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_release)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_version)), rffi.charp2str(rffi.cast(rffi.CCHARP, l_utsbuf.c_machine)), ) lltype.free(l_utsbuf, flavor='raw') return retval
def os_read_llimpl(fd, count): if count < 0: raise OSError(errno.EINVAL, None) inbuf = lltype.malloc(rffi.CCHARP.TO, count, flavor='raw') try: got = rffi.cast(lltype.Signed, os_read(rffi.cast(rffi.INT, fd), inbuf, rffi.cast(rffi.SIZE_T, count))) if got < 0: raise OSError(rposix.get_errno(), "os_read failed") # XXX too many copies of the data! l = [inbuf[i] for i in range(got)] finally: lltype.free(inbuf, flavor='raw') return ''.join(l)
def os_write_llimpl(fd, data): count = len(data) outbuf = lltype.malloc(rffi.CCHARP.TO, count, flavor='raw') try: for i in range(count): outbuf[i] = data[i] written = rffi.cast(lltype.Signed, os_write( rffi.cast(rffi.INT, fd), outbuf, rffi.cast(rffi.SIZE_T, count))) if written < 0: raise OSError(rposix.get_errno(), "os_write failed") finally: lltype.free(outbuf, flavor='raw') return written
def tcgetattr_llimpl(fd): c_struct = lltype.malloc(TERMIOSP.TO, flavor='raw') try: if c_tcgetattr(fd, c_struct) < 0: raise OSError(rposix.get_errno(), 'tcgetattr failed') cc = [chr(c_struct.c_c_cc[i]) for i in range(NCCS)] ispeed = c_cfgetispeed(c_struct) ospeed = c_cfgetospeed(c_struct) result = (intmask(c_struct.c_c_iflag), intmask(c_struct.c_c_oflag), intmask(c_struct.c_c_cflag), intmask(c_struct.c_c_lflag), intmask(ispeed), intmask(ospeed), cc) return result finally: lltype.free(c_struct, flavor='raw')