Guest User

Untitled

a guest
Jan 23rd, 2017
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.67 KB | None | 0 0
  1. #include <windows.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <io.h>
  5. #include <string>
  6.  
  7. std::string run(std::string const &command)
  8. {
  9. std::string ret;
  10.  
  11. try {
  12. HANDLE hOutputRead = INVALID_HANDLE_VALUE;
  13. HANDLE hInputWrite = INVALID_HANDLE_VALUE;
  14. HANDLE hErrorWrite = INVALID_HANDLE_VALUE;
  15.  
  16. HANDLE hOutputReadTmp = INVALID_HANDLE_VALUE;
  17. HANDLE hOutputWrite = INVALID_HANDLE_VALUE;
  18. HANDLE hInputWriteTmp = INVALID_HANDLE_VALUE;
  19. HANDLE hInputRead = INVALID_HANDLE_VALUE;
  20.  
  21. SECURITY_ATTRIBUTES sa;
  22.  
  23. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  24. sa.lpSecurityDescriptor = 0;
  25. sa.bInheritHandle = TRUE;
  26.  
  27. HANDLE currproc = GetCurrentProcess();
  28.  
  29. // パイプを作成
  30. if (!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
  31. throw std::string("Failed to CreatePipe");
  32.  
  33. // 子プロセスのエラー出力
  34. if (!DuplicateHandle(currproc, hOutputWrite, currproc, &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
  35. throw std::string("Failed to DuplicateHandle");
  36.  
  37. // パイプを作成
  38. if (!CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
  39. throw std::string("Failed to CreatePipe");
  40.  
  41. // 子プロセスの標準出力
  42. if (!DuplicateHandle(currproc, hOutputReadTmp, currproc, &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS))
  43. throw std::string("Failed to DupliateHandle");
  44.  
  45. // 子プロセスの標準入力
  46. if (!DuplicateHandle(currproc, hInputWriteTmp, currproc, &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS))
  47. throw std::string("Failed to DupliateHandle");
  48.  
  49. // 不要なハンドルを閉じる
  50. CloseHandle(hOutputReadTmp);
  51. CloseHandle(hInputWriteTmp);
  52.  
  53. // プロセス起動
  54. PROCESS_INFORMATION pi;
  55. STARTUPINFOA si;
  56.  
  57. ZeroMemory(&si, sizeof(STARTUPINFO));
  58. si.cb = sizeof(STARTUPINFO);
  59. si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  60. si.wShowWindow = SW_HIDE;
  61. si.hStdInput = hInputRead; // 標準入力ハンドル
  62. si.hStdOutput = hOutputWrite; // 標準出力ハンドル
  63. si.hStdError = hErrorWrite; // エラー出力ハンドル
  64.  
  65. char *tmp = (char *)alloca(command.size() + 1);
  66. strcpy(tmp, command.c_str());
  67. if (!CreateProcessA(0, tmp, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &si, &pi)) {
  68. throw std::string("Failed to CreateProcess");
  69. }
  70.  
  71. // 不要なハンドルを閉じる
  72. CloseHandle(hOutputWrite);
  73. CloseHandle(hInputRead);
  74. CloseHandle(hErrorWrite);
  75.  
  76. // 入力を閉じる
  77. CloseHandle(hInputWrite);
  78.  
  79. while (1) {
  80. char buf[256];
  81. DWORD len = 0;
  82. if (!ReadFile(hOutputRead, buf, sizeof(buf), &len, nullptr)) break;
  83. if (len < 1) break;
  84. ret += std::string(buf, len);
  85. }
  86.  
  87. CloseHandle(hOutputRead);
  88.  
  89. // 終了
  90. CloseHandle(pi.hThread);
  91. CloseHandle(pi.hProcess);
  92. } catch (std::string const &e) { // 例外
  93. OutputDebugStringA(e.c_str());
  94. }
  95.  
  96. return ret;
  97. }
  98.  
  99. int main()
  100. {
  101. DWORD t = GetTickCount();
  102.  
  103. std::string ret;
  104. for (int i = 0; i < 100; i++) {
  105. ret = run("git --version");
  106. }
  107. puts(ret.c_str());
  108.  
  109. t = GetTickCount() - t;
  110.  
  111. printf("%umsn", t);
  112. }
  113.  
  114. #include <stdlib.h>
  115. #include <unistd.h>
  116. #include <time.h>
  117. #include <sys/time.h>
  118. #include <string>
  119.  
  120. std::string run(char const *file, char *const *argv)
  121. {
  122. std::string ret;
  123.  
  124. try {
  125. const int R = 0;
  126. const int W = 1;
  127.  
  128. int fd_r;
  129. int fd_w;
  130.  
  131. int child_to_parent[2], parent_to_child[2];
  132. int pid;
  133.  
  134. if (pipe(child_to_parent) < 0) {
  135. throw std::string("failed: pipe");
  136. }
  137.  
  138. if (pipe(parent_to_child) < 0) {
  139. close(child_to_parent[R]);
  140. close(child_to_parent[W]);
  141. throw std::string("failed: pipe");
  142. }
  143.  
  144. pid = fork();
  145. if (pid < 0) {
  146. close(child_to_parent[R]);
  147. close(child_to_parent[W]);
  148. close(parent_to_child[R]);
  149. close(parent_to_child[W]);
  150. throw std::string("failed: fork");
  151. }
  152.  
  153. if (pid == 0) { // child
  154. close(parent_to_child[W]);
  155. close(child_to_parent[R]);
  156. dup2(parent_to_child[R], R);
  157. dup2(child_to_parent[W], W);
  158. close(parent_to_child[R]);
  159. close(child_to_parent[W]);
  160. if (execvp(file, argv) < 0) {
  161. close(parent_to_child[R]);
  162. close(child_to_parent[W]);
  163. fprintf(stderr, "failed: execn");
  164. exit(1);
  165. }
  166. }
  167.  
  168. close(parent_to_child[R]);
  169. close(child_to_parent[W]);
  170. fd_w = parent_to_child[W];
  171. fd_r = child_to_parent[R];
  172.  
  173. //
  174.  
  175. close(fd_w);
  176.  
  177. while (1) {
  178. char buf[256];
  179. int n = read(fd_r, buf, sizeof(buf));
  180. if (n < 1) break;
  181. ret += std::string(buf, n);
  182. }
  183.  
  184. close(fd_r);
  185.  
  186. } catch (std::string const &e) {
  187. fprintf(stderr, "%sn", e.c_str());
  188. exit(1);
  189. }
  190.  
  191. return ret;
  192. }
  193.  
  194. unsigned int get_tick_count()
  195. {
  196. struct timeval tv;
  197. if (gettimeofday(&tv, nullptr) != 0) return 0;
  198. return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
  199. }
  200.  
  201. int main()
  202. {
  203. static char *argv[] = {
  204. "git",
  205. "--version",
  206. nullptr
  207. };
  208.  
  209. unsigned int t = get_tick_count();
  210.  
  211. std::string ret;
  212. for (int i = 0; i < 10000; i++) {
  213. ret = run(argv[0], argv);
  214. }
  215. puts(ret.c_str());
  216.  
  217. t = get_tick_count() - t;
  218. printf("%umsn", t);
  219.  
  220. return 0;
  221. }
Add Comment
Please, Sign In to add comment