internal FileStreamContentProvider(PlatformAdaptationLayer pal, string path)
        {
            Assert.NotNull(pal, path);

            _path = path;
            _pal = new PALHolder(pal);
        }
Example #2
0
 private static void SetCurrentDirectory(PlatformAdaptationLayer/*!*/ pal, string/*!*/ dir) {
     try {
         // TODO: MRI calls Win32 API SetCurrentDirctory directly, while BCL normalizes the path first.
         pal.CurrentDirectory = dir;
     } catch (Exception e) {
         throw ToRubyException(e, dir, DirectoryOperation.ChangeDir);
     }
 }
Example #3
0
        /*!*/
        public static IEnumerable<string> GetMatches(PlatformAdaptationLayer/*!*/ pal, string/*!*/ pattern, int flags)
        {
            if (pattern.Length == 0) {
                yield break;
            }
            bool noEscape = ((flags & Constants.FNM_NOESCAPE) != 0);
            string[] groups = UngroupGlobs(pattern, noEscape);
            if (groups.Length == 0) {
                yield break;
            }

            foreach (string group in groups) {
                GlobMatcher matcher = new GlobMatcher(pal, group, flags);
                foreach (string filename in matcher.DoGlob()) {
                    yield return filename;
                }
            }
        }
Example #4
0
        private static void GetExecutable(PlatformAdaptationLayer/*!*/ pal, string/*!*/ command, out string executable, out string arguments) {
            command = command.Trim(' ');
            if (command.Length == 0) {
                throw RubyExceptions.CreateEINVAL(command);
            }

            // This seems to be quite complicated:
            // 1) If the first part of the command is a shell command (DIR, ECHO, ...) or
            //    if the command contains unquoted <, > or | then
            //    it uses ENV['COMSPEC'] to execute the command: %COMSPEC% /c "COMMAND"
            // 2) It looks for the shortest prefix of command that is separated by space from the rest of the command that is either
            //      a) An absolute path to an executable file.
            //      b) Try prepend paths from ENV['PATH']
            //      c) Try Environment.SpecialFolder.System.
            //      d) Try SHGetFolderPath(CSIDL_WINDOWS) - we can't get this from Environment.SpecialFolder, so we need to use 
            //         ENV["SystemRoot"] environment variable.
            //    In each step it tries to append ".exe" or ".com" extension if the path doesn't exist.
            // 
            //    For example, if the command is `x/a b/x` and the directory structure is
            //      x\a b\x.exe
            //      x\a.exe
            //    it executes a.exe.
            //    
            //    MRI probably calls CreateProcess Win32 API with lpApplicationName it resolves as described above and 
            //    lpCommandLine == command. System.Diagnostics.Process also uses this API with lpApplicationName == NULL and 
            //    lpCommandLine == '"{ProcessStartInfo.FileName}" {ProcessStartInfo.Arguments}'.
            //
            //    Although CreateProcess does all the searching for an executable if passed no lpApplicationName, 
            //    we need to do it ourselves because it is slightly different in MRI (is that a bug?) and also because System.Diagnostics.Process 
            //    quotes the FileName :(
            //    

            string comspec = pal.GetEnvironmentVariable("COMSPEC");
            if (!pal.FileExists(comspec)) {
                comspec = null;
            }

            if (comspec != null && IndexOfUnquotedSpecialCharacter(command) >= 0) {
                executable = comspec;
                arguments = "/c \"" + command + "\"";
                return;
            }

            int start = 0;
            while (true) {
                int next = command.IndexOf(' ', start);

                executable = (next >= 0) ? command.Substring(0, next) : command;
                arguments = (next >= 0) ? command.Substring(next + 1) : "";

                if (start == 0 && comspec != null && IsShellCommand(executable)) {
                    executable = comspec;
                    arguments = "/c \"" + command + "\"";
                    return;
                }

                try {
                    foreach (var path in GetExecutableFiles(pal, executable)) {
                        if (pal.FileExists(path)) {
                            // We need to set the path we found as executable. Althought makes command line of the target process
                            // different from when called by MRI it will execute the right process. If we passed the original executable name
                            // CreateProcess might resolve it to a different executable.
                            executable = path;
                            return;
                        }
                    }
                } catch (Exception e) {
                    if (next < 0) {
                        throw RubyExceptions.CreateENOENT(command, e);
                    }
                }

                if (next < 0) {
                    throw RubyExceptions.CreateENOENT(command);
                }

                start = next + 1;
                while (start < command.Length && command[start] == ' ') {
                    start++;
                }
            }
        }
Example #5
0
        private static IEnumerable<string>/*!*/ GetAbsolutePaths(PlatformAdaptationLayer/*!*/ pal, string/*!*/ path) {
            if (pal.IsAbsolutePath(path)) {
                yield return path;
            } else {
                yield return pal.GetFullPath(path);

                string var = pal.GetEnvironmentVariable("PATH");
                if (!String.IsNullOrEmpty(var)) {
                    foreach (var prefix in var.Split(Path.PathSeparator)) {
                        if (prefix.Length > 0) {
                            yield return Path.Combine(prefix, path);
                        }
                    }
                }

                var = Environment.GetFolderPath(Environment.SpecialFolder.System);
                if (!String.IsNullOrEmpty(var)) {
                    yield return Path.Combine(var, path);
                }

                var = pal.GetEnvironmentVariable("SystemRoot");
                if (!String.IsNullOrEmpty(var)) {
                    yield return Path.Combine(var, path);
                }
            }
        }
Example #6
0
        private static IEnumerable<string>/*!*/ GetExecutableFiles(PlatformAdaptationLayer/*!*/ pal, string/*!*/ path) {
            if (path[0] == '"' || path[path.Length - 1] == '"') {
                if (path.Length >= 3 && path[0] == '"' && path[path.Length - 1] == '"') {
                    path = path.Substring(1, path.Length - 2);
                } else {
                    yield break;
                }
            }

            string extension = Path.GetExtension(path);
            bool hasExtension = !String.IsNullOrEmpty(extension);
            bool isExecutable = hasExtension && Array.IndexOf(_ExecutableExtensions, extension.ToLowerInvariant()) >= 0;

            if (!hasExtension || isExecutable) {
                foreach (var fullPath in GetAbsolutePaths(pal, path)) {
                    if (hasExtension) {
                        yield return fullPath;
                    } else {
                        foreach (var ext in _ExecutableExtensions) {
                            yield return fullPath + ext;
                        }
                    }
                }
            }
        }
 internal PALHolder(PlatformAdaptationLayer pal)
 {
     _pal = pal;
 }
Example #8
0
 private static Stream OpenFile(CodeContext context, PlatformAdaptationLayer pal, string name, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) {
     try {
         return pal.OpenInputFileStream(name, fileMode, fileAccess, fileShare);
     } catch (UnauthorizedAccessException e) {
         throw PythonFile.ToIoException(context, name, e);
     } catch (IOException e) {
         PythonFile.AddFilename(context, name, e);
         throw e;
     }
 }
Example #9
0
 internal GlobMatcher(PlatformAdaptationLayer/*!*/ pal, string/*!*/ pattern, int flags) {
     _pal = pal;
     _pattern = (pattern == "**") ? "*" : pattern;
     _flags = flags | Constants.FNM_CASEFOLD;
     _result = new List<string>();
     _dirOnly = _pattern.LastCharacter() == '/';
     _stripTwo = false;
 }
 public CassettePlatformAdaptationLayer(PlatformAdaptationLayer innerPal, Func<IDirectory> getDirectory)
 {
     this.innerPal = innerPal;
     this.getDirectory = getDirectory;
 }
Example #11
0
 private static IList<string>/*!*/ DoGlob(PlatformAdaptationLayer/*!*/ pal, string/*!*/ pattern, int flags) {
     GlobMatcher matcher = new GlobMatcher(pal, pattern, flags);
     return matcher.DoGlob();
 }
 internal PALHolder(PlatformAdaptationLayer pal) {
     _pal = pal;
 }
Example #13
0
        private static object ChangeDirectory(PlatformAdaptationLayer/*!*/ pal, string/*!*/ strDir, MutableString/*!*/ dir, BlockParam block) {
            if (block == null) {
                SetCurrentDirectory(pal, strDir);
                return 0;
            }

            string current = pal.CurrentDirectory;
            try {
                SetCurrentDirectory(pal, strDir);
                object result;
                block.Yield(dir, out result);
                return result;
            } finally {
                SetCurrentDirectory(pal, current);
            }
        }
Example #14
0
 private static Stream OpenFile(PlatformAdaptationLayer pal, string name, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) {
     if (pal.DirectoryExists(name)) {
         // TODO: properly set errno
         throw PythonOps.IOError("[Errno 13] Permission denied");
     }
     return pal.OpenInputFileStream(name, fileMode, fileAccess, fileShare);
 }