| File: HostModelUtils.cs | Web Access |
| Project: src\runtime\src\installer\managed\Microsoft.NET.HostModel\Microsoft.NET.HostModel.csproj (Microsoft.NET.HostModel) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; #if NETFRAMEWORK using FileInfo = Microsoft.IO.FileInfo; #endif namespace Microsoft.NET.HostModel { internal static class HostModelUtils { #if NET // -rwxr-xr-x: the permissions an apphost or single-file bundle should have. private const UnixFileMode AppHostFileMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.GroupRead | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherExecute; #endif /// <summary> /// Creates a <see cref="FileStream"/> for writing an apphost or bundle, requesting the desired /// Unix permissions at creation time on platforms that support them. /// When <paramref name="bufferSize"/> is <see langword="null"/>, the default buffer size is used. /// </summary> public static FileStream CreateFileStreamForHost( string path, FileAccess access, FileShare share, int? bufferSize = null) { #if NET if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { FileStreamOptions options = new() { Mode = FileMode.Create, Access = access, Share = share, UnixCreateMode = AppHostFileMode, }; if (bufferSize is int size) { options.BufferSize = size; } return new FileStream(path, options); } #endif return bufferSize.HasValue ? new FileStream(path, FileMode.Create, access, share, bufferSize.Value) : new FileStream(path, FileMode.Create, access, share); } /// <summary> /// Ensures a host file has the required permissions. /// </summary> public static void SetPermissionsForHost(string filePath) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return; #if NET // File already has required permissions if ((File.GetUnixFileMode(filePath) & AppHostFileMode) == AppHostFileMode) return; File.SetUnixFileMode(filePath, AppHostFileMode); #endif } private const string CodesignPath = @"/usr/bin/codesign"; public static bool IsCodesignAvailable() => File.Exists(CodesignPath); public static (int ExitCode, string StdErr) RunCodesign(string args, string appHostPath) { Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.OSX)); Debug.Assert(IsCodesignAvailable()); var psi = new ProcessStartInfo() { Arguments = $"{args} \"{appHostPath}\"", FileName = CodesignPath, RedirectStandardError = true, UseShellExecute = false, }; using (var p = Process.Start(psi)) { p.WaitForExit(); return (p.ExitCode, p.StandardError.ReadToEnd()); } } public static long GetFileLength(string path) { var info = new FileInfo(path); return ((FileInfo)info.ResolveLinkTarget(true) ?? info).Length; } } }