├── test ├── a └── test.dart ├── .gitattributes ├── screencap └── screencap.png ├── dynamic_library ├── libterm.so └── libterm.dylib ├── c_resource └── termare │ ├── thread │ ├── thread │ ├── CMakeLists.txt │ └── thread.c │ ├── android │ ├── jniLibs │ │ ├── x86 │ │ │ └── libterm.so │ │ ├── x86_64 │ │ │ └── libterm.so │ │ ├── arm64-v8a │ │ │ └── libterm.so │ │ └── armeabi-v7a │ │ │ └── libterm.so │ ├── build_android │ ├── CMakeLists.txt │ └── cmd │ │ └── android.sh │ └── src │ ├── CMakeLists.txt │ ├── term.h │ ├── test.c │ └── term.c ├── lib ├── src │ ├── proc.dart │ ├── unix_proc.dart │ ├── win_proc.dart │ ├── foundation │ │ └── file_descriptor.dart │ ├── interface │ │ └── pseudo_terminal_interface.dart │ ├── utils │ │ ├── isolate_read.dart │ │ └── custom_utf.dart │ ├── unix │ │ └── termare_native.dart │ ├── unix_pty.dart │ ├── win_pty.dart │ └── unix_pty_c.dart └── dart_pty.dart ├── CHANGELOG.md ├── ffigen ├── simple │ ├── .gitignore │ ├── README.md │ ├── pubspec.yaml │ └── headers │ │ ├── fcntl.h │ │ ├── termios.h │ │ ├── ioctl.h │ │ ├── signal.h │ │ ├── dirent.h │ │ ├── string.h │ │ ├── wait.h │ │ ├── stdlib.h │ │ ├── stdio.h │ │ └── unistd.h └── term │ ├── pubspec.yaml │ ├── header │ └── term.h │ ├── pubspec.lock │ └── termare_native.dart ├── pubspec.yaml ├── .metadata ├── README-EN.md ├── .vscode ├── launch.json └── settings.json ├── pubspec.lock ├── LICENSE ├── .gitignore ├── README.md └── analysis_options.yaml /test/a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/test/a -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /screencap/screencap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/screencap/screencap.png -------------------------------------------------------------------------------- /dynamic_library/libterm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/dynamic_library/libterm.so -------------------------------------------------------------------------------- /dynamic_library/libterm.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/dynamic_library/libterm.dylib -------------------------------------------------------------------------------- /c_resource/termare/thread/thread: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/c_resource/termare/thread/thread -------------------------------------------------------------------------------- /c_resource/termare/android/jniLibs/x86/libterm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/c_resource/termare/android/jniLibs/x86/libterm.so -------------------------------------------------------------------------------- /c_resource/termare/android/jniLibs/x86_64/libterm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/c_resource/termare/android/jniLibs/x86_64/libterm.so -------------------------------------------------------------------------------- /c_resource/termare/android/jniLibs/arm64-v8a/libterm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/c_resource/termare/android/jniLibs/arm64-v8a/libterm.so -------------------------------------------------------------------------------- /c_resource/termare/android/jniLibs/armeabi-v7a/libterm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Termare/dart_pty/HEAD/c_resource/termare/android/jniLibs/armeabi-v7a/libterm.so -------------------------------------------------------------------------------- /lib/src/proc.dart: -------------------------------------------------------------------------------- 1 | abstract class Proc { 2 | // int get hProcess; 3 | 4 | void kill(); 5 | 6 | Future wait(); 7 | 8 | void waitSync(); 9 | } 10 | -------------------------------------------------------------------------------- /c_resource/termare/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7 FATAL_ERROR) 2 | project(term VERSION 1.0.0 LANGUAGES C) 3 | aux_source_directory(. DIR_SRCS) 4 | add_library(term SHARED term.c) 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.0.1] - TODO: Add release date. 2 | 3 | * TODO: Describe initial release. 4 | 5 | ## [0.0.2] - TODO: Add release date. 6 | 7 | update 8 | ## [0.0.3] - TODO: Add release date. 9 | 10 | update -------------------------------------------------------------------------------- /c_resource/termare/thread/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7 FATAL_ERROR) 2 | add_compile_options(-std=c++11) 3 | project(thread VERSION 1.0.0 LANGUAGES C) 4 | 5 | SET(CMAKE_C_COMPILER g++) 6 | aux_source_directory(. DIR_SRCS) 7 | add_executable(thread thread.c) -------------------------------------------------------------------------------- /c_resource/termare/android/build_android: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd `dirname $0` 3 | pwd 4 | rm -rf ./build 5 | a="armeabi-v7a arm64-v8a x86 x86_64" 6 | for abi in $a; 7 | do 8 | export ABI=$abi 9 | sh cmd/android.sh 10 | done 11 | #cp -rf ../../android/libs/* ../../android/app/libs/ 12 | -------------------------------------------------------------------------------- /ffigen/simple/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | # Remove the following pattern if you wish to check in your lock file. 5 | pubspec.lock 6 | 7 | # Conventional directory for build outputs. 8 | build/ 9 | 10 | # Directory created by dartdoc. 11 | doc/api/ 12 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dart_pty 2 | description: create pseudo terminal and fork process use dart 3 | version: 0.0.4 4 | author: mengyanshou<906262255@qq.com> 5 | homepage: 6 | 7 | environment: 8 | sdk: ">=2.12.0 <3.0.0" 9 | 10 | dependencies: 11 | ffi: ^1.0.0 12 | win32: ^2.1.0 13 | signale: ^0.0.6 14 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 54c9441723ec61baaeb0fbf71fdcf4e415116e6e 8 | channel: master 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /ffigen/simple/README.md: -------------------------------------------------------------------------------- 1 | # Simple header example 2 | 3 | A very simple example, generates bindings for a very small header file (`headers/example.h`). 4 | 5 | ## Generating bindings 6 | At the root of this example (`example/simple`), run - 7 | ``` 8 | dart run ffigen 9 | ``` 10 | This will generate bindings in a file: [generated_bindings.dart](./generated_bindings.dart). 11 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | # dart_pty 2 | 3 | Language: English | [中文简体](README-CN.md) 4 | 5 | ## introduction 6 | 7 | create pseudo terminal and fork process use dart. 8 | 9 | ## Usage 10 | ```dart 11 | Map environment = {'TEST':'TEST_VALUE'}; 12 | UnixPtyC unixPthC = UnixPtyC(environment: environment); 13 | unixPthC.write('env'); 14 | String result = unixPthC.read(); 15 | ``` -------------------------------------------------------------------------------- /lib/dart_pty.dart: -------------------------------------------------------------------------------- 1 | library dart_pty; 2 | 3 | import 'dart:ffi'; 4 | 5 | import 'package:dart_pty/src/native_header/generated_bindings.dart'; 6 | 7 | export 'src/interface/pseudo_terminal_interface.dart'; 8 | 9 | NativeLibrary? _nativeLibrary; 10 | NativeLibrary get nativeLibrary { 11 | _nativeLibrary ??= NativeLibrary(DynamicLibrary.process()); 12 | return _nativeLibrary!; 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Flutter", 9 | "program": "lib/main.dart", 10 | "request": "launch", 11 | "type": "dart" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /c_resource/termare/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.6) # cmake version 2 | 3 | project(term) # project name 4 | 5 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/jniLibs/$ENV{ABI}) # set output path 6 | 7 | aux_source_directory(${PROJECT_SOURCE_DIR}/../src SRC_FILES) # scan source code files 8 | 9 | add_library(term SHARED ${SRC_FILES}) # add source code files to library, and set build type to dynamic library. 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "iostream": "cpp", 4 | "__threading_support": "c", 5 | "fcntl.h": "c", 6 | "dirent.h": "c", 7 | "signal.h": "c", 8 | "stdio.h": "c", 9 | "string.h": "c", 10 | "stdlib.h": "c", 11 | "ioctl.h": "c", 12 | "wait.h": "c", 13 | "termios.h": "c", 14 | "unistd.h": "c", 15 | "_pid_t.h": "c", 16 | "_types.h": "c" 17 | } 18 | } -------------------------------------------------------------------------------- /ffigen/term/pubspec.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | name: simple_example 6 | 7 | environment: 8 | sdk: '>=2.12.0 <3.0.0' 9 | 10 | dev_dependencies: 11 | ffigen: ^2.4.2 12 | 13 | ffigen: 14 | name: TermareNative 15 | description: Bindings to `headers/example.h`. 16 | output: 'generated_bindings.dart' 17 | headers: 18 | entry-points: 19 | - '**.h' 20 | -------------------------------------------------------------------------------- /ffigen/simple/pubspec.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | 5 | name: simple_example 6 | 7 | environment: 8 | sdk: '>=2.12.0 <3.0.0' 9 | 10 | dev_dependencies: 11 | ffigen: ^2.4.2 12 | 13 | ffigen: 14 | name: NativeLibrary 15 | description: Bindings to `headers/example.h`. 16 | output: 'generated_bindings.dart' 17 | headers: 18 | entry-points: 19 | - '**.h' 20 | -------------------------------------------------------------------------------- /c_resource/termare/thread/thread.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int *thread(void *arg) 8 | { 9 | pthread_t newthid; 10 | 11 | newthid = pthread_self(); 12 | printf("this is a new thread, thread ID = %d\n", newthid); 13 | return NULL; 14 | } 15 | 16 | int main(void) 17 | { 18 | pthread_t thid; 19 | 20 | printf("main thread ,ID is %d\n", pthread_self()); 21 | if (pthread_create(&thid, NULL, (void *)thread, NULL) != 0) 22 | { 23 | printf("thread creation failed\n"); 24 | exit(1); 25 | } 26 | exit(0); 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/unix_proc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi'; 2 | 3 | import 'proc.dart'; 4 | 5 | class UnixProc implements Proc { 6 | UnixProc(this.pid); 7 | 8 | final int pid; 9 | 10 | @override 11 | void waitSync() { 12 | rawWait(pid); 13 | } 14 | 15 | @override 16 | Future wait() async { 17 | // return executor.submitCallable(rawWait, hProcess); 18 | } 19 | 20 | @override 21 | void kill() { 22 | // unistd.kill(hProcess, SIGKILL); 23 | } 24 | } 25 | 26 | void rawWait(int pid) { 27 | // final status = allocate(); 28 | // unistd.waitpid(pid, status, 0); 29 | // unistd.waitpid(pid, nullptr, 0); 30 | } 31 | -------------------------------------------------------------------------------- /c_resource/termare/android/cmd/android.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export NDK_HOME=/Users/nightmare/Library/Android/sdk/ndk/22.0.7026061 # or set to your ndk home 3 | 4 | export MAKE_PATH=build/make-cache 5 | 6 | export TARGET_ABI=$ABI 7 | 8 | create_makefile() { 9 | cmake \ 10 | -DANDROID_ABI=$TARGET_ABI \ 11 | -DANDROID_PLATFORM=android-16 \ 12 | -DCMAKE_BUILD_TYPE=release \ 13 | -DANDROID_NDK=$NDK_HOME \ 14 | -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ 15 | -DANDROID_TOOLCHAIN=clang -B $MAKE_PATH -S . 16 | } 17 | 18 | create_makefile 19 | 20 | cd $MAKE_PATH 21 | 22 | make clean 23 | make 24 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | ffi: 5 | dependency: "direct main" 6 | description: 7 | name: ffi 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "1.0.0" 11 | signale: 12 | dependency: "direct main" 13 | description: 14 | name: signale 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "0.0.7" 18 | win32: 19 | dependency: "direct main" 20 | description: 21 | name: win32 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "2.1.3" 25 | sdks: 26 | dart: ">=2.13.0 <3.0.0" 27 | -------------------------------------------------------------------------------- /ffigen/term/header/term.h: -------------------------------------------------------------------------------- 1 | 2 | int create_ptm( 3 | int rows, 4 | int columns); 5 | void create_subprocess(char *env, 6 | char const *cmd, 7 | char const *cwd, 8 | char *const argv[], 9 | char **envp, 10 | int *pProcessId, 11 | int ptmfd); 12 | void write_to_fd(int fd, char *str); 13 | void setNonblock(int fd); 14 | char *get_output_from_fd(int fd); 15 | char *getFilePathFromFd(int fd); 16 | typedef void (*Callback)(char *p); 17 | void setPtyWindowSize(int fd, int rows, int cols); 18 | void init_dart_print(Callback callback); 19 | void post_thread(int ptmfd, Callback callback); -------------------------------------------------------------------------------- /c_resource/termare/src/term.h: -------------------------------------------------------------------------------- 1 | 2 | int create_ptm( 3 | int rows, 4 | int columns); 5 | void create_subprocess(char *env, 6 | char const *cmd, 7 | char const *cwd, 8 | char *const argv[], 9 | char **envp, 10 | int *pProcessId, 11 | int ptmfd); 12 | void write_to_fd(int fd, char *str); 13 | void setNonblock(int fd); 14 | char *get_output_from_fd(int fd); 15 | char *getFilePathFromFd(int fd); 16 | typedef void (*Callback)(char *p); 17 | void setPtyWindowSize(int fd, int rows, int cols); 18 | void init_dart_print(Callback callback); 19 | void post_thread(int ptmfd, Callback callback); 20 | int waitFor(int pid); -------------------------------------------------------------------------------- /c_resource/termare/src/test.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void SetNoBlock(int fd) 8 | { 9 | int fl = fcntl(fd, F_GETFL); 10 | if (fl < 0) 11 | { 12 | perror("fcntl"); 13 | return; 14 | } 15 | int a = fcntl(fd, F_SETFL, 1); 16 | fl = fcntl(fd, F_GETFL); 17 | printf("%d\n", fl); 18 | a = fcntl(fd, F_SETFL, 3); 19 | fl = fcntl(fd, F_GETFL); 20 | printf("%d\n", fl); 21 | a = fcntl(fd, F_SETFL, 7); 22 | fl = fcntl(fd, F_GETFL); 23 | printf("%d\n", fl); 24 | printf("%d\n", a); 25 | return; 26 | } 27 | 28 | int main() 29 | { 30 | SetNoBlock(0); //将标准输入设为非阻塞 31 | // while (1) 32 | // { 33 | // char buf[1024] = {0}; 34 | // ssize_t num = read(0, buf, sizeof(buf) - 1); 35 | // if (num == -1 && errno == EAGAIN) 36 | // { 37 | // printf("stdin data is not ready\n"); 38 | // sleep(1); 39 | // continue; 40 | // } 41 | // printf("input:%s\n", buf); 42 | // } 43 | return 0; 44 | } -------------------------------------------------------------------------------- /ffigen/simple/headers/fcntl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #include 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Termare 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/src/win_proc.dart: -------------------------------------------------------------------------------- 1 | // import 'dart:ffi'; 2 | 3 | // import 'package:ffi/ffi.dart'; 4 | // import 'package:win32/win32.dart' as win32; 5 | 6 | // import 'proc.dart'; 7 | // import 'utils/globals.dart'; 8 | 9 | // class WinProc implements Proc { 10 | // WinProc(this.hProcess, this.hPC); 11 | 12 | // final int hProcess; 13 | // final int hPC; 14 | 15 | // @override 16 | // void waitSync() { 17 | // rawWait(hProcess); 18 | // } 19 | 20 | // @override 21 | // Future wait() async { 22 | // return executor.submitCallable(rawWait, hProcess); 23 | // } 24 | 25 | // @override 26 | // void kill() { 27 | // // unistd.kill(hProcess, SIGKILL); 28 | // // win32.CreateProcess 29 | // win32.ClosePseudoConsole(Pointer.fromAddress(hPC)); 30 | // } 31 | // } 32 | 33 | // void rawWait(int hProcess) { 34 | // // final status = allocate(); 35 | // // unistd.waitpid(pid, status, 0); 36 | // final count = 1; 37 | // final pids = allocate(count: count); 38 | // final infinite = 0xFFFFFFFF; 39 | // pids.elementAt(0).value = hProcess; 40 | // win32.MsgWaitForMultipleObjects(count, pids, 1, infinite, win32.QS_ALLEVENTS); 41 | // } 42 | -------------------------------------------------------------------------------- /lib/src/foundation/file_descriptor.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi'; 2 | import 'dart:io'; 3 | import 'dart:typed_data'; 4 | 5 | import 'package:dart_pty/src/native_header/generated_bindings.dart'; 6 | import 'package:ffi/ffi.dart'; 7 | import 'package:signale/signale.dart'; 8 | 9 | class FileDescriptor { 10 | const FileDescriptor(this.fd, this.nativeLibrary); 11 | final int fd; 12 | final NativeLibrary nativeLibrary; 13 | 14 | Uint8List? read(int length) { 15 | //动态申请空间 16 | final Pointer resultPoint = calloc(length + 1); 17 | final int len = nativeLibrary.read(fd, resultPoint.cast(), length); 18 | if (len <= 0) { 19 | calloc.free(resultPoint); 20 | return null; 21 | } else { 22 | return resultPoint.asTypedList(len); 23 | } 24 | } 25 | 26 | void setNonblock(int fd, {bool verbose = true}) { 27 | int flag = -1; 28 | flag = nativeLibrary.fcntl(fd, F_GETFL, 0); //获取当前flag 29 | Log.d('当前flag = $flag', tag: 'FileDescriptor'); 30 | flag |= Platform.isAndroid ? O_NONBLOCK_ANDROID : O_NONBLOCK; //设置新falg 31 | Log.d('设置新flag = $flag', tag: 'FileDescriptor'); 32 | nativeLibrary.fcntl(fd, F_SETFL, flag); //更新flag 33 | flag = nativeLibrary.fcntl(fd, F_GETFL, 0); //获取当前flag 34 | Log.d('再次获取到的flag = $flag', tag: 'FileDescriptor'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ffigen/simple/headers/termios.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef __TERMIOS_H__ 24 | #define __TERMIOS_H__ 25 | 26 | #include 27 | #include 28 | #include <_types.h> 29 | #include 30 | 31 | __BEGIN_DECLS 32 | pid_t tcgetsid(int); 33 | __END_DECLS 34 | 35 | #endif /* __TERMIOS_H__ */ 36 | -------------------------------------------------------------------------------- /test/test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dart_pty/src/interface/pseudo_terminal_interface.dart'; 4 | 5 | Future main() async { 6 | final Map environment = { 7 | 'TERM': 'xterm-256color', 8 | }; 9 | String executable = 'bash'; 10 | if (Platform.isWindows) { 11 | executable = 'wsl'; 12 | } 13 | final PseudoTerminal pseudoTerminal = PseudoTerminal( 14 | executable: 'ssh', 15 | environment: environment, 16 | workingDirectory: '/', 17 | arguments: 18 | '-o PreferredAuthentications=password -o PubkeyAuthentication=no -o PasswordAuthentication=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null nightmare@nightmare.fun' 19 | .split(' '), 20 | useIsolate: true, 21 | ); 22 | await Future.delayed(const Duration(milliseconds: 100)); 23 | pseudoTerminal.startPolling(); 24 | pseudoTerminal.out!.listen((line) { 25 | print('--->$line'); 26 | if (RegExp('yes/no').hasMatch(line)) { 27 | pseudoTerminal.write('yes\n'); 28 | } else if (RegExp('assword:').hasMatch(line)) { 29 | pseudoTerminal.write('xxx\n'); 30 | } else if (RegExp('Select account').hasMatch(line)) { 31 | pseudoTerminal.write('2\n'); 32 | } else if (RegExp('~]').hasMatch(line)) { 33 | pseudoTerminal.write('./run.sh\n'); 34 | } else { 35 | print(line); 36 | } 37 | 38 | pseudoTerminal.schedulingRead(); 39 | }); 40 | } 41 | -------------------------------------------------------------------------------- /lib/src/interface/pseudo_terminal_interface.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:typed_data'; 3 | import '../unix_pty.dart'; 4 | 5 | // 抽象函数的思想完全借鉴 pty 的代码. 6 | abstract class PseudoTerminal { 7 | factory PseudoTerminal({ 8 | int row = 25, 9 | int column = 80, 10 | String? executable, 11 | String workingDirectory = '.', 12 | List arguments = const [], 13 | Map environment = const { 14 | 'TERM': 'xterm-256color', 15 | }, 16 | bool? useIsolate, 17 | }) { 18 | // TODO 19 | if (Platform.isMacOS) { 20 | } else if (Platform.isLinux) { 21 | } else if (Platform.isAndroid) { 22 | } else if (Platform.isWindows) { 23 | // return WinPty( 24 | // rowLen: row, 25 | // columnLen: column, 26 | // workingDirectory: workingDirectory, 27 | // executable: executable, 28 | // arguments: arguments, 29 | // environment: environment, 30 | // ); 31 | } 32 | return UnixPty( 33 | rowLen: row, 34 | columnLen: column, 35 | workingDirectory: workingDirectory, 36 | executable: executable, 37 | arguments: arguments, 38 | environment: environment, 39 | useIsolate: useIsolate ?? const bool.fromEnvironment('dart.vm.product'), 40 | ); 41 | } 42 | 43 | late int pseudoTerminalId; 44 | Stream? out; 45 | 46 | Uint8List? readSync(); 47 | 48 | Uint8List? read(); 49 | 50 | void write(String data); 51 | 52 | void resize(int row, int column); 53 | 54 | // Proc createSubprocess( 55 | // String executable, { 56 | // String workingDirectory = '.', 57 | // List arguments, 58 | // Map environment, 59 | // }); 60 | 61 | String getTtyPath(); 62 | void close(); 63 | 64 | void startPolling(); 65 | void schedulingRead(); 66 | } 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dart_pty 2 | 3 | Language: 中文简体 | [English](README-EN.md) 4 | 5 | 创建终端的 dart 实现。 6 | 7 | **当前已经实现纯 dart 动态调用底层库获得终端,不再需要依赖项目的 so 库** 8 | ## 介绍 9 | 10 | 创建一个伪终端并执行一个子进程。也是终端模拟器的底层实现。 11 | 与一些语言提供的执行进程不同,它不仅能够无缓冲的拿到 stdout、stderr 输出,还能拿到所有的终端序列,也能对进程进行交互。 12 | 13 | 14 | **举个简单的例子** 15 | 16 | 我们在 shell 执行以下命令: 17 | ```shell 18 | echo -e "\033[31m hello \033[0m" 19 | ``` 20 | 这个时候会看见终端打印了红色的“hello”,因为终端模拟器不仅拿到了字符“hello”,还拿到了前后改变颜色的控制序列。 21 | 22 | 我们通过 java 的 runtime.exec 函数,或者 python 的 system 函数,c 语言的 system 函数,这一系列高级语言所提供的执行进程的函数,我们执行 python,会发现无论如何也拿不到命令的输出,其原因在于终端与管道的缓冲机制。 23 | 24 | 所以此项目在于实现获得进程实时的输出流,并提供与进程交互的功能。 25 | ## 使用方法 26 | 参考 [test.dart](test/test.dart) 27 | ```dart 28 | import 'dart:io'; 29 | 30 | import 'package:dart_pty/src/interface/pseudo_terminal_interface.dart'; 31 | 32 | Future main() async { 33 | final Map environment = {'TEST': 'TEST_VALUE'}; 34 | String executable = 'sh'; 35 | if (Platform.isWindows) { 36 | executable = 'wsl'; 37 | } 38 | final PseudoTerminal pseudoTerminal = PseudoTerminal( 39 | executable: executable, 40 | environment: environment, 41 | workingDirectory: '/', 42 | ); 43 | await Future.delayed(const Duration(milliseconds: 100)); 44 | pseudoTerminal.out!.listen((line) { 45 | print('\x1b[31m' + '>' * 40); 46 | print('\x1b[32m$line'); 47 | print('\x1b[31m' + '<' * 40); 48 | }); 49 | pseudoTerminal.startPolling(); 50 | await Future.delayed(const Duration(milliseconds: 100), () async { 51 | while (true) { 52 | final String input = stdin.readLineSync()!; 53 | input.split('').forEach((element) { 54 | pseudoTerminal.write(element); 55 | }); 56 | pseudoTerminal.write('\n'); 57 | pseudoTerminal.schedulingRead(); 58 | await Future.delayed(const Duration(milliseconds: 100)); 59 | } 60 | }); 61 | } 62 | 63 | ``` 64 | 运行效果: 65 | 66 | ![截图](screencap/screencap.png) 67 | 68 | ## 相关文章 69 | 70 | - [Flutter 终端模拟器探索篇(二)| 完整终端模拟器](https://juejin.cn/post/6844904082155503629) 71 | 72 | 简言之是通过 open unix 系列设备的 /dev/ptmx 节点和主要的 dup2 函数来获得的这样一个伪终端。 73 | ## Q&A 74 | ### 伪终端是否意味着他并不是一个真的终端? 75 | 76 | 在 unix 设备的 /dev 下只要极少的节点是成对的,也就是说写进其中一个节点会立马从另一个节点输出, 77 | 这样成对的文件节点就称为终端。 78 | 但这类成对的节点非常少,并且对普通用户来说,它们是不可知的,我们并不知道哪些是成对的。 79 | 但我们可以通过 open /dev/ptmx 的方式来获得一对成对的节点,即为伪终端, 80 | 几乎所有的日常使用的终端模拟器都是伪终端。 81 | 82 | ### 能不用集成 so 库就能实现本地终端吗? 83 | 84 | 已经实现~ 85 | -------------------------------------------------------------------------------- /lib/src/utils/isolate_read.dart: -------------------------------------------------------------------------------- 1 | // // 从isolate中读取 2 | 3 | // import 'dart:async'; 4 | // import 'dart:ffi'; 5 | // import 'dart:isolate'; 6 | 7 | // import 'package:dart_pty/src/unix/cunistd.dart'; 8 | // import 'package:ffi/ffi.dart'; 9 | 10 | // class IsolateRead { 11 | // IsolateRead() { 12 | // init(); 13 | // } 14 | // // 将阻塞ui的方法通过isolate读取并异步返回 15 | // Isolate isolate; 16 | // SendPort sendPort; 17 | 18 | // Stream receiveAsBroadcastStream; 19 | // final ReceivePort receive = ReceivePort(); 20 | // Future init() async {} 21 | 22 | // Future> read( 23 | // int fileDescriptor, 24 | // ) async { 25 | // List result = []; 26 | // isolate ??= 27 | // await Isolate.spawn(readFileDescriptorIsolate, receive.sendPort); 28 | // // sendPort = await receive.first as SendPort; 29 | // receiveAsBroadcastStream ??= receive.asBroadcastStream(); 30 | // if (sendPort == null) { 31 | // await receiveAsBroadcastStream.every( 32 | // (dynamic data) { 33 | // print('来自子isolate的消息====>$data'); 34 | // sendPort = data as SendPort; 35 | // // return false会马上退出监听 36 | // return false; 37 | // }, 38 | // ); 39 | // } 40 | // // debugPrintWithColor( 41 | // // 'isolate启动', 42 | // // backgroundColor: PrintColor.white, 43 | // // fontColor: PrintColor.red, 44 | // // ); 45 | // // 这个定义是用来接收子isolate那边的SendPort 46 | // // 发送本次需要读取的文件描述符 47 | // sendPort?.send(fileDescriptor); 48 | // // result = await receive.first; 49 | // // print('来自子isolate的单次消息====>$result'); 50 | // await receiveAsBroadcastStream.every((dynamic data) { 51 | // print('来自子isolate的消息====>$data'); 52 | 53 | // result = data as List; 54 | // return false; 55 | // }); 56 | // return result; 57 | // } 58 | // } 59 | 60 | // Future readFileDescriptorIsolate(SendPort sendPort) async { 61 | // Pointer readSync(int fd, {bool verbose = false}) { 62 | // CUnistd cunistd = CUnistd(DynamicLibrary.process()); 63 | // //动态申请空间 64 | // Pointer str = allocate(count: 4097); 65 | // //read函数返回从fd中读取到字符的长度 66 | // //读取的内容存进str,4096表示此次读取4096个字节,如果只读到10个则length为10 67 | // int length = cunistd.read(fd, str.cast(), 4096); 68 | // print('readFileDescriptorIsolate方法读取数据长度为>>>>>>>$length'); 69 | // if (length == -1) { 70 | // free(str); 71 | // return Pointer.fromAddress(0); 72 | // } else { 73 | // str[length] = 0; 74 | // return str; 75 | // } 76 | // } 77 | 78 | // print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>子Isolate启动'); 79 | // final ReceivePort receivePort = ReceivePort(); 80 | // // 将这边的一个ReceivePort对象发给主isolate 81 | // sendPort.send(receivePort.sendPort); 82 | // receivePort.listen((dynamic message) { 83 | // print('来自主islate的消息===>$message'); 84 | // print('来自主islate的消息类型===>${message.runtimeType}'); 85 | // Pointer utf8 = readSync(message as int).cast(); 86 | // if (utf8 == null) { 87 | // return; 88 | // } 89 | // int len = 0; 90 | // while (utf8.elementAt(++len).value != 0) {} 91 | // List units = List(len); 92 | // for (int i = 0; i < len; ++i) { 93 | // units[i] = utf8.elementAt(i).value; 94 | // } 95 | // print('units=====>$units'); 96 | // sendPort.send(units); 97 | // // free(utf8); 98 | // }); 99 | // } 100 | -------------------------------------------------------------------------------- /ffigen/term/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | args: 5 | dependency: transitive 6 | description: 7 | name: args 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "2.1.0" 11 | async: 12 | dependency: transitive 13 | description: 14 | name: async 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "2.6.1" 18 | charcode: 19 | dependency: transitive 20 | description: 21 | name: charcode 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "1.2.0" 25 | cli_util: 26 | dependency: transitive 27 | description: 28 | name: cli_util 29 | url: "https://pub.flutter-io.cn" 30 | source: hosted 31 | version: "0.3.0" 32 | collection: 33 | dependency: transitive 34 | description: 35 | name: collection 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "1.15.0" 39 | ffi: 40 | dependency: transitive 41 | description: 42 | name: ffi 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "1.0.0" 46 | ffigen: 47 | dependency: "direct dev" 48 | description: 49 | name: ffigen 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "2.4.2" 53 | file: 54 | dependency: transitive 55 | description: 56 | name: file 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "6.1.0" 60 | glob: 61 | dependency: transitive 62 | description: 63 | name: glob 64 | url: "https://pub.flutter-io.cn" 65 | source: hosted 66 | version: "2.0.1" 67 | logging: 68 | dependency: transitive 69 | description: 70 | name: logging 71 | url: "https://pub.flutter-io.cn" 72 | source: hosted 73 | version: "1.0.1" 74 | matcher: 75 | dependency: transitive 76 | description: 77 | name: matcher 78 | url: "https://pub.flutter-io.cn" 79 | source: hosted 80 | version: "0.12.10" 81 | meta: 82 | dependency: transitive 83 | description: 84 | name: meta 85 | url: "https://pub.flutter-io.cn" 86 | source: hosted 87 | version: "1.3.0" 88 | path: 89 | dependency: transitive 90 | description: 91 | name: path 92 | url: "https://pub.flutter-io.cn" 93 | source: hosted 94 | version: "1.8.0" 95 | pedantic: 96 | dependency: transitive 97 | description: 98 | name: pedantic 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "1.11.0" 102 | quiver: 103 | dependency: transitive 104 | description: 105 | name: quiver 106 | url: "https://pub.flutter-io.cn" 107 | source: hosted 108 | version: "3.0.1" 109 | source_span: 110 | dependency: transitive 111 | description: 112 | name: source_span 113 | url: "https://pub.flutter-io.cn" 114 | source: hosted 115 | version: "1.8.1" 116 | stack_trace: 117 | dependency: transitive 118 | description: 119 | name: stack_trace 120 | url: "https://pub.flutter-io.cn" 121 | source: hosted 122 | version: "1.10.0" 123 | string_scanner: 124 | dependency: transitive 125 | description: 126 | name: string_scanner 127 | url: "https://pub.flutter-io.cn" 128 | source: hosted 129 | version: "1.1.0" 130 | term_glyph: 131 | dependency: transitive 132 | description: 133 | name: term_glyph 134 | url: "https://pub.flutter-io.cn" 135 | source: hosted 136 | version: "1.2.0" 137 | yaml: 138 | dependency: transitive 139 | description: 140 | name: yaml 141 | url: "https://pub.flutter-io.cn" 142 | source: hosted 143 | version: "3.1.0" 144 | sdks: 145 | dart: ">=2.12.0 <3.0.0" 146 | -------------------------------------------------------------------------------- /ffigen/simple/headers/ioctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 29 | /*- 30 | * Copyright (c) 1982, 1986, 1990, 1993, 1994 31 | * The Regents of the University of California. All rights reserved. 32 | * (c) UNIX System Laboratories, Inc. 33 | * All or some portions of this file are derived from material licensed 34 | * to the University of California by American Telephone and Telegraph 35 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 36 | * the permission of UNIX System Laboratories, Inc. 37 | * 38 | * Redistribution and use in source and binary forms, with or without 39 | * modification, are permitted provided that the following conditions 40 | * are met: 41 | * 1. Redistributions of source code must retain the above copyright 42 | * notice, this list of conditions and the following disclaimer. 43 | * 2. Redistributions in binary form must reproduce the above copyright 44 | * notice, this list of conditions and the following disclaimer in the 45 | * documentation and/or other materials provided with the distribution. 46 | * 3. All advertising materials mentioning features or use of this software 47 | * must display the following acknowledgement: 48 | * This product includes software developed by the University of 49 | * California, Berkeley and its contributors. 50 | * 4. Neither the name of the University nor the names of its contributors 51 | * may be used to endorse or promote products derived from this software 52 | * without specific prior written permission. 53 | * 54 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 | * SUCH DAMAGE. 65 | * 66 | * @(#)ioctl.h 8.6 (Berkeley) 3/28/94 67 | */ 68 | 69 | #ifndef _SYS_IOCTL_H_ 70 | #define _SYS_IOCTL_H_ 71 | 72 | #include 73 | 74 | /* 75 | * Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ 76 | * and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented 77 | * nonwithstanding). 78 | */ 79 | struct ttysize { 80 | unsigned short ts_lines; 81 | unsigned short ts_cols; 82 | unsigned short ts_xxx; 83 | unsigned short ts_yyy; 84 | }; 85 | #define TIOCGSIZE TIOCGWINSZ 86 | #define TIOCSSIZE TIOCSWINSZ 87 | 88 | #include 89 | 90 | #include 91 | #include 92 | 93 | 94 | #include 95 | 96 | __BEGIN_DECLS 97 | int ioctl(int, unsigned long, ...); 98 | __END_DECLS 99 | #endif /* !_SYS_IOCTL_H_ */ 100 | 101 | /* 102 | * Keep outside _SYS_IOCTL_H_ 103 | * Compatability with old terminal driver 104 | * 105 | * Source level -> #define USE_OLD_TTY 106 | * Kernel level -> always on 107 | */ 108 | #if defined(USE_OLD_TTY) || defined(BSD_KERNEL_PRIVATE) 109 | #include 110 | #endif /* !_SYS_IOCTL_H_ */ 111 | -------------------------------------------------------------------------------- /ffigen/simple/headers/signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*- 24 | * Copyright (c) 1991, 1993 25 | * The Regents of the University of California. All rights reserved. 26 | * 27 | * Redistribution and use in source and binary forms, with or without 28 | * modification, are permitted provided that the following conditions 29 | * are met: 30 | * 1. Redistributions of source code must retain the above copyright 31 | * notice, this list of conditions and the following disclaimer. 32 | * 2. Redistributions in binary form must reproduce the above copyright 33 | * notice, this list of conditions and the following disclaimer in the 34 | * documentation and/or other materials provided with the distribution. 35 | * 3. All advertising materials mentioning features or use of this software 36 | * must display the following acknowledgement: 37 | * This product includes software developed by the University of 38 | * California, Berkeley and its contributors. 39 | * 4. Neither the name of the University nor the names of its contributors 40 | * may be used to endorse or promote products derived from this software 41 | * without specific prior written permission. 42 | * 43 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 | * SUCH DAMAGE. 54 | * 55 | * @(#)signal.h 8.3 (Berkeley) 3/30/94 56 | */ 57 | 58 | #ifndef _USER_SIGNAL_H 59 | #define _USER_SIGNAL_H 60 | 61 | #include 62 | #include <_types.h> 63 | #include 64 | 65 | #include 66 | #include 67 | 68 | #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 69 | extern __const char *__const sys_signame[NSIG]; 70 | extern __const char *__const sys_siglist[NSIG]; 71 | #endif 72 | 73 | __BEGIN_DECLS 74 | int raise(int); 75 | __END_DECLS 76 | 77 | #ifndef _ANSI_SOURCE 78 | __BEGIN_DECLS 79 | void (* _Nullable bsd_signal(int, void (* _Nullable)(int)))(int); 80 | int kill(pid_t, int) __DARWIN_ALIAS(kill); 81 | int killpg(pid_t, int) __DARWIN_ALIAS(killpg); 82 | int pthread_kill(pthread_t, int); 83 | int pthread_sigmask(int, const sigset_t *, sigset_t *) __DARWIN_ALIAS(pthread_sigmask); 84 | int sigaction(int, const struct sigaction * __restrict, 85 | struct sigaction * __restrict); 86 | int sigaddset(sigset_t *, int); 87 | int sigaltstack(const stack_t * __restrict, stack_t * __restrict) __DARWIN_ALIAS(sigaltstack) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 88 | int sigdelset(sigset_t *, int); 89 | int sigemptyset(sigset_t *); 90 | int sigfillset(sigset_t *); 91 | int sighold(int); 92 | int sigignore(int); 93 | int siginterrupt(int, int); 94 | int sigismember(const sigset_t *, int); 95 | int sigpause(int) __DARWIN_ALIAS_C(sigpause); 96 | int sigpending(sigset_t *); 97 | int sigprocmask(int, const sigset_t * __restrict, sigset_t * __restrict); 98 | int sigrelse(int); 99 | void (* _Nullable sigset(int, void (* _Nullable)(int)))(int); 100 | int sigsuspend(const sigset_t *) __DARWIN_ALIAS_C(sigsuspend); 101 | int sigwait(const sigset_t * __restrict, int * __restrict) __DARWIN_ALIAS_C(sigwait); 102 | #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) 103 | void psignal(unsigned int, const char *); 104 | int sigblock(int); 105 | int sigsetmask(int); 106 | int sigvec(int, struct sigvec *, struct sigvec *); 107 | #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ 108 | __END_DECLS 109 | 110 | /* List definitions after function declarations, or Reiser cpp gets upset. */ 111 | __header_always_inline int 112 | __sigbits(int __signo) 113 | { 114 | return __signo > __DARWIN_NSIG ? 0 : (1 << (__signo - 1)); 115 | } 116 | 117 | #define sigaddset(set, signo) (*(set) |= __sigbits(signo), 0) 118 | #define sigdelset(set, signo) (*(set) &= ~__sigbits(signo), 0) 119 | #define sigismember(set, signo) ((*(set) & __sigbits(signo)) != 0) 120 | #define sigemptyset(set) (*(set) = 0, 0) 121 | #define sigfillset(set) (*(set) = ~(sigset_t)0, 0) 122 | #endif /* !_ANSI_SOURCE */ 123 | 124 | #endif /* !_USER_SIGNAL_H */ 125 | -------------------------------------------------------------------------------- /lib/src/utils/custom_utf.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:ffi'; 3 | 4 | class NiUtf { 5 | List unitsCache = []; //这个缓存是为了解决拿到的最后字符不完整 6 | String? listToStaring(List units) { 7 | int len = units.length; 8 | units = unitsCache + units; 9 | // print('len=====$len'); 10 | len = len + unitsCache.length; 11 | print('>>>>>>>>>len======$len'); 12 | unitsCache.clear(); 13 | //只有当为0开头经过二进制转换才小于7位,如果读取到的最后一个字符为0开头, 14 | //说明这整个UTF8字符占用1个字节,不存在后面还有其他字节没有读取到的情况 15 | /// 128 16 | /// 10000000 17 | if (units.last & 0xff & 128 == 0) { 18 | // print('===>${units.last}'); 19 | try { 20 | return utf8.decode(units, allowMalformed: false); 21 | } catch (e) { 22 | print(units); 23 | print(e); 24 | } 25 | 26 | /// 11000000 27 | /// &11111111 28 | /// =11000000 29 | } else if (units.last & 192 == 192) { 30 | print('结尾数'); 31 | unitsCache = units.sublist(len - 1, len); 32 | units.removeRange(len - 1, len); 33 | } else { 34 | // print('发现需要拼包的序列'); 35 | // print(units.last); 36 | // print(units); 37 | // print('拆包中'); 38 | int number = 0; 39 | while (true) { 40 | //等于2说明移位后为10 41 | final int cur = units[len - 1 - number]; 42 | // print('当前指向的数===>$cur'); 43 | if (cur >> 6 == 2) { 44 | // print('经过一个10'); 45 | //经过一次10开头的便记录一次 46 | } else if (cur.toRadixString(2).startsWith('1' * (number + 2))) { 47 | //此时该字节以number+2个字节开始,说明该次读取不完整 48 | //因为此时该字节开始的1应该为number+1个(10开始的个数加上此时这个字节) 49 | unitsCache = units.sublist(len - number, len); 50 | units.removeRange(len - number, len); 51 | break; 52 | } else if (cur.toRadixString(2).startsWith('1' * (number + 1))) { 53 | { 54 | break; 55 | } 56 | } 57 | number++; 58 | } 59 | } 60 | try { 61 | return utf8.decode(units, allowMalformed: true); 62 | } catch (e) { 63 | print('===>$units'); 64 | print(e); 65 | } 66 | return null; 67 | } 68 | 69 | List? getCodeUnits(Pointer str) { 70 | if (str == null) { 71 | return null; 72 | } 73 | int len = 0; 74 | while (str.elementAt(++len).value != 0) {} 75 | List units = List.filled(len, 0); 76 | for (int i = 0; i < len; ++i) { 77 | units[i] = str.elementAt(i).value; 78 | } 79 | units = unitsCache + units; 80 | // print('len=====$len'); 81 | len = len + unitsCache.length; 82 | unitsCache.clear(); 83 | //只有当为0开头经过二进制转换才小于7位,如果读取到的最后一个字符为0开头, 84 | //说明这整个UTF8字符占用1个字节,不存在后面还有其他字节没有读取到的情况 85 | /// 128 86 | /// 10000000 87 | if (units.last & 128 == 0) { 88 | // print('===>${units.last}'); 89 | try { 90 | return units; 91 | } catch (e) { 92 | print(units); 93 | print(e); 94 | } 95 | 96 | /// 11000000 97 | /// &11111111 98 | /// =11000000 99 | } else if (units.last & 192 == 192) { 100 | // print('结尾数'); 101 | unitsCache = units.sublist(len - 1, len); 102 | units.removeRange(len - 1, len); 103 | } else { 104 | // print('发现需要拼包的序列'); 105 | // print(units.last); 106 | // print(units); 107 | // print('拆包中'); 108 | int number = 0; 109 | while (true) { 110 | //等于2说明移位后为10 111 | final int cur = units[len - 1 - number]; 112 | // print('当前指向的数===>$cur'); 113 | if (cur >> 6 == 2) { 114 | // print('经过一个10'); 115 | //经过一次10开头的便记录一次 116 | } else if (cur.toRadixString(2).startsWith('1' * (number + 2))) { 117 | //此时该字节以number+2个字节开始,说明该次读取不完整 118 | //因为此时该字节开始的1应该为number+1个(10开始的个数加上此时这个字节) 119 | unitsCache = units.sublist(len - number, len); 120 | units.removeRange(len - number, len); 121 | break; 122 | } else if (cur.toRadixString(2).startsWith('1' * (number + 1))) { 123 | { 124 | break; 125 | } 126 | } 127 | number++; 128 | } 129 | } 130 | try { 131 | return units; 132 | } catch (e) { 133 | print('===>$units'); 134 | print(e); 135 | } 136 | return null; 137 | } 138 | 139 | String? cStringtoString(Pointer str) { 140 | if (str == null) { 141 | return null; 142 | } 143 | int len = 0; 144 | while (str.elementAt(++len).value != 0) {} 145 | List units = []; 146 | units.length = len; 147 | for (int i = 0; i < len; ++i) { 148 | units[i] = str.elementAt(i).value; 149 | } 150 | units = unitsCache + units; 151 | // print('len=====$len'); 152 | len = len + unitsCache.length; 153 | unitsCache.clear(); 154 | //只有当为0开头经过二进制转换才小于7位,如果读取到的最后一个字符为0开头, 155 | //说明这整个UTF8字符占用1个字节,不存在后面还有其他字节没有读取到的情况 156 | /// 128 157 | /// 10000000 158 | if (units.last & 128 == 0) { 159 | // print('===>${units.last}'); 160 | try { 161 | return utf8.decode(units, allowMalformed: true); 162 | } catch (e) { 163 | print(units); 164 | print(e); 165 | } 166 | 167 | /// 11000000 168 | /// &11111111 169 | /// =11000000 170 | } else if (units.last & 192 == 192) { 171 | // print('结尾数'); 172 | unitsCache = units.sublist(len - 1, len); 173 | units.removeRange(len - 1, len); 174 | } else { 175 | // print('发现需要拼包的序列'); 176 | // print(units.last); 177 | // print(units); 178 | // print('拆包中'); 179 | int number = 0; 180 | while (true) { 181 | //等于2说明移位后为10 182 | final int cur = units[len - 1 - number]; 183 | // print('当前指向的数===>$cur'); 184 | if (cur >> 6 == 2) { 185 | // print('经过一个10'); 186 | //经过一次10开头的便记录一次 187 | } else if (cur.toRadixString(2).startsWith('1' * (number + 2))) { 188 | //此时该字节以number+2个字节开始,说明该次读取不完整 189 | //因为此时该字节开始的1应该为number+1个(10开始的个数加上此时这个字节) 190 | unitsCache = units.sublist(len - number, len); 191 | units.removeRange(len - number, len); 192 | break; 193 | } else if (cur.toRadixString(2).startsWith('1' * (number + 1))) { 194 | { 195 | break; 196 | } 197 | } 198 | number++; 199 | } 200 | } 201 | try { 202 | return utf8.decode(units, allowMalformed: true); 203 | } catch (e) { 204 | print('===>$units'); 205 | print(e); 206 | } 207 | return null; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /ffigen/term/termare_native.dart: -------------------------------------------------------------------------------- 1 | // AUTO GENERATED FILE, DO NOT EDIT. 2 | // 3 | // Generated by `package:ffigen`. 4 | import 'dart:ffi' as ffi; 5 | 6 | /// Bindings to `headers/example.h`. 7 | class TermareNative { 8 | /// Holds the symbol lookup function. 9 | final ffi.Pointer Function(String symbolName) 10 | _lookup; 11 | 12 | /// The symbols are looked up in [dynamicLibrary]. 13 | TermareNative(ffi.DynamicLibrary dynamicLibrary) 14 | : _lookup = dynamicLibrary.lookup; 15 | 16 | /// The symbols are looked up with [lookup]. 17 | TermareNative.fromLookup( 18 | ffi.Pointer Function(String symbolName) 19 | lookup) 20 | : _lookup = lookup; 21 | 22 | int create_ptm( 23 | int rows, 24 | int columns, 25 | ) { 26 | return _create_ptm( 27 | rows, 28 | columns, 29 | ); 30 | } 31 | 32 | late final _create_ptm_ptr = 33 | _lookup>('create_ptm'); 34 | late final _dart_create_ptm _create_ptm = 35 | _create_ptm_ptr.asFunction<_dart_create_ptm>(); 36 | 37 | void create_subprocess( 38 | ffi.Pointer env, 39 | ffi.Pointer cmd, 40 | ffi.Pointer cwd, 41 | ffi.Pointer> argv, 42 | ffi.Pointer> envp, 43 | ffi.Pointer pProcessId, 44 | int ptmfd, 45 | ) { 46 | return _create_subprocess( 47 | env, 48 | cmd, 49 | cwd, 50 | argv, 51 | envp, 52 | pProcessId, 53 | ptmfd, 54 | ); 55 | } 56 | 57 | late final _create_subprocess_ptr = 58 | _lookup>('create_subprocess'); 59 | late final _dart_create_subprocess _create_subprocess = 60 | _create_subprocess_ptr.asFunction<_dart_create_subprocess>(); 61 | 62 | void write_to_fd( 63 | int fd, 64 | ffi.Pointer str, 65 | ) { 66 | return _write_to_fd( 67 | fd, 68 | str, 69 | ); 70 | } 71 | 72 | late final _write_to_fd_ptr = 73 | _lookup>('write_to_fd'); 74 | late final _dart_write_to_fd _write_to_fd = 75 | _write_to_fd_ptr.asFunction<_dart_write_to_fd>(); 76 | 77 | void setNonblock( 78 | int fd, 79 | ) { 80 | return _setNonblock( 81 | fd, 82 | ); 83 | } 84 | 85 | late final _setNonblock_ptr = 86 | _lookup>('setNonblock'); 87 | late final _dart_setNonblock _setNonblock = 88 | _setNonblock_ptr.asFunction<_dart_setNonblock>(); 89 | 90 | ffi.Pointer get_output_from_fd( 91 | int fd, 92 | ) { 93 | return _get_output_from_fd( 94 | fd, 95 | ); 96 | } 97 | 98 | late final _get_output_from_fd_ptr = 99 | _lookup>('get_output_from_fd'); 100 | late final _dart_get_output_from_fd _get_output_from_fd = 101 | _get_output_from_fd_ptr.asFunction<_dart_get_output_from_fd>(); 102 | 103 | ffi.Pointer getFilePathFromFd( 104 | int fd, 105 | ) { 106 | return _getFilePathFromFd( 107 | fd, 108 | ); 109 | } 110 | 111 | late final _getFilePathFromFd_ptr = 112 | _lookup>('getFilePathFromFd'); 113 | late final _dart_getFilePathFromFd _getFilePathFromFd = 114 | _getFilePathFromFd_ptr.asFunction<_dart_getFilePathFromFd>(); 115 | 116 | void setPtyWindowSize( 117 | int fd, 118 | int rows, 119 | int cols, 120 | ) { 121 | return _setPtyWindowSize( 122 | fd, 123 | rows, 124 | cols, 125 | ); 126 | } 127 | 128 | late final _setPtyWindowSize_ptr = 129 | _lookup>('setPtyWindowSize'); 130 | late final _dart_setPtyWindowSize _setPtyWindowSize = 131 | _setPtyWindowSize_ptr.asFunction<_dart_setPtyWindowSize>(); 132 | 133 | void init_dart_print( 134 | ffi.Pointer> callback, 135 | ) { 136 | return _init_dart_print( 137 | callback, 138 | ); 139 | } 140 | 141 | late final _init_dart_print_ptr = 142 | _lookup>('init_dart_print'); 143 | late final _dart_init_dart_print _init_dart_print = 144 | _init_dart_print_ptr.asFunction<_dart_init_dart_print>(); 145 | 146 | void post_thread( 147 | int ptmfd, 148 | ffi.Pointer> callback, 149 | ) { 150 | return _post_thread( 151 | ptmfd, 152 | callback, 153 | ); 154 | } 155 | 156 | late final _post_thread_ptr = 157 | _lookup>('post_thread'); 158 | late final _dart_post_thread _post_thread = 159 | _post_thread_ptr.asFunction<_dart_post_thread>(); 160 | } 161 | 162 | typedef _c_create_ptm = ffi.Int32 Function( 163 | ffi.Int32 rows, 164 | ffi.Int32 columns, 165 | ); 166 | 167 | typedef _dart_create_ptm = int Function( 168 | int rows, 169 | int columns, 170 | ); 171 | 172 | typedef _c_create_subprocess = ffi.Void Function( 173 | ffi.Pointer env, 174 | ffi.Pointer cmd, 175 | ffi.Pointer cwd, 176 | ffi.Pointer> argv, 177 | ffi.Pointer> envp, 178 | ffi.Pointer pProcessId, 179 | ffi.Int32 ptmfd, 180 | ); 181 | 182 | typedef _dart_create_subprocess = void Function( 183 | ffi.Pointer env, 184 | ffi.Pointer cmd, 185 | ffi.Pointer cwd, 186 | ffi.Pointer> argv, 187 | ffi.Pointer> envp, 188 | ffi.Pointer pProcessId, 189 | int ptmfd, 190 | ); 191 | 192 | typedef _c_write_to_fd = ffi.Void Function( 193 | ffi.Int32 fd, 194 | ffi.Pointer str, 195 | ); 196 | 197 | typedef _dart_write_to_fd = void Function( 198 | int fd, 199 | ffi.Pointer str, 200 | ); 201 | 202 | typedef _c_setNonblock = ffi.Void Function( 203 | ffi.Int32 fd, 204 | ); 205 | 206 | typedef _dart_setNonblock = void Function( 207 | int fd, 208 | ); 209 | 210 | typedef _c_get_output_from_fd = ffi.Pointer Function( 211 | ffi.Int32 fd, 212 | ); 213 | 214 | typedef _dart_get_output_from_fd = ffi.Pointer Function( 215 | int fd, 216 | ); 217 | 218 | typedef _c_getFilePathFromFd = ffi.Pointer Function( 219 | ffi.Int32 fd, 220 | ); 221 | 222 | typedef _dart_getFilePathFromFd = ffi.Pointer Function( 223 | int fd, 224 | ); 225 | 226 | typedef _c_setPtyWindowSize = ffi.Void Function( 227 | ffi.Int32 fd, 228 | ffi.Int32 rows, 229 | ffi.Int32 cols, 230 | ); 231 | 232 | typedef _dart_setPtyWindowSize = void Function( 233 | int fd, 234 | int rows, 235 | int cols, 236 | ); 237 | 238 | typedef Callback = ffi.Void Function( 239 | ffi.Pointer, 240 | ); 241 | 242 | typedef _c_init_dart_print = ffi.Void Function( 243 | ffi.Pointer> callback, 244 | ); 245 | 246 | typedef _dart_init_dart_print = void Function( 247 | ffi.Pointer> callback, 248 | ); 249 | 250 | typedef _c_post_thread = ffi.Void Function( 251 | ffi.Int32 ptmfd, 252 | ffi.Pointer> callback, 253 | ); 254 | 255 | typedef _dart_post_thread = void Function( 256 | int ptmfd, 257 | ffi.Pointer> callback, 258 | ); 259 | -------------------------------------------------------------------------------- /lib/src/unix/termare_native.dart: -------------------------------------------------------------------------------- 1 | // AUTO GENERATED FILE, DO NOT EDIT. 2 | // 3 | // Generated by `package:ffigen`. 4 | import 'dart:ffi' as ffi; 5 | 6 | /// Bindings to `headers/example.h`. 7 | class TermareNative { 8 | /// Holds the symbol lookup function. 9 | final ffi.Pointer Function(String symbolName) 10 | _lookup; 11 | 12 | /// The symbols are looked up in [dynamicLibrary]. 13 | TermareNative(ffi.DynamicLibrary dynamicLibrary) 14 | : _lookup = dynamicLibrary.lookup; 15 | 16 | /// The symbols are looked up with [lookup]. 17 | TermareNative.fromLookup( 18 | ffi.Pointer Function(String symbolName) 19 | lookup) 20 | : _lookup = lookup; 21 | 22 | int create_ptm( 23 | int rows, 24 | int columns, 25 | ) { 26 | return _create_ptm( 27 | rows, 28 | columns, 29 | ); 30 | } 31 | 32 | late final _create_ptm_ptr = 33 | _lookup>('create_ptm'); 34 | late final _dart_create_ptm _create_ptm = 35 | _create_ptm_ptr.asFunction<_dart_create_ptm>(); 36 | 37 | void create_subprocess( 38 | ffi.Pointer env, 39 | ffi.Pointer cmd, 40 | ffi.Pointer cwd, 41 | ffi.Pointer> argv, 42 | ffi.Pointer> envp, 43 | ffi.Pointer pProcessId, 44 | int ptmfd, 45 | ) { 46 | return _create_subprocess( 47 | env, 48 | cmd, 49 | cwd, 50 | argv, 51 | envp, 52 | pProcessId, 53 | ptmfd, 54 | ); 55 | } 56 | 57 | late final _create_subprocess_ptr = 58 | _lookup>('create_subprocess'); 59 | late final _dart_create_subprocess _create_subprocess = 60 | _create_subprocess_ptr.asFunction<_dart_create_subprocess>(); 61 | 62 | void write_to_fd( 63 | int fd, 64 | ffi.Pointer str, 65 | ) { 66 | return _write_to_fd( 67 | fd, 68 | str, 69 | ); 70 | } 71 | 72 | late final _write_to_fd_ptr = 73 | _lookup>('write_to_fd'); 74 | late final _dart_write_to_fd _write_to_fd = 75 | _write_to_fd_ptr.asFunction<_dart_write_to_fd>(); 76 | 77 | void setNonblock( 78 | int fd, 79 | ) { 80 | return _setNonblock( 81 | fd, 82 | ); 83 | } 84 | 85 | late final _setNonblock_ptr = 86 | _lookup>('setNonblock'); 87 | late final _dart_setNonblock _setNonblock = 88 | _setNonblock_ptr.asFunction<_dart_setNonblock>(); 89 | 90 | ffi.Pointer get_output_from_fd( 91 | int fd, 92 | ) { 93 | return _get_output_from_fd( 94 | fd, 95 | ); 96 | } 97 | 98 | late final _get_output_from_fd_ptr = 99 | _lookup>('get_output_from_fd'); 100 | late final _dart_get_output_from_fd _get_output_from_fd = 101 | _get_output_from_fd_ptr.asFunction<_dart_get_output_from_fd>(); 102 | 103 | ffi.Pointer getFilePathFromFd( 104 | int fd, 105 | ) { 106 | return _getFilePathFromFd( 107 | fd, 108 | ); 109 | } 110 | 111 | late final _getFilePathFromFd_ptr = 112 | _lookup>('getFilePathFromFd'); 113 | late final _dart_getFilePathFromFd _getFilePathFromFd = 114 | _getFilePathFromFd_ptr.asFunction<_dart_getFilePathFromFd>(); 115 | 116 | void setPtyWindowSize( 117 | int fd, 118 | int rows, 119 | int cols, 120 | ) { 121 | return _setPtyWindowSize( 122 | fd, 123 | rows, 124 | cols, 125 | ); 126 | } 127 | 128 | late final _setPtyWindowSize_ptr = 129 | _lookup>('setPtyWindowSize'); 130 | late final _dart_setPtyWindowSize _setPtyWindowSize = 131 | _setPtyWindowSize_ptr.asFunction<_dart_setPtyWindowSize>(); 132 | 133 | void init_dart_print( 134 | ffi.Pointer> callback, 135 | ) { 136 | return _init_dart_print( 137 | callback, 138 | ); 139 | } 140 | 141 | late final _init_dart_print_ptr = 142 | _lookup>('init_dart_print'); 143 | late final _dart_init_dart_print _init_dart_print = 144 | _init_dart_print_ptr.asFunction<_dart_init_dart_print>(); 145 | 146 | void post_thread( 147 | int ptmfd, 148 | ffi.Pointer> callback, 149 | ) { 150 | return _post_thread( 151 | ptmfd, 152 | callback, 153 | ); 154 | } 155 | 156 | late final _post_thread_ptr = 157 | _lookup>('post_thread'); 158 | late final _dart_post_thread _post_thread = 159 | _post_thread_ptr.asFunction<_dart_post_thread>(); 160 | } 161 | 162 | typedef _c_create_ptm = ffi.Int32 Function( 163 | ffi.Int32 rows, 164 | ffi.Int32 columns, 165 | ); 166 | 167 | typedef _dart_create_ptm = int Function( 168 | int rows, 169 | int columns, 170 | ); 171 | 172 | typedef _c_create_subprocess = ffi.Void Function( 173 | ffi.Pointer env, 174 | ffi.Pointer cmd, 175 | ffi.Pointer cwd, 176 | ffi.Pointer> argv, 177 | ffi.Pointer> envp, 178 | ffi.Pointer pProcessId, 179 | ffi.Int32 ptmfd, 180 | ); 181 | 182 | typedef _dart_create_subprocess = void Function( 183 | ffi.Pointer env, 184 | ffi.Pointer cmd, 185 | ffi.Pointer cwd, 186 | ffi.Pointer> argv, 187 | ffi.Pointer> envp, 188 | ffi.Pointer pProcessId, 189 | int ptmfd, 190 | ); 191 | 192 | typedef _c_write_to_fd = ffi.Void Function( 193 | ffi.Int32 fd, 194 | ffi.Pointer str, 195 | ); 196 | 197 | typedef _dart_write_to_fd = void Function( 198 | int fd, 199 | ffi.Pointer str, 200 | ); 201 | 202 | typedef _c_setNonblock = ffi.Void Function( 203 | ffi.Int32 fd, 204 | ); 205 | 206 | typedef _dart_setNonblock = void Function( 207 | int fd, 208 | ); 209 | 210 | typedef _c_get_output_from_fd = ffi.Pointer Function( 211 | ffi.Int32 fd, 212 | ); 213 | 214 | typedef _dart_get_output_from_fd = ffi.Pointer Function( 215 | int fd, 216 | ); 217 | 218 | typedef _c_getFilePathFromFd = ffi.Pointer Function( 219 | ffi.Int32 fd, 220 | ); 221 | 222 | typedef _dart_getFilePathFromFd = ffi.Pointer Function( 223 | int fd, 224 | ); 225 | 226 | typedef _c_setPtyWindowSize = ffi.Void Function( 227 | ffi.Int32 fd, 228 | ffi.Int32 rows, 229 | ffi.Int32 cols, 230 | ); 231 | 232 | typedef _dart_setPtyWindowSize = void Function( 233 | int fd, 234 | int rows, 235 | int cols, 236 | ); 237 | 238 | typedef Callback = ffi.Void Function( 239 | ffi.Pointer, 240 | ); 241 | 242 | typedef _c_init_dart_print = ffi.Void Function( 243 | ffi.Pointer> callback, 244 | ); 245 | 246 | typedef _dart_init_dart_print = void Function( 247 | ffi.Pointer> callback, 248 | ); 249 | 250 | typedef _c_post_thread = ffi.Void Function( 251 | ffi.Int32 ptmfd, 252 | ffi.Pointer> callback, 253 | ); 254 | 255 | typedef _dart_post_thread = void Function( 256 | int ptmfd, 257 | ffi.Pointer> callback, 258 | ); 259 | -------------------------------------------------------------------------------- /c_resource/termare/src/term.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "term.h" 12 | #define TERMUX_UNUSED(x) x __attribute__((__unused__)) 13 | #ifdef __APPLE__ 14 | #define LACKS_PTSNAME_R 15 | #endif 16 | 17 | Callback dart_print; 18 | void init_dart_print(Callback callback) 19 | { 20 | dart_print = callback; 21 | } 22 | //cmd 执行程序 23 | //cwd 当前工作目录 24 | //argv 参数,类似于["-i","-c"] 25 | 26 | int create_ptm( 27 | int rows, 28 | int columns) 29 | { 30 | dart_print("hhhhh"); 31 | //调用open这个路径会随机获得一个大于0的整形值 32 | // dartprint("创建终端中"); 33 | int ptm = open("/dev/ptmx", O_RDWR | O_CLOEXEC); 34 | //这个值会从0依次上增 35 | // if (ptm < 0) return throw_runtime_exception(env, "Cannot open /dev/ptmx"); 36 | #ifdef LACKS_PTSNAME_R 37 | char *devname; 38 | #else 39 | char devname[64]; 40 | // dartprint("得到pst路径"); 41 | #endif 42 | if (grantpt(ptm) || unlockpt(ptm) || 43 | #ifdef LACKS_PTSNAME_R 44 | (devname = ptsname(ptm)) == NULL 45 | #else 46 | ptsname_r(ptm, devname, sizeof(devname)) 47 | #endif 48 | ) 49 | { 50 | // return throw_runtime_exception(env, "Cannot grantpt()/unlockpt()/ptsname_r() on /dev/ptmx"); 51 | } 52 | // Enable UTF-8 mode and disable flow control to prevent Ctrl+S from locking up the display. 53 | struct termios tios; 54 | tcgetattr(ptm, &tios); 55 | tios.c_iflag |= IUTF8; 56 | tios.c_iflag &= ~(IXON | IXOFF); 57 | tcsetattr(ptm, TCSANOW, &tios); 58 | 59 | /** Set initial winsize. */ 60 | struct winsize sz = {.ws_row = (unsigned short)rows, .ws_col = (unsigned short)columns}; 61 | ioctl(ptm, TIOCSWINSZ, &sz); 62 | return ptm; 63 | } 64 | // int main(int argc, char **argv, char **env) 65 | // { 66 | // if (env) 67 | // for (; *env; ++env) 68 | // printf("%s\n", *env); 69 | // int ptm = create_ptm(25, 80); 70 | // printf("PseudoTerminal ->%d\n", ptm); 71 | // int *pid; 72 | // create_subprocess(NULL, "sh", ".", NULL, env, pid, ptm); 73 | // printf("processID -> %d\n", *pid); 74 | // return 0; 75 | // } 76 | 77 | int *thread(Callback callback) 78 | { 79 | 80 | pthread_t newthid; 81 | 82 | newthid = pthread_self(); 83 | printf("this is a new thread, thread ID = %d\n", newthid); 84 | callback("子线程打印"); 85 | return NULL; 86 | } 87 | void post_thread(int ptmfd, Callback callback) 88 | { 89 | pthread_t thid; 90 | callback("主线程打印"); 91 | printf("main thread ,ID is %d\n", pthread_self()); 92 | if (pthread_create(&thid, NULL, (void *)thread, callback) != 0) 93 | { 94 | printf("thread creation failed\n"); 95 | exit(1); 96 | } 97 | } 98 | void create_subprocess(char *env, 99 | char const *cmd, 100 | char const *cwd, 101 | char *const argv[], 102 | char **envp, 103 | int *pProcessId, 104 | int ptmfd) 105 | { 106 | // printf("asdd"); 107 | #ifdef LACKS_PTSNAME_R 108 | char *devname; 109 | #else 110 | char devname[64]; 111 | #endif 112 | 113 | #ifdef LACKS_PTSNAME_R 114 | devname = ptsname(ptmfd); 115 | #else 116 | ptsname_r(ptmfd, devname, sizeof(devname)); 117 | #endif 118 | //创建一个进程,返回是它的pid 119 | pid_t pid = fork(); 120 | if (pid < 0) 121 | { 122 | // return throw_runtime_exception(env, "Fork failed"); 123 | } 124 | else if (pid > 0) 125 | { 126 | *pProcessId = (int)pid; 127 | // int pts = open(devname, O_RDWR); 128 | // if (pts < 0) 129 | // exit(-1); 130 | // //下面三个大概将stdin,stdout,stderr复制到了这个pts里面 131 | // //ptmx,pts pseudo terminal master and slave 132 | // // dup2(pts, 0); 133 | // dup2(pts, 1); 134 | // dup2(pts, 2); 135 | 136 | return; 137 | } 138 | else 139 | { 140 | // Clear signals which the Android java process may have blocked: 141 | sigset_t signals_to_unblock; 142 | sigfillset(&signals_to_unblock); 143 | sigprocmask(SIG_UNBLOCK, &signals_to_unblock, 0); 144 | 145 | close(ptmfd); 146 | setsid(); 147 | //O_RDWR读写,devname为/dev/pts/0,1,2,3... 148 | int pts = open(devname, O_RDWR); 149 | if (pts < 0) 150 | exit(-1); 151 | //下面三个大概将stdin,stdout,stderr复制到了这个pts里面 152 | //ptmx,pts pseudo terminal master and slave 153 | dup2(pts, 0); 154 | dup2(pts, 1); 155 | dup2(pts, 2); 156 | //Linux的api,打开一个文件夹 157 | DIR *self_dir = opendir("/proc/self/fd"); 158 | if (self_dir != NULL) 159 | { 160 | //dirfd没查到,好像把文件夹转换为文件描述符 161 | int self_dir_fd = dirfd(self_dir); 162 | struct dirent *entry; 163 | while ((entry = readdir(self_dir)) != NULL) 164 | { 165 | int fd = atoi(entry->d_name); 166 | if (fd > 2 && fd != self_dir_fd) 167 | close(fd); 168 | } 169 | closedir(self_dir); 170 | } //清除环境变量 171 | // clearenv(); 172 | 173 | if (envp) 174 | for (; *envp; ++envp) 175 | putenv(*envp); 176 | 177 | if (chdir(cwd) != 0) 178 | { 179 | char *error_message; 180 | // No need to free asprintf()-allocated memory since doing execvp() or exit() below. 181 | if (asprintf(&error_message, "chdir(\"%s\")", cwd) == -1) 182 | error_message = "chdir()"; 183 | perror(error_message); 184 | fflush(stderr); 185 | } 186 | //执行程序 187 | execvp(cmd, argv); 188 | 189 | // Show terminal output about failing exec() call: 190 | char *error_message; 191 | if (asprintf(&error_message, "exec(\"%s\")", cmd) == -1) 192 | error_message = "exec()"; 193 | perror(error_message); 194 | _exit(1); 195 | } 196 | } 197 | void write_to_fd(int fd, char *str) 198 | { 199 | write(fd, str, strlen(str)); 200 | } 201 | void setNonblock(int fd) 202 | { 203 | int flag = -1; 204 | flag = fcntl(fd, F_GETFL); //获取当前flag 205 | flag |= O_NONBLOCK; //设置新falg 206 | fcntl(fd, F_SETFL, flag); //更新flag 207 | } 208 | char *get_output_from_fd(int fd) 209 | { 210 | //动态申请空间 211 | char *str = (char *)malloc((81921) * sizeof(char)); 212 | //read函数返回从fd中读取到字符的长度 213 | //读取的内容存进str,4096表示此次读取4096个字节,如果只读到10个则length为10 214 | int length = read(fd, str, 81920); 215 | if (length == -1) 216 | { 217 | free(str); 218 | return NULL; 219 | } 220 | else 221 | { 222 | str[length] = '\0'; 223 | return str; 224 | } 225 | } 226 | 227 | int waitFor(int pid) 228 | { 229 | int status; 230 | waitpid(pid, &status, 0); 231 | if (WIFEXITED(status)) 232 | { 233 | return WEXITSTATUS(status); 234 | } 235 | else if (WIFSIGNALED(status)) 236 | { 237 | return -WTERMSIG(status); 238 | } 239 | else 240 | { 241 | // Should never happen - waitpid(2) says "One of the first three macros will evaluate to a non-zero (true) value". 242 | return 0; 243 | } 244 | } 245 | void setPtyWindowSize(int fd, int rows, int cols) 246 | { 247 | struct winsize sz = {.ws_row = (unsigned short)rows, .ws_col = (unsigned short)cols}; 248 | ioctl(fd, TIOCSWINSZ, &sz); 249 | } 250 | -------------------------------------------------------------------------------- /ffigen/simple/headers/dirent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000, 2002-2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*- 24 | * Copyright (c) 1989, 1993 25 | * The Regents of the University of California. All rights reserved. 26 | * 27 | * Redistribution and use in source and binary forms, with or without 28 | * modification, are permitted provided that the following conditions 29 | * are met: 30 | * 1. Redistributions of source code must retain the above copyright 31 | * notice, this list of conditions and the following disclaimer. 32 | * 2. Redistributions in binary form must reproduce the above copyright 33 | * notice, this list of conditions and the following disclaimer in the 34 | * documentation and/or other materials provided with the distribution. 35 | * 3. All advertising materials mentioning features or use of this software 36 | * must display the following acknowledgement: 37 | * This product includes software developed by the University of 38 | * California, Berkeley and its contributors. 39 | * 4. Neither the name of the University nor the names of its contributors 40 | * may be used to endorse or promote products derived from this software 41 | * without specific prior written permission. 42 | * 43 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 | * SUCH DAMAGE. 54 | * 55 | * @(#)dirent.h 8.2 (Berkeley) 7/28/94 56 | */ 57 | 58 | #ifndef _DIRENT_H_ 59 | #define _DIRENT_H_ 60 | 61 | /* 62 | * The kernel defines the format of directory entries 63 | */ 64 | #include <_types.h> 65 | #include 66 | #include 67 | #include 68 | #include /* __darwin_pthread_mutex_t */ 69 | 70 | struct _telldir; /* forward reference */ 71 | 72 | /* structure describing an open directory. */ 73 | typedef struct { 74 | int __dd_fd; /* file descriptor associated with directory */ 75 | long __dd_loc; /* offset in current buffer */ 76 | long __dd_size; /* amount of data returned */ 77 | char *__dd_buf; /* data buffer */ 78 | int __dd_len; /* size of data buffer */ 79 | long __dd_seek; /* magic cookie returned */ 80 | __unused long __padding; /* (__dd_rewind space left for bincompat) */ 81 | int __dd_flags; /* flags for readdir */ 82 | __darwin_pthread_mutex_t __dd_lock; /* for thread locking */ 83 | struct _telldir *__dd_td; /* telldir position recording */ 84 | } DIR; 85 | 86 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 87 | 88 | /* definitions for library routines operating on directories. */ 89 | #define DIRBLKSIZ 1024 90 | 91 | /* flags for opendir2 */ 92 | #define DTF_HIDEW 0x0001 /* hide whiteout entries */ 93 | #define DTF_NODUP 0x0002 /* don't return duplicate names */ 94 | #define DTF_REWIND 0x0004 /* rewind after reading union stack */ 95 | #define __DTF_READALL 0x0008 /* everything has been read */ 96 | #define __DTF_SKIPREAD 0x0010 /* assume internal buffer is populated */ 97 | #define __DTF_ATEND 0x0020 /* there's nothing more to read in the kernel */ 98 | 99 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 100 | 101 | #ifndef KERNEL 102 | 103 | __BEGIN_DECLS 104 | 105 | int closedir(DIR *) __DARWIN_ALIAS(closedir); 106 | 107 | DIR *opendir(const char *) __DARWIN_ALIAS_I(opendir); 108 | 109 | struct dirent *readdir(DIR *) __DARWIN_INODE64(readdir); 110 | int readdir_r(DIR *, struct dirent *, struct dirent **) __DARWIN_INODE64(readdir_r); 111 | 112 | void rewinddir(DIR *) __DARWIN_ALIAS_I(rewinddir); 113 | 114 | void seekdir(DIR *, long) __DARWIN_ALIAS_I(seekdir); 115 | 116 | long telldir(DIR *) __DARWIN_ALIAS_I(telldir); 117 | 118 | __END_DECLS 119 | 120 | 121 | /* Additional functionality provided by: 122 | * POSIX.1-2008 123 | */ 124 | 125 | #if __DARWIN_C_LEVEL >= 200809L 126 | __BEGIN_DECLS 127 | 128 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 129 | DIR *fdopendir(int) __DARWIN_ALIAS_I(fdopendir); 130 | 131 | int alphasort(const struct dirent **, const struct dirent **) __DARWIN_INODE64(alphasort); 132 | 133 | #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8) || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0) 134 | #include 135 | #include 136 | #define dirfd(dirp) ({ \ 137 | DIR *_dirp = (dirp); \ 138 | int ret = -1; \ 139 | if (_dirp == NULL || _dirp->__dd_fd < 0) \ 140 | errno = EINVAL; \ 141 | else \ 142 | ret = _dirp->__dd_fd; \ 143 | ret; \ 144 | }) 145 | #else 146 | int dirfd(DIR *dirp) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); 147 | #endif 148 | 149 | int scandir(const char *, struct dirent ***, 150 | int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **)) __DARWIN_INODE64(scandir); 151 | #ifdef __BLOCKS__ 152 | #if __has_attribute(noescape) 153 | #define __scandir_noescape __attribute__((__noescape__)) 154 | #else 155 | #define __scandir_noescape 156 | #endif 157 | 158 | int scandir_b(const char *, struct dirent ***, 159 | int (^)(const struct dirent *) __scandir_noescape, 160 | int (^)(const struct dirent **, const struct dirent **) __scandir_noescape) 161 | __DARWIN_INODE64(scandir_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 162 | #endif /* __BLOCKS__ */ 163 | 164 | __END_DECLS 165 | #endif /* __DARWIN_C_LEVEL >= 200809L */ 166 | 167 | 168 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 169 | __BEGIN_DECLS 170 | 171 | int getdirentries(int, char *, int, long *) 172 | 173 | #if __DARWIN_64_BIT_INO_T 174 | /* 175 | * getdirentries() doesn't work when 64-bit inodes is in effect, so we 176 | * generate a link error. 177 | */ 178 | __asm("_getdirentries_is_not_available_when_64_bit_inodes_are_in_effect") 179 | #else /* !__DARWIN_64_BIT_INO_T */ 180 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_6, __IPHONE_2_0,__IPHONE_2_0) 181 | #endif /* __DARWIN_64_BIT_INO_T */ 182 | ; 183 | 184 | DIR *__opendir2(const char *, int) __DARWIN_ALIAS_I(__opendir2); 185 | 186 | __END_DECLS 187 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 188 | 189 | #endif /* !KERNEL */ 190 | 191 | #endif /* !_DIRENT_H_ */ 192 | -------------------------------------------------------------------------------- /ffigen/simple/headers/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000, 2007, 2010 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*- 24 | * Copyright (c) 1990, 1993 25 | * The Regents of the University of California. All rights reserved. 26 | * 27 | * Redistribution and use in source and binary forms, with or without 28 | * modification, are permitted provided that the following conditions 29 | * are met: 30 | * 1. Redistributions of source code must retain the above copyright 31 | * notice, this list of conditions and the following disclaimer. 32 | * 2. Redistributions in binary form must reproduce the above copyright 33 | * notice, this list of conditions and the following disclaimer in the 34 | * documentation and/or other materials provided with the distribution. 35 | * 3. All advertising materials mentioning features or use of this software 36 | * must display the following acknowledgement: 37 | * This product includes software developed by the University of 38 | * California, Berkeley and its contributors. 39 | * 4. Neither the name of the University nor the names of its contributors 40 | * may be used to endorse or promote products derived from this software 41 | * without specific prior written permission. 42 | * 43 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 | * SUCH DAMAGE. 54 | * 55 | * @(#)string.h 8.1 (Berkeley) 6/2/93 56 | */ 57 | 58 | #ifndef _STRING_H_ 59 | #define _STRING_H_ 60 | 61 | #include <_types.h> 62 | #include 63 | #include 64 | #include 65 | #include 66 | 67 | /* ANSI-C */ 68 | 69 | __BEGIN_DECLS 70 | void *memchr(const void *__s, int __c, size_t __n); 71 | int memcmp(const void *__s1, const void *__s2, size_t __n); 72 | void *memcpy(void *__dst, const void *__src, size_t __n); 73 | void *memmove(void *__dst, const void *__src, size_t __len); 74 | void *memset(void *__b, int __c, size_t __len); 75 | char *strcat(char *__s1, const char *__s2); 76 | char *strchr(const char *__s, int __c); 77 | int strcmp(const char *__s1, const char *__s2); 78 | int strcoll(const char *__s1, const char *__s2); 79 | char *strcpy(char *__dst, const char *__src); 80 | size_t strcspn(const char *__s, const char *__charset); 81 | char *strerror(int __errnum) __DARWIN_ALIAS(strerror); 82 | size_t strlen(const char *__s); 83 | char *strncat(char *__s1, const char *__s2, size_t __n); 84 | int strncmp(const char *__s1, const char *__s2, size_t __n); 85 | char *strncpy(char *__dst, const char *__src, size_t __n); 86 | char *strpbrk(const char *__s, const char *__charset); 87 | char *strrchr(const char *__s, int __c); 88 | size_t strspn(const char *__s, const char *__charset); 89 | char *strstr(const char *__big, const char *__little); 90 | char *strtok(char *__str, const char *__sep); 91 | size_t strxfrm(char *__s1, const char *__s2, size_t __n); 92 | __END_DECLS 93 | 94 | 95 | 96 | /* Additional functionality provided by: 97 | * POSIX.1c-1995, 98 | * POSIX.1i-1995, 99 | * and the omnibus ISO/IEC 9945-1: 1996 100 | */ 101 | 102 | #if __DARWIN_C_LEVEL >= 199506L 103 | __BEGIN_DECLS 104 | char *strtok_r(char *__str, const char *__sep, char **__lasts); 105 | __END_DECLS 106 | #endif /* __DARWIN_C_LEVEL >= 199506L */ 107 | 108 | 109 | 110 | /* Additional functionality provided by: 111 | * POSIX.1-2001 112 | */ 113 | 114 | #if __DARWIN_C_LEVEL >= 200112L 115 | __BEGIN_DECLS 116 | int strerror_r(int __errnum, char *__strerrbuf, size_t __buflen); 117 | char *strdup(const char *__s1); 118 | void *memccpy(void *__dst, const void *__src, int __c, size_t __n); 119 | __END_DECLS 120 | #endif /* __DARWIN_C_LEVEL >= 200112L */ 121 | 122 | 123 | 124 | /* Additional functionality provided by: 125 | * POSIX.1-2008 126 | */ 127 | 128 | #if __DARWIN_C_LEVEL >= 200809L 129 | __BEGIN_DECLS 130 | char *stpcpy(char *__dst, const char *__src); 131 | char *stpncpy(char *__dst, const char *__src, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 132 | char *strndup(const char *__s1, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 133 | size_t strnlen(const char *__s1, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 134 | char *strsignal(int __sig); 135 | __END_DECLS 136 | #endif /* __DARWIN_C_LEVEL >= 200809L */ 137 | 138 | /* C11 Annex K */ 139 | 140 | #if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 141 | #include 142 | #include 143 | 144 | __BEGIN_DECLS 145 | errno_t memset_s(void *__s, rsize_t __smax, int __c, rsize_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); 146 | __END_DECLS 147 | #endif 148 | 149 | /* Darwin extensions */ 150 | 151 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 152 | #include 153 | 154 | __BEGIN_DECLS 155 | void *memmem(const void *__big, size_t __big_len, const void *__little, size_t __little_len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 156 | void memset_pattern4(void *__b, const void *__pattern4, size_t __len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); 157 | void memset_pattern8(void *__b, const void *__pattern8, size_t __len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); 158 | void memset_pattern16(void *__b, const void *__pattern16, size_t __len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); 159 | 160 | char *strcasestr(const char *__big, const char *__little); 161 | char *strnstr(const char *__big, const char *__little, size_t __len); 162 | size_t strlcat(char *__dst, const char *__source, size_t __size); 163 | size_t strlcpy(char *__dst, const char *__source, size_t __size); 164 | void strmode(int __mode, char *__bp); 165 | char *strsep(char **__stringp, const char *__delim); 166 | 167 | /* SUS places swab() in unistd.h. It is listed here for source compatibility */ 168 | void swab(const void * __restrict, void * __restrict, ssize_t); 169 | 170 | __OSX_AVAILABLE(10.12.1) __IOS_AVAILABLE(10.1) 171 | __TVOS_AVAILABLE(10.0.1) __WATCHOS_AVAILABLE(3.1) 172 | int timingsafe_bcmp(const void *__b1, const void *__b2, size_t __len); 173 | 174 | __OSX_AVAILABLE(11.0) __IOS_AVAILABLE(14.0) 175 | __TVOS_AVAILABLE(14.0) __WATCHOS_AVAILABLE(7.0) 176 | int strsignal_r(int __sig, char *__strsignalbuf, size_t __buflen); 177 | __END_DECLS 178 | 179 | /* Some functions historically defined in string.h were placed in strings.h 180 | * by SUS. We are using "strings.h" instead of to avoid an issue 181 | * where /Developer/Headers/FlatCarbon/Strings.h could be included instead on 182 | * case-insensitive file systems. 183 | */ 184 | #include "strings.h" 185 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 186 | 187 | 188 | #ifdef _USE_EXTENDED_LOCALES_ 189 | #include 190 | #endif /* _USE_EXTENDED_LOCALES_ */ 191 | 192 | #if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus) 193 | /* Security checking functions. */ 194 | #include 195 | #endif 196 | 197 | #endif /* _STRING_H_ */ 198 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Specify analysis options. 2 | # 3 | # Until there are meta linter rules, each desired lint must be explicitly enabled. 4 | # See: https://github.com/dart-lang/linter/issues/288 5 | # 6 | # For a list of lints, see: http://dart-lang.github.io/linter/lints/ 7 | # See the configuration guide for more 8 | # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer 9 | # 10 | # There are other similar analysis options files in the flutter repos, 11 | # which should be kept in sync with this file: 12 | # 13 | # - analysis_options.yaml (this file) 14 | # - packages/flutter/lib/analysis_options_user.yaml 15 | # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml 16 | # - https://github.com/flutter/engine/blob/master/analysis_options.yaml 17 | # 18 | # This file contains the analysis options used by Flutter tools, such as IntelliJ, 19 | # Android Studio, and the `flutter analyze` command. 20 | 21 | analyzer: 22 | strong-mode: 23 | implicit-casts: false 24 | implicit-dynamic: false 25 | errors: 26 | # treat missing required parameters as a warning (not a hint) 27 | missing_required_param: warning 28 | # treat missing returns as a warning (not a hint) 29 | missing_return: warning 30 | # allow having TODOs in the code 31 | todo: ignore 32 | # Ignore analyzer hints for updating pubspecs when using Future or 33 | # Stream and not importing dart:async 34 | # Please see https://github.com/flutter/flutter/pull/24528 for details. 35 | sdk_version_async_exported_from_core: ignore 36 | exclude: 37 | - "bin/cache/**" 38 | # the following two are relative to the stocks example and the flutter package respectively 39 | # see https://github.com/dart-lang/sdk/issues/28463 40 | - "lib/i18n/messages_*.dart" 41 | - "lib/src/http/**" 42 | 43 | linter: 44 | rules: 45 | # these rules are documented on and in the same order as 46 | # the Dart Lint rules page to make maintenance easier 47 | # https://github.com/dart-lang/linter/blob/master/example/all.yaml 48 | - always_declare_return_types 49 | - always_put_control_body_on_new_line 50 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 51 | - always_require_non_null_named_parameters 52 | # - always_specify_types 53 | - annotate_overrides 54 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types 55 | # - avoid_as # required for implicit-casts: true 56 | # - avoid_bool_literals_in_conditional_expressions 57 | # - avoid_catches_without_on_clauses # we do this commonly 58 | # - avoid_catching_errors # we do this commonly 59 | - avoid_classes_with_only_static_members 60 | # - avoid_double_and_int_checks # only useful when targeting JS runtime 61 | - avoid_empty_else 62 | # - avoid_equals_and_hash_code_on_mutable_classes # not yet tested 63 | - avoid_field_initializers_in_const_classes 64 | # - avoid_function_literals_in_foreach_calls 65 | # - avoid_implementing_value_types # not yet tested 66 | - avoid_init_to_null 67 | # - avoid_js_rounded_ints # only useful when targeting JS runtime 68 | - avoid_null_checks_in_equality_operators 69 | # - avoid_positional_boolean_parameters # not yet tested 70 | # - avoid_print # not yet tested 71 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 72 | # - avoid_redundant_argument_values # not yet tested 73 | - avoid_relative_lib_imports 74 | - avoid_renaming_method_parameters 75 | - avoid_return_types_on_setters 76 | # - avoid_returning_null # there are plenty of valid reasons to return null 77 | # - avoid_returning_null_for_future # not yet tested 78 | - avoid_returning_null_for_void 79 | # - avoid_returning_this # there are plenty of valid reasons to return this 80 | # - avoid_setters_without_getters # not yet tested 81 | # - avoid_shadowing_type_parameters # not yet tested 82 | - avoid_single_cascade_in_expression_statements 83 | # - avoid_slow_async_io 84 | - avoid_types_as_parameter_names 85 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types 86 | # - avoid_unnecessary_containers # not yet tested 87 | - avoid_unused_constructor_parameters 88 | - avoid_void_async 89 | # - avoid_web_libraries_in_flutter # not yet tested 90 | - await_only_futures 91 | - camel_case_extensions 92 | - camel_case_types 93 | - cancel_subscriptions 94 | # - cascade_invocations # not yet tested 95 | # - close_sinks # not reliable enough 96 | # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 97 | # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 98 | - control_flow_in_finally 99 | # - curly_braces_in_flow_control_structures # not yet tested 100 | # - diagnostic_describe_all_properties # not yet tested 101 | - directives_ordering 102 | - empty_catches 103 | - empty_constructor_bodies 104 | - empty_statements 105 | # - file_names # not yet tested 106 | - flutter_style_todos 107 | - hash_and_equals 108 | - implementation_imports 109 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 110 | - iterable_contains_unrelated_type 111 | # - join_return_with_assignment # not yet tested 112 | - library_names 113 | - library_prefixes 114 | # - lines_longer_than_80_chars # not yet tested 115 | - list_remove_unrelated_type 116 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 117 | # - missing_whitespace_between_adjacent_strings # not yet tested 118 | - no_adjacent_strings_in_list 119 | - no_duplicate_case_values 120 | # - no_logic_in_create_state # not yet tested 121 | # - no_runtimeType_toString # not yet tested 122 | - non_constant_identifier_names 123 | # - null_closures # not yet tested 124 | # - omit_local_variable_types # opposite of always_specify_types 125 | # - one_member_abstracts # too many false positives 126 | # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 127 | - overridden_fields 128 | - package_api_docs 129 | - package_names 130 | - package_prefixed_library_names 131 | # - parameter_assignments # we do this commonly 132 | - prefer_adjacent_string_concatenation 133 | - prefer_asserts_in_initializer_lists 134 | # - prefer_asserts_with_message # not yet tested 135 | - prefer_collection_literals 136 | - prefer_conditional_assignment 137 | - prefer_const_constructors 138 | - prefer_const_constructors_in_immutables 139 | - prefer_const_declarations 140 | - prefer_const_literals_to_create_immutables 141 | # - prefer_constructors_over_static_methods # not yet tested 142 | - prefer_contains 143 | # - prefer_double_quotes # opposite of prefer_single_quotes 144 | - prefer_equal_for_default_values 145 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 146 | - prefer_final_fields 147 | - prefer_final_in_for_each 148 | - prefer_final_locals 149 | - prefer_for_elements_to_map_fromIterable 150 | - prefer_foreach 151 | # - prefer_function_declarations_over_variables # not yet tested 152 | - prefer_generic_function_type_aliases 153 | - prefer_if_elements_to_conditional_expressions 154 | - prefer_if_null_operators 155 | - prefer_initializing_formals 156 | - prefer_inlined_adds 157 | # - prefer_int_literals # not yet tested 158 | # - prefer_interpolation_to_compose_strings # not yet tested 159 | - prefer_is_empty 160 | - prefer_is_not_empty 161 | - prefer_is_not_operator 162 | - prefer_iterable_whereType 163 | # - prefer_mixin # https://github.com/dart-lang/language/issues/32 164 | # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 165 | # - prefer_relative_imports # not yet tested 166 | - prefer_single_quotes 167 | - prefer_spread_collections 168 | - prefer_typing_uninitialized_variables 169 | - prefer_void_to_null 170 | # - provide_deprecation_message # not yet tested 171 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 172 | - recursive_getters 173 | - slash_for_doc_comments 174 | # - sort_child_properties_last # not yet tested 175 | - sort_constructors_first 176 | - sort_pub_dependencies 177 | - sort_unnamed_constructors_first 178 | - test_types_in_equals 179 | - throw_in_finally 180 | # - type_annotate_public_apis # subset of always_specify_types 181 | - type_init_formals 182 | # - unawaited_futures # too many false positives 183 | # - unnecessary_await_in_return # not yet tested 184 | - unnecessary_brace_in_string_interps 185 | - unnecessary_const 186 | # - unnecessary_final # conflicts with prefer_final_locals 187 | - unnecessary_getters_setters 188 | # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 189 | - unnecessary_new 190 | - unnecessary_null_aware_assignments 191 | - unnecessary_null_in_if_null_operators 192 | - unnecessary_overrides 193 | - unnecessary_parenthesis 194 | - unnecessary_statements 195 | - unnecessary_string_interpolations 196 | - unnecessary_this 197 | - unrelated_type_equality_checks 198 | # - unsafe_html # not yet tested 199 | - use_full_hex_values_for_flutter_colors 200 | # - use_function_type_syntax_for_parameters # not yet tested 201 | # - use_key_in_widget_constructors # not yet tested 202 | - use_rethrow_when_possible 203 | # - use_setters_to_change_properties # not yet tested 204 | # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 205 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 206 | - valid_regexps 207 | - void_checks 208 | -------------------------------------------------------------------------------- /lib/src/unix_pty.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'dart:ffi'; 4 | import 'dart:io'; 5 | import 'dart:isolate'; 6 | import 'dart:typed_data'; 7 | 8 | import 'package:dart_pty/dart_pty.dart'; 9 | import 'package:dart_pty/src/foundation/file_descriptor.dart'; 10 | import 'package:dart_pty/src/unix_proc.dart'; 11 | import 'package:ffi/ffi.dart'; 12 | import 'package:signale/signale.dart'; 13 | 14 | import 'interface/pseudo_terminal_interface.dart'; 15 | import 'native_header/generated_bindings.dart'; 16 | import 'proc.dart'; 17 | 18 | // TODO 19 | // termare; 20 | 21 | class UnixPty implements PseudoTerminal { 22 | UnixPty({ 23 | required this.rowLen, 24 | required this.columnLen, 25 | String? executable, 26 | String workingDirectory = '', 27 | List arguments = const [], 28 | Map environment = const {}, 29 | this.useIsolate = false, 30 | }) { 31 | out = _out.stream.asBroadcastStream(); 32 | // 这个函数实现的功能是完整的 33 | pseudoTerminalId = createPseudoTerminal(); 34 | fd = FileDescriptor(pseudoTerminalId, nativeLibrary); 35 | if (!useIsolate) { 36 | fd.setNonblock(pseudoTerminalId); 37 | } 38 | _createSubprocess( 39 | executable!, 40 | workingDirectory: workingDirectory, 41 | arguments: arguments, 42 | environment: environment, 43 | ); 44 | } 45 | Isolate? readIsolate; 46 | // 创建一个pty,返回它的ptm文本描述符,这个ptm在之后的读写,fork子进程还会用到 47 | int createPseudoTerminal() { 48 | Log.d('Create Start', tag: 'Term'); 49 | final ptmxPath = '/dev/ptmx'.toNativeUtf8(); 50 | final int ptm = nativeLibrary.open( 51 | ptmxPath.cast(), 52 | O_RDWR | O_CLOEXEC, 53 | ); 54 | if (nativeLibrary.grantpt(ptm) != 0 || nativeLibrary.unlockpt(ptm) != 0) { 55 | // 说明二者有一个失败 56 | Log.e('Cannot grantpt()/unlockpt()/ptsname_r() on /dev/ptmx'); 57 | return -1; 58 | } 59 | final Pointer tios = calloc(); 60 | // addressOf 可以获取指针 61 | nativeLibrary.tcgetattr(ptm, tios); 62 | tios.ref.c_iflag |= IUTF8; 63 | tios.ref.c_iflag &= ~(IXON | IXOFF); 64 | nativeLibrary.tcsetattr(ptm, TCSANOW, tios); 65 | // free(tios); 66 | // =========== 设置终端大小 ============= 67 | final Pointer size = calloc(); 68 | size.ref.ws_row = rowLen; 69 | size.ref.ws_col = columnLen; 70 | nativeLibrary.ioctl( 71 | ptm, 72 | TIOCSWINSZ, 73 | size, 74 | ); 75 | calloc.free(size); 76 | // free(ptmxPath); 77 | 78 | Log.d('Create End', tag: 'Term'); 79 | Log.d('Ptm = $ptm', tag: 'Term'); 80 | return ptm; 81 | // nativeLibrary.grantpt() 82 | } 83 | 84 | final bool useIsolate; 85 | late FileDescriptor fd; 86 | // final NiUtf _niUtf = NiUtf(); 87 | final int rowLen; 88 | final int columnLen; 89 | 90 | @override 91 | late int pseudoTerminalId; 92 | late int pid; 93 | Proc? _createSubprocess( 94 | String executable, { 95 | String workingDirectory = '.', 96 | List arguments = const [], 97 | Map environment = const {}, 98 | }) { 99 | final List fullArg = [executable, ...arguments]; 100 | Pointer devname = calloc(); 101 | // 获得pts路径 102 | devname = nativeLibrary.ptsname(pseudoTerminalId).cast(); 103 | Log.d(devname.cast().toDartString()); 104 | final int pid = nativeLibrary.fork(); 105 | if (pid < 0) { 106 | Log.i('fork faild'); 107 | } else if (pid > 0) { 108 | Log.i('fork 主进程'); 109 | this.pid = pid; 110 | // 这里会返回子进程的pid 111 | return UnixProc(pid); 112 | } else { 113 | Log.i('fork 子进程'); 114 | // Clear signals which the Android java process may have blocked: 115 | final Pointer signalsToUnblock = calloc(); 116 | // sigset_t signals_to_unblock; 117 | Log.i('sigfillset start'); 118 | nativeLibrary.sigfillset(signalsToUnblock); 119 | Log.i('sigfillset done'); 120 | nativeLibrary.sigprocmask( 121 | SIG_UNBLOCK, 122 | signalsToUnblock, 123 | nullptr, 124 | ); 125 | Log.i('sigprocmask done'); 126 | nativeLibrary.close(pseudoTerminalId); 127 | Log.i('close done'); 128 | nativeLibrary.setsid(); 129 | Log.i('setsid done'); 130 | final int pts = nativeLibrary.open(devname, O_RDWR); 131 | if (pts < 0) { 132 | return null; 133 | } 134 | nativeLibrary.dup2(pts, 0); 135 | nativeLibrary.dup2(pts, 1); 136 | nativeLibrary.dup2(pts, 2); 137 | Log.i('dup2 done'); 138 | // final Pointer selfDir = nativeLibrary.opendir( 139 | // '/proc/self/fd'.toNativeUtf8().cast(), 140 | // ); 141 | 142 | // if (selfDir.address != 0) { 143 | // final int selfDirFd = nativeLibrary.dirfd(selfDir); 144 | // Pointer entry = calloc(); 145 | // entry = nativeLibrary.readdir(selfDir); 146 | // while (entry != nullptr) { 147 | // final int fd = nativeLibrary.atoi(entry.ref.d_name); 148 | // if (fd > 2 && fd != selfDirFd) { 149 | // nativeLibrary.close(fd); 150 | // } 151 | // } 152 | 153 | // nativeLibrary.closedir(selfDir); 154 | // } 155 | // Log.d('初始化环境变量'); 156 | // print('test'); 157 | final Map platformEnvironment = Map.from( 158 | Platform.environment, 159 | ); 160 | for (final String key in environment.keys) { 161 | platformEnvironment[key] = environment[key]!; 162 | } 163 | 164 | for (int i = 0; i < platformEnvironment.keys.length; i++) { 165 | final String env = 166 | '${platformEnvironment.keys.elementAt(i)}=${platformEnvironment[platformEnvironment.keys.elementAt(i)]}'; 167 | nativeLibrary.putenv(env.toNativeUtf8().cast()); 168 | } 169 | 170 | final Pointer> argv = calloc>( 171 | fullArg.length + 1, 172 | ); 173 | // Log.e('fullArg -> $fullArg'); 174 | for (int i = 0; i < fullArg.length; i++) { 175 | argv[i] = fullArg[i].toNativeUtf8(); 176 | } 177 | argv[fullArg.length] = nullptr; 178 | if (nativeLibrary.chdir(workingDirectory.toNativeUtf8().cast()) != 0) { 179 | // nativeLibrary.perror('切换工作目录失败'.toNativeUtf8().cast()); 180 | // nativeLibrary.fflush(stderr); 181 | Log.e('切换工作目录失败'); 182 | // stdout.flush(); 183 | // stderr.write('\x1b[31m切换工作目录失败\x1b[0m'); 184 | // stderr.flush(); 185 | // stdout.write('切换工作目录失败'); 186 | // stdout.flush(); 187 | } 188 | nativeLibrary.execvp( 189 | executable.toNativeUtf8().cast(), 190 | argv.cast(), 191 | ); 192 | Log.e('执行$executable命令失败'); 193 | } 194 | } 195 | 196 | final _out = StreamController(); 197 | 198 | @override 199 | Stream? out; 200 | 201 | static const bufferLimit = 81920; 202 | 203 | @override 204 | Uint8List? readSync() => fd.read(bufferLimit); 205 | 206 | @override 207 | void write(String data) { 208 | final Pointer utf8Pointer = data.toNativeUtf8(); 209 | nativeLibrary.write( 210 | pseudoTerminalId, 211 | utf8Pointer.cast(), 212 | nativeLibrary.strlen(utf8Pointer.cast()), 213 | ); 214 | } 215 | 216 | @override 217 | String getTtyPath() { 218 | Pointer devname = calloc(); 219 | // 获得pts路径 220 | devname = nativeLibrary.ptsname(pseudoTerminalId); 221 | final String result = devname.cast().toDartString(); 222 | // 下面代码引发crash 223 | // calloc.free(devname); 224 | return result; 225 | } 226 | 227 | @override 228 | void resize(int row, int column) { 229 | print('$this resize'); 230 | final Pointer size = calloc(); 231 | size.ref.ws_row = row; 232 | size.ref.ws_col = column; 233 | nativeLibrary.ioctl( 234 | pseudoTerminalId, 235 | Platform.isAndroid ? TIOCSWINSZ_ANDROID : TIOCSWINSZ, 236 | size, 237 | ); 238 | } 239 | 240 | @override 241 | Uint8List? read() { 242 | return readSync(); 243 | } 244 | 245 | bool pollingIsStart = false; 246 | @override 247 | void startPolling() { 248 | _startPolling(); 249 | } 250 | 251 | SendPort? sendPort; 252 | Future _startPolling() async { 253 | if (pollingIsStart) { 254 | return; 255 | } 256 | pollingIsStart = true; 257 | if (useIsolate) { 258 | final ReceivePort receivePort = ReceivePort(); 259 | receivePort.listen((dynamic msg) { 260 | // Log.e('msg -> $msg ${msg.runtimeType}'); 261 | if (sendPort == null) { 262 | sendPort = msg as SendPort; 263 | // 先让子 isolate 先读一次数据 264 | sendPort?.send(true); 265 | } else { 266 | _out.sink.add(msg as String); 267 | } 268 | }); 269 | readIsolate = await Isolate.spawn<_IsolateArgs>( 270 | isolateRead, 271 | _IsolateArgs(receivePort.sendPort, pseudoTerminalId), 272 | ); 273 | // Log.e('readIsolate -> $readIsolate'); 274 | // readIsolate.kill() 275 | return; 276 | } 277 | final input = StreamController>(sync: true); 278 | input.stream.transform(utf8.decoder).listen(_out.sink.add); 279 | while (true) { 280 | // Log.w('轮训...'); 281 | final Uint8List? list = readSync(); 282 | if (list != null) { 283 | input.sink.add(list); 284 | } 285 | await Future.delayed(const Duration(milliseconds: 20)); 286 | } 287 | } 288 | 289 | @override 290 | void schedulingRead() { 291 | sendPort?.send(true); 292 | } 293 | 294 | @override 295 | void close() { 296 | sendPort?.send(false); 297 | readIsolate?.kill(priority: Isolate.immediate); 298 | nativeLibrary.kill(pid, SIGKILL); 299 | } 300 | } 301 | 302 | class _IsolateArgs { 303 | _IsolateArgs( 304 | this.sendPort, 305 | this.arg, 306 | ); 307 | 308 | final SendPort sendPort; 309 | final T arg; 310 | } 311 | 312 | // 新isolate的入口函数 313 | Future isolateRead(_IsolateArgs args) async { 314 | // 实例化一个ReceivePort 以接收消息 315 | final ReceivePort receivePort = ReceivePort(); 316 | // 把它的sendPort发送给宿主isolate,以便宿主可以给它发送消息 317 | args.sendPort.send(receivePort.sendPort); 318 | final FileDescriptor fd = FileDescriptor(args.arg as int, nativeLibrary); 319 | 320 | final input = StreamController>(sync: true); 321 | 322 | input.stream.transform(utf8.decoder).listen(args.sendPort.send); 323 | 324 | await for (final dynamic action in receivePort) { 325 | if (!(action as bool)) { 326 | Log.w('收到退出指令'); 327 | break; 328 | } 329 | final Uint8List? result = fd.read(81920); 330 | // Log.w('读取...$result'); 331 | if (result != null) { 332 | input.sink.add(result); 333 | } 334 | } 335 | } 336 | -------------------------------------------------------------------------------- /ffigen/simple/headers/wait.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 29 | /* 30 | * Copyright (c) 1982, 1986, 1989, 1993, 1994 31 | * The Regents of the University of California. All rights reserved. 32 | * 33 | * Redistribution and use in source and binary forms, with or without 34 | * modification, are permitted provided that the following conditions 35 | * are met: 36 | * 1. Redistributions of source code must retain the above copyright 37 | * notice, this list of conditions and the following disclaimer. 38 | * 2. Redistributions in binary form must reproduce the above copyright 39 | * notice, this list of conditions and the following disclaimer in the 40 | * documentation and/or other materials provided with the distribution. 41 | * 3. All advertising materials mentioning features or use of this software 42 | * must display the following acknowledgement: 43 | * This product includes software developed by the University of 44 | * California, Berkeley and its contributors. 45 | * 4. Neither the name of the University nor the names of its contributors 46 | * may be used to endorse or promote products derived from this software 47 | * without specific prior written permission. 48 | * 49 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 | * SUCH DAMAGE. 60 | * 61 | * @(#)wait.h 8.2 (Berkeley) 7/10/94 62 | */ 63 | 64 | #ifndef _SYS_WAIT_H_ 65 | #define _SYS_WAIT_H_ 66 | 67 | #include 68 | #include 69 | 70 | /* 71 | * This file holds definitions relevent to the wait4 system call 72 | * and the alternate interfaces that use it (wait, wait3, waitpid). 73 | */ 74 | 75 | /* 76 | * [XSI] The type idtype_t shall be defined as an enumeration type whose 77 | * possible values shall include at least P_ALL, P_PID, and P_PGID. 78 | */ 79 | typedef enum { 80 | P_ALL, 81 | P_PID, 82 | P_PGID 83 | } idtype_t; 84 | 85 | /* 86 | * [XSI] The id_t and pid_t types shall be defined as described 87 | * in 88 | */ 89 | #include 90 | #include 91 | 92 | /* 93 | * [XSI] The siginfo_t type shall be defined as described in 94 | * [XSI] The rusage structure shall be defined as described in 95 | * [XSI] Inclusion of the header may also make visible all 96 | * symbols from and 97 | * 98 | * NOTE: This requirement is currently being satisfied by the direct 99 | * inclusion of and , below. 100 | * 101 | * Software should not depend on the exposure of anything other 102 | * than the types siginfo_t and struct rusage as a result of 103 | * this inclusion. If you depend on any types or manifest 104 | * values othe than siginfo_t and struct rusage from either of 105 | * those files, you should explicitly include them yourself, as 106 | * well, or in future releases your stware may not compile 107 | * without modification. 108 | */ 109 | #include /* [XSI] for siginfo_t */ 110 | #include /* [XSI] for struct rusage */ 111 | 112 | /* 113 | * Option bits for the third argument of wait4. WNOHANG causes the 114 | * wait to not hang if there are no stopped or terminated processes, rather 115 | * returning an error indication in this case (pid==0). WUNTRACED 116 | * indicates that the caller should receive status about untraced children 117 | * which stop due to signals. If children are stopped and a wait without 118 | * this option is done, it is as though they were still running... nothing 119 | * about them is returned. 120 | */ 121 | #define WNOHANG 0x00000001 /* [XSI] no hang in wait/no child to reap */ 122 | #define WUNTRACED 0x00000002 /* [XSI] notify on stop, untraced child */ 123 | 124 | /* 125 | * Macros to test the exit status returned by wait 126 | * and extract the relevant values. 127 | */ 128 | #if defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE) 129 | #define _W_INT(i) (i) 130 | #else 131 | #define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */ 132 | #define WCOREFLAG 0200 133 | #endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ 134 | 135 | /* These macros are permited, as they are in the implementation namespace */ 136 | #define _WSTATUS(x) (_W_INT(x) & 0177) 137 | #define _WSTOPPED 0177 /* _WSTATUS if process is stopped */ 138 | 139 | /* 140 | * [XSI] The header shall define the following macros for 141 | * analysis of process status values 142 | */ 143 | #if __DARWIN_UNIX03 144 | #define WEXITSTATUS(x) ((_W_INT(x) >> 8) & 0x000000ff) 145 | #else /* !__DARWIN_UNIX03 */ 146 | #define WEXITSTATUS(x) (_W_INT(x) >> 8) 147 | #endif /* !__DARWIN_UNIX03 */ 148 | /* 0x13 == SIGCONT */ 149 | #define WSTOPSIG(x) (_W_INT(x) >> 8) 150 | #define WIFCONTINUED(x) (_WSTATUS(x) == _WSTOPPED && WSTOPSIG(x) == 0x13) 151 | #define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED && WSTOPSIG(x) != 0x13) 152 | #define WIFEXITED(x) (_WSTATUS(x) == 0) 153 | #define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0) 154 | #define WTERMSIG(x) (_WSTATUS(x)) 155 | #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 156 | #define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG) 157 | 158 | #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) 159 | #define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED) 160 | #endif /* (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ 161 | 162 | /* 163 | * [XSI] The following symbolic constants shall be defined as possible 164 | * values for the fourth argument to waitid(). 165 | */ 166 | /* WNOHANG already defined for wait4() */ 167 | /* WUNTRACED defined for wait4() but not for waitid() */ 168 | #define WEXITED 0x00000004 /* [XSI] Processes which have exitted */ 169 | #if __DARWIN_UNIX03 170 | /* waitid() parameter */ 171 | #define WSTOPPED 0x00000008 /* [XSI] Any child stopped by signal */ 172 | #endif 173 | #define WCONTINUED 0x00000010 /* [XSI] Any child stopped then continued */ 174 | #define WNOWAIT 0x00000020 /* [XSI] Leave process returned waitable */ 175 | 176 | 177 | #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 178 | /* POSIX extensions and 4.2/4.3 compatability: */ 179 | 180 | /* 181 | * Tokens for special values of the "pid" parameter to wait4. 182 | */ 183 | #define WAIT_ANY (-1) /* any process */ 184 | #define WAIT_MYPGRP 0 /* any process in my process group */ 185 | 186 | #include 187 | 188 | /* 189 | * Deprecated: 190 | * Structure of the information in the status word returned by wait4. 191 | * If w_stopval==_WSTOPPED, then the second structure describes 192 | * the information returned, else the first. 193 | */ 194 | union wait { 195 | int w_status; /* used in syscall */ 196 | /* 197 | * Terminated process status. 198 | */ 199 | struct { 200 | #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN 201 | unsigned int w_Termsig:7, /* termination signal */ 202 | w_Coredump:1, /* core dump indicator */ 203 | w_Retcode:8, /* exit code if w_termsig==0 */ 204 | w_Filler:16; /* upper bits filler */ 205 | #endif 206 | #if __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN 207 | unsigned int w_Filler:16, /* upper bits filler */ 208 | w_Retcode:8, /* exit code if w_termsig==0 */ 209 | w_Coredump:1, /* core dump indicator */ 210 | w_Termsig:7; /* termination signal */ 211 | #endif 212 | } w_T; 213 | /* 214 | * Stopped process status. Returned 215 | * only for traced children unless requested 216 | * with the WUNTRACED option bit. 217 | */ 218 | struct { 219 | #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN 220 | unsigned int w_Stopval:8, /* == W_STOPPED if stopped */ 221 | w_Stopsig:8, /* signal that stopped us */ 222 | w_Filler:16; /* upper bits filler */ 223 | #endif 224 | #if __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN 225 | unsigned int w_Filler:16, /* upper bits filler */ 226 | w_Stopsig:8, /* signal that stopped us */ 227 | w_Stopval:8; /* == W_STOPPED if stopped */ 228 | #endif 229 | } w_S; 230 | }; 231 | #define w_termsig w_T.w_Termsig 232 | #define w_coredump w_T.w_Coredump 233 | #define w_retcode w_T.w_Retcode 234 | #define w_stopval w_S.w_Stopval 235 | #define w_stopsig w_S.w_Stopsig 236 | 237 | #endif /* (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ 238 | 239 | #if !(__DARWIN_UNIX03 - 0) 240 | /* 241 | * Stopped state value; cannot use waitid() parameter of the same name 242 | * in the same scope 243 | */ 244 | #define WSTOPPED _WSTOPPED 245 | #endif /* !__DARWIN_UNIX03 */ 246 | 247 | __BEGIN_DECLS 248 | pid_t wait(int *) __DARWIN_ALIAS_C(wait); 249 | pid_t waitpid(pid_t, int *, int) __DARWIN_ALIAS_C(waitpid); 250 | #ifndef _ANSI_SOURCE 251 | int waitid(idtype_t, id_t, siginfo_t *, int) __DARWIN_ALIAS_C(waitid); 252 | #endif /* !_ANSI_SOURCE */ 253 | #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 254 | pid_t wait3(int *, int, struct rusage *); 255 | pid_t wait4(pid_t, int *, int, struct rusage *); 256 | #endif /* (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ 257 | __END_DECLS 258 | #endif /* !_SYS_WAIT_H_ */ 259 | -------------------------------------------------------------------------------- /lib/src/win_pty.dart: -------------------------------------------------------------------------------- 1 | // import 'dart:async'; 2 | // import 'dart:ffi'; 3 | // import 'dart:io'; 4 | // import 'dart:typed_data'; 5 | 6 | // import 'package:ffi/ffi.dart'; 7 | // // import 'package:pty/src/util/win32_additional.dart'; 8 | // import 'package:win32/win32.dart' as win32; 9 | 10 | // import 'interface/pseudo_terminal_interface.dart'; 11 | 12 | // class _NamedPipe { 13 | // _NamedPipe({bool nowait = false}) { 14 | // final pipeName = r'\\.\pipe\dart-pty-pipe'; 15 | // final pPipeName = pipeName.toNativeUtf16(); 16 | 17 | // final waitMode = nowait ? win32.PIPE_NOWAIT : win32.PIPE_WAIT; 18 | 19 | // final namedPipe = win32.CreateNamedPipe( 20 | // pPipeName, 21 | // win32.PIPE_ACCESS_DUPLEX, 22 | // waitMode | win32.PIPE_READMODE_MESSAGE | win32.PIPE_TYPE_MESSAGE, 23 | // win32.PIPE_UNLIMITED_INSTANCES, 24 | // 4096, 25 | // 4096, 26 | // 0, 27 | // nullptr, 28 | // ); 29 | 30 | // if (namedPipe == win32.INVALID_HANDLE_VALUE) { 31 | // throw PtyException('CreateNamedPipe failed: ${win32.GetLastError()}'); 32 | // } 33 | 34 | // final namedPipeClient = win32.CreateFile( 35 | // pPipeName, 36 | // win32.GENERIC_READ | win32.GENERIC_WRITE, 37 | // 0, // no sharing 38 | // nullptr, // default security attributes 39 | // win32.OPEN_EXISTING, // opens existing pipe , 40 | // 0, // default attributes 41 | // 0, // no template file 42 | // ); 43 | // calloc.free(pPipeName); 44 | 45 | // if (namedPipeClient == win32.INVALID_HANDLE_VALUE) { 46 | // throw PtyException('CreateFile on named pipe failed'); 47 | // } 48 | 49 | // readSide = namedPipe; 50 | // writeSide = namedPipeClient; 51 | // } 52 | 53 | // late final int readSide; 54 | // late final int writeSide; 55 | // } 56 | 57 | // class WinPty implements PseudoTerminal { 58 | // WinPty({ 59 | // required this.rowLen, 60 | // required this.columnLen, 61 | // String? executable, 62 | // List arguments = const [], 63 | // String? workingDirectory, 64 | // Map environment = const {}, 65 | // bool blocking = false, 66 | // }) { 67 | // // create input pipe 68 | // out = _out.stream.asBroadcastStream(); 69 | // final hReadPipe = calloc(); 70 | // final hWritePipe = calloc(); 71 | // final pipe2 = win32.CreatePipe(hReadPipe, hWritePipe, nullptr, 512); 72 | // if (pipe2 == win32.INVALID_HANDLE_VALUE) { 73 | // throw PtyException('CreatePipe failed: ${win32.GetLastError()}'); 74 | // } 75 | // final inputWriteSide = hWritePipe.value; 76 | // final inputReadSide = hReadPipe.value; 77 | 78 | // // create output pipe 79 | // final pipe1 = _NamedPipe(nowait: !blocking); 80 | // final outputReadSide = pipe1.readSide; 81 | // final outputWriteSide = pipe1.writeSide; 82 | 83 | // // final pipe2 = _NamedPipe(nowait: false); 84 | // // final inputWriteSide = pipe2.writeSide; 85 | // // final inputReadSide = pipe2.readSide; 86 | 87 | // // create pty 88 | // final hPty = calloc(); 89 | // final size = calloc().ref; 90 | // size.X = 80; 91 | // size.Y = 25; 92 | // final hr = win32.CreatePseudoConsole( 93 | // size, 94 | // inputReadSide, 95 | // outputWriteSide, 96 | // 0, 97 | // hPty, 98 | // ); 99 | 100 | // if (win32.FAILED(hr)) { 101 | // throw PtyException('CreatePseudoConsole failed.'); 102 | // } 103 | 104 | // // Setup startup info 105 | // final si = calloc(); 106 | // si.ref.StartupInfo.cb = sizeOf(); 107 | 108 | // // Explicitly set stdio of the child process to NULL. This is required for 109 | // // ConPTY to work properly. 110 | // si.ref.StartupInfo.hStdInput = nullptr.address; 111 | // si.ref.StartupInfo.hStdOutput = nullptr.address; 112 | // si.ref.StartupInfo.hStdError = nullptr.address; 113 | // si.ref.StartupInfo.dwFlags = win32.STARTF_USESTDHANDLES; 114 | 115 | // final bytesRequired = calloc(); 116 | // win32.InitializeProcThreadAttributeList(nullptr, 1, 0, bytesRequired); 117 | // si.ref.lpAttributeList = calloc(bytesRequired.value); 118 | 119 | // var ret = win32.InitializeProcThreadAttributeList( 120 | // si.ref.lpAttributeList, 1, 0, bytesRequired); 121 | 122 | // if (ret == win32.FALSE) { 123 | // throw PtyException('InitializeProcThreadAttributeList failed.'); 124 | // } 125 | 126 | // // use pty 127 | // ret = win32.UpdateProcThreadAttribute( 128 | // si.ref.lpAttributeList, 129 | // 0, 130 | // win32.PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, 131 | // Pointer.fromAddress(hPty.value), 132 | // sizeOf(), 133 | // nullptr, 134 | // nullptr, 135 | // ); 136 | 137 | // if (ret == win32.FALSE) { 138 | // throw PtyException('UpdateProcThreadAttribute failed.'); 139 | // } 140 | 141 | // // build command line 142 | // final commandBuffer = StringBuffer(); 143 | // commandBuffer.write(executable); 144 | // if (arguments.isNotEmpty) { 145 | // for (var argument in arguments) { 146 | // commandBuffer.write(' '); 147 | // commandBuffer.write(argument); 148 | // } 149 | // } 150 | // final pCommandLine = commandBuffer.toString().toNativeUtf16(); 151 | 152 | // // build current directory 153 | // Pointer pCurrentDirectory = nullptr; 154 | // if (workingDirectory != null) { 155 | // pCurrentDirectory = workingDirectory.toNativeUtf16(); 156 | // } 157 | 158 | // // build environment 159 | // Pointer pEnvironment = nullptr; 160 | // if (environment != null && environment.isNotEmpty) { 161 | // final buffer = StringBuffer(); 162 | 163 | // for (var env in environment.entries) { 164 | // buffer.write(env.key); 165 | // buffer.write('='); 166 | // buffer.write(env.value); 167 | // buffer.write('\u0000'); 168 | // } 169 | 170 | // pEnvironment = buffer.toString().toNativeUtf16(); 171 | // } 172 | 173 | // // start the process. 174 | // final pi = calloc(); 175 | // ret = win32.CreateProcess( 176 | // nullptr, 177 | // pCommandLine, 178 | // nullptr, 179 | // nullptr, 180 | // win32.FALSE, 181 | // win32.EXTENDED_STARTUPINFO_PRESENT | win32.CREATE_UNICODE_ENVIRONMENT, 182 | // // pass pEnvironment here causes crash 183 | // // TODO: fix this 184 | // // pEnvironment, 185 | // nullptr, 186 | // pCurrentDirectory, 187 | // si.cast(), 188 | // pi, 189 | // ); 190 | 191 | // calloc.free(pCommandLine); 192 | 193 | // if (pCurrentDirectory != nullptr) { 194 | // calloc.free(pCurrentDirectory); 195 | // } 196 | 197 | // if (pEnvironment != nullptr) { 198 | // calloc.free(pEnvironment); 199 | // } 200 | 201 | // if (ret == 0) { 202 | // throw PtyException('CreateProcess failed: ${win32.GetLastError()}'); 203 | // } 204 | // _inputWriteSide = inputWriteSide; 205 | // _outputReadSide = outputReadSide; 206 | // _hPty = hPty.value; 207 | // _hProcess = pi.ref.hProcess; 208 | // } 209 | 210 | // final int rowLen; 211 | // final int columnLen; 212 | // late int _inputWriteSide; 213 | // late int _outputReadSide; 214 | // late int _hPty; 215 | // late int _hProcess; 216 | 217 | // static const _bufferSize = 4096; 218 | // final _buffer = calloc(_bufferSize + 1).address; 219 | 220 | // @override 221 | // Future> read() async { 222 | // return readSync(); 223 | // } 224 | 225 | // @override 226 | // int? exitCodeNonBlocking() { 227 | // final exitCodePtr = calloc(); 228 | // final ret = win32.GetExitCodeProcess(_hProcess, exitCodePtr); 229 | 230 | // final exitCode = exitCodePtr.value; 231 | // calloc.free(exitCodePtr); 232 | 233 | // const STILL_ACTIVE = 259; 234 | // if (ret == 0 || exitCode == STILL_ACTIVE) { 235 | // return null; 236 | // } 237 | 238 | // return exitCode; 239 | // } 240 | 241 | // @override 242 | // int exitCodeBlocking() { 243 | // const n = 1; 244 | // final pid = calloc(n); 245 | // final infinite = 0xFFFFFFFF; 246 | // pid.elementAt(0).value = _hProcess; 247 | // win32.MsgWaitForMultipleObjects(n, pid, 1, infinite, win32.QS_ALLEVENTS); 248 | // return pid.elementAt(0).value; 249 | // } 250 | 251 | // @override 252 | // bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { 253 | // final ret = win32.TerminateProcess(_hProcess, nullptr.address); 254 | // win32.ClosePseudoConsole(_hPty); 255 | // return ret != 0; 256 | // } 257 | 258 | // @override 259 | // void resize(int width, int height) { 260 | // final size = calloc(); 261 | // size.ref.X = height; 262 | // size.ref.Y = width; 263 | // final hr = win32.ResizePseudoConsole(_hPty, size.ref); 264 | // if (win32.FAILED(hr)) { 265 | // throw PtyException('ResizePseudoConsole failed.'); 266 | // } 267 | // calloc.free(size); 268 | // } 269 | 270 | // // @override 271 | // // int get pid { 272 | // // return _hProcess; 273 | // // } 274 | 275 | // @override 276 | // void write(String data) { 277 | // final buffer = data.toNativeUtf8(); 278 | // final written = calloc(); 279 | // win32.WriteFile(_inputWriteSide, buffer, data.length, written, nullptr); 280 | // calloc.free(buffer); 281 | // calloc.free(written); 282 | // } 283 | 284 | // @override 285 | // Stream>? out; 286 | 287 | // @override 288 | // late int pseudoTerminalId; 289 | 290 | // @override 291 | // String getTtyPath() { 292 | // // TODO: implement getTtyPath 293 | // throw UnimplementedError(); 294 | // } 295 | 296 | // @override 297 | // Uint8List? readSync() { 298 | // final pReadlen = calloc(); 299 | // final buffer = Pointer.fromAddress(_buffer); 300 | // final ret = win32.ReadFile( 301 | // _outputReadSide, 302 | // buffer, 303 | // _bufferSize, 304 | // pReadlen, 305 | // nullptr, 306 | // ); 307 | 308 | // final readlen = pReadlen.value; 309 | // calloc.free(pReadlen); 310 | 311 | // if (ret == 0) { 312 | // return []; 313 | // } 314 | 315 | // if (readlen <= 0) { 316 | // return []; 317 | // } else { 318 | // return buffer.cast().asTypedList(readlen); 319 | // } 320 | // } 321 | 322 | // @override 323 | // void startPolling() { 324 | // _startPolling(); 325 | // } 326 | 327 | // final _out = StreamController>(); 328 | // Future _startPolling() async { 329 | // while (true) { 330 | // final List list = readSync(); 331 | // if (list.isNotEmpty) { 332 | // _out.sink.add(list); 333 | // } 334 | // await Future.delayed(const Duration(milliseconds: 20)); 335 | // } 336 | // } 337 | // } 338 | 339 | // // void rawWait(int hProcess) { 340 | // // // final status = allocate(); 341 | // // // unistd.waitpid(pid, status, 0); 342 | // // final count = 1; 343 | // // final pids = calloc(count); 344 | // // final infinite = 0xFFFFFFFF; 345 | // // pids.elementAt(0).value = hProcess; 346 | // // win32.MsgWaitForMultipleObjects(count, pids, 1, infinite, win32.QS_ALLEVENTS); 347 | // // } 348 | // class PtyException implements Exception { 349 | // PtyException(this.message); 350 | 351 | // final String message; 352 | 353 | // @override 354 | // String toString() { 355 | // return message; 356 | // } 357 | // } 358 | -------------------------------------------------------------------------------- /lib/src/unix_pty_c.dart: -------------------------------------------------------------------------------- 1 | // // 整个代码是c写的,dart负责调用 2 | // import 'dart:async'; 3 | // import 'dart:convert'; 4 | // import 'dart:ffi'; 5 | // import 'dart:io'; 6 | // import 'dart:isolate'; 7 | // import 'dart:typed_data'; 8 | 9 | // import 'package:dart_pty/dart_pty.dart'; 10 | // import 'package:dart_pty/src/proc.dart'; 11 | // import 'package:ffi/ffi.dart'; 12 | // import 'package:signale/signale.dart'; 13 | 14 | // import 'foundation/file_descriptor.dart'; 15 | // import 'interface/pseudo_terminal_interface.dart'; 16 | // import 'native_header/generated_bindings.dart'; 17 | // import 'unix/termare_native.dart'; 18 | // import 'unix_proc.dart'; 19 | // import 'utils/custom_utf.dart'; 20 | 21 | // // 这个需要配合c语言实现 22 | // // 已经不需要了,待纯 dart 调用底层 api 稳定后移除 23 | 24 | // void dartCallback(Pointer int8) { 25 | // Pointer utf8Pointer = int8.cast(); 26 | // print(utf8Pointer.toDartString()); 27 | // } 28 | 29 | // class UnixPtyC implements PseudoTerminal { 30 | // UnixPtyC({ 31 | // required this.rowLen, 32 | // required this.columnLen, 33 | // this.libPath, 34 | // String? executable, 35 | // String workingDirectory = '', 36 | // List arguments = const [], 37 | // Map environment = const {}, 38 | // }) { 39 | // release = true | 40 | // const bool.fromEnvironment( 41 | // 'dart.vm.product', 42 | // defaultValue: false, 43 | // ); 44 | // out = _out.stream.asBroadcastStream(); 45 | // DynamicLibrary dynamicLibrary; 46 | // if (libPath != null) { 47 | // dynamicLibrary = DynamicLibrary.open(libPath!); 48 | // } else { 49 | // dynamicLibrary = DynamicLibrary.process(); 50 | // } 51 | 52 | // termareNative = TermareNative(dynamicLibrary); 53 | // final Pointer> callback = 54 | // Pointer.fromFunction(dartCallback); 55 | // termareNative.init_dart_print(callback); 56 | // pseudoTerminalId = createPseudoTerminal(); 57 | // fd = FileDescriptor(pseudoTerminalId, nativeLibrary); 58 | // _createSubprocess( 59 | // executable!, 60 | // workingDirectory: workingDirectory, 61 | // arguments: arguments, 62 | // environment: environment, 63 | // ); 64 | // if (!release) { 65 | // int flag = -1; 66 | // flag = nativeLibrary.fcntl(fd.fd, F_GETFL, 0); //获取当前flag 67 | // Log.d('>>>>>>>> 当前flag = $flag'); 68 | // flag |= O_NONBLOCK; //设置新falg 69 | // Log.d('>>>>>>>> 设置新flag = $flag'); 70 | // // nativeLibrary.fcntl(fd.fd, F_SETFL, flag); //更新flag 71 | // termareNative.setNonblock(pseudoTerminalId); 72 | // flag = nativeLibrary.fcntl(fd.fd, F_GETFL, 0); //获取当前flag 73 | // Log.d('>>>>>>>> 再次获取到的flag = $flag'); 74 | // } 75 | // Log.d('<- pseudoTerminalId : $pseudoTerminalId ->'); 76 | // } 77 | // // 创建一个pty,返回它的ptm文本描述符,这个ptm在之后的读写,fork子进程还会用到 78 | // int createPseudoTerminal({bool verbose = true}) { 79 | // Log.d('Create Start'); 80 | // final ptmxPath = '/dev/ptmx'.toNativeUtf8(); 81 | // final int ptm = nativeLibrary.open( 82 | // ptmxPath.cast(), 83 | // O_RDWR | O_CLOEXEC, 84 | // ); 85 | // if (nativeLibrary.grantpt(ptm) != 0 || nativeLibrary.unlockpt(ptm) != 0) { 86 | // // 说明二者有一个失败 87 | // print('Cannot grantpt()/unlockpt()/ptsname_r() on /dev/ptmx'); 88 | // return -1; 89 | // } 90 | // final Pointer tios = calloc(); 91 | // // addressOf 可以获取指针 92 | // nativeLibrary.tcgetattr(ptm, tios); 93 | // tios.ref.c_iflag |= IUTF8; 94 | // tios.ref.c_iflag &= ~(IXON | IXOFF); 95 | // nativeLibrary.tcsetattr(ptm, TCSANOW, tios); 96 | // // free(tios); 97 | // // =========== 设置终端大小 ============= 98 | // final Pointer size = calloc(); 99 | // size.ref.ws_row = rowLen; 100 | // size.ref.ws_col = columnLen; 101 | // nativeLibrary.ioctl( 102 | // ptm, 103 | // TIOCSWINSZ, 104 | // size, 105 | // ); 106 | // calloc.free(size); 107 | // // free(ptmxPath); 108 | 109 | // Log.d('Create End'); 110 | 111 | // return ptm; 112 | // // nativeLibrary.grantpt() 113 | // } 114 | 115 | // late FileDescriptor fd; 116 | // late bool release; 117 | // final String? libPath; 118 | // final int rowLen; 119 | // final int columnLen; 120 | // late TermareNative termareNative; 121 | // static const bufferLimit = 81920; 122 | 123 | // @override 124 | // void write(String data) { 125 | // final Pointer utf8Pointer = data.toNativeUtf8(); 126 | // nativeLibrary.write( 127 | // pseudoTerminalId, 128 | // utf8Pointer.cast(), 129 | // nativeLibrary.strlen(utf8Pointer.cast()), 130 | // ); 131 | // } 132 | 133 | // @override 134 | // Uint8List? readSync() => fd.read(81920); 135 | 136 | // Proc? _createSubprocess( 137 | // String executable, { 138 | // String workingDirectory = '.', 139 | // List arguments = const [], 140 | // Map environment = const {}, 141 | // }) { 142 | // Pointer devname = calloc(1); 143 | // // 获得pts路径 144 | // devname = nativeLibrary.ptsname(pseudoTerminalId).cast(); 145 | // final int pid = nativeLibrary.fork(); 146 | // if (pid < 0) { 147 | // print('fork faild'); 148 | // } else if (pid > 0) { 149 | // print('fork 主进程'); 150 | 151 | // // 这里会返回子进程的pid 152 | // return UnixProc(pid); 153 | // } else { 154 | // print('fork 子进程'); 155 | // // Clear signals which the Android java process may have blocked: 156 | // final Pointer signalsToUnblock = calloc(); 157 | // // sigset_t signals_to_unblock; 158 | // nativeLibrary.sigfillset(signalsToUnblock); 159 | // nativeLibrary.sigprocmask( 160 | // SIG_UNBLOCK, 161 | // signalsToUnblock, 162 | // Pointer.fromAddress(0), 163 | // ); 164 | // nativeLibrary.close(pseudoTerminalId); 165 | // nativeLibrary.setsid(); 166 | // final int pts = nativeLibrary.open(devname, O_RDWR); 167 | // if (pts < 0) { 168 | // return null; 169 | // } 170 | // nativeLibrary.dup2(pts, 0); 171 | // nativeLibrary.dup2(pts, 1); 172 | // nativeLibrary.dup2(pts, 2); 173 | // // final Pointer selfDir = nativeLibrary.opendir( 174 | // // '/proc/self/fd'.toNativeUtf8().cast(), 175 | // // ); 176 | 177 | // // if (selfDir.address != 0) { 178 | // // final int selfDirFd = nativeLibrary.dirfd(selfDir); 179 | // // Pointer entry = calloc(); 180 | // // entry = nativeLibrary.readdir(selfDir); 181 | // // while (entry != nullptr) { 182 | // // final int fd = nativeLibrary.atoi(entry.ref.d_name); 183 | // // if (fd > 2 && fd != selfDirFd) { 184 | // // nativeLibrary.close(fd); 185 | // // } 186 | // // } 187 | 188 | // // nativeLibrary.closedir(selfDir); 189 | // // } 190 | // // Log.d('初始化环境变量'); 191 | // // print('test'); 192 | // final Map platformEnvironment = Map.from( 193 | // Platform.environment, 194 | // ); 195 | // for (final String key in environment.keys) { 196 | // platformEnvironment[key] = environment[key]!; 197 | // } 198 | 199 | // for (int i = 0; i < platformEnvironment.keys.length; i++) { 200 | // final String env = 201 | // '${platformEnvironment.keys.elementAt(i)}=${platformEnvironment[platformEnvironment.keys.elementAt(i)]}'; 202 | // nativeLibrary.putenv(env.toNativeUtf8().cast()); 203 | // } 204 | 205 | // final Pointer> argv = calloc>( 206 | // platformEnvironment.length + 1, 207 | // ); 208 | // for (int i = 0; i < arguments.length; i++) { 209 | // argv[i] = arguments[i].toNativeUtf8(); 210 | // } 211 | // if (nativeLibrary.chdir(workingDirectory.toNativeUtf8().cast()) != 0) { 212 | // Log.e('切换工作目录失败'); 213 | // } 214 | // nativeLibrary.execvp( 215 | // executable.toNativeUtf8().cast(), 216 | // argv.cast(), 217 | // ); 218 | // Log.e('执行$executable命令失败'); 219 | // } 220 | // } 221 | 222 | // @override 223 | // void resize(int row, int column) { 224 | // termareNative.setPtyWindowSize(pseudoTerminalId, row, column); 225 | // } 226 | 227 | // @override 228 | // Uint8List? read() { 229 | // return readSync(); 230 | // } 231 | 232 | // @override 233 | // String getTtyPath() { 234 | // Pointer devname = calloc(); 235 | // // 获得pts路径 236 | // devname = nativeLibrary.ptsname(pseudoTerminalId); 237 | // final String result = devname.cast().toDartString(); 238 | // // 下面代码引发crash 239 | // // calloc.free(devname); 240 | // return result; 241 | // } 242 | 243 | // @override 244 | // late int pseudoTerminalId; 245 | 246 | // final _out = StreamController(); 247 | 248 | // @override 249 | // void startPolling() { 250 | // _startPolling(); 251 | // } 252 | 253 | // SendPort? sendPort; 254 | // Future _startPolling() async { 255 | // if (release) { 256 | // final ReceivePort receivePort = ReceivePort(); 257 | // receivePort.listen((dynamic msg) { 258 | // if (sendPort == null) { 259 | // sendPort = msg as SendPort; 260 | // // 先让子 isolate 先读一次数据 261 | // sendPort?.send(true); 262 | // } else { 263 | // // Log.e('msg -> $msg'); 264 | // _out.sink.add(msg as String); 265 | // } 266 | // }); 267 | // Isolate.spawn<_IsolateArgs>( 268 | // isolateRead, 269 | // _IsolateArgs(receivePort.sendPort, pseudoTerminalId), 270 | // ); 271 | // return; 272 | // } 273 | // final input = StreamController>(sync: true); 274 | // input.stream.transform(utf8.decoder).listen(_out.sink.add); 275 | // while (true) { 276 | // // Log.w('轮训...'); 277 | // final Uint8List? list = readSync(); 278 | // if (list != null) { 279 | // input.sink.add(list); 280 | // } 281 | // await Future.delayed(const Duration(milliseconds: 20)); 282 | // } 283 | // } 284 | 285 | // @override 286 | // Stream? out; 287 | // @override 288 | // bool operator ==(dynamic other) { 289 | // // 判断是否是非 290 | // if (other is! PseudoTerminal) { 291 | // return false; 292 | // } 293 | // if (other is PseudoTerminal) { 294 | // return other.hashCode == hashCode; 295 | // } 296 | // return false; 297 | // } 298 | 299 | // @override 300 | // int get hashCode => pseudoTerminalId.hashCode; 301 | 302 | // @override 303 | // void schedulingRead() { 304 | // sendPort?.send(true); 305 | // } 306 | // } 307 | 308 | // class _IsolateArgs { 309 | // _IsolateArgs( 310 | // this.sendPort, 311 | // this.arg, 312 | // ); 313 | 314 | // final SendPort sendPort; 315 | // final T arg; 316 | // } 317 | 318 | // // 新isolate的入口函数 319 | // Future isolateRead(_IsolateArgs args) async { 320 | // // 实例化一个ReceivePort 以接收消息 321 | // final ReceivePort receivePort = ReceivePort(); 322 | // args.sendPort.send(receivePort.sendPort); 323 | // final FileDescriptor fd = FileDescriptor(args.arg as int, nativeLibrary); 324 | 325 | // final input = StreamController>(sync: true); 326 | 327 | // input.stream.transform(utf8.decoder).listen(args.sendPort.send); 328 | // // 把它的sendPort发送给宿主isolate,以便宿主可以给它发送消息 329 | 330 | // await for (final dynamic _ in receivePort) { 331 | // final Uint8List? result = fd.read(81920); 332 | // // Log.w('读取...$result'); 333 | // if (result != null) { 334 | // input.sink.add(result); 335 | // } 336 | // } 337 | // } 338 | -------------------------------------------------------------------------------- /ffigen/simple/headers/stdlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000, 2002 - 2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*- 24 | * Copyright (c) 1990, 1993 25 | * The Regents of the University of California. All rights reserved. 26 | * 27 | * Redistribution and use in source and binary forms, with or without 28 | * modification, are permitted provided that the following conditions 29 | * are met: 30 | * 1. Redistributions of source code must retain the above copyright 31 | * notice, this list of conditions and the following disclaimer. 32 | * 2. Redistributions in binary form must reproduce the above copyright 33 | * notice, this list of conditions and the following disclaimer in the 34 | * documentation and/or other materials provided with the distribution. 35 | * 3. All advertising materials mentioning features or use of this software 36 | * must display the following acknowledgement: 37 | * This product includes software developed by the University of 38 | * California, Berkeley and its contributors. 39 | * 4. Neither the name of the University nor the names of its contributors 40 | * may be used to endorse or promote products derived from this software 41 | * without specific prior written permission. 42 | * 43 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 | * SUCH DAMAGE. 54 | * 55 | * @(#)stdlib.h 8.5 (Berkeley) 5/19/95 56 | */ 57 | 58 | #ifndef _STDLIB_H_ 59 | #define _STDLIB_H_ 60 | 61 | #include 62 | #include 63 | 64 | #include <_types.h> 65 | #if !defined(_ANSI_SOURCE) 66 | #include 67 | #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 68 | #include 69 | #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ 70 | #endif /* !_ANSI_SOURCE */ 71 | 72 | /* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: 73 | * _GCC_SIZE_T */ 74 | #include 75 | 76 | #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 77 | #include 78 | #include 79 | #endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ 80 | 81 | #include 82 | 83 | typedef struct { 84 | int quot; /* quotient */ 85 | int rem; /* remainder */ 86 | } div_t; 87 | 88 | typedef struct { 89 | long quot; /* quotient */ 90 | long rem; /* remainder */ 91 | } ldiv_t; 92 | 93 | #if !__DARWIN_NO_LONG_LONG 94 | typedef struct { 95 | long long quot; 96 | long long rem; 97 | } lldiv_t; 98 | #endif /* !__DARWIN_NO_LONG_LONG */ 99 | 100 | #include 101 | 102 | #define EXIT_FAILURE 1 103 | #define EXIT_SUCCESS 0 104 | 105 | #define RAND_MAX 0x7fffffff 106 | 107 | #ifdef _USE_EXTENDED_LOCALES_ 108 | #include <_xlocale.h> 109 | #endif /* _USE_EXTENDED_LOCALES_ */ 110 | 111 | #ifndef MB_CUR_MAX 112 | #ifdef _USE_EXTENDED_LOCALES_ 113 | #define MB_CUR_MAX (___mb_cur_max()) 114 | #ifndef MB_CUR_MAX_L 115 | #define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) 116 | #endif /* !MB_CUR_MAX_L */ 117 | #else /* !_USE_EXTENDED_LOCALES_ */ 118 | extern int __mb_cur_max; 119 | #define MB_CUR_MAX __mb_cur_max 120 | #endif /* _USE_EXTENDED_LOCALES_ */ 121 | #endif /* MB_CUR_MAX */ 122 | 123 | #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) \ 124 | && defined(_USE_EXTENDED_LOCALES_) && !defined(MB_CUR_MAX_L) 125 | #define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) 126 | #endif 127 | 128 | #include 129 | 130 | __BEGIN_DECLS 131 | void abort(void) __cold __dead2; 132 | int abs(int) __pure2; 133 | int atexit(void (* _Nonnull)(void)); 134 | double atof(const char *); 135 | int atoi(const char *); 136 | long atol(const char *); 137 | #if !__DARWIN_NO_LONG_LONG 138 | long long 139 | atoll(const char *); 140 | #endif /* !__DARWIN_NO_LONG_LONG */ 141 | void *bsearch(const void *__key, const void *__base, size_t __nel, 142 | size_t __width, int (* _Nonnull __compar)(const void *, const void *)); 143 | /* calloc is now declared in _malloc.h */ 144 | div_t div(int, int) __pure2; 145 | void exit(int) __dead2; 146 | /* free is now declared in _malloc.h */ 147 | char *getenv(const char *); 148 | long labs(long) __pure2; 149 | ldiv_t ldiv(long, long) __pure2; 150 | #if !__DARWIN_NO_LONG_LONG 151 | long long 152 | llabs(long long); 153 | lldiv_t lldiv(long long, long long); 154 | #endif /* !__DARWIN_NO_LONG_LONG */ 155 | /* malloc is now declared in _malloc.h */ 156 | int mblen(const char *__s, size_t __n); 157 | size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); 158 | int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); 159 | /* posix_memalign is now declared in _malloc.h */ 160 | void qsort(void *__base, size_t __nel, size_t __width, 161 | int (* _Nonnull __compar)(const void *, const void *)); 162 | int rand(void) __swift_unavailable("Use arc4random instead."); 163 | /* realloc is now declared in _malloc.h */ 164 | void srand(unsigned) __swift_unavailable("Use arc4random instead."); 165 | double strtod(const char *, char **) __DARWIN_ALIAS(strtod); 166 | float strtof(const char *, char **) __DARWIN_ALIAS(strtof); 167 | long strtol(const char *__str, char **__endptr, int __base); 168 | long double 169 | strtold(const char *, char **); 170 | #if !__DARWIN_NO_LONG_LONG 171 | long long 172 | strtoll(const char *__str, char **__endptr, int __base); 173 | #endif /* !__DARWIN_NO_LONG_LONG */ 174 | unsigned long 175 | strtoul(const char *__str, char **__endptr, int __base); 176 | #if !__DARWIN_NO_LONG_LONG 177 | unsigned long long 178 | strtoull(const char *__str, char **__endptr, int __base); 179 | #endif /* !__DARWIN_NO_LONG_LONG */ 180 | 181 | #if TARGET_OS_IPHONE 182 | #define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(ios_msg) 183 | #else 184 | #define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(osx_msg) 185 | #endif 186 | 187 | __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable") 188 | __API_AVAILABLE(macos(10.0)) __IOS_PROHIBITED 189 | __WATCHOS_PROHIBITED __TVOS_PROHIBITED 190 | int system(const char *) __DARWIN_ALIAS_C(system); 191 | 192 | #undef __swift_unavailable_on 193 | 194 | size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); 195 | int wctomb(char *, wchar_t); 196 | 197 | #ifndef _ANSI_SOURCE 198 | void _Exit(int) __dead2; 199 | long a64l(const char *); 200 | double drand48(void); 201 | char *ecvt(double, int, int *__restrict, int *__restrict); /* LEGACY */ 202 | double erand48(unsigned short[3]); 203 | char *fcvt(double, int, int *__restrict, int *__restrict); /* LEGACY */ 204 | char *gcvt(double, int, char *); /* LEGACY */ 205 | int getsubopt(char **, char * const *, char **); 206 | int grantpt(int); 207 | #if __DARWIN_UNIX03 208 | char *initstate(unsigned, char *, size_t); /* no __DARWIN_ALIAS needed */ 209 | #else /* !__DARWIN_UNIX03 */ 210 | char *initstate(unsigned long, char *, long); 211 | #endif /* __DARWIN_UNIX03 */ 212 | long jrand48(unsigned short[3]) __swift_unavailable("Use arc4random instead."); 213 | char *l64a(long); 214 | void lcong48(unsigned short[7]); 215 | long lrand48(void) __swift_unavailable("Use arc4random instead."); 216 | char *mktemp(char *); 217 | int mkstemp(char *); 218 | long mrand48(void) __swift_unavailable("Use arc4random instead."); 219 | long nrand48(unsigned short[3]) __swift_unavailable("Use arc4random instead."); 220 | int posix_openpt(int); 221 | char *ptsname(int); 222 | 223 | #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 224 | int ptsname_r(int fildes, char *buffer, size_t buflen) __API_AVAILABLE(macos(10.13.4), ios(11.3), tvos(11.3), watchos(4.3)); 225 | #endif 226 | 227 | int putenv(char *) __DARWIN_ALIAS(putenv); 228 | long random(void) __swift_unavailable("Use arc4random instead."); 229 | int rand_r(unsigned *) __swift_unavailable("Use arc4random instead."); 230 | #if (__DARWIN_UNIX03 && !defined(_POSIX_C_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(_DARWIN_BETTER_REALPATH) 231 | char *realpath(const char * __restrict, char * __restrict) __DARWIN_EXTSN(realpath); 232 | #else /* (!__DARWIN_UNIX03 || _POSIX_C_SOURCE) && !_DARWIN_C_SOURCE && !_DARWIN_BETTER_REALPATH */ 233 | char *realpath(const char * __restrict, char * __restrict) __DARWIN_ALIAS(realpath); 234 | #endif /* (__DARWIN_UNIX03 && _POSIX_C_SOURCE) || _DARWIN_C_SOURCE || _DARWIN_BETTER_REALPATH */ 235 | unsigned short 236 | *seed48(unsigned short[3]); 237 | int setenv(const char * __name, const char * __value, int __overwrite) __DARWIN_ALIAS(setenv); 238 | #if __DARWIN_UNIX03 239 | void setkey(const char *) __DARWIN_ALIAS(setkey); 240 | #else /* !__DARWIN_UNIX03 */ 241 | int setkey(const char *); 242 | #endif /* __DARWIN_UNIX03 */ 243 | char *setstate(const char *); 244 | void srand48(long); 245 | #if __DARWIN_UNIX03 246 | void srandom(unsigned); 247 | #else /* !__DARWIN_UNIX03 */ 248 | void srandom(unsigned long); 249 | #endif /* __DARWIN_UNIX03 */ 250 | int unlockpt(int); 251 | #if __DARWIN_UNIX03 252 | int unsetenv(const char *) __DARWIN_ALIAS(unsetenv); 253 | #else /* !__DARWIN_UNIX03 */ 254 | void unsetenv(const char *); 255 | #endif /* __DARWIN_UNIX03 */ 256 | #endif /* !_ANSI_SOURCE */ 257 | 258 | #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) 259 | #include 260 | #include 261 | #include 262 | #include <_types/_uint32_t.h> 263 | 264 | uint32_t arc4random(void); 265 | void arc4random_addrandom(unsigned char * /*dat*/, int /*datlen*/) 266 | __OSX_DEPRECATED(10.0, 10.12, "use arc4random_stir") 267 | __IOS_DEPRECATED(2.0, 10.0, "use arc4random_stir") 268 | __TVOS_DEPRECATED(2.0, 10.0, "use arc4random_stir") 269 | __WATCHOS_DEPRECATED(1.0, 3.0, "use arc4random_stir"); 270 | void arc4random_buf(void * __buf, size_t __nbytes) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 271 | void arc4random_stir(void); 272 | uint32_t 273 | arc4random_uniform(uint32_t __upper_bound) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 274 | #ifdef __BLOCKS__ 275 | int atexit_b(void (^ _Nonnull)(void)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 276 | void *bsearch_b(const void *__key, const void *__base, size_t __nel, 277 | size_t __width, int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 278 | #endif /* __BLOCKS__ */ 279 | 280 | /* getcap(3) functions */ 281 | char *cgetcap(char *, const char *, int); 282 | int cgetclose(void); 283 | int cgetent(char **, char **, const char *); 284 | int cgetfirst(char **, char **); 285 | int cgetmatch(const char *, const char *); 286 | int cgetnext(char **, char **); 287 | int cgetnum(char *, const char *, long *); 288 | int cgetset(const char *); 289 | int cgetstr(char *, const char *, char **); 290 | int cgetustr(char *, const char *, char **); 291 | 292 | int daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0, __MAC_10_5, __IPHONE_2_0, __IPHONE_2_0, "Use posix_spawn APIs instead.") __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 293 | char *devname(dev_t, mode_t); 294 | char *devname_r(dev_t, mode_t, char *buf, int len); 295 | char *getbsize(int *, long *); 296 | int getloadavg(double [], int); 297 | const char 298 | *getprogname(void); 299 | void setprogname(const char *); 300 | 301 | #ifdef __BLOCKS__ 302 | #if __has_attribute(noescape) 303 | #define __sort_noescape __attribute__((__noescape__)) 304 | #else 305 | #define __sort_noescape 306 | #endif 307 | #endif /* __BLOCKS__ */ 308 | 309 | int heapsort(void *__base, size_t __nel, size_t __width, 310 | int (* _Nonnull __compar)(const void *, const void *)); 311 | #ifdef __BLOCKS__ 312 | int heapsort_b(void *__base, size_t __nel, size_t __width, 313 | int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) 314 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 315 | #endif /* __BLOCKS__ */ 316 | int mergesort(void *__base, size_t __nel, size_t __width, 317 | int (* _Nonnull __compar)(const void *, const void *)); 318 | #ifdef __BLOCKS__ 319 | int mergesort_b(void *__base, size_t __nel, size_t __width, 320 | int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) 321 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 322 | #endif /* __BLOCKS__ */ 323 | void psort(void *__base, size_t __nel, size_t __width, 324 | int (* _Nonnull __compar)(const void *, const void *)) 325 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 326 | #ifdef __BLOCKS__ 327 | void psort_b(void *__base, size_t __nel, size_t __width, 328 | int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) 329 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 330 | #endif /* __BLOCKS__ */ 331 | void psort_r(void *__base, size_t __nel, size_t __width, void *, 332 | int (* _Nonnull __compar)(void *, const void *, const void *)) 333 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 334 | #ifdef __BLOCKS__ 335 | void qsort_b(void *__base, size_t __nel, size_t __width, 336 | int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) 337 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 338 | #endif /* __BLOCKS__ */ 339 | void qsort_r(void *__base, size_t __nel, size_t __width, void *, 340 | int (* _Nonnull __compar)(void *, const void *, const void *)); 341 | int radixsort(const unsigned char **__base, int __nel, const unsigned char *__table, 342 | unsigned __endbyte); 343 | int rpmatch(const char *) 344 | __API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0)); 345 | int sradixsort(const unsigned char **__base, int __nel, const unsigned char *__table, 346 | unsigned __endbyte); 347 | void sranddev(void); 348 | void srandomdev(void); 349 | void *reallocf(void *__ptr, size_t __size) __alloc_size(2); 350 | long long 351 | strtonum(const char *__numstr, long long __minval, long long __maxval, const char **__errstrp) 352 | __API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)); 353 | #if !__DARWIN_NO_LONG_LONG 354 | long long 355 | strtoq(const char *__str, char **__endptr, int __base); 356 | unsigned long long 357 | strtouq(const char *__str, char **__endptr, int __base); 358 | #endif /* !__DARWIN_NO_LONG_LONG */ 359 | extern char *suboptarg; /* getsubopt(3) external variable */ 360 | /* valloc is now declared in _malloc.h */ 361 | #endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ 362 | 363 | /* Poison the following routines if -fshort-wchar is set */ 364 | #if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU 365 | #pragma GCC poison mbstowcs mbtowc wcstombs wctomb 366 | #endif 367 | __END_DECLS 368 | 369 | #ifdef _USE_EXTENDED_LOCALES_ 370 | #include 371 | #endif /* _USE_EXTENDED_LOCALES_ */ 372 | 373 | #endif /* _STDLIB_H_ */ 374 | -------------------------------------------------------------------------------- /ffigen/simple/headers/stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000, 2005, 2007, 2009, 2010 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*- 24 | * Copyright (c) 1990, 1993 25 | * The Regents of the University of California. All rights reserved. 26 | * 27 | * This code is derived from software contributed to Berkeley by 28 | * Chris Torek. 29 | * 30 | * Redistribution and use in source and binary forms, with or without 31 | * modification, are permitted provided that the following conditions 32 | * are met: 33 | * 1. Redistributions of source code must retain the above copyright 34 | * notice, this list of conditions and the following disclaimer. 35 | * 2. Redistributions in binary form must reproduce the above copyright 36 | * notice, this list of conditions and the following disclaimer in the 37 | * documentation and/or other materials provided with the distribution. 38 | * 3. All advertising materials mentioning features or use of this software 39 | * must display the following acknowledgement: 40 | * This product includes software developed by the University of 41 | * California, Berkeley and its contributors. 42 | * 4. Neither the name of the University nor the names of its contributors 43 | * may be used to endorse or promote products derived from this software 44 | * without specific prior written permission. 45 | * 46 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 47 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 50 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 | * SUCH DAMAGE. 57 | * 58 | * @(#)stdio.h 8.5 (Berkeley) 4/29/95 59 | */ 60 | 61 | #ifndef _STDIO_H_ 62 | #define _STDIO_H_ 63 | 64 | #include <_stdio.h> 65 | 66 | __BEGIN_DECLS 67 | extern FILE *__stdinp; 68 | extern FILE *__stdoutp; 69 | extern FILE *__stderrp; 70 | __END_DECLS 71 | 72 | #define __SLBF 0x0001 /* line buffered */ 73 | #define __SNBF 0x0002 /* unbuffered */ 74 | #define __SRD 0x0004 /* OK to read */ 75 | #define __SWR 0x0008 /* OK to write */ 76 | /* RD and WR are never simultaneously asserted */ 77 | #define __SRW 0x0010 /* open for reading & writing */ 78 | #define __SEOF 0x0020 /* found EOF */ 79 | #define __SERR 0x0040 /* found error */ 80 | #define __SMBF 0x0080 /* _buf is from malloc */ 81 | #define __SAPP 0x0100 /* fdopen()ed in append mode */ 82 | #define __SSTR 0x0200 /* this is an sprintf/snprintf string */ 83 | #define __SOPT 0x0400 /* do fseek() optimisation */ 84 | #define __SNPT 0x0800 /* do not do fseek() optimisation */ 85 | #define __SOFF 0x1000 /* set iff _offset is in fact correct */ 86 | #define __SMOD 0x2000 /* true => fgetln modified _p text */ 87 | #define __SALC 0x4000 /* allocate string space dynamically */ 88 | #define __SIGN 0x8000 /* ignore this file in _fwalk */ 89 | 90 | /* 91 | * The following three definitions are for ANSI C, which took them 92 | * from System V, which brilliantly took internal interface macros and 93 | * made them official arguments to setvbuf(), without renaming them. 94 | * Hence, these ugly _IOxxx names are *supposed* to appear in user code. 95 | * 96 | * Although numbered as their counterparts above, the implementation 97 | * does not rely on this. 98 | */ 99 | #define _IOFBF 0 /* setvbuf should set fully buffered */ 100 | #define _IOLBF 1 /* setvbuf should set line buffered */ 101 | #define _IONBF 2 /* setvbuf should set unbuffered */ 102 | 103 | #define BUFSIZ 1024 /* size of buffer used by setbuf */ 104 | #define EOF (-1) 105 | 106 | /* must be == _POSIX_STREAM_MAX */ 107 | #define FOPEN_MAX 20 /* must be <= OPEN_MAX */ 108 | #define FILENAME_MAX 1024 /* must be <= PATH_MAX */ 109 | 110 | /* System V/ANSI C; this is the wrong way to do this, do *not* use these. */ 111 | #ifndef _ANSI_SOURCE 112 | #define P_tmpdir "/var/tmp/" 113 | #endif 114 | #define L_tmpnam 1024 /* XXX must be == PATH_MAX */ 115 | #define TMP_MAX 308915776 116 | 117 | #ifndef SEEK_SET 118 | #define SEEK_SET 0 /* set file offset to offset */ 119 | #endif 120 | #ifndef SEEK_CUR 121 | #define SEEK_CUR 1 /* set file offset to current plus offset */ 122 | #endif 123 | #ifndef SEEK_END 124 | #define SEEK_END 2 /* set file offset to EOF plus offset */ 125 | #endif 126 | 127 | #define stdin __stdinp 128 | #define stdout __stdoutp 129 | #define stderr __stderrp 130 | 131 | #ifdef _DARWIN_UNLIMITED_STREAMS 132 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 133 | #error "_DARWIN_UNLIMITED_STREAMS specified, but -miphoneos-version-min version does not support it." 134 | #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 135 | #error "_DARWIN_UNLIMITED_STREAMS specified, but -mmacosx-version-min version does not support it." 136 | #endif 137 | #endif 138 | 139 | /* ANSI-C */ 140 | 141 | __BEGIN_DECLS 142 | void clearerr(FILE *); 143 | int fclose(FILE *); 144 | int feof(FILE *); 145 | int ferror(FILE *); 146 | int fflush(FILE *); 147 | int fgetc(FILE *); 148 | int fgetpos(FILE * __restrict, fpos_t *); 149 | char *fgets(char * __restrict, int, FILE *); 150 | #if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) 151 | FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fopen)); 152 | #else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ 153 | FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen)); 154 | #endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ 155 | int fprintf(FILE * __restrict, const char * __restrict, ...) __printflike(2, 3); 156 | int fputc(int, FILE *); 157 | int fputs(const char * __restrict, FILE * __restrict) __DARWIN_ALIAS(fputs); 158 | size_t fread(void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream); 159 | FILE *freopen(const char * __restrict, const char * __restrict, 160 | FILE * __restrict) __DARWIN_ALIAS(freopen); 161 | int fscanf(FILE * __restrict, const char * __restrict, ...) __scanflike(2, 3); 162 | int fseek(FILE *, long, int); 163 | int fsetpos(FILE *, const fpos_t *); 164 | long ftell(FILE *); 165 | size_t fwrite(const void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream) __DARWIN_ALIAS(fwrite); 166 | int getc(FILE *); 167 | int getchar(void); 168 | char *gets(char *); 169 | void perror(const char *) __cold; 170 | int printf(const char * __restrict, ...) __printflike(1, 2); 171 | int putc(int, FILE *); 172 | int putchar(int); 173 | int puts(const char *); 174 | int remove(const char *); 175 | int rename (const char *__old, const char *__new); 176 | void rewind(FILE *); 177 | int scanf(const char * __restrict, ...) __scanflike(1, 2); 178 | void setbuf(FILE * __restrict, char * __restrict); 179 | int setvbuf(FILE * __restrict, char * __restrict, int, size_t); 180 | int sprintf(char * __restrict, const char * __restrict, ...) __printflike(2, 3) __swift_unavailable("Use snprintf instead."); 181 | int sscanf(const char * __restrict, const char * __restrict, ...) __scanflike(2, 3); 182 | FILE *tmpfile(void); 183 | 184 | __swift_unavailable("Use mkstemp(3) instead.") 185 | #if !defined(_POSIX_C_SOURCE) 186 | __deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead.") 187 | #endif 188 | char *tmpnam(char *); 189 | int ungetc(int, FILE *); 190 | int vfprintf(FILE * __restrict, const char * __restrict, va_list) __printflike(2, 0); 191 | int vprintf(const char * __restrict, va_list) __printflike(1, 0); 192 | int vsprintf(char * __restrict, const char * __restrict, va_list) __printflike(2, 0) __swift_unavailable("Use vsnprintf instead."); 193 | __END_DECLS 194 | 195 | 196 | 197 | /* Additional functionality provided by: 198 | * POSIX.1-1988 199 | */ 200 | 201 | #if __DARWIN_C_LEVEL >= 198808L 202 | #define L_ctermid 1024 /* size for ctermid(); PATH_MAX */ 203 | 204 | __BEGIN_DECLS 205 | #include <_ctermid.h> 206 | 207 | #if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) 208 | FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fdopen)); 209 | #else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ 210 | FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fdopen)); 211 | #endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ 212 | int fileno(FILE *); 213 | __END_DECLS 214 | #endif /* __DARWIN_C_LEVEL >= 198808L */ 215 | 216 | 217 | /* Additional functionality provided by: 218 | * POSIX.2-1992 C Language Binding Option 219 | */ 220 | #if TARGET_OS_IPHONE 221 | #define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(ios_msg) 222 | #else 223 | #define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(osx_msg) 224 | #endif 225 | 226 | #if __DARWIN_C_LEVEL >= 199209L 227 | __BEGIN_DECLS 228 | int pclose(FILE *) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); 229 | #if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) 230 | FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); 231 | #else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ 232 | FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); 233 | #endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ 234 | __END_DECLS 235 | #endif /* __DARWIN_C_LEVEL >= 199209L */ 236 | 237 | #undef __swift_unavailable_on 238 | 239 | /* Additional functionality provided by: 240 | * POSIX.1c-1995, 241 | * POSIX.1i-1995, 242 | * and the omnibus ISO/IEC 9945-1: 1996 243 | */ 244 | 245 | #if __DARWIN_C_LEVEL >= 199506L 246 | 247 | /* Functions internal to the implementation. */ 248 | __BEGIN_DECLS 249 | int __srget(FILE *); 250 | int __svfscanf(FILE *, const char *, va_list) __scanflike(2, 0); 251 | int __swbuf(int, FILE *); 252 | __END_DECLS 253 | 254 | /* 255 | * The __sfoo macros are here so that we can 256 | * define function versions in the C library. 257 | */ 258 | #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) 259 | #if defined(__GNUC__) && defined(__STDC__) 260 | __header_always_inline int __sputc(int _c, FILE *_p) { 261 | if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) 262 | return (*_p->_p++ = _c); 263 | else 264 | return (__swbuf(_c, _p)); 265 | } 266 | #else 267 | /* 268 | * This has been tuned to generate reasonable code on the vax using pcc. 269 | */ 270 | #define __sputc(c, p) \ 271 | (--(p)->_w < 0 ? \ 272 | (p)->_w >= (p)->_lbfsize ? \ 273 | (*(p)->_p = (c)), *(p)->_p != '\n' ? \ 274 | (int)*(p)->_p++ : \ 275 | __swbuf('\n', p) : \ 276 | __swbuf((int)(c), p) : \ 277 | (*(p)->_p = (c), (int)*(p)->_p++)) 278 | #endif 279 | 280 | #define __sfeof(p) (((p)->_flags & __SEOF) != 0) 281 | #define __sferror(p) (((p)->_flags & __SERR) != 0) 282 | #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) 283 | #define __sfileno(p) ((p)->_file) 284 | 285 | __BEGIN_DECLS 286 | void flockfile(FILE *); 287 | int ftrylockfile(FILE *); 288 | void funlockfile(FILE *); 289 | int getc_unlocked(FILE *); 290 | int getchar_unlocked(void); 291 | int putc_unlocked(int, FILE *); 292 | int putchar_unlocked(int); 293 | 294 | /* Removed in Issue 6 */ 295 | #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L 296 | int getw(FILE *); 297 | int putw(int, FILE *); 298 | #endif 299 | 300 | __swift_unavailable("Use mkstemp(3) instead.") 301 | #if !defined(_POSIX_C_SOURCE) 302 | __deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead.") 303 | #endif 304 | char *tempnam(const char *__dir, const char *__prefix) __DARWIN_ALIAS(tempnam); 305 | __END_DECLS 306 | 307 | #ifndef lint 308 | #define getc_unlocked(fp) __sgetc(fp) 309 | #define putc_unlocked(x, fp) __sputc(x, fp) 310 | #endif /* lint */ 311 | 312 | #define getchar_unlocked() getc_unlocked(stdin) 313 | #define putchar_unlocked(x) putc_unlocked(x, stdout) 314 | #endif /* __DARWIN_C_LEVEL >= 199506L */ 315 | 316 | 317 | 318 | /* Additional functionality provided by: 319 | * POSIX.1-2001 320 | * ISO C99 321 | */ 322 | 323 | #if __DARWIN_C_LEVEL >= 200112L 324 | #include 325 | 326 | __BEGIN_DECLS 327 | int fseeko(FILE * __stream, off_t __offset, int __whence); 328 | off_t ftello(FILE * __stream); 329 | __END_DECLS 330 | #endif /* __DARWIN_C_LEVEL >= 200112L */ 331 | 332 | #if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) 333 | __BEGIN_DECLS 334 | int snprintf(char * __restrict __str, size_t __size, const char * __restrict __format, ...) __printflike(3, 4); 335 | int vfscanf(FILE * __restrict __stream, const char * __restrict __format, va_list) __scanflike(2, 0); 336 | int vscanf(const char * __restrict __format, va_list) __scanflike(1, 0); 337 | int vsnprintf(char * __restrict __str, size_t __size, const char * __restrict __format, va_list) __printflike(3, 0); 338 | int vsscanf(const char * __restrict __str, const char * __restrict __format, va_list) __scanflike(2, 0); 339 | __END_DECLS 340 | #endif /* __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) */ 341 | 342 | 343 | 344 | /* Additional functionality provided by: 345 | * POSIX.1-2008 346 | */ 347 | 348 | #if __DARWIN_C_LEVEL >= 200809L 349 | #include 350 | 351 | __BEGIN_DECLS 352 | int dprintf(int, const char * __restrict, ...) __printflike(2, 3) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 353 | int vdprintf(int, const char * __restrict, va_list) __printflike(2, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 354 | ssize_t getdelim(char ** __restrict __linep, size_t * __restrict __linecapp, int __delimiter, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 355 | ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 356 | FILE *fmemopen(void * __restrict __buf, size_t __size, const char * __restrict __mode) __API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); 357 | FILE *open_memstream(char **__bufp, size_t *__sizep) __API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); 358 | __END_DECLS 359 | #endif /* __DARWIN_C_LEVEL >= 200809L */ 360 | 361 | 362 | 363 | /* Darwin extensions */ 364 | 365 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 366 | __BEGIN_DECLS 367 | extern __const int sys_nerr; /* perror(3) external variables */ 368 | extern __const char *__const sys_errlist[]; 369 | 370 | int asprintf(char ** __restrict, const char * __restrict, ...) __printflike(2, 3); 371 | char *ctermid_r(char *); 372 | char *fgetln(FILE *, size_t *); 373 | __const char *fmtcheck(const char *, const char *); 374 | int fpurge(FILE *); 375 | void setbuffer(FILE *, char *, int); 376 | int setlinebuf(FILE *); 377 | int vasprintf(char ** __restrict, const char * __restrict, va_list) __printflike(2, 0); 378 | FILE *zopen(const char *, const char *, int); 379 | 380 | 381 | /* 382 | * Stdio function-access interface. 383 | */ 384 | FILE *funopen(const void *, 385 | int (* _Nullable)(void *, char *, int), 386 | int (* _Nullable)(void *, const char *, int), 387 | fpos_t (* _Nullable)(void *, fpos_t, int), 388 | int (* _Nullable)(void *)); 389 | __END_DECLS 390 | #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) 391 | #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) 392 | 393 | #define feof_unlocked(p) __sfeof(p) 394 | #define ferror_unlocked(p) __sferror(p) 395 | #define clearerr_unlocked(p) __sclearerr(p) 396 | #define fileno_unlocked(p) __sfileno(p) 397 | 398 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 399 | 400 | 401 | #ifdef _USE_EXTENDED_LOCALES_ 402 | #include 403 | #endif /* _USE_EXTENDED_LOCALES_ */ 404 | 405 | #if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus) 406 | /* Security checking functions. */ 407 | #include 408 | #endif 409 | 410 | #endif /* _STDIO_H_ */ 411 | -------------------------------------------------------------------------------- /ffigen/simple/headers/unistd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000, 2002-2006, 2008-2010, 2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*- 24 | * Copyright (c) 1998-1999 Apple Computer, Inc. All Rights Reserved 25 | * Copyright (c) 1991, 1993, 1994 26 | * The Regents of the University of California. All rights reserved. 27 | * 28 | * Redistribution and use in source and binary forms, with or without 29 | * modification, are permitted provided that the following conditions 30 | * are met: 31 | * 1. Redistributions of source code must retain the above copyright 32 | * notice, this list of conditions and the following disclaimer. 33 | * 2. Redistributions in binary form must reproduce the above copyright 34 | * notice, this list of conditions and the following disclaimer in the 35 | * documentation and/or other materials provided with the distribution. 36 | * 3. All advertising materials mentioning features or use of this software 37 | * must display the following acknowledgement: 38 | * This product includes software developed by the University of 39 | * California, Berkeley and its contributors. 40 | * 4. Neither the name of the University nor the names of its contributors 41 | * may be used to endorse or promote products derived from this software 42 | * without specific prior written permission. 43 | * 44 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 45 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 48 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 | * SUCH DAMAGE. 55 | * 56 | * @(#)unistd.h 8.12 (Berkeley) 4/27/95 57 | * 58 | * Copyright (c) 1998 Apple Compter, Inc. 59 | * All Rights Reserved 60 | */ 61 | 62 | /* History: 63 | 7/14/99 EKN at Apple fixed getdirentriesattr from getdirentryattr 64 | 3/26/98 CHW at Apple added real interface to searchfs call 65 | 3/5/98 CHW at Apple added hfs semantic system calls headers 66 | */ 67 | 68 | #ifndef _UNISTD_H_ 69 | #define _UNISTD_H_ 70 | 71 | #include <_types.h> 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | /* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: 79 | * _GCC_SIZE_T */ 80 | #include 81 | #include 82 | #include 83 | #include 84 | #include 85 | 86 | #define STDIN_FILENO 0 /* standard input file descriptor */ 87 | #define STDOUT_FILENO 1 /* standard output file descriptor */ 88 | #define STDERR_FILENO 2 /* standard error file descriptor */ 89 | 90 | 91 | /* Version test macros */ 92 | /* _POSIX_VERSION and _POSIX2_VERSION from sys/unistd.h */ 93 | #define _XOPEN_VERSION 600 /* [XSI] */ 94 | #define _XOPEN_XCU_VERSION 4 /* Older standard */ 95 | 96 | 97 | /* Please keep this list in the same order as the applicable standard */ 98 | #define _POSIX_ADVISORY_INFO (-1) /* [ADV] */ 99 | #define _POSIX_ASYNCHRONOUS_IO (-1) /* [AIO] */ 100 | #define _POSIX_BARRIERS (-1) /* [BAR] */ 101 | #define _POSIX_CHOWN_RESTRICTED 200112L 102 | #define _POSIX_CLOCK_SELECTION (-1) /* [CS] */ 103 | #define _POSIX_CPUTIME (-1) /* [CPT] */ 104 | #define _POSIX_FSYNC 200112L /* [FSC] */ 105 | #define _POSIX_IPV6 200112L 106 | #define _POSIX_JOB_CONTROL 200112L 107 | #define _POSIX_MAPPED_FILES 200112L /* [MF] */ 108 | #define _POSIX_MEMLOCK (-1) /* [ML] */ 109 | #define _POSIX_MEMLOCK_RANGE (-1) /* [MR] */ 110 | #define _POSIX_MEMORY_PROTECTION 200112L /* [MPR] */ 111 | #define _POSIX_MESSAGE_PASSING (-1) /* [MSG] */ 112 | #define _POSIX_MONOTONIC_CLOCK (-1) /* [MON] */ 113 | #define _POSIX_NO_TRUNC 200112L 114 | #define _POSIX_PRIORITIZED_IO (-1) /* [PIO] */ 115 | #define _POSIX_PRIORITY_SCHEDULING (-1) /* [PS] */ 116 | #define _POSIX_RAW_SOCKETS (-1) /* [RS] */ 117 | #define _POSIX_READER_WRITER_LOCKS 200112L /* [THR] */ 118 | #define _POSIX_REALTIME_SIGNALS (-1) /* [RTS] */ 119 | #define _POSIX_REGEXP 200112L 120 | #define _POSIX_SAVED_IDS 200112L /* XXX required */ 121 | #define _POSIX_SEMAPHORES (-1) /* [SEM] */ 122 | #define _POSIX_SHARED_MEMORY_OBJECTS (-1) /* [SHM] */ 123 | #define _POSIX_SHELL 200112L 124 | #define _POSIX_SPAWN (-1) /* [SPN] */ 125 | #define _POSIX_SPIN_LOCKS (-1) /* [SPI] */ 126 | #define _POSIX_SPORADIC_SERVER (-1) /* [SS] */ 127 | #define _POSIX_SYNCHRONIZED_IO (-1) /* [SIO] */ 128 | #define _POSIX_THREAD_ATTR_STACKADDR 200112L /* [TSA] */ 129 | #define _POSIX_THREAD_ATTR_STACKSIZE 200112L /* [TSS] */ 130 | #define _POSIX_THREAD_CPUTIME (-1) /* [TCT] */ 131 | #define _POSIX_THREAD_PRIO_INHERIT (-1) /* [TPI] */ 132 | #define _POSIX_THREAD_PRIO_PROTECT (-1) /* [TPP] */ 133 | #define _POSIX_THREAD_PRIORITY_SCHEDULING (-1) /* [TPS] */ 134 | #define _POSIX_THREAD_PROCESS_SHARED 200112L /* [TSH] */ 135 | #define _POSIX_THREAD_SAFE_FUNCTIONS 200112L /* [TSF] */ 136 | #define _POSIX_THREAD_SPORADIC_SERVER (-1) /* [TSP] */ 137 | #define _POSIX_THREADS 200112L /* [THR] */ 138 | #define _POSIX_TIMEOUTS (-1) /* [TMO] */ 139 | #define _POSIX_TIMERS (-1) /* [TMR] */ 140 | #define _POSIX_TRACE (-1) /* [TRC] */ 141 | #define _POSIX_TRACE_EVENT_FILTER (-1) /* [TEF] */ 142 | #define _POSIX_TRACE_INHERIT (-1) /* [TRI] */ 143 | #define _POSIX_TRACE_LOG (-1) /* [TRL] */ 144 | #define _POSIX_TYPED_MEMORY_OBJECTS (-1) /* [TYM] */ 145 | #ifndef _POSIX_VDISABLE 146 | #define _POSIX_VDISABLE 0xff /* same as sys/termios.h */ 147 | #endif /* _POSIX_VDISABLE */ 148 | 149 | #if __DARWIN_C_LEVEL >= 199209L 150 | #define _POSIX2_C_BIND 200112L 151 | #define _POSIX2_C_DEV 200112L /* c99 command */ 152 | #define _POSIX2_CHAR_TERM 200112L 153 | #define _POSIX2_FORT_DEV (-1) /* fort77 command */ 154 | #define _POSIX2_FORT_RUN 200112L 155 | #define _POSIX2_LOCALEDEF 200112L /* localedef command */ 156 | #define _POSIX2_PBS (-1) 157 | #define _POSIX2_PBS_ACCOUNTING (-1) 158 | #define _POSIX2_PBS_CHECKPOINT (-1) 159 | #define _POSIX2_PBS_LOCATE (-1) 160 | #define _POSIX2_PBS_MESSAGE (-1) 161 | #define _POSIX2_PBS_TRACK (-1) 162 | #define _POSIX2_SW_DEV 200112L 163 | #define _POSIX2_UPE 200112L /* XXXX no fc, newgrp, tabs */ 164 | #endif /* __DARWIN_C_LEVEL */ 165 | 166 | #define __ILP32_OFF32 (-1) 167 | #define __ILP32_OFFBIG (-1) 168 | 169 | #define __LP64_OFF64 (1) 170 | #define __LPBIG_OFFBIG (1) 171 | 172 | #if __DARWIN_C_LEVEL >= 200112L 173 | #define _POSIX_V6_ILP32_OFF32 __ILP32_OFF32 174 | #define _POSIX_V6_ILP32_OFFBIG __ILP32_OFFBIG 175 | #define _POSIX_V6_LP64_OFF64 __LP64_OFF64 176 | #define _POSIX_V6_LPBIG_OFFBIG __LPBIG_OFFBIG 177 | #endif /* __DARWIN_C_LEVEL >= 200112L */ 178 | 179 | #if __DARWIN_C_LEVEL >= 200809L 180 | #define _POSIX_V7_ILP32_OFF32 __ILP32_OFF32 181 | #define _POSIX_V7_ILP32_OFFBIG __ILP32_OFFBIG 182 | #define _POSIX_V7_LP64_OFF64 __LP64_OFF64 183 | #define _POSIX_V7_LPBIG_OFFBIG __LPBIG_OFFBIG 184 | #endif /* __DARWIN_C_LEVEL >= 200809L */ 185 | 186 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 187 | #define _V6_ILP32_OFF32 __ILP32_OFF32 188 | #define _V6_ILP32_OFFBIG __ILP32_OFFBIG 189 | #define _V6_LP64_OFF64 __LP64_OFF64 190 | #define _V6_LPBIG_OFFBIG __LPBIG_OFFBIG 191 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 192 | 193 | #if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL 194 | /* Removed in Issue 7 */ 195 | #define _XBS5_ILP32_OFF32 __ILP32_OFF32 196 | #define _XBS5_ILP32_OFFBIG __ILP32_OFFBIG 197 | #define _XBS5_LP64_OFF64 __LP64_OFF64 198 | #define _XBS5_LPBIG_OFFBIG __LPBIG_OFFBIG 199 | #endif /* __DARWIN_C_LEVEL < 200809L */ 200 | 201 | #if __DARWIN_C_LEVEL >= 199506L /* This really should be XSI */ 202 | #define _XOPEN_CRYPT (1) 203 | #define _XOPEN_ENH_I18N (1) /* XXX required */ 204 | #define _XOPEN_LEGACY (-1) /* no ftime gcvt, wcswcs */ 205 | #define _XOPEN_REALTIME (-1) /* no q'ed signals, mq_* */ 206 | #define _XOPEN_REALTIME_THREADS (-1) /* no posix_spawn, et. al. */ 207 | #define _XOPEN_SHM (1) 208 | #define _XOPEN_STREAMS (-1) /* Issue 6 */ 209 | #define _XOPEN_UNIX (1) 210 | #endif /* XSI */ 211 | 212 | /* configurable system variables */ 213 | #define _SC_ARG_MAX 1 214 | #define _SC_CHILD_MAX 2 215 | #define _SC_CLK_TCK 3 216 | #define _SC_NGROUPS_MAX 4 217 | #define _SC_OPEN_MAX 5 218 | #define _SC_JOB_CONTROL 6 219 | #define _SC_SAVED_IDS 7 220 | #define _SC_VERSION 8 221 | #define _SC_BC_BASE_MAX 9 222 | #define _SC_BC_DIM_MAX 10 223 | #define _SC_BC_SCALE_MAX 11 224 | #define _SC_BC_STRING_MAX 12 225 | #define _SC_COLL_WEIGHTS_MAX 13 226 | #define _SC_EXPR_NEST_MAX 14 227 | #define _SC_LINE_MAX 15 228 | #define _SC_RE_DUP_MAX 16 229 | #define _SC_2_VERSION 17 230 | #define _SC_2_C_BIND 18 231 | #define _SC_2_C_DEV 19 232 | #define _SC_2_CHAR_TERM 20 233 | #define _SC_2_FORT_DEV 21 234 | #define _SC_2_FORT_RUN 22 235 | #define _SC_2_LOCALEDEF 23 236 | #define _SC_2_SW_DEV 24 237 | #define _SC_2_UPE 25 238 | #define _SC_STREAM_MAX 26 239 | #define _SC_TZNAME_MAX 27 240 | 241 | #if __DARWIN_C_LEVEL >= 199309L 242 | #define _SC_ASYNCHRONOUS_IO 28 243 | #define _SC_PAGESIZE 29 244 | #define _SC_MEMLOCK 30 245 | #define _SC_MEMLOCK_RANGE 31 246 | #define _SC_MEMORY_PROTECTION 32 247 | #define _SC_MESSAGE_PASSING 33 248 | #define _SC_PRIORITIZED_IO 34 249 | #define _SC_PRIORITY_SCHEDULING 35 250 | #define _SC_REALTIME_SIGNALS 36 251 | #define _SC_SEMAPHORES 37 252 | #define _SC_FSYNC 38 253 | #define _SC_SHARED_MEMORY_OBJECTS 39 254 | #define _SC_SYNCHRONIZED_IO 40 255 | #define _SC_TIMERS 41 256 | #define _SC_AIO_LISTIO_MAX 42 257 | #define _SC_AIO_MAX 43 258 | #define _SC_AIO_PRIO_DELTA_MAX 44 259 | #define _SC_DELAYTIMER_MAX 45 260 | #define _SC_MQ_OPEN_MAX 46 261 | #define _SC_MAPPED_FILES 47 /* swap _SC_PAGESIZE vs. BSD */ 262 | #define _SC_RTSIG_MAX 48 263 | #define _SC_SEM_NSEMS_MAX 49 264 | #define _SC_SEM_VALUE_MAX 50 265 | #define _SC_SIGQUEUE_MAX 51 266 | #define _SC_TIMER_MAX 52 267 | #endif /* __DARWIN_C_LEVEL >= 199309L */ 268 | 269 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 270 | #define _SC_NPROCESSORS_CONF 57 271 | #define _SC_NPROCESSORS_ONLN 58 272 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 273 | 274 | #if __DARWIN_C_LEVEL >= 200112L 275 | #define _SC_2_PBS 59 276 | #define _SC_2_PBS_ACCOUNTING 60 277 | #define _SC_2_PBS_CHECKPOINT 61 278 | #define _SC_2_PBS_LOCATE 62 279 | #define _SC_2_PBS_MESSAGE 63 280 | #define _SC_2_PBS_TRACK 64 281 | #define _SC_ADVISORY_INFO 65 282 | #define _SC_BARRIERS 66 283 | #define _SC_CLOCK_SELECTION 67 284 | #define _SC_CPUTIME 68 285 | #define _SC_FILE_LOCKING 69 286 | #define _SC_GETGR_R_SIZE_MAX 70 287 | #define _SC_GETPW_R_SIZE_MAX 71 288 | #define _SC_HOST_NAME_MAX 72 289 | #define _SC_LOGIN_NAME_MAX 73 290 | #define _SC_MONOTONIC_CLOCK 74 291 | #define _SC_MQ_PRIO_MAX 75 292 | #define _SC_READER_WRITER_LOCKS 76 293 | #define _SC_REGEXP 77 294 | #define _SC_SHELL 78 295 | #define _SC_SPAWN 79 296 | #define _SC_SPIN_LOCKS 80 297 | #define _SC_SPORADIC_SERVER 81 298 | #define _SC_THREAD_ATTR_STACKADDR 82 299 | #define _SC_THREAD_ATTR_STACKSIZE 83 300 | #define _SC_THREAD_CPUTIME 84 301 | #define _SC_THREAD_DESTRUCTOR_ITERATIONS 85 302 | #define _SC_THREAD_KEYS_MAX 86 303 | #define _SC_THREAD_PRIO_INHERIT 87 304 | #define _SC_THREAD_PRIO_PROTECT 88 305 | #define _SC_THREAD_PRIORITY_SCHEDULING 89 306 | #define _SC_THREAD_PROCESS_SHARED 90 307 | #define _SC_THREAD_SAFE_FUNCTIONS 91 308 | #define _SC_THREAD_SPORADIC_SERVER 92 309 | #define _SC_THREAD_STACK_MIN 93 310 | #define _SC_THREAD_THREADS_MAX 94 311 | #define _SC_TIMEOUTS 95 312 | #define _SC_THREADS 96 313 | #define _SC_TRACE 97 314 | #define _SC_TRACE_EVENT_FILTER 98 315 | #define _SC_TRACE_INHERIT 99 316 | #define _SC_TRACE_LOG 100 317 | #define _SC_TTY_NAME_MAX 101 318 | #define _SC_TYPED_MEMORY_OBJECTS 102 319 | #define _SC_V6_ILP32_OFF32 103 320 | #define _SC_V6_ILP32_OFFBIG 104 321 | #define _SC_V6_LP64_OFF64 105 322 | #define _SC_V6_LPBIG_OFFBIG 106 323 | #define _SC_IPV6 118 324 | #define _SC_RAW_SOCKETS 119 325 | #define _SC_SYMLOOP_MAX 120 326 | #endif /* __DARWIN_C_LEVEL >= 200112L */ 327 | 328 | #if __DARWIN_C_LEVEL >= 199506L /* Really XSI */ 329 | #define _SC_ATEXIT_MAX 107 330 | #define _SC_IOV_MAX 56 331 | #define _SC_PAGE_SIZE _SC_PAGESIZE 332 | #define _SC_XOPEN_CRYPT 108 333 | #define _SC_XOPEN_ENH_I18N 109 334 | #define _SC_XOPEN_LEGACY 110 /* Issue 6 */ 335 | #define _SC_XOPEN_REALTIME 111 /* Issue 6 */ 336 | #define _SC_XOPEN_REALTIME_THREADS 112 /* Issue 6 */ 337 | #define _SC_XOPEN_SHM 113 338 | #define _SC_XOPEN_STREAMS 114 /* Issue 6 */ 339 | #define _SC_XOPEN_UNIX 115 340 | #define _SC_XOPEN_VERSION 116 341 | #define _SC_XOPEN_XCU_VERSION 121 342 | #endif /* XSI */ 343 | 344 | #if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL 345 | /* Removed in Issue 7 */ 346 | #define _SC_XBS5_ILP32_OFF32 122 347 | #define _SC_XBS5_ILP32_OFFBIG 123 348 | #define _SC_XBS5_LP64_OFF64 124 349 | #define _SC_XBS5_LPBIG_OFFBIG 125 350 | #endif /* __DARWIN_C_LEVEL <= 200809L */ 351 | 352 | #if __DARWIN_C_LEVEL >= 200112L 353 | #define _SC_SS_REPL_MAX 126 354 | #define _SC_TRACE_EVENT_NAME_MAX 127 355 | #define _SC_TRACE_NAME_MAX 128 356 | #define _SC_TRACE_SYS_MAX 129 357 | #define _SC_TRACE_USER_EVENT_MAX 130 358 | #endif 359 | 360 | #if __DARWIN_C_LEVEL < 200112L || __DARWIN_C_LEVEL >= __DARWIN_C_FULL 361 | /* Removed in Issue 6 */ 362 | #define _SC_PASS_MAX 131 363 | #endif 364 | 365 | /* 132-199 available for future use */ 366 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 367 | #define _SC_PHYS_PAGES 200 368 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 369 | 370 | #if __DARWIN_C_LEVEL >= 199209L 371 | #ifndef _CS_PATH /* Defined in */ 372 | #define _CS_PATH 1 373 | #endif 374 | #endif 375 | 376 | #if __DARWIN_C_LEVEL >= 200112 377 | #define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 378 | #define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3 379 | #define _CS_POSIX_V6_ILP32_OFF32_LIBS 4 380 | #define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5 381 | #define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 6 382 | #define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 7 383 | #define _CS_POSIX_V6_LP64_OFF64_CFLAGS 8 384 | #define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 9 385 | #define _CS_POSIX_V6_LP64_OFF64_LIBS 10 386 | #define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 11 387 | #define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12 388 | #define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13 389 | #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14 390 | #endif 391 | 392 | #if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL 393 | /* Removed in Issue 7 */ 394 | #define _CS_XBS5_ILP32_OFF32_CFLAGS 20 395 | #define _CS_XBS5_ILP32_OFF32_LDFLAGS 21 396 | #define _CS_XBS5_ILP32_OFF32_LIBS 22 397 | #define _CS_XBS5_ILP32_OFF32_LINTFLAGS 23 398 | #define _CS_XBS5_ILP32_OFFBIG_CFLAGS 24 399 | #define _CS_XBS5_ILP32_OFFBIG_LDFLAGS 25 400 | #define _CS_XBS5_ILP32_OFFBIG_LIBS 26 401 | #define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 27 402 | #define _CS_XBS5_LP64_OFF64_CFLAGS 28 403 | #define _CS_XBS5_LP64_OFF64_LDFLAGS 29 404 | #define _CS_XBS5_LP64_OFF64_LIBS 30 405 | #define _CS_XBS5_LP64_OFF64_LINTFLAGS 31 406 | #define _CS_XBS5_LPBIG_OFFBIG_CFLAGS 32 407 | #define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 33 408 | #define _CS_XBS5_LPBIG_OFFBIG_LIBS 34 409 | #define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 35 410 | #endif 411 | 412 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 413 | #define _CS_DARWIN_USER_DIR 65536 414 | #define _CS_DARWIN_USER_TEMP_DIR 65537 415 | #define _CS_DARWIN_USER_CACHE_DIR 65538 416 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 417 | 418 | 419 | #ifdef _DARWIN_UNLIMITED_GETGROUPS 420 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 421 | #error "_DARWIN_UNLIMITED_GETGROUPS specified, but -miphoneos-version-min version does not support it." 422 | #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 423 | #error "_DARWIN_UNLIMITED_GETGROUPS specified, but -mmacosx-version-min version does not support it." 424 | #endif 425 | #endif 426 | 427 | /* POSIX.1-1990 */ 428 | 429 | __BEGIN_DECLS 430 | void _exit(int) __dead2; 431 | int access(const char *, int); 432 | unsigned int 433 | alarm(unsigned int); 434 | int chdir(const char *); 435 | int chown(const char *, uid_t, gid_t); 436 | 437 | int close(int) __DARWIN_ALIAS_C(close); 438 | 439 | int dup(int); 440 | int dup2(int, int); 441 | int execl(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 442 | int execle(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 443 | int execlp(const char * __file, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 444 | int execv(const char * __path, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 445 | int execve(const char * __file, char * const * __argv, char * const * __envp) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 446 | int execvp(const char * __file, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 447 | pid_t fork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 448 | long fpathconf(int, int); 449 | char *getcwd(char *, size_t); 450 | gid_t getegid(void); 451 | uid_t geteuid(void); 452 | gid_t getgid(void); 453 | #if defined(_DARWIN_UNLIMITED_GETGROUPS) || defined(_DARWIN_C_SOURCE) 454 | int getgroups(int, gid_t []) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(getgroups)); 455 | #else /* !_DARWIN_UNLIMITED_GETGROUPS && !_DARWIN_C_SOURCE */ 456 | int getgroups(int, gid_t []); 457 | #endif /* _DARWIN_UNLIMITED_GETGROUPS || _DARWIN_C_SOURCE */ 458 | char *getlogin(void); 459 | pid_t getpgrp(void); 460 | pid_t getpid(void); 461 | pid_t getppid(void); 462 | uid_t getuid(void); 463 | int isatty(int); 464 | int link(const char *, const char *); 465 | off_t lseek(int, off_t, int); 466 | long pathconf(const char *, int); 467 | 468 | int pause(void) __DARWIN_ALIAS_C(pause); 469 | 470 | int pipe(int [2]); 471 | 472 | ssize_t read(int, void *, size_t) __DARWIN_ALIAS_C(read); 473 | 474 | int rmdir(const char *); 475 | int setgid(gid_t); 476 | int setpgid(pid_t, pid_t); 477 | pid_t setsid(void); 478 | int setuid(uid_t); 479 | 480 | unsigned int 481 | sleep(unsigned int) __DARWIN_ALIAS_C(sleep); 482 | 483 | long sysconf(int); 484 | pid_t tcgetpgrp(int); 485 | int tcsetpgrp(int, pid_t); 486 | char *ttyname(int); 487 | 488 | #if __DARWIN_UNIX03 489 | int ttyname_r(int, char *, size_t) __DARWIN_ALIAS(ttyname_r); 490 | #else /* !__DARWIN_UNIX03 */ 491 | char *ttyname_r(int, char *, size_t); 492 | #endif /* __DARWIN_UNIX03 */ 493 | 494 | int unlink(const char *); 495 | 496 | ssize_t write(int __fd, const void * __buf, size_t __nbyte) __DARWIN_ALIAS_C(write); 497 | __END_DECLS 498 | 499 | 500 | 501 | /* Additional functionality provided by: 502 | * POSIX.2-1992 C Language Binding Option 503 | */ 504 | 505 | #if __DARWIN_C_LEVEL >= 199209L 506 | __BEGIN_DECLS 507 | size_t confstr(int, char *, size_t) __DARWIN_ALIAS(confstr); 508 | 509 | int getopt(int, char * const [], const char *) __DARWIN_ALIAS(getopt); 510 | 511 | extern char *optarg; /* getopt(3) external variables */ 512 | extern int optind, opterr, optopt; 513 | __END_DECLS 514 | #endif /* __DARWIN_C_LEVEL >= 199209L */ 515 | 516 | 517 | 518 | /* Additional functionality provided by: 519 | * POSIX.1c-1995, 520 | * POSIX.1i-1995, 521 | * and the omnibus ISO/IEC 9945-1: 1996 522 | */ 523 | 524 | #if __DARWIN_C_LEVEL >= 199506L 525 | #include <_ctermid.h> 526 | /* These F_* are really XSI or Issue 6 */ 527 | #define F_ULOCK 0 /* unlock locked section */ 528 | #define F_LOCK 1 /* lock a section for exclusive use */ 529 | #define F_TLOCK 2 /* test and lock a section for exclusive use */ 530 | #define F_TEST 3 /* test a section for locks by other procs */ 531 | 532 | __BEGIN_DECLS 533 | 534 | /* Begin XSI */ 535 | /* Removed in Issue 6 */ 536 | #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L 537 | #if !defined(_POSIX_C_SOURCE) 538 | __deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED 539 | #endif 540 | void *brk(const void *); 541 | int chroot(const char *) __POSIX_C_DEPRECATED(199506L); 542 | #endif 543 | 544 | char *crypt(const char *, const char *); 545 | #if __DARWIN_UNIX03 546 | void encrypt(char *, int) __DARWIN_ALIAS(encrypt); 547 | #else /* !__DARWIN_UNIX03 */ 548 | int encrypt(char *, int); 549 | #endif /* __DARWIN_UNIX03 */ 550 | int fchdir(int); 551 | long gethostid(void); 552 | pid_t getpgid(pid_t); 553 | pid_t getsid(pid_t); 554 | 555 | /* Removed in Issue 6 */ 556 | #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L 557 | int getdtablesize(void) __POSIX_C_DEPRECATED(199506L); 558 | int getpagesize(void) __pure2 __POSIX_C_DEPRECATED(199506L); 559 | char *getpass(const char *) __POSIX_C_DEPRECATED(199506L); 560 | #endif 561 | 562 | /* Removed in Issue 7 */ 563 | #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L 564 | char *getwd(char *) __POSIX_C_DEPRECATED(200112L); /* obsoleted by getcwd() */ 565 | #endif 566 | 567 | int lchown(const char *, uid_t, gid_t) __DARWIN_ALIAS(lchown); 568 | 569 | int lockf(int, int, off_t) __DARWIN_ALIAS_C(lockf); 570 | 571 | int nice(int) __DARWIN_ALIAS(nice); 572 | 573 | ssize_t pread(int __fd, void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pread); 574 | 575 | ssize_t pwrite(int __fd, const void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pwrite); 576 | 577 | /* Removed in Issue 6 */ 578 | #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L 579 | /* Note that Issue 5 changed the argument as intprt_t, 580 | * but we keep it as int for binary compatability. */ 581 | #if !defined(_POSIX_C_SOURCE) 582 | __deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED 583 | #endif 584 | void *sbrk(int); 585 | #endif 586 | 587 | #if __DARWIN_UNIX03 588 | pid_t setpgrp(void) __DARWIN_ALIAS(setpgrp); 589 | #else /* !__DARWIN_UNIX03 */ 590 | int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */ 591 | #endif /* __DARWIN_UNIX03 */ 592 | 593 | int setregid(gid_t, gid_t) __DARWIN_ALIAS(setregid); 594 | 595 | int setreuid(uid_t, uid_t) __DARWIN_ALIAS(setreuid); 596 | 597 | void swab(const void * __restrict, void * __restrict, ssize_t); 598 | void sync(void); 599 | int truncate(const char *, off_t); 600 | useconds_t ualarm(useconds_t, useconds_t); 601 | int usleep(useconds_t) __DARWIN_ALIAS_C(usleep); 602 | pid_t vfork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 603 | /* End XSI */ 604 | 605 | int fsync(int) __DARWIN_ALIAS_C(fsync); 606 | 607 | int ftruncate(int, off_t); 608 | int getlogin_r(char *, size_t); 609 | __END_DECLS 610 | #endif /* __DARWIN_C_LEVEL >= 199506L */ 611 | 612 | 613 | 614 | /* Additional functionality provided by: 615 | * POSIX.1-2001 616 | * ISO C99 617 | */ 618 | 619 | #if __DARWIN_C_LEVEL >= 200112L 620 | __BEGIN_DECLS 621 | int fchown(int, uid_t, gid_t); 622 | int gethostname(char *, size_t); 623 | ssize_t readlink(const char * __restrict, char * __restrict, size_t); 624 | int setegid(gid_t); 625 | int seteuid(uid_t); 626 | int symlink(const char *, const char *); 627 | __END_DECLS 628 | #endif /* __DARWIN_C_LEVEL >= 200112L */ 629 | 630 | 631 | 632 | /* Darwin extensions */ 633 | 634 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 635 | #include 636 | 637 | #include 638 | #include 639 | #include 640 | 641 | __BEGIN_DECLS 642 | void _Exit(int) __dead2; 643 | int accessx_np(const struct accessx_descriptor *, size_t, int *, uid_t); 644 | int acct(const char *); 645 | int add_profil(char *, size_t, unsigned long, unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 646 | void endusershell(void); 647 | int execvP(const char * __file, const char * __searchpath, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 648 | char *fflagstostr(unsigned long); 649 | int getdomainname(char *, int); 650 | int getgrouplist(const char *, int, int *, int *); 651 | #if defined(__has_include) 652 | #if __has_include() 653 | #include 654 | #else 655 | #include 656 | #endif 657 | #else 658 | #include 659 | #endif 660 | mode_t getmode(const void *, mode_t); 661 | int getpeereid(int, uid_t *, gid_t *); 662 | int getsgroups_np(int *, uuid_t); 663 | char *getusershell(void); 664 | int getwgroups_np(int *, uuid_t); 665 | int initgroups(const char *, int); 666 | int issetugid(void); 667 | char *mkdtemp(char *); 668 | int mknod(const char *, mode_t, dev_t); 669 | int mkpath_np(const char *path, mode_t omode) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); /* returns errno */ 670 | int mkpathat_np(int dfd, const char *path, mode_t omode) /* returns errno */ 671 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 672 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); 673 | int mkstemp(char *); 674 | int mkstemps(char *, int); 675 | char *mktemp(char *); 676 | int mkostemp(char *path, int oflags) 677 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 678 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); 679 | int mkostemps(char *path, int slen, int oflags) 680 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 681 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); 682 | /* Non-portable mkstemp that uses open_dprotected_np */ 683 | int mkstemp_dprotected_np(char *path, int dpclass, int dpflags) 684 | __OSX_UNAVAILABLE __IOS_AVAILABLE(10.0) 685 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); 686 | char *mkdtempat_np(int dfd, char *path) 687 | __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) 688 | __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); 689 | int mkstempsat_np(int dfd, char *path, int slen) 690 | __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) 691 | __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); 692 | int mkostempsat_np(int dfd, char *path, int slen, int oflags) 693 | __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) 694 | __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); 695 | int nfssvc(int, void *); 696 | int profil(char *, size_t, unsigned long, unsigned int); 697 | 698 | __deprecated_msg("Use of per-thread security contexts is error-prone and discouraged.") 699 | int pthread_setugid_np(uid_t, gid_t); 700 | int pthread_getugid_np( uid_t *, gid_t *); 701 | 702 | int reboot(int); 703 | int revoke(const char *); 704 | 705 | __deprecated int rcmd(char **, int, const char *, const char *, const char *, int *); 706 | __deprecated int rcmd_af(char **, int, const char *, const char *, const char *, int *, 707 | int); 708 | __deprecated int rresvport(int *); 709 | __deprecated int rresvport_af(int *, int); 710 | __deprecated int iruserok(unsigned long, int, const char *, const char *); 711 | __deprecated int iruserok_sa(const void *, int, int, const char *, const char *); 712 | __deprecated int ruserok(const char *, int, const char *, const char *); 713 | 714 | int setdomainname(const char *, int); 715 | int setgroups(int, const gid_t *); 716 | void sethostid(long); 717 | int sethostname(const char *, int); 718 | #if __DARWIN_UNIX03 719 | void setkey(const char *) __DARWIN_ALIAS(setkey); 720 | #else /* !__DARWIN_UNIX03 */ 721 | int setkey(const char *); 722 | #endif /* __DARWIN_UNIX03 */ 723 | int setlogin(const char *); 724 | void *setmode(const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(setmode)); 725 | int setrgid(gid_t); 726 | int setruid(uid_t); 727 | int setsgroups_np(int, const uuid_t); 728 | void setusershell(void); 729 | int setwgroups_np(int, const uuid_t); 730 | int strtofflags(char **, unsigned long *, unsigned long *); 731 | int swapon(const char *); 732 | int ttyslot(void); 733 | int undelete(const char *); 734 | int unwhiteout(const char *); 735 | void *valloc(size_t); 736 | 737 | __WATCHOS_PROHIBITED __TVOS_PROHIBITED 738 | __OS_AVAILABILITY_MSG(ios,deprecated=10.0,"syscall(2) is unsupported; " 739 | "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") 740 | __OS_AVAILABILITY_MSG(macosx,deprecated=10.12,"syscall(2) is unsupported; " 741 | "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") 742 | int syscall(int, ...); 743 | 744 | extern char *suboptarg; /* getsubopt(3) external variable */ 745 | int getsubopt(char **, char * const *, char **); 746 | 747 | /* HFS & HFS Plus semantics system calls go here */ 748 | #ifdef __LP64__ 749 | int fgetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); 750 | int fsetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); 751 | int getattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(getattrlist); 752 | int setattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(setattrlist); 753 | int exchangedata(const char*,const char*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 754 | int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 755 | 756 | #else /* __LP64__ */ 757 | int fgetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); 758 | int fsetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); 759 | int getattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(getattrlist); 760 | int setattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(setattrlist); 761 | int exchangedata(const char*,const char*,unsigned long) 762 | __OSX_DEPRECATED(10.0, 10.13, "use renamex_np with the RENAME_SWAP flag") 763 | __IOS_DEPRECATED(2.0, 11.0, "use renamex_np with the RENAME_SWAP flag") 764 | __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 765 | int getdirentriesattr(int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 766 | 767 | #endif /* __LP64__ */ 768 | 769 | struct fssearchblock; 770 | struct searchstate; 771 | 772 | int searchfs(const char *, struct fssearchblock *, unsigned long *, unsigned int, unsigned int, struct searchstate *) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; 773 | int fsctl(const char *,unsigned long,void*,unsigned int); 774 | int ffsctl(int,unsigned long,void*,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); 775 | 776 | #define SYNC_VOLUME_FULLSYNC 0x01 /* Flush data and metadata to platter, not just to disk cache */ 777 | #define SYNC_VOLUME_WAIT 0x02 /* Wait for sync to complete */ 778 | 779 | int fsync_volume_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); 780 | int sync_volume_np(const char *, int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); 781 | 782 | extern int optreset; 783 | 784 | __END_DECLS 785 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 786 | 787 | #endif /* _UNISTD_H_ */ 788 | --------------------------------------------------------------------------------