Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c23ee42

Browse files
author
Eclipse Che Sync
committed
Rebase against the upstream 42415d8
vscode-upstream-sha1: 42415d8
2 parents 237294d + 42415d8 commit c23ee42

58 files changed

Lines changed: 1798 additions & 678 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

code/build/azure-pipelines/win32/cli-build-win32.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ steps:
6060
VSCODE_CLI_ENV:
6161
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-windows-static-md/lib
6262
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-windows-static-md/include
63+
RUSTFLAGS: '-C target-feature=+crt-static'
6364

6465
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
6566
- template: ../cli/cli-compile-and-publish.yml
@@ -69,6 +70,7 @@ steps:
6970
VSCODE_CLI_ENV:
7071
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-windows-static-md/lib
7172
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-windows-static-md/include
73+
RUSTFLAGS: '-C target-feature=+crt-static'
7274

7375
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}:
7476
- template: ../cli/cli-compile-and-publish.yml
@@ -78,3 +80,4 @@ steps:
7880
VSCODE_CLI_ENV:
7981
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x86-windows-static-md/lib
8082
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x86-windows-static-md/include
83+
RUSTFLAGS: '-C target-feature=+crt-static'

code/cli/.cargo/config.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

code/cli/Cargo.lock

Lines changed: 27 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

code/cli/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ const_format = "0.2"
5050
sha2 = "0.10"
5151
base64 = "0.13"
5252
shell-escape = "0.1.5"
53+
thiserror = "1.0"
54+
cfg-if = "1.0.0"
55+
pin-project = "1.0"
5356

5457
[build-dependencies]
5558
serde = { version = "1.0" }

code/cli/src/async_pipe.rs

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
use crate::{constants::APPLICATION_NAME, util::errors::CodeError};
7+
use std::path::{Path, PathBuf};
8+
use uuid::Uuid;
9+
10+
// todo: we could probably abstract this into some crate, if one doesn't already exist
11+
12+
cfg_if::cfg_if! {
13+
if #[cfg(unix)] {
14+
pub type AsyncPipe = tokio::net::UnixStream;
15+
pub type AsyncPipeWriteHalf = tokio::net::unix::OwnedWriteHalf;
16+
pub type AsyncPipeReadHalf = tokio::net::unix::OwnedReadHalf;
17+
18+
pub async fn get_socket_rw_stream(path: &Path) -> Result<AsyncPipe, CodeError> {
19+
tokio::net::UnixStream::connect(path)
20+
.await
21+
.map_err(CodeError::AsyncPipeFailed)
22+
}
23+
24+
pub async fn listen_socket_rw_stream(path: &Path) -> Result<AsyncPipeListener, CodeError> {
25+
tokio::net::UnixListener::bind(path)
26+
.map(AsyncPipeListener)
27+
.map_err(CodeError::AsyncPipeListenerFailed)
28+
}
29+
30+
pub struct AsyncPipeListener(tokio::net::UnixListener);
31+
32+
impl AsyncPipeListener {
33+
pub async fn accept(&mut self) -> Result<AsyncPipe, CodeError> {
34+
self.0.accept().await.map_err(CodeError::AsyncPipeListenerFailed).map(|(s, _)| s)
35+
}
36+
}
37+
38+
pub fn socket_stream_split(pipe: AsyncPipe) -> (AsyncPipeReadHalf, AsyncPipeWriteHalf) {
39+
pipe.into_split()
40+
}
41+
} else {
42+
use tokio::{time::sleep, io::{AsyncRead, AsyncWrite, ReadBuf}};
43+
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions, NamedPipeClient, NamedPipeServer};
44+
use std::{time::Duration, pin::Pin, task::{Context, Poll}, io};
45+
use pin_project::pin_project;
46+
47+
#[pin_project(project = AsyncPipeProj)]
48+
pub enum AsyncPipe {
49+
PipeClient(#[pin] NamedPipeClient),
50+
PipeServer(#[pin] NamedPipeServer),
51+
}
52+
53+
impl AsyncRead for AsyncPipe {
54+
fn poll_read(
55+
self: Pin<&mut Self>,
56+
cx: &mut Context<'_>,
57+
buf: &mut ReadBuf<'_>,
58+
) -> Poll<io::Result<()>> {
59+
match self.project() {
60+
AsyncPipeProj::PipeClient(c) => c.poll_read(cx, buf),
61+
AsyncPipeProj::PipeServer(c) => c.poll_read(cx, buf),
62+
}
63+
}
64+
}
65+
66+
impl AsyncWrite for AsyncPipe {
67+
fn poll_write(
68+
self: Pin<&mut Self>,
69+
cx: &mut Context<'_>,
70+
buf: &[u8],
71+
) -> Poll<io::Result<usize>> {
72+
match self.project() {
73+
AsyncPipeProj::PipeClient(c) => c.poll_write(cx, buf),
74+
AsyncPipeProj::PipeServer(c) => c.poll_write(cx, buf),
75+
}
76+
}
77+
78+
fn poll_write_vectored(
79+
self: Pin<&mut Self>,
80+
cx: &mut Context<'_>,
81+
bufs: &[io::IoSlice<'_>],
82+
) -> Poll<Result<usize, io::Error>> {
83+
match self.project() {
84+
AsyncPipeProj::PipeClient(c) => c.poll_write_vectored(cx, bufs),
85+
AsyncPipeProj::PipeServer(c) => c.poll_write_vectored(cx, bufs),
86+
}
87+
}
88+
89+
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
90+
match self.project() {
91+
AsyncPipeProj::PipeClient(c) => c.poll_flush(cx),
92+
AsyncPipeProj::PipeServer(c) => c.poll_flush(cx),
93+
}
94+
}
95+
96+
fn is_write_vectored(&self) -> bool {
97+
match self {
98+
AsyncPipe::PipeClient(c) => c.is_write_vectored(),
99+
AsyncPipe::PipeServer(c) => c.is_write_vectored(),
100+
}
101+
}
102+
103+
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
104+
match self.project() {
105+
AsyncPipeProj::PipeClient(c) => c.poll_shutdown(cx),
106+
AsyncPipeProj::PipeServer(c) => c.poll_shutdown(cx),
107+
}
108+
}
109+
}
110+
111+
pub type AsyncPipeWriteHalf = tokio::io::WriteHalf<AsyncPipe>;
112+
pub type AsyncPipeReadHalf = tokio::io::ReadHalf<AsyncPipe>;
113+
114+
pub async fn get_socket_rw_stream(path: &Path) -> Result<AsyncPipe, CodeError> {
115+
// Tokio says we can need to try in a loop. Do so.
116+
// https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/struct.NamedPipeClient.html
117+
let client = loop {
118+
match ClientOptions::new().open(path) {
119+
Ok(client) => break client,
120+
// ERROR_PIPE_BUSY https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
121+
Err(e) if e.raw_os_error() == Some(231) => sleep(Duration::from_millis(100)).await,
122+
Err(e) => return Err(CodeError::AsyncPipeFailed(e)),
123+
}
124+
};
125+
126+
Ok(AsyncPipe::PipeClient(client))
127+
}
128+
129+
pub struct AsyncPipeListener {
130+
path: PathBuf,
131+
server: NamedPipeServer
132+
}
133+
134+
impl AsyncPipeListener {
135+
pub async fn accept(&mut self) -> Result<AsyncPipe, CodeError> {
136+
// see https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/struct.NamedPipeServer.html
137+
// this is a bit weird in that the server becomes the client once
138+
// they get a connection, and we create a new client.
139+
140+
self.server
141+
.connect()
142+
.await
143+
.map_err(CodeError::AsyncPipeListenerFailed)?;
144+
145+
// Construct the next server to be connected before sending the one
146+
// we already have of onto a task. This ensures that the server
147+
// isn't closed (after it's done in the task) before a new one is
148+
// available. Otherwise the client might error with
149+
// `io::ErrorKind::NotFound`.
150+
let next_server = ServerOptions::new()
151+
.create(&self.path)
152+
.map_err(CodeError::AsyncPipeListenerFailed)?;
153+
154+
155+
Ok(AsyncPipe::PipeServer(std::mem::replace(&mut self.server, next_server)))
156+
}
157+
}
158+
159+
pub async fn listen_socket_rw_stream(path: &Path) -> Result<AsyncPipeListener, CodeError> {
160+
let server = ServerOptions::new()
161+
.first_pipe_instance(true)
162+
.create(path)
163+
.map_err(CodeError::AsyncPipeListenerFailed)?;
164+
165+
Ok(AsyncPipeListener { path: path.to_owned(), server })
166+
}
167+
168+
pub fn socket_stream_split(pipe: AsyncPipe) -> (AsyncPipeReadHalf, AsyncPipeWriteHalf) {
169+
tokio::io::split(pipe)
170+
}
171+
}
172+
}
173+
174+
/// Gets a random name for a pipe/socket on the paltform
175+
pub fn get_socket_name() -> PathBuf {
176+
cfg_if::cfg_if! {
177+
if #[cfg(unix)] {
178+
std::env::temp_dir().join(format!("{}-{}", APPLICATION_NAME, Uuid::new_v4()))
179+
} else {
180+
PathBuf::from(format!(r"\\.\pipe\{}-{}", APPLICATION_NAME, Uuid::new_v4()))
181+
}
182+
}
183+
}

code/cli/src/commands.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
mod context;
77

88
pub mod args;
9+
pub mod internal_wsl;
910
pub mod tunnels;
1011
pub mod update;
1112
pub mod version;
12-
pub mod internal_wsl;
1313
pub use context::CommandContext;

code/cli/src/commands/internal_wsl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
use crate::{
7-
tunnels::{serve_wsl, shutdown_signal::ShutdownSignal},
7+
tunnels::{serve_wsl, shutdown_signal::ShutdownRequest},
88
util::{errors::AnyError, prereqs::PreReqChecker},
99
};
1010

1111
use super::CommandContext;
1212

1313
pub async fn serve(ctx: CommandContext) -> Result<i32, AnyError> {
14-
let signal = ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC]);
14+
let signal = ShutdownRequest::create_rx([ShutdownRequest::CtrlC]);
1515
let platform = spanf!(
1616
ctx.log,
1717
ctx.log.span("prereq"),

0 commit comments

Comments
 (0)