com.oracle.graal.python.builtins.modules.PosixModuleBuiltins Maven / Gradle / Ivy
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates.
* Copyright (c) 2014, Regents of the University of California
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.graal.python.builtins.modules;
import static com.oracle.graal.python.nodes.BuiltinNames.T_NT;
import static com.oracle.graal.python.nodes.BuiltinNames.T_POSIX;
import static com.oracle.graal.python.nodes.StringLiterals.T_DOT;
import static com.oracle.graal.python.runtime.PosixConstants.AT_FDCWD;
import static com.oracle.graal.python.runtime.PosixConstants.AT_SYMLINK_FOLLOW;
import static com.oracle.graal.python.runtime.PosixConstants.O_CLOEXEC;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached;
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.oracle.graal.python.annotations.ArgumentClinic;
import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
import com.oracle.graal.python.annotations.ArgumentClinic.PrimitiveType;
import com.oracle.graal.python.annotations.ClinicConverterFactory;
import com.oracle.graal.python.annotations.ClinicConverterFactory.ArgumentName;
import com.oracle.graal.python.annotations.ClinicConverterFactory.BuiltinName;
import com.oracle.graal.python.builtins.Builtin;
import com.oracle.graal.python.builtins.CoreFunctions;
import com.oracle.graal.python.builtins.Python3Core;
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.PythonBuiltins;
import com.oracle.graal.python.builtins.PythonOS;
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins.AuditNode;
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary;
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.LenNode;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
import com.oracle.graal.python.builtins.objects.floats.PFloat;
import com.oracle.graal.python.builtins.objects.ints.PInt;
import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.builtins.objects.module.PythonModule;
import com.oracle.graal.python.builtins.objects.posix.PScandirIterator;
import com.oracle.graal.python.builtins.objects.str.PString;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.tuple.StructSequence;
import com.oracle.graal.python.lib.PyIndexCheckNode;
import com.oracle.graal.python.lib.PyLongAsIntNode;
import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode;
import com.oracle.graal.python.lib.PyLongAsLongNode;
import com.oracle.graal.python.lib.PyNumberIndexNode;
import com.oracle.graal.python.lib.PyOSFSPathNode;
import com.oracle.graal.python.lib.PyObjectAsFileDescriptor;
import com.oracle.graal.python.lib.PyObjectSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithRaise;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
import com.oracle.graal.python.nodes.expression.BinaryArithmetic;
import com.oracle.graal.python.nodes.expression.BinaryOpNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode;
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode.ArgumentCastNodeWithRaise;
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode.ArgumentCastNodeWithRaiseAndIndirectCall;
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode;
import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode;
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.PosixConstants;
import com.oracle.graal.python.runtime.PosixConstants.IntConstant;
import com.oracle.graal.python.runtime.PosixSupport;
import com.oracle.graal.python.runtime.PosixSupportLibrary;
import com.oracle.graal.python.runtime.PosixSupportLibrary.Buffer;
import com.oracle.graal.python.runtime.PosixSupportLibrary.OpenPtyResult;
import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
import com.oracle.graal.python.runtime.PosixSupportLibrary.Timeval;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.PythonOptions;
import com.oracle.graal.python.runtime.exception.PException;
import com.oracle.graal.python.runtime.exception.PythonExitException;
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
import com.oracle.graal.python.runtime.sequence.PSequence;
import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.graal.python.util.OverflowException;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Exclusive;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.GenerateCached;
import com.oracle.truffle.api.dsl.GenerateInline;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.api.strings.TruffleString.Encoding;
@CoreFunctions(defineModule = "posix", extendsModule = "nt", isEager = true)
public final class PosixModuleBuiltins extends PythonBuiltins {
static final StructSequence.BuiltinTypeDescriptor STAT_RESULT_DESC = new StructSequence.BuiltinTypeDescriptor(
PythonBuiltinClassType.PStatResult,
// @formatter:off The formatter joins these lines making it less readable
"stat_result: Result from stat, fstat, or lstat.\n\n" +
"This object may be accessed either as a tuple of\n" +
" (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n" +
"or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n" +
"\n" +
"Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n" +
"or st_flags, they are available as attributes only.\n" +
"\n" +
"See os.stat for more information.",
// @formatter:on
10,
new String[]{
"st_mode", "st_ino", "st_dev", "st_nlink", "st_uid", "st_gid", "st_size",
null, null, null,
"st_atime", "st_mtime", "st_ctime",
"st_atime_ns", "st_mtime_ns", "st_ctime_ns"
},
new String[]{
"protection bits", "inode", "device", "number of hard links",
"user ID of owner", "group ID of owner", "total size, in bytes",
"integer time of last access", "integer time of last modification", "integer time of last change",
"time of last access", "time of last modification", "time of last change",
"time of last access in nanoseconds", "time of last modification in nanoseconds", "time of last change in nanoseconds"
});
static final StructSequence.BuiltinTypeDescriptor STATVFS_RESULT_DESC = new StructSequence.BuiltinTypeDescriptor(
PythonBuiltinClassType.PStatvfsResult,
// @formatter:off The formatter joins these lines making it less readable
"statvfs_result: Result from statvfs or fstatvfs.\n\n" +
"This object may be accessed either as a tuple of\n" +
" (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n" +
"or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n" +
"\n" +
"See os.statvfs for more information.",
// @formatter:on
10,
new String[]{
"f_bsize", "f_frsize", "f_blocks", "f_bfree", "f_bavail", "f_files",
"f_ffree", "f_favail", "f_flag", "f_namemax", "f_fsid"
},
null);
private static final StructSequence.BuiltinTypeDescriptor TERMINAL_SIZE_DESC = new StructSequence.BuiltinTypeDescriptor(
PythonBuiltinClassType.PTerminalSize,
"A tuple of (columns, lines) for holding terminal window size",
2,
new String[]{"columns", "lines"},
new String[]{"width of the terminal window in characters", "height of the terminal window in characters"});
private static final StructSequence.BuiltinTypeDescriptor UNAME_RESULT_DESC = new StructSequence.BuiltinTypeDescriptor(
PythonBuiltinClassType.PUnameResult,
// @formatter:off The formatter joins these lines making it less readable
"uname_result: Result from os.uname().\n\n" +
"This object may be accessed either as a tuple of\n" +
" (sysname, nodename, release, version, machine),\n" +
"or via the attributes sysname, nodename, release, version, and machine.\n" +
"\n" +
"See os.uname for more information.",
// @formatter:on
5,
new String[]{"sysname", "nodename", "release", "version", "machine"},
new String[]{
"operating system name", "name of machine on network (implementation-defined)",
"operating system release", "operating system version", "hardware identifier"
});
@Override
protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFactories() {
return PosixModuleBuiltinsFactory.getFactories();
}
public PosixModuleBuiltins() {
addConstants(PosixConstants.openFlags);
addConstants(PosixConstants.waitOptions);
addConstants(PosixConstants.accessMode);
addConstants(PosixConstants.exitStatus);
addConstants(PosixConstants.rtld);
addConstant(PosixConstants.SEEK_DATA);
addConstant(PosixConstants.SEEK_HOLE);
}
private void addConstant(IntConstant c) {
if (c.defined) {
addBuiltinConstant(c.name, c.getValueIfDefined());
}
}
private void addConstants(IntConstant[] constants) {
for (IntConstant c : constants) {
addConstant(c);
}
}
@Override
public void initialize(Python3Core core) {
super.initialize(core);
ArrayList haveFunctions = new ArrayList<>();
if (PythonOS.getPythonOS() != PythonOS.PLATFORM_WIN32) {
Collections.addAll(haveFunctions, tsLiteral("HAVE_FACCESSAT"), tsLiteral("HAVE_FCHDIR"), tsLiteral("HAVE_FCHMOD"), tsLiteral("HAVE_FCHMODAT"), tsLiteral("HAVE_FDOPENDIR"),
tsLiteral("HAVE_FSTATAT"), tsLiteral("HAVE_FTRUNCATE"), tsLiteral("HAVE_FUTIMES"), tsLiteral("HAVE_LUTIMES"),
tsLiteral("HAVE_MKDIRAT"), tsLiteral("HAVE_OPENAT"), tsLiteral("HAVE_READLINKAT"), tsLiteral("HAVE_RENAMEAT"), tsLiteral("HAVE_SYMLINKAT"), tsLiteral("HAVE_UNLINKAT"));
// Not implemented yet:
// "HAVE_FCHOWN", "HAVE_FCHOWNAT", "HAVE_FEXECVE", "HAVE_FPATHCONF", "HAVE_FSTATVFS",
// "HAVE_FUTIMESAT", "HAVE_LINKAT", "HAVE_LCHFLAGS", "HAVE_LCHMOD", "HAVE_LCHOWN",
// "HAVE_LSTAT", "HAVE_MEMFD_CREATE", "HAVE_MKFIFOAT", "HAVE_MKNODAT"
if (PosixConstants.HAVE_FUTIMENS.value) {
haveFunctions.add(tsLiteral("HAVE_FUTIMENS"));
}
if (PosixConstants.HAVE_UTIMENSAT.value) {
haveFunctions.add(tsLiteral("HAVE_UTIMENSAT"));
}
} else {
haveFunctions.add(tsLiteral("HAVE_FTRUNCATE"));
haveFunctions.add(tsLiteral("MS_WINDOWS"));
}
addBuiltinConstant("_have_functions", core.factory().createList(haveFunctions.toArray()));
addBuiltinConstant("environ", core.factory().createDict());
StructSequence.initType(core, STAT_RESULT_DESC);
StructSequence.initType(core, STATVFS_RESULT_DESC);
StructSequence.initType(core, TERMINAL_SIZE_DESC);
StructSequence.initType(core, UNAME_RESULT_DESC);
// Some classes (e.g. stat_result, see below) are formally part of the 'os' module, although
// they are exposed by the 'posix' module. In CPython, they are defined in posixmodule.c,
// with their __module__ being set to 'os', and later they are imported by os.py.
// Our infrastructure in PythonBuiltinClassType currently does not allow us to
// define a class in one module (os) and make it public in another (posix), so we create
// them directly in the 'os' module, and expose them in the `posix` module as well.
// Note that the classes are still re-imported by os.py.
PythonModule posix;
if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) {
posix = core.lookupBuiltinModule(T_NT);
} else {
posix = core.lookupBuiltinModule(T_POSIX);
}
posix.setAttribute(PythonBuiltinClassType.PStatResult.getName(), core.lookupType(PythonBuiltinClassType.PStatResult));
posix.setAttribute(PythonBuiltinClassType.PStatvfsResult.getName(), core.lookupType(PythonBuiltinClassType.PStatvfsResult));
posix.setAttribute(PythonBuiltinClassType.PTerminalSize.getName(), core.lookupType(PythonBuiltinClassType.PTerminalSize));
posix.setAttribute(tsLiteral("error"), core.lookupType(PythonBuiltinClassType.OSError));
}
@Override
public void postInitialize(Python3Core core) {
super.postInitialize(core);
PosixSupportLibrary posixLib = PosixSupportLibrary.getUncached();
Object posixSupport = core.getContext().getPosixSupport();
// fill the environ dictionary with the current environment
// TODO we should probably use PosixSupportLibrary to get environ
Map getenv = System.getenv();
PDict environ = core.factory().createDict();
String pyenvLauncherKey = "__PYVENV_LAUNCHER__";
for (Entry entry : getenv.entrySet()) {
if (entry.getKey().equals("GRAAL_PYTHON_ARGS") && entry.getValue().endsWith("\013")) {
// was already processed at startup in GraalPythonMain and
// we don't want subprocesses to pick it up
continue;
}
Object key, val;
if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) {
key = toTruffleStringUncached(entry.getKey());
} else {
key = core.factory().createBytes(entry.getKey().getBytes());
}
if (pyenvLauncherKey.equals(entry.getKey())) {
// On Mac, the CPython launcher uses this env variable to specify the real Python
// executable. It will be honored by packages like "site". So, if it is set, we
// overwrite it with our executable to ensure that subprocesses will use us.
TruffleString value = core.getContext().getOption(PythonOptions.Executable);
try {
Object k = posixLib.createPathFromString(posixSupport, toTruffleStringUncached(pyenvLauncherKey));
Object v = posixLib.createPathFromString(posixSupport, value);
posixLib.setenv(posixSupport, k, v, true);
} catch (PosixException ignored) {
}
if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) {
val = value;
} else {
val = core.factory().createBytes(value.toJavaStringUncached().getBytes());
}
} else {
if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) {
val = toTruffleStringUncached(entry.getValue());
} else {
val = core.factory().createBytes((entry.getValue().getBytes()));
}
}
environ.setItem(key, val);
}
PythonModule posix;
if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) {
posix = core.lookupBuiltinModule(T_NT);
} else {
posix = core.lookupBuiltinModule(T_POSIX);
}
Object environAttr = posix.getAttribute(tsLiteral("environ"));
((PDict) environAttr).setDictStorage(environ.getDictStorage());
if (posixLib.getBackend(posixSupport).toJavaStringUncached().equals("java")) {
posix.setAttribute(toTruffleStringUncached("statvfs"), PNone.NO_VALUE);
posix.setAttribute(toTruffleStringUncached("geteuid"), PNone.NO_VALUE);
}
}
@Builtin(name = "stat_result", minNumOfPositionalArgs = 1, parameterNames = {"$cls", "sequence", "dict"}, constructsClass = PythonBuiltinClassType.PStatResult)
@ImportStatic(PosixModuleBuiltins.class)
@GenerateNodeFactory
public abstract static class StatResultNode extends PythonTernaryBuiltinNode {
@Specialization
public static PTuple generic(VirtualFrame frame, Object cls, Object sequence, Object dict,
@Cached("create(STAT_RESULT_DESC)") StructSequence.NewNode newNode) {
PTuple p = (PTuple) newNode.execute(frame, cls, sequence, dict);
Object[] data = CompilerDirectives.castExact(p.getSequenceStorage(), ObjectSequenceStorage.class).getInternalArray();
for (int i = 7; i <= 9; i++) {
if (data[i + 3] == PNone.NONE) {
data[i + 3] = data[i];
}
}
return p;
}
}
@Builtin(name = "statvfs_result", minNumOfPositionalArgs = 1, parameterNames = {"$cls", "sequence", "dict"}, constructsClass = PythonBuiltinClassType.PStatvfsResult)
@ImportStatic(PosixModuleBuiltins.class)
@GenerateNodeFactory
public abstract static class StatvfsResultNode extends PythonTernaryBuiltinNode {
@Specialization
public static Object generic(VirtualFrame frame, Object cls, Object sequence, Object dict,
@Cached("create(STATVFS_RESULT_DESC)") StructSequence.NewNode newNode) {
return newNode.execute(frame, cls, sequence, dict);
}
}
@Builtin(name = "putenv", minNumOfPositionalArgs = 2, parameterNames = {"name", "value"})
@ArgumentClinic(name = "name", conversionClass = FsConverterNode.class)
@ArgumentClinic(name = "value", conversionClass = FsConverterNode.class)
@GenerateNodeFactory
public abstract static class PutenvNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.PutenvNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone putenv(VirtualFrame frame, PBytes nameBytes, PBytes valueBytes,
@Bind("this") Node inliningTarget,
@Cached BytesNodes.ToBytesNode toBytesNode,
@Cached SysModuleBuiltins.AuditNode auditNode,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
// Unlike in other posix builtins, we go through str -> bytes -> byte[] -> String
// conversions for emulated backend because the bytes version after fsencode conversion
// is subject to sys.audit.
byte[] name = toBytesNode.execute(nameBytes);
byte[] value = toBytesNode.execute(valueBytes);
Object nameOpaque = checkNull(posixLib.createPathFromBytes(getPosixSupport(), name));
Object valueOpaque = checkNull(posixLib.createPathFromBytes(getPosixSupport(), value));
checkEqualSign(name);
auditNode.audit(inliningTarget, "os.putenv", nameBytes, valueBytes);
try {
posixLib.setenv(getPosixSupport(), nameOpaque, valueOpaque, true);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
return PNone.NONE;
}
private Object checkNull(Object value) {
if (value == null) {
throw raise(ValueError, ErrorMessages.EMBEDDED_NULL_BYTE);
}
return value;
}
private void checkEqualSign(byte[] bytes) {
for (byte b : bytes) {
if (b == '=') {
throw raise(ValueError, ErrorMessages.ILLEGAL_ENVIRONMENT_VARIABLE_NAME);
}
}
}
}
@Builtin(name = "unsetenv", minNumOfPositionalArgs = 1, parameterNames = {"name"})
@ArgumentClinic(name = "name", conversionClass = FsConverterNode.class)
@GenerateNodeFactory
public abstract static class UnsetenvNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.UnsetenvNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone putenv(VirtualFrame frame, PBytes nameBytes,
@Bind("this") Node inliningTarget,
@Cached BytesNodes.ToBytesNode toBytesNode,
@Cached SysModuleBuiltins.AuditNode auditNode,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
byte[] name = toBytesNode.execute(nameBytes);
Object nameOpaque = checkNull(posixLib.createPathFromBytes(getPosixSupport(), name));
auditNode.audit(inliningTarget, "os.unsetenv", nameBytes);
try {
posixLib.unsetenv(getPosixSupport(), nameOpaque);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
return PNone.NONE;
}
private Object checkNull(Object value) {
if (value == null) {
throw raise(ValueError, ErrorMessages.EMBEDDED_NULL_BYTE);
}
return value;
}
}
@Builtin(name = "execv", minNumOfPositionalArgs = 2, parameterNames = {"pathname", "argv"})
@ArgumentClinic(name = "pathname", conversionClass = PathConversionNode.class, args = {"false", "false"})
@GenerateNodeFactory
@SuppressWarnings("truffle-static-method")
public abstract static class ExecvNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.ExecvNodeClinicProviderGen.INSTANCE;
}
@Specialization
Object execvArgsList(VirtualFrame frame, PosixPath path, PList argv,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared @Cached ToArrayNode toArrayNode,
@Shared @Cached ObjectToOpaquePathNode toOpaquePathNode,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
@Shared @Cached GilNode gil,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
execv(frame, path, argv, argv.getSequenceStorage(), inliningTarget, posixLib, toArrayNode, toOpaquePathNode, auditNode, gil, constructAndRaiseNode);
throw CompilerDirectives.shouldNotReachHere("execv should not return normally");
}
@Specialization
Object execvArgsTuple(VirtualFrame frame, PosixPath path, PTuple argv,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared @Cached ToArrayNode toArrayNode,
@Shared @Cached ObjectToOpaquePathNode toOpaquePathNode,
@Shared @Cached AuditNode auditNode,
@Shared @Cached GilNode gil,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
execv(frame, path, argv, argv.getSequenceStorage(), inliningTarget, posixLib, toArrayNode, toOpaquePathNode, auditNode, gil, constructAndRaiseNode);
throw CompilerDirectives.shouldNotReachHere("execv should not return normally");
}
@Specialization(guards = {"!isList(argv)", "!isPTuple(argv)"})
@SuppressWarnings("unused")
Object execvInvalidArgs(VirtualFrame frame, PosixPath path, Object argv) {
throw raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S, "execv()", 2, "tuple or list");
}
private void execv(VirtualFrame frame, PosixPath path, Object argv, SequenceStorage argvStorage,
Node inliningTarget,
PosixSupportLibrary posixLib,
SequenceStorageNodes.ToArrayNode toArrayNode,
ObjectToOpaquePathNode toOpaquePathNode,
SysModuleBuiltins.AuditNode auditNode,
GilNode gil,
PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
Object[] args = toArrayNode.execute(inliningTarget, argvStorage);
if (args.length < 1) {
throw raise(ValueError, ErrorMessages.ARG_MUST_NOT_BE_EMPTY, "execv()", 2);
}
Object[] opaqueArgs = new Object[args.length];
for (int i = 0; i < args.length; ++i) {
opaqueArgs[i] = toOpaquePathNode.execute(frame, inliningTarget, args[i], i == 0);
}
// TODO ValueError "execv() arg 2 first element cannot be empty"
auditNode.audit(inliningTarget, "os.exec", path.originalObject, argv, PNone.NONE);
gil.release(true);
try {
posixLib.execv(getPosixSupport(), path.value, opaqueArgs);
} catch (PosixException e) {
gil.acquire();
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
} finally {
gil.acquire();
}
throw CompilerDirectives.shouldNotReachHere("execv should not return normally");
}
}
@Builtin(name = "getpid", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class GetPidNode extends PythonBuiltinNode {
@Specialization
long getPid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) {
return posixLib.getpid(getPosixSupport());
}
}
@Builtin(name = "getuid", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class GetUidNode extends PythonBuiltinNode {
@Specialization
long getUid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) {
return posixLib.getuid(getPosixSupport());
}
}
@Builtin(name = "geteuid", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class GetEUidNode extends PythonBuiltinNode {
@Specialization
long getUid(@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) {
return posixLib.geteuid(getPosixSupport());
}
}
@Builtin(name = "getgid", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class GetGidNode extends PythonBuiltinNode {
@Specialization
long getGid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) {
return posixLib.getgid(getPosixSupport());
}
}
@Builtin(name = "getppid", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class GetPpidNode extends PythonBuiltinNode {
@Specialization
long getPpid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) {
return posixLib.getppid(getPosixSupport());
}
}
@Builtin(name = "getpgid", minNumOfPositionalArgs = 1, parameterNames = {"pid"})
@ArgumentClinic(name = "pid", conversionClass = PidtConversionNode.class)
@GenerateNodeFactory
public abstract static class GetPgidNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.GetPgidNodeClinicProviderGen.INSTANCE;
}
@Specialization
long getPgid(VirtualFrame frame, long pid,
@Bind("this") Node inliningTarget,
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return posixLib.getpgid(getPosixSupport(), pid);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "setpgid", minNumOfPositionalArgs = 2, parameterNames = {"pid", "pgid"})
@ArgumentClinic(name = "pid", conversionClass = PidtConversionNode.class)
@ArgumentClinic(name = "pgid", conversionClass = PidtConversionNode.class)
@GenerateNodeFactory
public abstract static class SetPgidNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.SetPgidNodeClinicProviderGen.INSTANCE;
}
@Specialization
Object setPgid(VirtualFrame frame, long pid, long pgid,
@Bind("this") Node inliningTarget,
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.setpgid(getPosixSupport(), pid, pgid);
return PNone.NONE;
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "setpgrp", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class SetPgrpdNode extends PythonBuiltinNode {
@Specialization
Object getPpid(VirtualFrame frame,
@Bind("this") Node inliningTarget,
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.setpgid(getPosixSupport(), 0, 0);
return PNone.NONE;
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "getpgrp", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class GetPgrpNode extends PythonBuiltinNode {
@Specialization
long getPpid(@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) {
return posixLib.getpgrp(getPosixSupport());
}
}
@Builtin(name = "getsid", minNumOfPositionalArgs = 1, parameterNames = {"pid"})
@ArgumentClinic(name = "pid", conversionClass = PidtConversionNode.class)
@GenerateNodeFactory
public abstract static class GetSidNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.GetSidNodeClinicProviderGen.INSTANCE;
}
@Specialization
long getSid(VirtualFrame frame, long pid,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return posixLib.getsid(getPosixSupport(), pid);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "setsid")
@GenerateNodeFactory
public abstract static class SetSidNode extends PythonBuiltinNode {
@Specialization
Object setsid(VirtualFrame frame,
@Bind("this") Node inliningTarget,
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.setsid(getPosixSupport());
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
return PNone.NONE;
}
}
@Builtin(name = "openpty")
@GenerateNodeFactory
public abstract static class OpenPtyNode extends PythonBuiltinNode {
@Specialization
Object openpty(VirtualFrame frame,
@Bind("this") Node inliningTarget,
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
OpenPtyResult result = posixLib.openpty(getPosixSupport());
posixLib.setInheritable(getPosixSupport(), result.masterFd(), false);
posixLib.setInheritable(getPosixSupport(), result.slaveFd(), false);
return factory().createTuple(new int[]{result.masterFd(), result.slaveFd()});
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "open", minNumOfPositionalArgs = 2, parameterNames = {"path", "flags", "mode"}, keywordOnlyNames = {"dir_fd"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "flags", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "mode", conversion = ClinicConversion.Int, defaultValue = "0777")
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@GenerateNodeFactory
public abstract static class OpenNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.OpenNodeClinicProviderGen.INSTANCE;
}
@Specialization
int open(VirtualFrame frame, PosixPath path, int flags, int mode, int dirFd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached InlinedBranchProfile errorProfile,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
int fixedFlags = flags;
if (O_CLOEXEC.defined) {
fixedFlags |= O_CLOEXEC.getValueIfDefined();
}
auditNode.audit(inliningTarget, "open", path.originalObject, PNone.NONE, fixedFlags);
gil.release(true);
try {
while (true) {
try {
return posixLib.openat(getPosixSupport(), dirFd, path.value, fixedFlags, mode);
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) {
PythonContext.triggerAsyncActions(this);
} else {
gil.acquire(); // need GIL to construct OSError
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
}
}
} finally {
gil.acquire();
}
}
}
@Builtin(name = "close", minNumOfPositionalArgs = 1, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@GenerateNodeFactory
public abstract static class CloseNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.CloseNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone close(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
PythonContext ctx = getContext();
if (ctx.getSharedMultiprocessingData().decrementFDRefCount(fd)) {
return PNone.NONE;
}
gil.release(true);
try {
posixLib.close(getPosixSupport(), fd);
} finally {
gil.acquire();
}
return PNone.NONE;
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "read", minNumOfPositionalArgs = 2, parameterNames = {"fd", "length"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "length", conversion = ClinicConversion.Index)
@GenerateNodeFactory
public abstract static class ReadNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.ReadNodeClinicProviderGen.INSTANCE;
}
@Specialization
PBytes doRead(VirtualFrame frame, int fd, int length,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached InlinedBranchProfile errorProfile1,
@Cached InlinedBranchProfile errorProfile2,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
if (length < 0) {
int error = OSErrorEnum.EINVAL.getNumber();
throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, posixLib.strerror(getPosixSupport(), error));
}
try {
return read(fd, length, inliningTarget, posixLib, errorProfile1, gil);
} catch (PosixException e) {
errorProfile2.enter(inliningTarget);
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
public PBytes read(int fd, int length,
Node inliningTarget,
PosixSupportLibrary posixLib,
InlinedBranchProfile errorProfile, GilNode gil) throws PosixException {
gil.release(true);
try {
while (true) {
try {
Buffer result = posixLib.read(getPosixSupport(), fd, length);
if (result.length > Integer.MAX_VALUE) {
// sanity check that it is safe to cast result.length to int, to be
// removed once we support large arrays
throw CompilerDirectives.shouldNotReachHere("Posix read() returned more bytes than requested");
}
return factory().createBytes(result.data, 0, (int) result.length);
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) {
PythonContext.triggerAsyncActions(this);
} else {
throw e;
}
}
}
} finally {
gil.acquire();
}
}
}
@Builtin(name = "write", minNumOfPositionalArgs = 2, parameterNames = {"fd", "data"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "data", conversion = ClinicConversion.ReadableBuffer)
@GenerateNodeFactory
public abstract static class WriteNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.WriteNodeClinicProviderGen.INSTANCE;
}
@Specialization(limit = "3")
@SuppressWarnings("truffle-static-method")
long doWrite(VirtualFrame frame, int fd, Object dataBuffer,
@Bind("this") Node inliningTarget,
@CachedLibrary("dataBuffer") PythonBufferAccessLibrary bufferLib,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached InlinedBranchProfile errorProfile,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return write(fd, bufferLib.getInternalOrCopiedByteArray(dataBuffer), bufferLib.getBufferLength(dataBuffer), inliningTarget, posixLib, errorProfile, gil);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
} finally {
bufferLib.release(dataBuffer, frame, this);
}
}
public long write(int fd, byte[] dataBytes,
int dataLen, Node inliningTarget, PosixSupportLibrary posixLib,
InlinedBranchProfile errorProfile, GilNode gil) throws PosixException {
gil.release(true);
try {
while (true) {
try {
return posixLib.write(getPosixSupport(), fd, new Buffer(dataBytes, dataLen));
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) {
PythonContext.triggerAsyncActions(this);
} else {
throw e;
}
}
}
} finally {
gil.acquire();
}
}
}
@Builtin(name = "dup", minNumOfPositionalArgs = 1, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@GenerateNodeFactory
abstract static class DupNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.DupNodeClinicProviderGen.INSTANCE;
}
@Specialization
int dup(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return posixLib.dup(getPosixSupport(), fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "dup2", minNumOfPositionalArgs = 2, parameterNames = {"fd", "fd2", "inheritable"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "fd2", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "inheritable", conversion = ClinicConversion.Boolean, defaultValue = "true")
@GenerateNodeFactory
abstract static class Dup2Node extends PythonTernaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.Dup2NodeClinicProviderGen.INSTANCE;
}
@Specialization
int dup2(VirtualFrame frame, int fd, int fd2, boolean inheritable,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
if (fd < 0 || fd2 < 0) {
// CPython does not set errno here and raises a 'random' OSError
// (possibly with errno=0 Success)
int error = OSErrorEnum.EINVAL.getNumber();
throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, posixLib.strerror(getPosixSupport(), error));
}
try {
return posixLib.dup2(getPosixSupport(), fd, fd2, inheritable);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "get_inheritable", minNumOfPositionalArgs = 1, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@GenerateNodeFactory
abstract static class GetInheritableNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.GetInheritableNodeClinicProviderGen.INSTANCE;
}
@Specialization
boolean getInheritable(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return posixLib.getInheritable(getPosixSupport(), fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "set_inheritable", minNumOfPositionalArgs = 2, parameterNames = {"fd", "inheritable"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "inheritable", conversion = ClinicConversion.Int)
@GenerateNodeFactory
abstract static class SetInheritableNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.SetInheritableNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone setInheritable(VirtualFrame frame, int fd, int inheritable,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
// not sure why inheritable is not a boolean, but that is how they do it in CPython
posixLib.setInheritable(getPosixSupport(), fd, inheritable != 0);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
return PNone.NONE;
}
}
@Builtin(name = "pipe", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
abstract static class PipeNode extends PythonBuiltinNode {
@Specialization
PTuple pipe(VirtualFrame frame,
@Bind("this") Node inliningTarget,
@Cached GilNode gil,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
int[] pipe;
gil.release(true);
try {
pipe = posixLib.pipe(getPosixSupport());
} catch (PosixException e) {
gil.acquire(); // need to acquire the gil to construct the OSError object
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
} finally {
gil.acquire();
}
return factory().createTuple(new Object[]{pipe[0], pipe[1]});
}
}
public static int mapPythonSeekWhenceToPosix(int pythonWhence) {
// See os.py
switch (pythonWhence) {
case 0:
return PosixConstants.SEEK_SET.value;
case 1:
return PosixConstants.SEEK_CUR.value;
case 2:
return PosixConstants.SEEK_END.value;
default:
return pythonWhence;
}
}
@Builtin(name = "lseek", minNumOfPositionalArgs = 3, parameterNames = {"fd", "pos", "how"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "pos", conversionClass = OffsetConversionNode.class)
@ArgumentClinic(name = "how", conversion = ClinicConversion.Int)
@GenerateNodeFactory
public abstract static class LseekNode extends PythonTernaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.LseekNodeClinicProviderGen.INSTANCE;
}
@Specialization
long lseek(VirtualFrame frame, int fd, long pos, int how,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return posixLib.lseek(getPosixSupport(), fd, pos, mapPythonSeekWhenceToPosix(how));
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "ftruncate", minNumOfPositionalArgs = 2, parameterNames = {"fd", "length"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "length", conversionClass = OffsetConversionNode.class)
@GenerateNodeFactory
public abstract static class FtruncateNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.FtruncateNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone ftruncate(VirtualFrame frame, int fd, long length,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached GilNode gil,
@Cached InlinedBranchProfile errorProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.truncate", fd, length);
while (true) {
try {
gil.release(true);
try {
posixLib.ftruncate(getPosixSupport(), fd, length);
} finally {
gil.acquire();
}
return PNone.NONE;
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) {
PythonContext.triggerAsyncActions(this);
} else {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
}
}
@Builtin(name = "fsync", minNumOfPositionalArgs = 1, parameterNames = "fd")
@ArgumentClinic(name = "fd", conversionClass = FileDescriptorConversionNode.class)
@GenerateNodeFactory
abstract static class FSyncNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.FSyncNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone fsync(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached InlinedBranchProfile errorProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
while (true) {
try {
posixLib.fsync(getPosixSupport(), fd);
return PNone.NONE;
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) {
PythonContext.triggerAsyncActions(this);
} else {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
}
}
@Builtin(name = "get_blocking", minNumOfPositionalArgs = 1, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@GenerateNodeFactory
abstract static class GetBlockingNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.GetBlockingNodeClinicProviderGen.INSTANCE;
}
@Specialization
boolean getBlocking(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return posixLib.getBlocking(getPosixSupport(), fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "set_blocking", minNumOfPositionalArgs = 2, parameterNames = {"fd", "blocking"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@ArgumentClinic(name = "blocking", conversion = ClinicConversion.IntToBoolean)
@GenerateNodeFactory
abstract static class SetBlockingNode extends PythonBinaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.SetBlockingNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone setBlocking(VirtualFrame frame, int fd, boolean blocking,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.setBlocking(getPosixSupport(), fd, blocking);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
return PNone.NONE;
}
}
@Builtin(name = "get_terminal_size", minNumOfPositionalArgs = 0, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int, defaultValue = "1")
@GenerateNodeFactory
abstract static class GetTerminalSizeNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.GetTerminalSizeNodeClinicProviderGen.INSTANCE;
}
@Specialization
PTuple getTerminalSize(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
// TODO default value should be fileno(stdout)
try {
int[] result = posixLib.getTerminalSize(getPosixSupport(), fd);
return factory().createStructSeq(TERMINAL_SIZE_DESC, result[0], result[1]);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "stat", minNumOfPositionalArgs = 1, parameterNames = {"path"}, keywordOnlyNames = {"dir_fd", "follow_symlinks"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "true"})
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@ArgumentClinic(name = "follow_symlinks", conversion = ClinicConversion.Boolean, defaultValue = "true")
@GenerateNodeFactory
abstract static class StatNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.StatNodeClinicProviderGen.INSTANCE;
}
@Specialization
PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd, boolean followSymlinks,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared("positive") @Cached InlinedConditionProfile positiveLongProfile,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
long[] out = posixLib.fstatat(getPosixSupport(), dirFd, path.value, followSymlinks);
return createStatResult(inliningTarget, factory(), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
}
@Specialization(guards = "!isDefault(dirFd)")
@SuppressWarnings("unused")
PTuple doStatFdWithDirFd(PosixFd fd, int dirFd, boolean followSymlinks) {
throw raise(ValueError, ErrorMessages.CANT_SPECIFY_DIRFD_WITHOUT_PATH, "stat");
}
@Specialization(guards = {"isDefault(dirFd)", "!followSymlinks"})
@SuppressWarnings("unused")
PTuple doStatFdWithFollowSymlinks(VirtualFrame frame, PosixFd fd, int dirFd, boolean followSymlinks) {
throw raise(ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "stat");
}
@Specialization(guards = {"isDefault(dirFd)", "followSymlinks"})
PTuple doStatFd(VirtualFrame frame, PosixFd fd, @SuppressWarnings("unused") int dirFd, @SuppressWarnings("unused") boolean followSymlinks,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared("positive") @Cached InlinedConditionProfile positiveLongProfile,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
long[] out = posixLib.fstat(getPosixSupport(), fd.fd);
return createStatResult(inliningTarget, factory(), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject);
}
}
protected static boolean isDefault(int dirFd) {
return dirFd == AT_FDCWD.value;
}
}
@Builtin(name = "lstat", minNumOfPositionalArgs = 1, parameterNames = {"path"}, keywordOnlyNames = {"dir_fd"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@GenerateNodeFactory
abstract static class LStatNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.LStatNodeClinicProviderGen.INSTANCE;
}
@Specialization
PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile positiveLongProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
// TODO we used to return all zeros when the filename was equal to sys.executable
long[] out = posixLib.fstatat(getPosixSupport(), dirFd, path.value, false);
return createStatResult(inliningTarget, factory(), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
}
}
@Builtin(name = "fstat", minNumOfPositionalArgs = 1, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@GenerateNodeFactory
abstract static class FStatNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.FStatNodeClinicProviderGen.INSTANCE;
}
@Specialization
PTuple doStatFd(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile positiveLongProfile,
@Cached InlinedBranchProfile errorProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
while (true) {
try {
long[] out = posixLib.fstat(getPosixSupport(), fd);
return createStatResult(inliningTarget, factory(), positiveLongProfile, out);
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) {
PythonContext.triggerAsyncActions(this);
} else {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
}
}
@Builtin(name = "statvfs", minNumOfPositionalArgs = 1, parameterNames = {"path"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "true"})
@GenerateNodeFactory
abstract static class StatvfsNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.StatvfsNodeClinicProviderGen.INSTANCE;
}
@Specialization
PTuple doStatvfsPath(VirtualFrame frame, PosixPath path,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared @Cached InlinedConditionProfile positiveLongProfile,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
long[] out = posixLib.statvfs(getPosixSupport(), path.value);
return createStatvfsResult(inliningTarget, factory(), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
}
@Specialization()
PTuple doStatvfsFd(VirtualFrame frame, PosixFd fd,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared @Cached InlinedConditionProfile positiveLongProfile,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
long[] out = posixLib.fstatvfs(getPosixSupport(), fd.fd);
return createStatvfsResult(inliningTarget, factory(), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject);
}
}
private static PTuple createStatvfsResult(Node inliningTarget, PythonObjectFactory factory, InlinedConditionProfile positiveLongProfile, long[] out) {
Object[] res = new Object[out.length];
for (int i = 0; i < out.length; i++) {
res[i] = PInt.createPythonIntFromUnsignedLong(inliningTarget, factory, positiveLongProfile, out[i]);
}
return factory.createStructSeq(STATVFS_RESULT_DESC, res);
}
}
@Builtin(name = "uname", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
abstract static class UnameNode extends PythonBuiltinNode {
@Specialization
PTuple uname(VirtualFrame frame,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return factory().createStructSeq(UNAME_RESULT_DESC, posixLib.uname(getPosixSupport()));
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "unlink", minNumOfPositionalArgs = 1, parameterNames = {"path"}, varArgsMarker = true, keywordOnlyNames = {"dir_fd"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@GenerateNodeFactory
abstract static class UnlinkNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.UnlinkNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone unlink(VirtualFrame frame, PosixPath path, int dirFd,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Bind("this") Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.remove", path.originalObject, dirFdForAudit(dirFd));
try {
posixLib.unlinkat(getPosixSupport(), dirFd, path.value, false);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
return PNone.NONE;
}
}
@Builtin(name = "remove", minNumOfPositionalArgs = 1, parameterNames = {"path"}, varArgsMarker = true, keywordOnlyNames = {"dir_fd"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@GenerateNodeFactory
abstract static class RemoveNode extends UnlinkNode {
// although this built-in is the same as unlink(), we need to provide our own
// ArgumentClinicProvider because the error messages contain the name of the built-in
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.RemoveNodeClinicProviderGen.INSTANCE;
}
}
@Builtin(name = "link", minNumOfPositionalArgs = 2, parameterNames = {"src", "dst"}, keywordOnlyNames = {"src_dir_fd", "dst_dir_fd", "follow_symlinks"})
@ArgumentClinic(name = "src", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "dst", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "src_dir_fd", conversionClass = DirFdConversionNode.class)
@ArgumentClinic(name = "dst_dir_fd", conversionClass = DirFdConversionNode.class)
@ArgumentClinic(name = "follow_symlinks", conversion = ClinicConversion.Boolean, defaultValue = "false")
@GenerateNodeFactory
abstract static class LinkNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.LinkNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone link(VirtualFrame frame, PosixPath src, PosixPath dst, int srcDirFd, int dstDirFd, boolean followSymlinks,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.linkat(getPosixSupport(), srcDirFd, src.value, dstDirFd, dst.value, followSymlinks ? AT_SYMLINK_FOLLOW.value : 0);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, src.originalObject, dst.originalObject);
}
return PNone.NONE;
}
}
@Builtin(name = "symlink", minNumOfPositionalArgs = 2, parameterNames = {"src", "dst", "target_is_directory"}, keywordOnlyNames = {"dir_fd"})
@ArgumentClinic(name = "src", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "dst", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "target_is_directory", conversion = ClinicConversion.Boolean, defaultValue = "false")
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@GenerateNodeFactory
abstract static class SymlinkNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.SymlinkNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone symlink(VirtualFrame frame, PosixPath src, PosixPath dst, @SuppressWarnings("unused") boolean targetIsDir, int dirFd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.symlinkat(getPosixSupport(), src.value, dirFd, dst.value);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, src.originalObject, dst.originalObject);
}
return PNone.NONE;
}
}
@Builtin(name = "mkdir", minNumOfPositionalArgs = 1, parameterNames = {"path", "mode"}, keywordOnlyNames = {"dir_fd"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "mode", conversion = ClinicConversion.Int, defaultValue = "0777")
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@GenerateNodeFactory
abstract static class MkdirNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.MkdirNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone mkdir(VirtualFrame frame, PosixPath path, int mode, int dirFd,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Bind("this") Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.mkdir", path.originalObject, mode, dirFdForAudit(dirFd));
try {
posixLib.mkdirat(getPosixSupport(), dirFd, path.value, mode);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
return PNone.NONE;
}
}
@Builtin(name = "rmdir", minNumOfPositionalArgs = 1, parameterNames = {"path"}, keywordOnlyNames = {"dir_fd"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"})
@ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class)
@GenerateNodeFactory
abstract static class RmdirNode extends PythonClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.RmdirNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone rmdir(VirtualFrame frame, PosixPath path, int dirFd,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Bind("this") Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.rmdir", path.originalObject, dirFdForAudit(dirFd));
try {
posixLib.unlinkat(getPosixSupport(), dirFd, path.value, true);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
return PNone.NONE;
}
}
@Builtin(name = "getcwd", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
abstract static class GetcwdNode extends PythonBuiltinNode {
@Specialization
TruffleString getcwd(VirtualFrame frame,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return posixLib.getPathAsString(getPosixSupport(), posixLib.getcwd(getPosixSupport()));
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "getcwdb", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
abstract static class GetcwdbNode extends PythonBuiltinNode {
@Specialization
PBytes getcwdb(VirtualFrame frame,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
return opaquePathToBytes(posixLib.getcwd(getPosixSupport()), posixLib, getPosixSupport(), factory());
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
@Builtin(name = "chdir", minNumOfPositionalArgs = 1, parameterNames = {"path"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "true"})
@GenerateNodeFactory
abstract static class ChdirNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.ChdirNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone chdirPath(VirtualFrame frame, PosixPath path,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.chdir(getPosixSupport(), path.value);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
return PNone.NONE;
}
@Specialization
PNone chdirFd(VirtualFrame frame, PosixFd fd,
@Bind("this") Node inliningTarget,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
posixLib.fchdir(getPosixSupport(), fd.fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject);
}
return PNone.NONE;
}
}
@Builtin(name = "fchdir", minNumOfPositionalArgs = 1, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversionClass = FileDescriptorConversionNode.class)
@GenerateNodeFactory
abstract static class FchdirNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.FchdirNodeClinicProviderGen.INSTANCE;
}
@Specialization
PNone fchdir(VirtualFrame frame, int fd,
@Bind("this") Node inliningTarget,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Cached InlinedBranchProfile errorProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
while (true) {
try {
posixLib.fchdir(getPosixSupport(), fd);
return PNone.NONE;
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) {
PythonContext.triggerAsyncActions(this);
} else {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
}
}
}
@Builtin(name = "isatty", minNumOfPositionalArgs = 1, parameterNames = {"fd"})
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int)
@GenerateNodeFactory
abstract static class IsattyNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.IsattyNodeClinicProviderGen.INSTANCE;
}
@Specialization
boolean isatty(int fd,
@Cached GilNode gil,
@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) {
gil.release(true);
try {
return posixLib.isatty(getPosixSupport(), fd);
} finally {
gil.acquire();
}
}
}
@Builtin(name = "ScandirIterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PScandirIterator, isPublic = false)
@GenerateNodeFactory
abstract static class ScandirIteratorNode extends PythonBuiltinNode {
@Specialization
@SuppressWarnings("unused")
Object scandirIterator(Object args, Object kwargs) {
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "posix.ScandirIterator");
}
}
@Builtin(name = "DirEntry", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDirEntry, isPublic = true)
@GenerateNodeFactory
abstract static class DirEntryNode extends PythonBuiltinNode {
@Specialization
@SuppressWarnings("unused")
Object dirEntry(Object args, Object kwargs) {
throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "posix.DirEntry");
}
}
@Builtin(name = "scandir", minNumOfPositionalArgs = 0, parameterNames = {"path"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"true", "true"})
@GenerateNodeFactory
abstract static class ScandirNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.ScandirNodeClinicProviderGen.INSTANCE;
}
@Specialization
PScandirIterator scandirPath(VirtualFrame frame, PosixPath path,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Bind("this") Node inliningTarget,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.scandir", path.originalObject == null ? PNone.NONE : path.originalObject);
try {
return factory().createScandirIterator(getContext(), posixLib.opendir(getPosixSupport(), path.value), path, false);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
}
@Specialization
PScandirIterator scandirFd(VirtualFrame frame, PosixFd fd,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Bind("this") Node inliningTarget,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.scandir", fd.originalObject);
Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, getPosixSupport(), fd, constructAndRaiseNode);
return factory().createScandirIterator(getContext(), dirStream, fd, true);
}
}
@Builtin(name = "listdir", minNumOfPositionalArgs = 0, parameterNames = {"path"})
@ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"true", "true"})
@GenerateNodeFactory
abstract static class ListdirNode extends PythonUnaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
return PosixModuleBuiltinsClinicProviders.ListdirNodeClinicProviderGen.INSTANCE;
}
@Specialization
PList listdirPath(VirtualFrame frame, PosixPath path,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Bind("this") Node inliningTarget,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.listdir", path.originalObject == null ? PNone.NONE : path.originalObject);
try {
return listdir(frame, inliningTarget, posixLib.opendir(getPosixSupport(), path.value), path.wasBufferLike, false, posixLib, constructAndRaiseNode);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
}
@Specialization
PList listdirFd(VirtualFrame frame, PosixFd fd,
@Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
@Bind("this") Node inliningTarget,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(inliningTarget, "os.listdir", fd.originalObject);
Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, getPosixSupport(), fd, constructAndRaiseNode);
return listdir(frame, inliningTarget, dirStream, false, true, posixLib, constructAndRaiseNode);
}
private PList listdir(VirtualFrame frame, Node inliningTarget, Object dirStream, boolean produceBytes, boolean needsRewind, PosixSupportLibrary posixLib,
PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy