Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <io.h>
- #include <string>
- std::string run(std::string const &command)
- {
- std::string ret;
- try {
- HANDLE hOutputRead = INVALID_HANDLE_VALUE;
- HANDLE hInputWrite = INVALID_HANDLE_VALUE;
- HANDLE hErrorWrite = INVALID_HANDLE_VALUE;
- HANDLE hOutputReadTmp = INVALID_HANDLE_VALUE;
- HANDLE hOutputWrite = INVALID_HANDLE_VALUE;
- HANDLE hInputWriteTmp = INVALID_HANDLE_VALUE;
- HANDLE hInputRead = INVALID_HANDLE_VALUE;
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = 0;
- sa.bInheritHandle = TRUE;
- HANDLE currproc = GetCurrentProcess();
- // パイプを作成
- if (!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
- throw std::string("Failed to CreatePipe");
- // 子プロセスのエラー出力
- if (!DuplicateHandle(currproc, hOutputWrite, currproc, &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
- throw std::string("Failed to DuplicateHandle");
- // パイプを作成
- if (!CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
- throw std::string("Failed to CreatePipe");
- // 子プロセスの標準出力
- if (!DuplicateHandle(currproc, hOutputReadTmp, currproc, &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS))
- throw std::string("Failed to DupliateHandle");
- // 子プロセスの標準入力
- if (!DuplicateHandle(currproc, hInputWriteTmp, currproc, &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS))
- throw std::string("Failed to DupliateHandle");
- // 不要なハンドルを閉じる
- CloseHandle(hOutputReadTmp);
- CloseHandle(hInputWriteTmp);
- // プロセス起動
- PROCESS_INFORMATION pi;
- STARTUPINFOA si;
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE;
- si.hStdInput = hInputRead; // 標準入力ハンドル
- si.hStdOutput = hOutputWrite; // 標準出力ハンドル
- si.hStdError = hErrorWrite; // エラー出力ハンドル
- char *tmp = (char *)alloca(command.size() + 1);
- strcpy(tmp, command.c_str());
- if (!CreateProcessA(0, tmp, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &si, &pi)) {
- throw std::string("Failed to CreateProcess");
- }
- // 不要なハンドルを閉じる
- CloseHandle(hOutputWrite);
- CloseHandle(hInputRead);
- CloseHandle(hErrorWrite);
- // 入力を閉じる
- CloseHandle(hInputWrite);
- while (1) {
- char buf[256];
- DWORD len = 0;
- if (!ReadFile(hOutputRead, buf, sizeof(buf), &len, nullptr)) break;
- if (len < 1) break;
- ret += std::string(buf, len);
- }
- CloseHandle(hOutputRead);
- // 終了
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- } catch (std::string const &e) { // 例外
- OutputDebugStringA(e.c_str());
- }
- return ret;
- }
- int main()
- {
- DWORD t = GetTickCount();
- std::string ret;
- for (int i = 0; i < 100; i++) {
- ret = run("git --version");
- }
- puts(ret.c_str());
- t = GetTickCount() - t;
- printf("%umsn", t);
- }
- #include <stdlib.h>
- #include <unistd.h>
- #include <time.h>
- #include <sys/time.h>
- #include <string>
- std::string run(char const *file, char *const *argv)
- {
- std::string ret;
- try {
- const int R = 0;
- const int W = 1;
- int fd_r;
- int fd_w;
- int child_to_parent[2], parent_to_child[2];
- int pid;
- if (pipe(child_to_parent) < 0) {
- throw std::string("failed: pipe");
- }
- if (pipe(parent_to_child) < 0) {
- close(child_to_parent[R]);
- close(child_to_parent[W]);
- throw std::string("failed: pipe");
- }
- pid = fork();
- if (pid < 0) {
- close(child_to_parent[R]);
- close(child_to_parent[W]);
- close(parent_to_child[R]);
- close(parent_to_child[W]);
- throw std::string("failed: fork");
- }
- if (pid == 0) { // child
- close(parent_to_child[W]);
- close(child_to_parent[R]);
- dup2(parent_to_child[R], R);
- dup2(child_to_parent[W], W);
- close(parent_to_child[R]);
- close(child_to_parent[W]);
- if (execvp(file, argv) < 0) {
- close(parent_to_child[R]);
- close(child_to_parent[W]);
- fprintf(stderr, "failed: execn");
- exit(1);
- }
- }
- close(parent_to_child[R]);
- close(child_to_parent[W]);
- fd_w = parent_to_child[W];
- fd_r = child_to_parent[R];
- //
- close(fd_w);
- while (1) {
- char buf[256];
- int n = read(fd_r, buf, sizeof(buf));
- if (n < 1) break;
- ret += std::string(buf, n);
- }
- close(fd_r);
- } catch (std::string const &e) {
- fprintf(stderr, "%sn", e.c_str());
- exit(1);
- }
- return ret;
- }
- unsigned int get_tick_count()
- {
- struct timeval tv;
- if (gettimeofday(&tv, nullptr) != 0) return 0;
- return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
- }
- int main()
- {
- static char *argv[] = {
- "git",
- "--version",
- nullptr
- };
- unsigned int t = get_tick_count();
- std::string ret;
- for (int i = 0; i < 10000; i++) {
- ret = run(argv[0], argv);
- }
- puts(ret.c_str());
- t = get_tick_count() - t;
- printf("%umsn", t);
- return 0;
- }
Add Comment
Please, Sign In to add comment