初始化内容
This commit is contained in:
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
|
||||
[*.{c,cppi,cc,h,hpp}]
|
||||
indent_size = 2
|
||||
|
||||
# Tab indentation (no size specified)
|
||||
[Makefile,makefile,GNUmakefile]
|
||||
indent_style = tab
|
||||
|
||||
#[*.{js,py}]
|
||||
@@ -0,0 +1,76 @@
|
||||
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
|
||||
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
|
||||
name: CMake on multiple platforms
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
|
||||
fail-fast: false
|
||||
|
||||
# Set up a matrix to run the following 3 configurations:
|
||||
# 1. <Windows, Debug, latest MSVC compiler toolchain on the default runner image, default generator>
|
||||
# 2. <Linux, Debug, latest GCC compiler toolchain on the default runner image, default generator>
|
||||
# 3. <Linux, Debug, latest Clang compiler toolchain on the default runner image, default generator>
|
||||
#
|
||||
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
build_type: [Debug]
|
||||
c_compiler: [gcc, clang, cl]
|
||||
include:
|
||||
- os: windows-latest
|
||||
c_compiler: cl
|
||||
cpp_compiler: cl
|
||||
- os: ubuntu-latest
|
||||
c_compiler: gcc
|
||||
cpp_compiler: g++
|
||||
- os: ubuntu-latest
|
||||
c_compiler: clang
|
||||
cpp_compiler: clang++
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
c_compiler: gcc
|
||||
- os: windows-latest
|
||||
c_compiler: clang
|
||||
- os: ubuntu-latest
|
||||
c_compiler: cl
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set reusable strings
|
||||
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
|
||||
id: strings
|
||||
shell: bash
|
||||
run: |
|
||||
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Configure CMake
|
||||
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
|
||||
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
|
||||
run: >
|
||||
cmake -B ${{ steps.strings.outputs.build-output-dir }}
|
||||
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
|
||||
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
-DSUBPROCESS_TESTS=ON
|
||||
-S ${{ github.workspace }}
|
||||
|
||||
- name: Build
|
||||
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
|
||||
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{ steps.strings.outputs.build-output-dir }}
|
||||
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: ctest --build-config ${{ matrix.build_type }} --timeout 10 -j4
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
build
|
||||
.vscode
|
||||
Vendored
+63
@@ -0,0 +1,63 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(subprocess VERSION 2.2 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ standard to use")
|
||||
option(EXPORT_COMPILE_COMMANDS "create clang compile database" ON)
|
||||
option(SUBPROCESS_TESTS "enable subprocess tests" OFF)
|
||||
option(SUBPROCESS_INSTALL "enable subprocess install" OFF)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_library(subprocess INTERFACE)
|
||||
target_link_libraries(subprocess INTERFACE Threads::Threads)
|
||||
target_sources(subprocess PUBLIC
|
||||
FILE_SET HEADERS
|
||||
FILES
|
||||
cpp-subprocess/subprocess.hpp
|
||||
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
)
|
||||
add_library(cpp-subprocess::subprocess ALIAS subprocess)
|
||||
|
||||
if(SUBPROCESS_INSTALL)
|
||||
install(
|
||||
TARGETS subprocess COMPONENT subprocess
|
||||
EXPORT subprocess
|
||||
FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/subprocess-config.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/subprocess-config.cmake"
|
||||
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/subprocess"
|
||||
PATH_VARS PROJECT_NAME PROJECT_VERSION
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/beman.exemplar-version.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY ExactVersion
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/subprocess-config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/subprocess-version.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/subprocess"
|
||||
COMPONENT subprocess
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT subprocess
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/beman.exemplar"
|
||||
NAMESPACE cpp-subprocess::
|
||||
FILE subprocess-targets.cmake
|
||||
COMPONENT subprocess
|
||||
)
|
||||
endif()
|
||||
|
||||
if(SUBPROCESS_TESTS)
|
||||
include(CTest)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
The library is licensed under the MIT License
|
||||
<http://opensource.org/licenses/MIT>:
|
||||
|
||||
Copyright (c) 2016-2018 Arun Muralidharan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Vendored
+152
@@ -0,0 +1,152 @@
|
||||
## [Subprocessing in C++]
|
||||
|
||||
## Design Goals
|
||||
The only goal was to develop something that is as close as python2.7 subprocess module in dealing with processes.
|
||||
Could not find anything similar done for C++ and here we are.
|
||||
|
||||
This library had these design goals:
|
||||
- **Intuitive Interface**. Using modern C++ features, made the API usage as simple as that in python in most cases and even better in some (See pipiing example).
|
||||
|
||||
- **Correctness**. Dealing with processes is not a simple job. It has many low level details that needs to be taken care of. This library takes care of dealing with those low level details making it easier to launch processes.
|
||||
|
||||
- **Error Handling**. Currently the error handling is achieved via the use of exceptions. It is important that no errors are ignored silently. I am working towards achieving this goal, but most of the error conditions have been taken care of.
|
||||
|
||||
|
||||
## Supported Platforms
|
||||
This library supports MAC OS and Linux.
|
||||
|
||||
Support for Windows is limited at this time. Please report any specific use-cases that fail,
|
||||
and they will be fixed as they are reported.
|
||||
|
||||
## Integration
|
||||
Subprocess library has just a single source `subprocess.hpp` present at the top directory of this repository. All you need to do is add
|
||||
|
||||
```cpp
|
||||
#include "cpp-subprocess/subprocess.hpp"
|
||||
|
||||
using namespace subprocess;
|
||||
// OR
|
||||
// namespace sp = subprocess;
|
||||
// Or give any other alias you like.
|
||||
```
|
||||
to the files where you want to make use of subprocessing. Make sure to add necessary switches to add C++11 support (-std=c++11 in g++ and clang).
|
||||
|
||||
Checkout http://templated-thoughts.blogspot.in/2016/03/sub-processing-with-modern-c.html as well.
|
||||
|
||||
## CMake Projects
|
||||
|
||||
```cmake
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
cpp-subprocess
|
||||
GIT_REPOSITORY https://github.com/arun11299/cpp-subprocess.git
|
||||
GIT_TAG v2.2
|
||||
)
|
||||
FetchContent_MakeAvailable(cpp-subprocess)
|
||||
|
||||
target_link_libraries(<your_target> PRIVATE cpp-subprocess::subprocess)
|
||||
```
|
||||
|
||||
## Compiler Support
|
||||
Linux - g++ 4.8 and above
|
||||
Mac OS - Clang 3.4 and later
|
||||
Windows - MSVC 2015 and above
|
||||
|
||||
## Examples
|
||||
Here are few examples to show how to get started:
|
||||
|
||||
1) Executing simple unix commands
|
||||
The easy way:
|
||||
```cpp
|
||||
auto obuf = check_output({"ls", "-l"});
|
||||
std::cout << "Data : " << obuf.buf.data() << std::endl;
|
||||
std::cout << "Data len: " << obuf.length << std::endl;
|
||||
```
|
||||
|
||||
More detailed way:
|
||||
```cpp
|
||||
auto p = Popen({"ls", "-l"}, output{PIPE});
|
||||
auto obuf = p.communicate().first;
|
||||
std::cout << "Data : " << obuf.buf.data() << std::endl;
|
||||
std::cout << "Data len: " << obuf.length << std::endl;
|
||||
```
|
||||
|
||||
2) Output redirection
|
||||
Redirecting a message input to `cat` command to a file.
|
||||
|
||||
```cpp
|
||||
auto p = Popen({"cat", "-"}, input{PIPE}, output{"cat_fredirect.txt"});
|
||||
auto msg = "through stdin to stdout";
|
||||
p.send(msg, strlen(msg));
|
||||
p.wait();
|
||||
```
|
||||
OR
|
||||
```cpp
|
||||
auto p = Popen({"cat", "-"}, input{PIPE}, output{"cat_fredirect.txt"});
|
||||
auto msg = "through stdin to stdout";
|
||||
p.communicate(msg, strlen(msg))
|
||||
```
|
||||
|
||||
OR Reading redirected output from stdout
|
||||
```cpp
|
||||
auto p = Popen({"grep", "f"}, output{PIPE}, input{PIPE});
|
||||
auto msg = "one\ntwo\nthree\nfour\nfive\n";
|
||||
p.send(msg, strlen(msg));
|
||||
auto res = p.communicate();
|
||||
|
||||
std::cout << res.first.buf.data() << std::endl;
|
||||
```
|
||||
|
||||
3) Piping Support
|
||||
Your regular unix command piping
|
||||
|
||||
Ex: cat subprocess.hpp | grep template | cut -d, -f 1
|
||||
|
||||
```cpp
|
||||
auto cat = Popen({"cat", "../subprocess.hpp"}, output{PIPE});
|
||||
auto grep = Popen({"grep", "template"}, input{cat.output()}, output{PIPE});
|
||||
auto cut = Popen({"cut", "-d,", "-f", "1"}, input{grep.output()}, output{PIPE});
|
||||
auto res = cut.communicate().first;
|
||||
std::cout << res.buf.data() << std::endl;
|
||||
```
|
||||
|
||||
4) Easy Piping
|
||||
There is another way to do piping for simple commands like above:
|
||||
|
||||
```cpp
|
||||
auto res = pipeline("cat ../subprocess.hpp", "grep Args", "grep template");
|
||||
std::cout << res.buf.data() << std::endl;
|
||||
```
|
||||
|
||||
The commands provided to the `pipeline` function is in the order that would have appeared in your regular unix command.
|
||||
|
||||
5) Environment variables
|
||||
|
||||
For example, if a shell script requires some new environment variables to be defined, you can provide it with the below easy to use syntax.
|
||||
|
||||
```cpp
|
||||
int st= Popen("./env_script.sh", environment{{
|
||||
{"NEW_ENV1", "VALUE-1"},
|
||||
{"NEW_ENV2", "VALUE-2"},
|
||||
{"NEW_ENV3", "VALUE-3"}
|
||||
}}).wait();
|
||||
assert (st == 0);
|
||||
```
|
||||
|
||||
|
||||
5) Other examples
|
||||
There are lots of other examples in the tests with lot more overloaded API's to support most of the functionalities supported by python2.7.
|
||||
|
||||
## License
|
||||
|
||||
<img align="right" src="http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png">
|
||||
|
||||
The class is licensed under the [MIT License](http://opensource.org/licenses/MIT):
|
||||
|
||||
Copyright © 2016-2018 [Arun Muralidharan]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,7 @@
|
||||
set(SUBPROCESS_VERSION @PROJECT_VERSION@)
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake)
|
||||
|
||||
check_required_components(@PROJECT_NAME@)
|
||||
+2292
File diff suppressed because it is too large
Load Diff
+35
@@ -0,0 +1,35 @@
|
||||
set(test_names test_subprocess test_cat test_double_quotes test_env test_err_redirection test_exception test_split test_main test_ret_code)
|
||||
set(test_files env_script.sh write_err.sh write_err.txt)
|
||||
|
||||
|
||||
foreach(test_name IN LISTS test_names)
|
||||
add_executable(${test_name} ${test_name}.cc)
|
||||
target_link_libraries(${test_name} PRIVATE subprocess)
|
||||
|
||||
add_test(
|
||||
NAME ${test_name}
|
||||
COMMAND $<TARGET_FILE:${test_name}>
|
||||
)
|
||||
endforeach()
|
||||
|
||||
foreach(test_file IN LISTS test_files)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${test_file}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${test_file}
|
||||
COPYONLY
|
||||
)
|
||||
endforeach()
|
||||
|
||||
|
||||
set(TEST_REDIRECTION_PYTHON_SCRIPT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_redirection.py)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_redirection.cc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/test_redirection.cc
|
||||
@ONLY
|
||||
)
|
||||
add_executable(test_redirection ${CMAKE_CURRENT_BINARY_DIR}/test_redirection.cc)
|
||||
target_link_libraries(test_redirection PRIVATE subprocess)
|
||||
add_test(
|
||||
NAME test_redirection
|
||||
COMMAND $<TARGET_FILE:test_redirection>
|
||||
)
|
||||
+1
@@ -0,0 +1 @@
|
||||
through stdin to stdout
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "ENV1 = ${NEW_ENV1}"
|
||||
echo "ENV2 = ${NEW_ENV2}"
|
||||
echo "ENV3 = ${NEW_ENV3}"
|
||||
Vendored
BIN
Binary file not shown.
+74
@@ -0,0 +1,74 @@
|
||||
#include <iostream>
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
namespace sp = subprocess;
|
||||
|
||||
void test_cat_pipe_redirection()
|
||||
{
|
||||
std::cout << "Test::test_cat_pipe_redirection" << std::endl;
|
||||
auto p = sp::Popen({"cat", "-"}, sp::input{sp::PIPE}, sp::output{sp::PIPE});
|
||||
auto msg = "through stdin to stdout";
|
||||
auto res_buf = p.communicate(msg, strlen(msg)).first;
|
||||
assert(res_buf.length == strlen(msg));
|
||||
std::cout << "END_TEST" << std::endl;
|
||||
}
|
||||
|
||||
void test_cat_file_redirection()
|
||||
{
|
||||
std::cout << "Test::test_cat_file_redirection" << std::endl;
|
||||
auto p = sp::Popen({"cat", "-"}, sp::input{sp::PIPE}, sp::output{"cat_fredirect.txt"});
|
||||
auto msg = "through stdin to stdout";
|
||||
int wr_bytes = p.send(msg, strlen(msg));
|
||||
assert (wr_bytes == (int)strlen(msg));
|
||||
std::cout << "END_TEST" << std::endl;
|
||||
}
|
||||
|
||||
void test_cat_send_terminate()
|
||||
{
|
||||
std::cout << "Test::test_cat_send_terminate" << std::endl;
|
||||
std::vector<sp::Popen> pops;
|
||||
|
||||
for (int i=0; i < 5; i++) {
|
||||
pops.emplace_back(sp::Popen({"cat", "-"}, sp::input{sp::PIPE}));
|
||||
pops[i].send("3 5\n", 5);
|
||||
pops[i].close_input();
|
||||
}
|
||||
|
||||
for (int i=0; i < 5; i++) {
|
||||
pops[i].wait();
|
||||
}
|
||||
|
||||
std::cout << "END_TEST" << std::endl;
|
||||
}
|
||||
|
||||
void test_buffer_growth()
|
||||
{
|
||||
auto obuf = sp::check_output({"cat", "../subprocess.hpp"});
|
||||
std::cout << obuf.length << std::endl;
|
||||
assert (obuf.length > sp::DEFAULT_BUF_CAP_BYTES);
|
||||
}
|
||||
|
||||
void test_buffer_growth_threaded_comm()
|
||||
{
|
||||
std::cout << "Test::test_buffer_growth_threaded_comm" << std::endl;
|
||||
auto buf = sp::check_output("cat ../subprocess.hpp", sp::error{sp::PIPE});
|
||||
std::cout << buf.length << std::endl;
|
||||
assert (buf.length > sp::DEFAULT_BUF_CAP_BYTES);
|
||||
std::cout << "END_TEST" << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
#ifndef __USING_WINDOWS__
|
||||
|
||||
// test_cat_pipe_redirection();
|
||||
test_cat_send_terminate();
|
||||
/*
|
||||
test_cat_file_redirection();
|
||||
test_buffer_growth();
|
||||
test_buffer_growth_threaded_comm();
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
namespace sp = subprocess;
|
||||
|
||||
// JSON requires the use of double quotes (see: https://json.org/).
|
||||
// This test verifies proper handling of them.
|
||||
void test_double_quotes()
|
||||
{
|
||||
// A simple JSON object.
|
||||
const std::string expected{"{\"name\": \"value\"}"};
|
||||
#ifdef __USING_WINDOWS__
|
||||
const std::string command{"cmd.exe /c echo "};
|
||||
#else
|
||||
const std::string command{"echo "};
|
||||
#endif
|
||||
auto p = sp::Popen(command + expected, sp::output{sp::PIPE});
|
||||
const auto out = p.communicate().first;
|
||||
std::string result{out.buf.begin(), out.buf.end()};
|
||||
// The `echo` command appends a newline.
|
||||
result.erase(result.find_last_not_of(" \n\r\t") + 1);
|
||||
assert(result == expected);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_double_quotes();
|
||||
return 0;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
using namespace subprocess;
|
||||
|
||||
#ifndef __USING_WINDOWS__
|
||||
|
||||
void test_env()
|
||||
{
|
||||
int st= Popen("./env_script.sh", environment{{
|
||||
{"NEW_ENV1", "VALUE-1"},
|
||||
{"NEW_ENV2", "VALUE-2"},
|
||||
{"NEW_ENV3", "VALUE-3"}
|
||||
}}).wait();
|
||||
assert (st == 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
#ifndef __USING_WINDOWS__
|
||||
test_env();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <iostream>
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
using namespace subprocess;
|
||||
|
||||
void test_redirect()
|
||||
{
|
||||
auto p = Popen("./write_err.sh", output{"write_err.txt"}, error{STDOUT});
|
||||
std::cout << p.poll() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
#ifndef __USING_WINDOWS__
|
||||
test_redirect();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
namespace sp = subprocess;
|
||||
|
||||
void test_exception()
|
||||
{
|
||||
bool caught = false;
|
||||
try {
|
||||
auto p = sp::Popen("invalid_command");
|
||||
assert(false); // Expected to throw
|
||||
} catch (sp::CalledProcessError& e) {
|
||||
#ifdef __USING_WINDOWS__
|
||||
assert(std::strstr(e.what(), "CreateProcess failed: The system cannot find the file specified."));
|
||||
#else
|
||||
assert(std::strstr(e.what(), "execve failed: No such file or directory"));
|
||||
#endif
|
||||
caught = true;
|
||||
}
|
||||
assert(caught);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_exception();
|
||||
return 0;
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
struct bufsize { int siz_; };
|
||||
struct executable { std::string exe_; };
|
||||
|
||||
class Ex {
|
||||
public:
|
||||
template <typename... Args>
|
||||
Ex(Args&&... args) {
|
||||
set_options(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_options(T&& arg) {
|
||||
set_option(std::forward<T>(arg));
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void set_options(T&& first, Args&&... rem_args) {
|
||||
set_option(std::forward<T>(first));
|
||||
set_options(std::forward<Args>(rem_args)...);
|
||||
}
|
||||
|
||||
void set_option(bufsize&& bufs) {
|
||||
std::cout << "bufsize opt" << std::endl;
|
||||
bufsiz_ = bufs.siz_;
|
||||
}
|
||||
void set_option(executable&& exe) {
|
||||
std::cout << "exe opt" << std::endl;
|
||||
exe_name_ = std::move(exe.exe_);
|
||||
}
|
||||
|
||||
private:
|
||||
int bufsiz_ = 0;
|
||||
std::string exe_name_;
|
||||
};
|
||||
|
||||
int main() {
|
||||
Ex e(bufsize{1}, executable{"finger"});
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
using namespace subprocess;
|
||||
|
||||
int main() {
|
||||
auto p = Popen("python3 @TEST_REDIRECTION_PYTHON_SCRIPT_PATH@", output{PIPE}, error{PIPE});
|
||||
OutBuffer out_buf;
|
||||
ErrBuffer err_buf;
|
||||
std::tie(out_buf, err_buf) = p.communicate();
|
||||
std::string out{out_buf.buf.data()};
|
||||
std::string err{err_buf.buf.data()};
|
||||
|
||||
if (out.find("Hello message.") == std::string::npos) return EXIT_FAILURE;
|
||||
if (err.find("Hello message.") != std::string::npos) return EXIT_FAILURE;
|
||||
if (out.find("Error report.") != std::string::npos) return EXIT_FAILURE;
|
||||
if (err.find("Error report.") == std::string::npos) return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Hello message.")
|
||||
print("Error report.", file=sys.stderr)
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
#include <iostream>
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
namespace sp = subprocess;
|
||||
|
||||
void test_ret_code()
|
||||
{
|
||||
std::cout << "Test::test_poll_ret_code" << std::endl;
|
||||
#ifdef __USING_WINDOWS__
|
||||
auto p = sp::Popen({"cmd.exe", "/c", "exit", "1"});
|
||||
#else
|
||||
auto p = sp::Popen({"/usr/bin/false"});
|
||||
#endif
|
||||
while (p.poll() == -1) {
|
||||
#ifdef __USING_WINDOWS__
|
||||
Sleep(100);
|
||||
#else
|
||||
usleep(1000 * 100);
|
||||
#endif
|
||||
}
|
||||
assert (p.retcode() == 1);
|
||||
}
|
||||
|
||||
void test_ret_code_comm()
|
||||
{
|
||||
using namespace sp;
|
||||
auto cat = Popen({"cat", "../subprocess.hpp"}, output{PIPE});
|
||||
auto grep = Popen({"grep", "template"}, input{cat.output()}, output{PIPE});
|
||||
auto cut = Popen({"cut", "-d,", "-f", "1"}, input{grep.output()}, output{PIPE});
|
||||
auto res = cut.communicate().first;
|
||||
std::cout << res.buf.data() << std::endl;
|
||||
|
||||
std::cout << "retcode: " << cut.retcode() << std::endl;
|
||||
}
|
||||
|
||||
void test_ret_code_check_output()
|
||||
{
|
||||
using namespace sp;
|
||||
bool caught = false;
|
||||
try {
|
||||
auto obuf = check_output({"/bin/false"}, shell{false});
|
||||
assert(false); // Expected to throw
|
||||
} catch (CalledProcessError &e) {
|
||||
std::cout << "retcode: " << e.retcode << std::endl;
|
||||
assert (e.retcode == 1);
|
||||
caught = true;
|
||||
}
|
||||
assert(caught);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_ret_code();
|
||||
#ifndef __USING_WINDOWS__
|
||||
test_ret_code_comm();
|
||||
test_ret_code_check_output();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.test_ret_code</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Binary file not shown.
+42
@@ -0,0 +1,42 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::vector<std::string>
|
||||
split(const std::string& str, const std::string& delims=" \t")
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
size_t init = 0;
|
||||
|
||||
while (true) {
|
||||
auto pos = str.find_first_of(delims, init);
|
||||
if (pos == std::string::npos) {
|
||||
res.emplace_back(str.substr(init, str.length()));
|
||||
break;
|
||||
}
|
||||
res.emplace_back(str.substr(init, pos - init));
|
||||
pos++;
|
||||
init = pos;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string join(const std::vector<std::string>& vec)
|
||||
{
|
||||
std::string res;
|
||||
for (auto& elem : vec) {
|
||||
res.append(elem + " ");
|
||||
}
|
||||
res.erase(--res.end());
|
||||
return res;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
auto vec = split ("a b c");
|
||||
for (auto elem : vec) { std::cout << elem << std::endl; }
|
||||
|
||||
std::cout << join(vec).length() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
#include <iostream>
|
||||
#include <cpp-subprocess/subprocess.hpp>
|
||||
|
||||
using namespace subprocess;
|
||||
|
||||
void test_exename()
|
||||
{
|
||||
#ifdef __USING_WINDOWS__
|
||||
auto ret = call({"--version"}, executable{"cmake"}, shell{false});
|
||||
#else
|
||||
auto ret = call({"-l"}, executable{"ls"}, shell{false});
|
||||
#endif
|
||||
std::cout << ret << std::endl;
|
||||
}
|
||||
|
||||
void test_input()
|
||||
{
|
||||
auto p = Popen({"grep", "f"}, output{PIPE}, input{PIPE});
|
||||
const char* msg = "one\ntwo\nthree\nfour\nfive\n";
|
||||
p.send(msg, strlen(msg));
|
||||
auto res = p.communicate(nullptr, 0);
|
||||
std::cout << res.first.buf.data() << std::endl;
|
||||
}
|
||||
|
||||
void test_piping()
|
||||
{
|
||||
auto cat = Popen({"cat", "../subprocess.hpp"}, output{PIPE});
|
||||
auto grep = Popen({"grep", "template"}, input{cat.output()}, output{PIPE});
|
||||
auto cut = Popen({"cut", "-d,", "-f", "1"}, input{grep.output()}, output{PIPE});
|
||||
auto res = cut.communicate().first;
|
||||
std::cout << res.buf.data() << std::endl;
|
||||
}
|
||||
|
||||
void test_easy_piping()
|
||||
{
|
||||
auto res = pipeline("cat ../subprocess.hpp", "grep Args", "grep template");
|
||||
std::cout << res.buf.data() << std::endl;
|
||||
}
|
||||
|
||||
void test_shell()
|
||||
{
|
||||
#ifdef __USING_WINDOWS__
|
||||
auto obuf = check_output({"cmake", "--version"}, shell{false});
|
||||
#else
|
||||
auto obuf = check_output({"ls", "-l"}, shell{false});
|
||||
#endif
|
||||
std::cout << obuf.buf.data() << std::endl;
|
||||
}
|
||||
|
||||
void test_sleep()
|
||||
{
|
||||
auto p = Popen({"sleep", "30"}, shell{true});
|
||||
|
||||
while (p.poll() == -1)
|
||||
{
|
||||
std::cout << "Waiting..." << std::endl;
|
||||
#ifdef __USING_WINDOWS__
|
||||
#else
|
||||
sleep(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::cout << "Sleep ended: ret code = " << p.retcode() << std::endl;
|
||||
}
|
||||
|
||||
void test_read_all()
|
||||
{
|
||||
Popen p = Popen({"echo", "12345678"}, output{PIPE});
|
||||
|
||||
std::vector<char> buf(6);
|
||||
int rbytes = util::read_all(p.output(), buf);
|
||||
|
||||
std::string out(buf.begin(), buf.end());
|
||||
|
||||
assert(out == "12345678\n" && rbytes == 9); // echo puts a new line at the end of output
|
||||
std::cout << "read_all() succeeded" << std::endl;
|
||||
}
|
||||
|
||||
void test_simple_cmd()
|
||||
{
|
||||
auto p = Popen({"ls", "-l"}, output{PIPE});
|
||||
auto obuf = p.communicate().first;
|
||||
std::cout << "Data : " << obuf.buf.data() << std::endl;
|
||||
std::cout << "Data len: " << obuf.length << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
/*
|
||||
test_exename();
|
||||
test_input();
|
||||
test_piping();
|
||||
test_easy_piping();
|
||||
test_shell();
|
||||
test_sleep();
|
||||
test_read_all();
|
||||
*/
|
||||
test_simple_cmd();
|
||||
return 0;
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
>&2 echo "This is going to be a big chunk of error text consisting of garbage words that would never make sense....so here it goes....shouldnt I be doing my work instead ???? ...anyways....lets get to it......dsmvnskmnv;lsdnv;la,mdfv;, lasdnvs, dv;lknvlka;dv laldmflasmdlgvma lm glfdmg lasfgl;mflgms,vdmlmsdfl'bmsldfkmblsdfm blksdfmblk fsdl,b sdlfnbksan kjskanfkjbhv snf p'owMF;OANDOPGIHWEPO;JFOIEHGUYHT JNTG JWEBGIJN FV SDKMNV KJNKJ nokfnrgok weoirgoinfs ijbzx,mv;lksdcnvpisfuhgu wnergorgok nvglk;bn;mkf bkngfkbm fdlb;gfnb ;kdfgn b,mfdl's,g'l;am nsgaosnblm;adrg;lnklf nglkfmnvklb njfknblsmdnkfngsjdfbgsjdbghjb iblnrfgiof n gjsndv vewflkjvekrjgnlkmv mjbeijdfnwek vkijnnfg'koqrnbon nq'eopkfm[qef[lfkdnb ;smknv jk fnkmv ntipjvn kbvn iprtu ghj9p84w5toihnvlkmnlmk nvoijh90rjqo3mrok34 nfkm nnkof nerokmnrgo[j0igjwlkngvmfgnvml oirejgoiewjrfgoiwejrgko[ mwbkm grioejqg[ktrwngk;wnmb;mn;wfkb oirjgiontrgmnwe;fklvnfiobjneiorgn;mbn ijorgenowg;lwbenkownfboiwnrtgiovwnrtblntbontriobnwkrn; onboirw noignjwmKFCV;MKNSDVIUNRIPTN5I KNVK;JN ION EOQWNQ;LDKN V;FMNVKFN[B WPORJGOP[ WLERGNA;SLDKNV;MF NPOINRG;JWN;KNRPEFGI9485JBEKMSD NK;NKL; NFOSAJFKOSNKMN;CV, KAD;FKM;SOGMVLKSMD;,R F;OKA;FL APSLFM ADL;SKOK OKNEW KDJFOKSDJ Alpwpowejgoplwefkmglk p[reg porej gokwem vkl wmo ao[jk [klqmpkoem gpofem lksjn zflkvbn;kf hgioniog krngkmadnv;mfsdn bkleqrjl;wgnpoekw jqbfk mv;lm,redop[ jor[f klqr3ko[j vioadm ;lksdcmn ovj['or'aewnjkopj 'wk;w;k fwrite_err.sh sadkjlbnlfkblfkn blndsf kjwern gfpjknerkgn fknv k;qkgn kfv mscvlkmsn ldkfv nkamdkmv efkgv n;kemf mvwfbkm nfgkmbk bklwnmgklwmtrklgnfkl;b nwkjn glkwmfn lkmnrknwrkpg nkf nlmk nwljkengjklnwflgbnflkjbngkljwfgbn jnk wngpkwrtgnpo n"
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
writing error to stderr
|
||||
This is going to be a big chunk of error text consisting of garbage words that would never make sense....so here it goes....shouldnt I be doing my work instead ???? ...anyways....lets get to it......dsmvnskmnv;lsdnv;la,mdfv;, lasdnvs, dv;lknvlka;dv laldmflasmdlgvma lm glfdmg lasfgl;mflgms,vdmlmsdfl'bmsldfkmblsdfm blksdfmblk fsdl,b sdlfnbksan kjskanfkjbhv snf p'owMF;OANDOPGIHWEPO;JFOIEHGUYHT JNTG JWEBGIJN FV SDKMNV KJNKJ nokfnrgok weoirgoinfs ijbzx,mv;lksdcnvpisfuhgu wnergorgok nvglk;bn;mkf bkngfkbm fdlb;gfnb ;kdfgn b,mfdl's,g'l;am nsgaosnblm;adrg;lnklf nglkfmnvklb njfknblsmdnkfngsjdfbgsjdbghjb iblnrfgiof n gjsndv vewflkjvekrjgnlkmv mjbeijdfnwek vkijnnfg'koqrnbon nq'eopkfm[qef[lfkdnb ;smknv jk fnkmv ntipjvn kbvn iprtu ghj9p84w5toihnvlkmnlmk nvoijh90rjqo3mrok34 nfkm nnkof nerokmnrgo[j0igjwlkngvmfgnvml oirejgoiewjrfgoiwejrgko[ mwbkm grioejqg[ktrwngk;wnmb;mn;wfkb oirjgiontrgmnwe;fklvnfiobjneiorgn;mbn ijorgenowg;lwbenkownfboiwnrtgiovwnrtblntbontriobnwkrn; onboirw noignjwmKFCV;MKNSDVIUNRIPTN5I KNVK;JN ION EOQWNQ;LDKN V;FMNVKFN[B WPORJGOP[ WLERGNA;SLDKNV;MF NPOINRG;JWN;KNRPEFGI9485JBEKMSD NK;NKL; NFOSAJFKOSNKMN;CV, KAD;FKM;SOGMVLKSMD;,R F;OKA;FL APSLFM ADL;SKOK OKNEW KDJFOKSDJ Alpwpowejgoplwefkmglk p[reg porej gokwem vkl wmo ao[jk [klqmpkoem gpofem lksjn zflkvbn;kf hgioniog krngkmadnv;mfsdn bkleqrjl;wgnpoekw jqbfk mv;lm,redop[ jor[f klqr3ko[j vioadm ;lksdcmn ovj['or'aewnjkopj 'wk;w;k fwrite_err.sh sadkjlbnlfkblfkn blndsf kjwern gfpjknerkgn fknv k;qkgn kfv mscvlkmsn ldkfv nkamdkmv efkgv n;kemf mvwfbkm nfgkmbk bklwnmgklwmtrklgnfkl;b nwkjn glkwmfn lkmnrknwrkpg nkf nlmk nwljkengjklnwflgbnflkjbngkljwfgbn jnk wngpkwrtgnpo n
|
||||
This is going to be a big chunk of error text consisting of garbage words that would never make sense....so here it goes....shouldnt I be doing my work instead ???? ...anyways....lets get to it......dsmvnskmnv;lsdnv;la,mdfv;, lasdnvs, dv;lknvlka;dv laldmflasmdlgvma lm glfdmg lasfgl;mflgms,vdmlmsdfl'bmsldfkmblsdfm blksdfmblk fsdl,b sdlfnbksan kjskanfkjbhv snf p'owMF;OANDOPGIHWEPO;JFOIEHGUYHT JNTG JWEBGIJN FV SDKMNV KJNKJ nokfnrgok weoirgoinfs ijbzx,mv;lksdcnvpisfuhgu wnergorgok nvglk;bn;mkf bkngfkbm fdlb;gfnb ;kdfgn b,mfdl's,g'l;am nsgaosnblm;adrg;lnklf nglkfmnvklb njfknblsmdnkfngsjdfbgsjdbghjb iblnrfgiof n gjsndv vewflkjvekrjgnlkmv mjbeijdfnwek vkijnnfg'koqrnbon nq'eopkfm[qef[lfkdnb ;smknv jk fnkmv ntipjvn kbvn iprtu ghj9p84w5toihnvlkmnlmk nvoijh90rjqo3mrok34 nfkm nnkof nerokmnrgo[j0igjwlkngvmfgnvml oirejgoiewjrfgoiwejrgko[ mwbkm grioejqg[ktrwngk;wnmb;mn;wfkb oirjgiontrgmnwe;fklvnfiobjneiorgn;mbn ijorgenowg;lwbenkownfboiwnrtgiovwnrtblntbontriobnwkrn; onboirw noignjwmKFCV;MKNSDVIUNRIPTN5I KNVK;JN ION EOQWNQ;LDKN V;FMNVKFN[B WPORJGOP[ WLERGNA;SLDKNV;MF NPOINRG;JWN;KNRPEFGI9485JBEKMSD NK;NKL; NFOSAJFKOSNKMN;CV, KAD;FKM;SOGMVLKSMD;,R F;OKA;FL APSLFM ADL;SKOK OKNEW KDJFOKSDJ Alpwpowejgoplwefkmglk p[reg porej gokwem vkl wmo ao[jk [klqmpkoem gpofem lksjn zflkvbn;kf hgioniog krngkmadnv;mfsdn bkleqrjl;wgnpoekw jqbfk mv;lm,redop[ jor[f klqr3ko[j vioadm ;lksdcmn ovj['or'aewnjkopj 'wk;w;k fwrite_err.sh sadkjlbnlfkblfkn blndsf kjwern gfpjknerkgn fknv k;qkgn kfv mscvlkmsn ldkfv nkamdkmv efkgv n;kemf mvwfbkm nfgkmbk bklwnmgklwmtrklgnfkl;b nwkjn glkwmfn lkmnrknwrkpg nkf nlmk nwljkengjklnwflgbnflkjbngkljwfgbn jnk wngpkwrtgnpo n
|
||||
This is going to be a big chunk of error text consisting of garbage words that would never make sense....so here it goes....shouldnt I be doing my work instead ???? ...anyways....lets get to it......dsmvnskmnv;lsdnv;la,mdfv;, lasdnvs, dv;lknvlka;dv laldmflasmdlgvma lm glfdmg lasfgl;mflgms,vdmlmsdfl'bmsldfkmblsdfm blksdfmblk fsdl,b sdlfnbksan kjskanfkjbhv snf p'owMF;OANDOPGIHWEPO;JFOIEHGUYHT JNTG JWEBGIJN FV SDKMNV KJNKJ nokfnrgok weoirgoinfs ijbzx,mv;lksdcnvpisfuhgu wnergorgok nvglk;bn;mkf bkngfkbm fdlb;gfnb ;kdfgn b,mfdl's,g'l;am nsgaosnblm;adrg;lnklf nglkfmnvklb njfknblsmdnkfngsjdfbgsjdbghjb iblnrfgiof n gjsndv vewflkjvekrjgnlkmv mjbeijdfnwek vkijnnfg'koqrnbon nq'eopkfm[qef[lfkdnb ;smknv jk fnkmv ntipjvn kbvn iprtu ghj9p84w5toihnvlkmnlmk nvoijh90rjqo3mrok34 nfkm nnkof nerokmnrgo[j0igjwlkngvmfgnvml oirejgoiewjrfgoiwejrgko[ mwbkm grioejqg[ktrwngk;wnmb;mn;wfkb oirjgiontrgmnwe;fklvnfiobjneiorgn;mbn ijorgenowg;lwbenkownfboiwnrtgiovwnrtblntbontriobnwkrn; onboirw noignjwmKFCV;MKNSDVIUNRIPTN5I KNVK;JN ION EOQWNQ;LDKN V;FMNVKFN[B WPORJGOP[ WLERGNA;SLDKNV;MF NPOINRG;JWN;KNRPEFGI9485JBEKMSD NK;NKL; NFOSAJFKOSNKMN;CV, KAD;FKM;SOGMVLKSMD;,R F;OKA;FL APSLFM ADL;SKOK OKNEW KDJFOKSDJ Alpwpowejgoplwefkmglk p[reg porej gokwem vkl wmo ao[jk [klqmpkoem gpofem lksjn zflkvbn;kf hgioniog krngkmadnv;mfsdn bkleqrjl;wgnpoekw jqbfk mv;lm,redop[ jor[f klqr3ko[j vioadm ;lksdcmn ovj['or'aewnjkopj 'wk;w;k fwrite_err.sh sadkjlbnlfkblfkn blndsf kjwern gfpjknerkgn fknv k;qkgn kfv mscvlkmsn ldkfv nkamdkmv efkgv n;kemf mvwfbkm nfgkmbk bklwnmgklwmtrklgnfkl;b nwkjn glkwmfn lkmnrknwrkpg nkf nlmk nwljkengjklnwflgbnflkjbngkljwfgbn jnk wngpkwrtgnpo n
|
||||
This is going to be a big chunk of error text consisting of garbage words that would never make sense....so here it goes....shouldnt I be doing my work instead ???? ...anyways....lets get to it......dsmvnskmnv;lsdnv;la,mdfv;, lasdnvs, dv;lknvlka;dv laldmflasmdlgvma lm glfdmg lasfgl;mflgms,vdmlmsdfl'bmsldfkmblsdfm blksdfmblk fsdl,b sdlfnbksan kjskanfkjbhv snf p'owMF;OANDOPGIHWEPO;JFOIEHGUYHT JNTG JWEBGIJN FV SDKMNV KJNKJ nokfnrgok weoirgoinfs ijbzx,mv;lksdcnvpisfuhgu wnergorgok nvglk;bn;mkf bkngfkbm fdlb;gfnb ;kdfgn b,mfdl's,g'l;am nsgaosnblm;adrg;lnklf nglkfmnvklb njfknblsmdnkfngsjdfbgsjdbghjb iblnrfgiof n gjsndv vewflkjvekrjgnlkmv mjbeijdfnwek vkijnnfg'koqrnbon nq'eopkfm[qef[lfkdnb ;smknv jk fnkmv ntipjvn kbvn iprtu ghj9p84w5toihnvlkmnlmk nvoijh90rjqo3mrok34 nfkm nnkof nerokmnrgo[j0igjwlkngvmfgnvml oirejgoiewjrfgoiwejrgko[ mwbkm grioejqg[ktrwngk;wnmb;mn;wfkb oirjgiontrgmnwe;fklvnfiobjneiorgn;mbn ijorgenowg;lwbenkownfboiwnrtgiovwnrtblntbontriobnwkrn; onboirw noignjwmKFCV;MKNSDVIUNRIPTN5I KNVK;JN ION EOQWNQ;LDKN V;FMNVKFN[B WPORJGOP[ WLERGNA;SLDKNV;MF NPOINRG;JWN;KNRPEFGI9485JBEKMSD NK;NKL; NFOSAJFKOSNKMN;CV, KAD;FKM;SOGMVLKSMD;,R F;OKA;FL APSLFM ADL;SKOK OKNEW KDJFOKSDJ Alpwpowejgoplwefkmglk p[reg porej gokwem vkl wmo ao[jk [klqmpkoem gpofem lksjn zflkvbn;kf hgioniog krngkmadnv;mfsdn bkleqrjl;wgnpoekw jqbfk mv;lm,redop[ jor[f klqr3ko[j vioadm ;lksdcmn ovj['or'aewnjkopj 'wk;w;k fwrite_err.sh sadkjlbnlfkblfkn blndsf kjwern gfpjknerkgn fknv k;qkgn kfv mscvlkmsn ldkfv nkamdkmv efkgv n;kemf mvwfbkm nfgkmbk bklwnmgklwmtrklgnfkl;b nwkjn glkwmfn lkmnrknwrkpg nkf nlmk nwljkengjklnwflgbnflkjbngkljwfgbn jnk wngpkwrtgnpo n
|
||||
Reference in New Issue
Block a user