初始提交:terminalX 可运行态(M0/M1/M1.5 已真机验证)

- M0: libghostty SSH 终端(渲染/输入/连接)+ 白屏修复(OutputGate) + 会话状态机/自动重连
- M1: tsnet 用户态组网 + SSH-over-tsnet(fd 桥),shell 级真机验证;R5(Go+gvisor+C+++Swift 同进程) retire
- M1.5: tmux -CC 原生 tab(MVP)
- 结构: packages/(TXCore·TXTransport), apps/TerminalX, vendor/(libghostty-spm/libssh2/mbedtls/tsnet-bridge), artifacts/
- 文档: CLAUDE.md + docs/HANDOFF.md(新会话入口)
- 环境: 认证代理→依赖 vendor 本地化;Go 在 ~/.local/go;仅模拟器/未签名
- 待续: M2 mosh, tmux 多 pane, M4 安全(host key/SE)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kid
2026-07-24 10:20:46 +08:00
commit aa92d0e676
2761 changed files with 803505 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
#include "ghostty.h"
#include <stdbool.h>
#include <stdint.h>
#if defined(__arm64e__)
#include <pthread.h>
#include <ptrauth.h>
#include <stdatomic.h>
#include <stdlib.h>
enum {
ghostty_block_has_copy_dispose = 1 << 25,
ghostty_objc_isa_discriminator = 0x6AE1,
};
typedef struct {
uintptr_t reserved;
uintptr_t size;
void *copy_helper;
void *dispose_helper;
} ghostty_block_descriptor_s;
typedef struct {
void *isa;
int flags;
int reserved;
void *invoke;
ghostty_block_descriptor_s *descriptor;
} ghostty_block_s;
static atomic_flag ghostty_descriptor_lock = ATOMIC_FLAG_INIT;
static void *ghostty_sign_function_pointer(void *pointer,
uintptr_t discriminator) {
void *raw = ptrauth_strip(pointer, ptrauth_key_function_pointer);
return ptrauth_sign_unauthenticated(
raw, ptrauth_key_function_pointer, discriminator);
}
static void *ghostty_sign_objc_isa_pointer(void *pointer,
uintptr_t discriminator) {
void *raw = ptrauth_strip(pointer, ptrauth_key_objc_isa_pointer);
return ptrauth_sign_unauthenticated(
raw, ptrauth_key_objc_isa_pointer, discriminator);
}
static void ghostty_prepare_block_descriptor(ghostty_block_descriptor_s *descriptor) {
while (atomic_flag_test_and_set_explicit(&ghostty_descriptor_lock,
memory_order_acquire)) {
}
descriptor->copy_helper = ghostty_sign_function_pointer(
descriptor->copy_helper,
(uintptr_t)&descriptor->copy_helper);
descriptor->dispose_helper = ghostty_sign_function_pointer(
descriptor->dispose_helper,
(uintptr_t)&descriptor->dispose_helper);
atomic_flag_clear_explicit(&ghostty_descriptor_lock, memory_order_release);
}
const void *ghostty_arm64e_sign_function(const void *pointer) {
return ghostty_sign_function_pointer((void *)pointer, 0);
}
void ghostty_arm64e_prepare_block(void *raw_block) {
ghostty_block_s *block = raw_block;
if ((block->flags & ghostty_block_has_copy_dispose) != 0) {
ghostty_prepare_block_descriptor(block->descriptor);
}
block->isa = ghostty_sign_objc_isa_pointer(
block->isa,
ptrauth_blend_discriminator(&block->isa, ghostty_objc_isa_discriminator));
block->invoke = ghostty_sign_function_pointer(
block->invoke,
(uintptr_t)&block->invoke);
#if __has_feature(ptrauth_signed_block_descriptors)
block->descriptor = ptrauth_sign_unauthenticated(
ptrauth_strip(block->descriptor, ptrauth_key_block_descriptor_pointer),
ptrauth_key_block_descriptor_pointer,
ptrauth_blend_discriminator(&block->descriptor, 0xC0BB));
#endif
}
__attribute__((visibility("hidden"))) int pa_pthread_cr(
pthread_t *thread,
const pthread_attr_t *attributes,
void *(*start_routine)(void *),
void *argument) {
start_routine = ghostty_sign_function_pointer((void *)start_routine, 0);
return pthread_create(thread, attributes, start_routine, argument);
}
__attribute__((visibility("hidden"))) void pa_qs(
void *base,
size_t count,
size_t size,
int (*comparator)(const void *, const void *)) {
comparator = ghostty_sign_function_pointer((void *)comparator, 0);
qsort(base, count, size, comparator);
}
extern ghostty_app_t ghostty_arm64e_core_app_new(
const ghostty_runtime_config_s *,
ghostty_config_t);
extern ghostty_surface_t ghostty_arm64e_core_surface_new(
ghostty_app_t,
const ghostty_surface_config_s *);
GHOSTTY_API ghostty_app_t ghostty_app_new(
const ghostty_runtime_config_s *config,
ghostty_config_t ghostty_config) {
ghostty_runtime_config_s raw = *config;
raw.wakeup_cb = ptrauth_strip(raw.wakeup_cb, ptrauth_key_function_pointer);
raw.action_cb = ptrauth_strip(raw.action_cb, ptrauth_key_function_pointer);
raw.read_clipboard_cb =
ptrauth_strip(raw.read_clipboard_cb, ptrauth_key_function_pointer);
raw.confirm_read_clipboard_cb =
ptrauth_strip(raw.confirm_read_clipboard_cb, ptrauth_key_function_pointer);
raw.write_clipboard_cb =
ptrauth_strip(raw.write_clipboard_cb, ptrauth_key_function_pointer);
raw.close_surface_cb =
ptrauth_strip(raw.close_surface_cb, ptrauth_key_function_pointer);
return ghostty_arm64e_core_app_new(&raw, ghostty_config);
}
GHOSTTY_API ghostty_surface_t ghostty_surface_new(
ghostty_app_t app,
const ghostty_surface_config_s *config) {
ghostty_surface_config_s raw = *config;
raw.receive_buffer =
ptrauth_strip(raw.receive_buffer, ptrauth_key_function_pointer);
raw.receive_resize =
ptrauth_strip(raw.receive_resize, ptrauth_key_function_pointer);
return ghostty_arm64e_core_surface_new(app, &raw);
}
#else
const void *ghostty_arm64e_sign_function(const void *pointer) {
return pointer;
}
void ghostty_arm64e_prepare_block(void *block) {
(void)block;
}
#endif