/DICK.B1/IronPython.Modules/nt.cs
C# | 1616 lines | 1237 code | 269 blank | 110 comment | 226 complexity | 05172044dcb891d55e37f4083fef332a MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Microsoft Public License. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Microsoft Public License, please send an email to
- * ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Microsoft Public License.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
-
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Security.Cryptography;
-
- using Microsoft.Scripting;
- using Microsoft.Scripting.Runtime;
- using Microsoft.Scripting.Utils;
-
- using IronPython.Runtime;
- using IronPython.Runtime.Exceptions;
- using IronPython.Runtime.Operations;
- using IronPython.Runtime.Types;
-
- #if CLR2
- using Microsoft.Scripting.Math;
- #else
- using System.Numerics;
- #endif
-
- [assembly: PythonModule("nt", typeof(IronPython.Modules.PythonNT))]
- namespace IronPython.Modules {
- public static class PythonNT {
- public const string __doc__ = "Provides low-level operationg system access for files, the environment, etc...";
- #if !SILVERLIGHT
- private static Dictionary<int, Process> _processToIdMapping = new Dictionary<int, Process>();
- private static List<int> _freeProcessIds = new List<int>();
- private static int _processCount;
- #endif
-
- #region Public API Surface
-
- #if !SILVERLIGHT // FailFast
- public static void abort() {
- System.Environment.FailFast("IronPython os.abort");
- }
- #endif
-
- /// <summary>
- /// Checks for the specific permissions, provided by the mode parameter, are available for the provided path. Permissions can be:
- ///
- /// F_OK: Check to see if the file exists
- /// R_OK | W_OK | X_OK: Check for the specific permissions. Only W_OK is respected.
- /// </summary>
- public static bool access(CodeContext/*!*/ context, string path, int mode) {
- if (path == null) throw PythonOps.TypeError("expected string, got None");
-
- if (mode == F_OK) {
- return context.LanguageContext.DomainManager.Platform.FileExists(path);
- }
- #if !SILVERLIGHT
- // match the behavior of the VC C Runtime
- FileAttributes fa = File.GetAttributes(path);
- if ((fa & FileAttributes.Directory) != 0) {
- // directories have read & write access
- return true;
- }
-
- if ((fa & FileAttributes.ReadOnly) != 0 && (mode & W_OK) != 0) {
- // want to write but file is read-only
- return false;
- }
-
- return true;
- #else
- return false;
- #endif
- }
-
- #if !SILVERLIGHT // SetCurrentDirectory, FileInfo
- public static void chdir([NotNull]string path) {
- if (String.IsNullOrEmpty(path)) {
- throw PythonExceptions.CreateThrowable(WindowsError, PythonExceptions._WindowsError.ERROR_INVALID_NAME, "Path cannot be an empty string");
- }
-
- try {
- Directory.SetCurrentDirectory(path);
- } catch (Exception e) {
- throw ToPythonException(e, path);
- }
- }
-
- public static void chmod(string path, int mode) {
- FileInfo fi = new FileInfo(path);
- if ((mode & S_IWRITE) != 0) {
- fi.Attributes &= ~(FileAttributes.ReadOnly);
- } else {
- fi.Attributes |= FileAttributes.ReadOnly;
- }
- }
- #endif
-
- public static void close(CodeContext/*!*/ context, int fd) {
- PythonContext pythonContext = PythonContext.GetContext(context);
- PythonFile pf = pythonContext.FileManager.GetFileFromId(pythonContext, fd);
- pf.close();
- }
-
- #if !SILVERLIGHT
- /// <summary>
- /// single instance of environment dictionary is shared between multiple runtimes because the environment
- /// is shared by multiple runtimes.
- /// </summary>
- public static readonly object environ = new PythonDictionary(new EnvironmentDictionaryStorage());
- #endif
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
- public static readonly PythonType error = Builtin.OSError;
-
- public static void _exit(CodeContext/*!*/ context, int code) {
- PythonContext.GetContext(context).DomainManager.Platform.TerminateScriptExecution(code);
- }
-
- public static object fdopen(CodeContext/*!*/ context, int fd) {
- return fdopen(context, fd, "r");
- }
-
- public static object fdopen(CodeContext/*!*/ context, int fd, string mode) {
- return fdopen(context, fd, mode, 0);
- }
-
- public static object fdopen(CodeContext/*!*/ context, int fd, string mode, int bufsize) {
- // check for a valid file mode...
- PythonFile.ValidateMode(mode);
-
- PythonContext pythonContext = PythonContext.GetContext(context);
- PythonFile pf = pythonContext.FileManager.GetFileFromId(pythonContext, fd);
- return pf;
- }
-
- public static object fstat(CodeContext/*!*/ context, int fd) {
- PythonContext pythonContext = PythonContext.GetContext(context);
- PythonFile pf = pythonContext.FileManager.GetFileFromId(pythonContext, fd);
- if (pf.IsConsole) {
- return new stat_result(8192);
- }
- return lstat(pf.name);
- }
-
- public static string getcwd(CodeContext/*!*/ context) {
- return context.LanguageContext.DomainManager.Platform.CurrentDirectory;
- }
-
- public static string getcwdu(CodeContext/*!*/ context) {
- return context.LanguageContext.DomainManager.Platform.CurrentDirectory;
- }
-
- public static string _getfullpathname(CodeContext/*!*/ context, [NotNull]string/*!*/ dir) {
- PlatformAdaptationLayer pal = context.LanguageContext.DomainManager.Platform;
-
- try {
- return context.LanguageContext.DomainManager.Platform.GetFullPath(dir);
- } catch (ArgumentException) {
- // .NET validates the path, CPython doesn't... so we replace invalid chars with
- // Char.Maxvalue, get the full path, and then replace the Char.Maxvalue's back w/
- // their original value.
- string newdir = dir;
-
- if (IsWindows()) {
- if (newdir.Length >= 2 && newdir[1] == ':' &&
- (newdir[0] < 'a' || newdir[0] > 'z') && (newdir[0] < 'A' || newdir[0] > 'Z')) {
- // invalid drive, .NET will reject this
- if (newdir.Length == 2) {
- return newdir + Path.DirectorySeparatorChar;
- } else if (newdir[2] == Path.DirectorySeparatorChar) {
- return newdir;
- } else {
- return newdir.Substring(0, 2) + Path.DirectorySeparatorChar + newdir.Substring(2);
- }
- }
- if (newdir.Length > 2 && newdir.IndexOf(':', 2) != -1) {
- // : is an invalid char if it's not in the 2nd position
- newdir = newdir.Substring(0, 2) + newdir.Substring(2).Replace(':', Char.MaxValue);
- }
-
- if (newdir.Length > 0 && newdir[0] == ':') {
- newdir = Char.MaxValue + newdir.Substring(1);
- }
- }
-
- foreach (char c in Path.GetInvalidPathChars()) {
- newdir = newdir.Replace(c, Char.MaxValue);
- }
-
- // walk backwards through the path replacing the same characters. We should have
- // only updated the directory leaving the filename which we're fixing.
- string res = context.LanguageContext.DomainManager.Platform.GetFullPath(newdir);
- int curDir = dir.Length;
- for (int curRes = res.Length - 1; curRes >= 0; curRes--) {
- if (res[curRes] == Char.MaxValue) {
- for (curDir--; curDir >= 0; curDir--) {
- if (newdir[curDir] == Char.MaxValue) {
- res = res.Substring(0, curRes) + dir[curDir] + res.Substring(curRes + 1);
- break;
- }
- }
- }
- }
-
- return res;
- }
- }
-
- private static bool IsWindows() {
- return Environment.OSVersion.Platform == PlatformID.Win32NT ||
- Environment.OSVersion.Platform == PlatformID.Win32S ||
- Environment.OSVersion.Platform == PlatformID.Win32Windows;
- }
-
- #if !SILVERLIGHT
- public static int getpid() {
- return System.Diagnostics.Process.GetCurrentProcess().Id;
- }
- #endif
-
- public static List listdir(CodeContext/*!*/ context, [NotNull]string path) {
- if (path == String.Empty) {
- path = ".";
- }
-
- List ret = PythonOps.MakeList();
- try {
- addBase(context.LanguageContext.DomainManager.Platform.GetFileSystemEntries(path, "*"), ret);
- return ret;
- } catch (Exception e) {
- throw ToPythonException(e, path);
- }
- }
-
- //
- // lstat(path) -> stat result
- // Like stat(path), but do not follow symbolic links.
- //
- public static object lstat(string path) {
- return stat(path);
- }
-
- #if !SILVERLIGHT
- public static void mkdir(string path) {
- if (Directory.Exists(path))
- throw DirectoryExists();
-
- try {
- Directory.CreateDirectory(path);
- } catch (Exception e) {
- throw ToPythonException(e, path);
- }
- }
-
- public static void mkdir(string path, int mode) {
- if (Directory.Exists(path)) throw DirectoryExists();
- // we ignore mode
-
- try {
- Directory.CreateDirectory(path);
- } catch (Exception e) {
- throw ToPythonException(e, path);
- }
- }
-
- public static object open(CodeContext/*!*/ context, string filename, int flag) {
- return open(context, filename, flag, 0777);
- }
-
- private const int DefaultBufferSize = 4096;
-
- public static object open(CodeContext/*!*/ context, string filename, int flag, int mode) {
- try {
- FileMode fileMode = FileModeFromFlags(flag);
- FileAccess access = FileAccessFromFlags(flag);
- FileOptions options = FileOptionsFromFlags(flag);
- FileStream fs;
- if (access == FileAccess.Read && (fileMode == FileMode.CreateNew || fileMode == FileMode.Create || fileMode == FileMode.Append)) {
- // .NET doesn't allow Create/CreateNew w/ access == Read, so create the file, then close it, then
- // open it again w/ just read access.
- fs = new FileStream(filename, fileMode, FileAccess.Write, FileShare.None);
- fs.Close();
- fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, DefaultBufferSize, options);
- } else if(access == FileAccess.ReadWrite && fileMode == FileMode.Append) {
- fs = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.ReadWrite, DefaultBufferSize, options);
- } else {
- fs = new FileStream(filename, fileMode, access, FileShare.ReadWrite, DefaultBufferSize, options);
- }
-
- string mode2;
- if (fs.CanRead && fs.CanWrite) mode2 = "w+";
- else if (fs.CanWrite) mode2 = "w";
- else mode2 = "r";
-
- if ((flag & O_BINARY) != 0) {
- mode2 += "b";
- }
-
- return PythonContext.GetContext(context).FileManager.AddToStrongMapping(PythonFile.Create(context, fs, filename, mode2));
- } catch (Exception e) {
- throw ToPythonException(e, filename);
- }
- }
-
- private static FileOptions FileOptionsFromFlags(int flag) {
- FileOptions res = FileOptions.None;
- if ((flag & O_TEMPORARY) != 0) {
- res |= FileOptions.DeleteOnClose;
- }
- if ((flag & O_RANDOM) != 0) {
- res |= FileOptions.RandomAccess;
- }
- if ((flag & O_SEQUENTIAL) != 0) {
- res |= FileOptions.SequentialScan;
- }
-
- return res;
- }
-
- public static PythonFile popen(CodeContext/*!*/ context, string command) {
- return popen(context, command, "r");
- }
-
- public static PythonFile popen(CodeContext/*!*/ context, string command, string mode) {
- return popen(context, command, mode, 4096);
- }
-
- public static PythonFile popen(CodeContext/*!*/ context, string command, string mode, int bufsize) {
- if (String.IsNullOrEmpty(mode)) mode = "r";
- ProcessStartInfo psi = GetProcessInfo(command);
- psi.CreateNoWindow = true; // ipyw shouldn't create a new console window
- Process p;
- PythonFile res;
-
- try {
- switch (mode) {
- case "r":
- psi.RedirectStandardOutput = true;
- p = Process.Start(psi);
-
- res = new POpenFile(context, command, p, p.StandardOutput.BaseStream, "r");
- break;
- case "w":
- psi.RedirectStandardInput = true;
- p = Process.Start(psi);
-
- res = new POpenFile(context, command, p, p.StandardInput.BaseStream, "w");
- break;
- default:
- throw PythonOps.ValueError("expected 'r' or 'w' for mode, got {0}", mode);
- }
- } catch (Exception e) {
- throw ToPythonException(e);
- }
-
- return res;
- }
-
- public static PythonTuple popen2(CodeContext/*!*/ context, string command) {
- return popen2(context, command, "t");
- }
-
- public static PythonTuple popen2(CodeContext/*!*/ context, string command, string mode) {
- return popen2(context, command, "t", 4096);
- }
-
- public static PythonTuple popen2(CodeContext/*!*/ context, string command, string mode, int bufsize) {
- if (String.IsNullOrEmpty(mode)) mode = "t";
- if (mode != "t" && mode != "b") throw PythonOps.ValueError("mode must be 't' or 'b' (default is t)");
- if (mode == "t") mode = String.Empty;
-
- try {
- ProcessStartInfo psi = GetProcessInfo(command);
- psi.RedirectStandardInput = true;
- psi.RedirectStandardOutput = true;
- psi.CreateNoWindow = true; // ipyw shouldn't create a new console window
- Process p = Process.Start(psi);
-
- return PythonTuple.MakeTuple(new POpenFile(context, command, p, p.StandardInput.BaseStream, "w" + mode),
- new POpenFile(context, command, p, p.StandardOutput.BaseStream, "r" + mode));
- } catch (Exception e) {
- throw ToPythonException(e);
- }
- }
-
- public static PythonTuple popen3(CodeContext/*!*/ context, string command) {
- return popen3(context, command, "t");
- }
-
- public static PythonTuple popen3(CodeContext/*!*/ context, string command, string mode) {
- return popen3(context, command, "t", 4096);
- }
-
- public static PythonTuple popen3(CodeContext/*!*/ context, string command, string mode, int bufsize) {
- if (String.IsNullOrEmpty(mode)) mode = "t";
- if (mode != "t" && mode != "b") throw PythonOps.ValueError("mode must be 't' or 'b' (default is t)");
- if (mode == "t") mode = String.Empty;
-
- try {
- ProcessStartInfo psi = GetProcessInfo(command);
- psi.RedirectStandardInput = true;
- psi.RedirectStandardOutput = true;
- psi.RedirectStandardError = true;
- psi.CreateNoWindow = true; // ipyw shouldn't create a new console window
- Process p = Process.Start(psi);
-
- return PythonTuple.MakeTuple(new POpenFile(context, command, p, p.StandardInput.BaseStream, "w" + mode),
- new POpenFile(context, command, p, p.StandardOutput.BaseStream, "r" + mode),
- new POpenFile(context, command, p, p.StandardError.BaseStream, "r+" + mode));
- } catch (Exception e) {
- throw ToPythonException(e);
- }
- }
-
- public static void putenv(string varname, string value) {
- try {
- System.Environment.SetEnvironmentVariable(varname, value);
- } catch (Exception e) {
- throw ToPythonException(e);
- }
- }
- #endif
-
- public static string read(CodeContext/*!*/ context, int fd, int buffersize) {
- if (buffersize < 0) {
- throw PythonExceptions.CreateThrowable(PythonExceptions.OSError, PythonErrorNumber.EINVAL, "Invalid argument");
- }
-
- try {
- PythonContext pythonContext = PythonContext.GetContext(context);
- PythonFile pf = pythonContext.FileManager.GetFileFromId(pythonContext, fd);
- return pf.read();
- } catch (Exception e) {
- throw ToPythonException(e);
- }
- }
-
- #if !SILVERLIGHT
- public static void remove(string path) {
- UnlinkWorker(path);
- }
- #endif
-
- public static void rename(string src, string dst) {
- try {
- Directory.Move(src, dst);
- } catch (Exception e) {
- throw ToPythonException(e);
- }
- }
-
- public static void rmdir(string path) {
- try {
- Directory.Delete(path);
- } catch (Exception e) {
- throw ToPythonException(e, path);
- }
- }
-
- #if !SILVERLIGHT
- /// <summary>
- /// spawns a new process.
- ///
- /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
- /// is the exit code.
- ///
- /// Otherwise the call returns a handle to the process. The caller must then call nt.waitpid(pid, options)
- /// to free the handle and get the exit code of the process. Failure to call nt.waitpid will result
- /// in a handle leak.
- /// </summary>
- public static object spawnl(CodeContext/*!*/ context, int mode, string path, params object[] args) {
- return SpawnProcessImpl(context, MakeProcess(), mode, path, args);
- }
-
- /// <summary>
- /// spawns a new process.
- ///
- /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
- /// is the exit code.
- ///
- /// Otherwise the call returns a handle to the process. The caller must then call nt.waitpid(pid, options)
- /// to free the handle and get the exit code of the process. Failure to call nt.waitpid will result
- /// in a handle leak.
- /// </summary>
- public static object spawnle(CodeContext/*!*/ context, int mode, string path, params object[] args) {
- if (args.Length < 1) {
- throw PythonOps.TypeError("spawnle() takes at least three arguments ({0} given)", 2 + args.Length);
- }
-
- object env = args[args.Length - 1];
- object[] slicedArgs = ArrayUtils.RemoveFirst(args);
-
- Process process = MakeProcess();
- SetEnvironment(process.StartInfo.EnvironmentVariables, env);
-
- return SpawnProcessImpl(context, process, mode, path, slicedArgs);
- }
-
- /// <summary>
- /// spawns a new process.
- ///
- /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
- /// is the exit code.
- ///
- /// Otherwise the call returns a handle to the process. The caller must then call nt.waitpid(pid, options)
- /// to free the handle and get the exit code of the process. Failure to call nt.waitpid will result
- /// in a handle leak.
- /// </summary>
- public static object spawnv(CodeContext/*!*/ context, int mode, string path, object args) {
- return SpawnProcessImpl(context, MakeProcess(), mode, path, args);
- }
-
- /// <summary>
- /// spawns a new process.
- ///
- /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
- /// is the exit code.
- ///
- /// Otherwise the call returns a handle to the process. The caller must then call nt.waitpid(pid, options)
- /// to free the handle and get the exit code of the process. Failure to call nt.waitpid will result
- /// in a handle leak.
- /// </summary>
- public static object spawnve(CodeContext/*!*/ context, int mode, string path, object args, object env) {
- Process process = MakeProcess();
- SetEnvironment(process.StartInfo.EnvironmentVariables, env);
-
- return SpawnProcessImpl(context, process, mode, path, args);
- }
-
- private static Process MakeProcess() {
- try {
- return new Process();
- } catch (Exception e) {
- throw ToPythonException(e);
- }
- }
-
- private static object SpawnProcessImpl(CodeContext/*!*/ context, Process process, int mode, string path, object args) {
- try {
- process.StartInfo.Arguments = ArgumentsToString(context, args);
- process.StartInfo.FileName = path;
- process.StartInfo.UseShellExecute = false;
- } catch (Exception e) {
- throw ToPythonException(e, path);
- }
-
- if (!process.Start()) {
- throw PythonOps.OSError("Cannot start process: {0}", path);
- }
- if (mode == P_WAIT) {
- process.WaitForExit();
- int exitCode = process.ExitCode;
- process.Close();
- return exitCode;
- }
-
- lock (_processToIdMapping) {
- int id;
- if (_freeProcessIds.Count > 0) {
- id = _freeProcessIds[_freeProcessIds.Count - 1];
- _freeProcessIds.RemoveAt(_freeProcessIds.Count - 1);
- } else {
- // process IDs are handles on CPython/Win32 so we match
- // that behavior and return something that is handle like. Handles
- // on NT are guaranteed to have the low 2 bits not set and users
- // could use these for their own purposes. We therefore match that
- // behavior here.
- _processCount += 4;
- id = _processCount;
- }
-
- _processToIdMapping[id] = process;
- return ScriptingRuntimeHelpers.Int32ToObject(id);
- }
- }
-
- /// <summary>
- /// Copy elements from a Python mapping of dict environment variables to a StringDictionary.
- /// </summary>
- private static void SetEnvironment(System.Collections.Specialized.StringDictionary currentEnvironment, object newEnvironment) {
- PythonDictionary env = newEnvironment as PythonDictionary;
- if (env == null) {
- throw PythonOps.TypeError("env argument must be a dict");
- }
-
- currentEnvironment.Clear();
-
- string strKey, strValue;
- foreach (object key in env.keys()) {
- if (!Converter.TryConvertToString(key, out strKey)) {
- throw PythonOps.TypeError("env dict contains a non-string key");
- }
- if (!Converter.TryConvertToString(env[key], out strValue)) {
- throw PythonOps.TypeError("env dict contains a non-string value");
- }
- currentEnvironment[strKey] = strValue;
- }
- }
- #endif
-
- /// <summary>
- /// Convert a sequence of args to a string suitable for using to spawn a process.
- /// </summary>
- private static string ArgumentsToString(CodeContext/*!*/ context, object args) {
- IEnumerator argsEnumerator;
- System.Text.StringBuilder sb = null;
- if (!PythonOps.TryGetEnumerator(context, args, out argsEnumerator)) {
- throw PythonOps.TypeError("args parameter must be sequence, not {0}", DynamicHelpers.GetPythonType(args));
- }
-
- bool space = false;
- try {
- // skip the first element, which is the name of the command being run
- argsEnumerator.MoveNext();
- while (argsEnumerator.MoveNext()) {
- if (sb == null) sb = new System.Text.StringBuilder(); // lazy creation
- string strarg = PythonOps.ToString(argsEnumerator.Current);
- if (space) {
- sb.Append(' ');
- }
- if (strarg.IndexOf(' ') != -1) {
- sb.Append('"');
- // double quote any existing quotes
- sb.Append(strarg.Replace("\"", "\"\""));
- sb.Append('"');
- } else {
- sb.Append(strarg);
- }
- space = true;
- }
- } finally {
- IDisposable disposable = argsEnumerator as IDisposable;
- if (disposable != null) disposable.Dispose();
- }
-
- if (sb == null) return "";
- return sb.ToString();
- }
-
- #if !SILVERLIGHT
- public static void startfile(string filename, [DefaultParameterValue("open")]string operation) {
- System.Diagnostics.Process process = new System.Diagnostics.Process();
- process.StartInfo.FileName = filename;
- process.StartInfo.UseShellExecute = true;
- process.StartInfo.Verb = operation;
- try {
-
- process.Start();
- } catch (Exception e) {
- throw ToPythonException(e, filename);
- }
- }
- #endif
-
- [PythonType, DontMapIEnumerableToIter]
- public class stat_result : IList, IList<object> {
- private readonly object _mode, _size, _atime, _mtime, _ctime, _st_atime, _st_mtime, _st_ctime, _ino, _dev, _nlink, _uid, _gid;
-
- public const int n_fields = 13;
- public const int n_sequence_fields = 10;
- public const int n_unnamed_fields = 3;
-
- internal stat_result(int mode) : this(mode, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero, BigInteger.Zero) {
- _mode = mode;
- }
-
- internal stat_result(int mode, BigInteger size, BigInteger st_atime, BigInteger st_mtime, BigInteger st_ctime) {
- _mode = mode;
- _size = size;
- _st_atime = _atime = TryShrinkToInt(st_atime);
- _st_mtime = _mtime = TryShrinkToInt(st_mtime);
- _st_ctime = _ctime = TryShrinkToInt(st_ctime);
-
- _ino = _dev = _nlink = _uid = _gid = ScriptingRuntimeHelpers.Int32ToObject(0);
- }
-
- public stat_result(CodeContext/*!*/ context, IList statResult, [DefaultParameterValue(null)]PythonDictionary dict) {
- // dict is allowed by CPython's stat_result, but doesn't seem to do anything, so we ignore it here.
-
- if (statResult.Count < 10) {
- throw PythonOps.TypeError("stat_result() takes an at least 10-sequence ({0}-sequence given)", statResult.Count);
- }
-
- _mode = statResult[0];
- _ino = statResult[1];
- _dev = statResult[2];
- _nlink = statResult[3];
- _uid = statResult[4];
- _gid = statResult[5];
- _size = statResult[6];
- _atime = statResult[7];
- _mtime = statResult[8];
- _ctime = statResult[9];
-
- object dictTime;
- if (statResult.Count >= 11) {
- _st_atime = TryShrinkToInt(statResult[10]);
- } else if (TryGetDictValue(dict, "st_atime", out dictTime)) {
- _st_atime = dictTime;
- } else {
- _st_atime = TryShrinkToInt(_atime);
- }
-
- if (statResult.Count >= 12) {
- _st_mtime = TryShrinkToInt(statResult[11]);
- } else if (TryGetDictValue(dict, "st_mtime", out dictTime)) {
- _st_mtime = dictTime;
- } else {
- _st_mtime = TryShrinkToInt(_mtime);
- }
-
- if (statResult.Count >= 13) {
- _st_ctime = TryShrinkToInt(statResult[12]);
- } else if (TryGetDictValue(dict, "st_ctime", out dictTime)) {
- _st_ctime = dictTime;
- } else {
- _st_ctime = TryShrinkToInt(_ctime);
- }
- }
-
- private static bool TryGetDictValue(PythonDictionary dict, string name, out object dictTime) {
- if (dict != null && dict.TryGetValue(name, out dictTime)) {
- dictTime = TryShrinkToInt(dictTime);
- return true;
- }
-
- dictTime = null;
- return false;
- }
-
- private static object TryShrinkToInt(object value) {
- if (!(value is BigInteger)) {
- return value;
- }
-
- return BigIntegerOps.__int__((BigInteger)value);
- }
-
- public object st_atime {
- get {
- return _st_atime;
- }
- }
-
- public object st_ctime {
- get {
- return _st_ctime;
- }
- }
-
-
- public object st_mtime {
- get {
- return _st_mtime;
- }
- }
-
- public object st_dev {
- get {
- return TryShrinkToInt(_dev);
- }
- }
-
- public object st_gid {
- get {
- return _gid;
- }
- }
-
- public object st_ino {
- get {
- return _ino;
- }
- }
-
- public object st_mode {
- get {
- return TryShrinkToInt(_mode);
- }
- }
-
- public object st_nlink {
- get {
- return TryShrinkToInt(_nlink);
- }
- }
-
- public object st_size {
- get {
- return _size;
- }
- }
-
- public object st_uid {
- get {
- return _uid;
- }
- }
-
- public static PythonTuple operator +(stat_result stat, object tuple) {
- PythonTuple tupleObj = tuple as PythonTuple;
- if (tupleObj == null) {
- throw PythonOps.TypeError("can only concatenate tuple (not \"{0}\") to tuple", PythonTypeOps.GetName(tuple));
- }
- return stat.MakeTuple() + tupleObj;
- }
-
- public static bool operator >(stat_result stat, [NotNull]stat_result o) {
- return stat.MakeTuple() > PythonTuple.Make(o);
- }
-
- public static bool operator <(stat_result stat, [NotNull]stat_result o) {
- return stat.MakeTuple() < PythonTuple.Make(o);
- }
-
- public static bool operator >=(stat_result stat, [NotNull]stat_result o) {
- return stat.MakeTuple() >= PythonTuple.Make(o);
- }
-
- public static bool operator <=(stat_result stat, [NotNull]stat_result o) {
- return stat.MakeTuple() <= PythonTuple.Make(o);
- }
-
- public static bool operator >(stat_result stat, object o) {
- return true;
- }
-
- public static bool operator <(stat_result stat, object o) {
- return false;
- }
-
- public static bool operator >=(stat_result stat, object o) {
- return true;
- }
-
- public static bool operator <=(stat_result stat, object o) {
- return false;
- }
-
- public static PythonTuple operator *(stat_result stat, int size) {
- return stat.MakeTuple() * size;
- }
-
- public static PythonTuple operator *(int size, stat_result stat) {
- return stat.MakeTuple() * size;
- }
-
- public override string ToString() {
- return MakeTuple().ToString();
- }
-
- public string/*!*/ __repr__() {
- return ToString();
- }
-
- public PythonTuple __reduce__() {
- PythonDictionary timeDict = new PythonDictionary(3);
- timeDict["st_atime"] = st_atime;
- timeDict["st_ctime"] = st_ctime;
- timeDict["st_mtime"] = st_mtime;
-
- return PythonTuple.MakeTuple(
- DynamicHelpers.GetPythonTypeFromType(typeof(stat_result)),
- PythonTuple.MakeTuple(MakeTuple(), timeDict)
- );
- }
-
- #region ISequence Members
-
- //public object AddSequence(object other) {
- // return MakeTuple().AddSequence(other);
- //}
-
- //public object MultiplySequence(object count) {
- // return MakeTuple().MultiplySequence(count);
- //}
-
- public object this[int index] {
- get {
- return MakeTuple()[index];
- }
- }
-
- public object this[Slice slice] {
- get {
- return MakeTuple()[slice];
- }
- }
-
- public object __getslice__(int start, int stop) {
- return MakeTuple().__getslice__(start, stop);
- }
-
- public int __len__() {
- return MakeTuple().__len__();
- }
-
- public bool __contains__(object item) {
- return ((ICollection<object>)MakeTuple()).Contains(item);
- }
-
- #endregion
-
- private PythonTuple MakeTuple() {
- return PythonTuple.MakeTuple(
- st_mode,
- st_ino,
- st_dev,
- st_nlink,
- st_uid,
- st_gid,
- st_size,
- _atime,
- _mtime,
- _ctime
- );
- }
-
- #region Object overrides
-
- public override bool Equals(object obj) {
- if (obj is stat_result) {
- return MakeTuple().Equals(((stat_result)obj).MakeTuple());
- } else {
- return MakeTuple().Equals(obj);
- }
-
- }
-
- public override int GetHashCode() {
- return MakeTuple().GetHashCode();
- }
-
- #endregion
-
- #region IList<object> Members
-
- int IList<object>.IndexOf(object item) {
- return MakeTuple().IndexOf(item);
- }
-
- void IList<object>.Insert(int index, object item) {
- throw new InvalidOperationException();
- }
-
- void IList<object>.RemoveAt(int index) {
- throw new InvalidOperationException();
- }
-
- object IList<object>.this[int index] {
- get {
- return MakeTuple()[index];
- }
- set {
- throw new InvalidOperationException();
- }
- }
-
- #endregion
-
- #region ICollection<object> Members
-
- void ICollection<object>.Add(object item) {
- throw new InvalidOperationException();
- }
-
- void ICollection<object>.Clear() {
- throw new InvalidOperationException();
- }
-
- bool ICollection<object>.Contains(object item) {
- return __contains__(item);
- }
-
- void ICollection<object>.CopyTo(object[] array, int arrayIndex) {
- throw new NotImplementedException();
- }
-
- int ICollection<object>.Count {
- get { return __len__(); }
- }
-
- bool ICollection<object>.IsReadOnly {
- get { return true; }
- }
-
- bool ICollection<object>.Remove(object item) {
- throw new InvalidOperationException();
- }
-
- #endregion
-
- #region IEnumerable<object> Members
-
- IEnumerator<object> IEnumerable<object>.GetEnumerator() {
- foreach (object o in MakeTuple()) {
- yield return o;
- }
- }
-
- #endregion
-
- #region IEnumerable Members
-
- IEnumerator IEnumerable.GetEnumerator() {
- foreach (object o in MakeTuple()) {
- yield return o;
- }
- }
-
- #endregion
-
- #region IList Members
-
- int IList.Add(object value) {
- throw new InvalidOperationException();
- }
-
- void IList.Clear() {
- throw new InvalidOperationException();
- }
-
- bool IList.Contains(object value) {
- return __contains__(value);
- }
-
- int IList.IndexOf(object value) {
- return MakeTuple().IndexOf(value);
- }
-
- void IList.Insert(int index, object value) {
- throw new InvalidOperationException();
- }
-
- bool IList.IsFixedSize {
- get { return true; }
- }
-
- bool IList.IsReadOnly {
- get { return true; }
- }
-
- void IList.Remove(object value) {
- throw new InvalidOperationException();
- }
-
- void IList.RemoveAt(int index) {
- throw new InvalidOperationException();
- }
-
- object IList.this[int index] {
- get {
- return MakeTuple()[index];
- }
- set {
- throw new InvalidOperationException();
- }
- }
-
- #endregion
-
- #region ICollection Members
-
- void ICollection.CopyTo(Array array, int index) {
- throw new NotImplementedException();
- }
-
- int ICollection.Count {
- get { return __len__(); }
- }
-
- bool ICollection.IsSynchronized {
- get { return false; }
- }
-
- object ICollection.SyncRoot {
- get { return this; }
- }
-
- #endregion
- }
-
- private static bool HasExecutableExtension(string path) {
- string extension = Path.GetExtension(path).ToLower(CultureInfo.InvariantCulture);
- return (extension == ".exe" || extension == ".dll" || extension == ".com" || extension == ".bat");
- }
-
- [Documentation("stat(path) -> stat result\nGathers statistics about the specified file or directory")]
- public static object stat(string path) {
- if (path == null) throw PythonOps.TypeError("expected string, got NoneType");
-
- stat_result sr;
-
- try {
- FileInfo fi = new FileInfo(path);
- int mode = 0;
- long size;
-
- if (Directory.Exists(path)) {
- size = 0;
- mode = 0x4000 | S_IEXEC;
- } else if (File.Exists(path)) {
- size = fi.Length;
- mode = 0x8000;
- if (HasExecutableExtension(path)) {
- mode |= S_IEXEC;
- }
- } else {
- throw PythonExceptions.CreateThrowable(WindowsError, PythonExceptions._WindowsError.ERROR_PATH_NOT_FOUND, "file does not exist: " + path);
- }
-
- long st_atime = (long)PythonTime.TicksToTimestamp(fi.LastAccessTime.ToUniversalTime().Ticks);
- long st_ctime = (long)PythonTime.TicksToTimestamp(fi.CreationTime.ToUniversalTime().Ticks);
- long st_mtime = (long)PythonTime.TicksToTimestamp(fi.LastWriteTime.ToUniversalTime().Ticks);
- mode |= S_IREAD;
- if ((fi.Attributes & FileAttributes.ReadOnly) == 0) {
- mode |= S_IWRITE;
- }
-
- sr = new stat_result(mode, size, st_atime, st_mtime, st_ctime);
- } catch (ArgumentException) {
- throw PythonExceptions.CreateThrowable(WindowsError, PythonExceptions._WindowsError.ERROR_INVALID_NAME, "The path is invalid: " + path);
- } catch (Exception e) {
- throw ToPythonException(e, path);
- }
-
- return sr;
- }
-
- public static string strerror(int code) {
- switch(code) {
- case 0: return "No error";
- case PythonErrorNumber.E2BIG: return "Arg list too long";
- case PythonErrorNumber.EACCES: return "Permission denied";
- case PythonErrorNumber.EAGAIN: return "Resource temporarily unavailable";
- case PythonErrorNumber.EBADF: return "Bad file descriptor";
- case PythonErrorNumber.EBUSY: return "Resource device";
- case PythonErrorNumber.ECHILD: return "No child processes";
- case PythonErrorNumber.EDEADLK: return "Resource deadlock avoided";
- case PythonErrorNumber.EDOM: return "Domain error";
- case PythonErrorNumber.EDQUOT: return "Unknown error";
- case PythonErrorNumber.EEXIST: return "File exists";
- case PythonErrorNumber.EFAULT: return "Bad address";
- case PythonErrorNumber.EFBIG: return "File too large";
- case PythonErrorNumber.EILSEQ: return "Illegal byte sequence";
- case PythonErrorNumber.EINTR: return "Interrupted function call";
- case PythonErrorNumber.EINVAL: return "Invalid argument";
- case PythonErrorNumber.EIO: return "Input/output error";
- case PythonErrorNumber.EISCONN: return "Unknown error";
- case PythonErrorNumber.EISDIR: return "Is a directory";
- case PythonErrorNumber.EMFILE: return "Too many open files";
- case PythonErrorNumber.EMLINK: return "Too many links";
- case PythonErrorNumber.ENAMETOOLONG: return "Filename too long";
- case PythonErrorNumber.ENFILE: return "Too many open files in system";
- case PythonErrorNumber.ENODEV: return "No such device";
- case PythonErrorNumber.ENOENT: return "No such file or directory";
- case PythonErrorNumber.ENOEXEC: return "Exec format error";
- case PythonErrorNumber.ENOLCK: return "No locks available";
- case PythonErrorNumber.ENOMEM: return "Not enough space";
- case PythonErrorNumber.ENOSPC: return "No space left on device";
- case PythonErrorNumber.ENOSYS: return "Function not implemented";
- case PythonErrorNumber.ENOTDIR: return "Not a directory";
- case PythonErrorNumber.ENOTEMPTY: return "Directory not empty";
- case PythonErrorNumber.ENOTSOCK: return "Unknown error";
- case PythonErrorNumber.ENOTTY: return "Inappropriate I/O control operation";
- case PythonErrorNumber.ENXIO: return "No such device or address";
- case PythonErrorNumber.EPERM: return "Operation not permitted";
- case PythonErrorNumber.EPIPE: return "Broken pipe";
- case PythonErrorNumber.ERANGE: return "Result too large";
- case PythonErrorNumber.EROFS: return "Read-only file system";
- case PythonErrorNumber.ESPIPE: return "Invalid seek";
- case PythonErrorNumber.ESRCH: return "No such process";
- case PythonErrorNumber.EXDEV: return "Improper link";
- default:
- return "Unknown error " + code;
- }
- }
-
- private static PythonType WindowsError {
- get {
- #if !SILVERLIGHT
- return PythonExceptions.WindowsError;
- #else
- return PythonExceptions.OSError;
- #endif
- }
- }
-
- #if !SILVERLIGHT
- [Documentation("system(command) -> int\nExecute the command (a string) in a subshell.")]
- public static int system(string command) {
- ProcessStartInfo psi = GetProcessInfo(command);
- psi.CreateNoWindow = false;
-
- try {
- Process process = Process.Start(psi);
- if (process == null) {
- return -1;
- }
- process.WaitForExit();
- return process.ExitCode;
- } catch (Win32Exception) {
- return 1;
- }
- }
-
- public static string tempnam(CodeContext/*!*/ context) {
- return tempnam(context, null);
- }
-
- public static string tempnam(CodeContext/*!*/ context, string dir) {
- return tempnam(context, null, null);
- }
-
- public static string tempnam(CodeContext/*!*/ context, string dir, string prefix) {
- PythonOps.Warn(context, PythonExceptions.RuntimeWarning, "tempnam is a potential security risk to your program");
-
- try {
- dir = Path.GetTempPath(); // Reasonably consistent with CPython behavior under Windows
-
- return Path.GetFullPath(Path.Combine(dir, prefix ?? String.Empty) + Path.GetRandomFileName());
- } catch (Exception e) {
- throw ToPythonException(e, dir);
- }
- }
-
- public static object times() {
- System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();
-
- return PythonTuple.MakeTuple(p.UserProcessorTime.TotalSeconds,
- p.PrivilegedProcessorTime.TotalSeconds,
- 0, // child process system time
- 0, // child process os time
- DateTime.Now.Subtract(p.StartTime).TotalSeconds);
- }
- #endif
-
- #if !SILVERLIGHT
- public static PythonFile/*!*/ tmpfile(CodeContext/*!*/ context) {
- try {
- FileStream sw = new FileStream(Path.GetTempFileName(), FileMode.Open, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
-
- PythonFile res = PythonFile.Create(context, sw, sw.Name, "w+b");
- return res;
- } catch (Exception e) {
- throw ToPythonException(e);
- }
…
Large files files are truncated, but you can click here to view the full file