00001 #include "config.h" 00002 00003 #ifdef HAVE_UNISTD_H 00004 #include <unistd.h> 00005 #endif 00006 00007 #include <string> 00008 #include <cstring> 00009 #include <cassert> 00010 00011 #include "asserts.h" 00012 #include "error.h" 00013 #include "fs.h" 00014 #include "exec.h" 00015 #include "fdstream.h" 00016 00017 // static char confdir[4096] = { 0 }; 00018 00019 /* 00020 void test1(void) 00021 { 00022 execute exe; 00023 bool thrown = false; 00024 00025 try { 00026 exe.fork(); 00027 } 00028 catch (error &e) { 00029 thrown = true; 00030 } 00031 assert(!thrown); 00032 exe.wait(); 00033 if (exe.is_child()) exe.exit(0); 00034 } 00035 */ 00036 00037 /* 00038 void test2(void) 00039 { 00040 execute exe; 00041 00042 exe.fork(); 00043 if (exe.is_parent()) { 00044 char *msg_to_child = "Message from parent"; 00045 char msg_from_child[4096] = { 0 }; 00046 char msg_from_err[4096] = { 0 }; 00047 00048 assert(exe.child_running()); 00049 assert(!exe.child_exited()); 00050 assert(!exe.child_exited_normally()); 00051 assert(!exe.child_signaled()); 00052 assert(exe.child_exit_code() == 0); 00053 assert(exe.child_signal_no() == 0); 00054 00055 if (write(exe.in_fd(), msg_to_child, strlen(msg_to_child)) 00056 != (int)strlen(msg_to_child)) 00057 throw(ERROR(errno,"Error writing to child's input pipe")); 00058 if (read(exe.out_fd(), msg_from_child, 4096) == 0) 00059 throw(ERROR(errno,"Error reading from child's output pipe")); 00060 if (read(exe.err_fd(), msg_from_err, 4096) == 0) 00061 throw(ERROR(errno,"Error reading from child's error pipe")); 00062 00063 exe.wait(); 00064 00065 assert(static_cast<std::string>(msg_from_child) == "Message from child"); 00066 assert(static_cast<std::string>(msg_from_err) == "Message from child err"); 00067 assert(!exe.child_running()); 00068 assert(exe.child_exited()); 00069 assert(exe.child_exited_normally()); 00070 assert(!exe.child_signaled()); 00071 assert(exe.child_exit_code() == 0); 00072 assert(exe.child_signal_no() == 0); 00073 } 00074 if (exe.is_child()) { 00075 char msg_from_parent[4096] = { 0 }; 00076 char *msg_to_parent = "Message from child"; 00077 char *msg_to_err = "Message from child err"; 00078 00079 if (read(exe.in_fd(), msg_from_parent, 4096) == 0) 00080 throw(ERROR(errno,"Error reading input from parent")); 00081 if (write(exe.out_fd(), msg_to_parent, strlen(msg_to_parent)) 00082 != (int)strlen(msg_to_parent)) 00083 throw(ERROR(errno,"Error writing output to parent")); 00084 if (write(exe.err_fd(), msg_to_err, strlen(msg_to_err)) 00085 != (int)strlen(msg_to_err)) 00086 throw(ERROR(errno,"Error writing error to parent")); 00087 00088 assert(static_cast<std::string>(msg_from_parent) == "Message from parent"); 00089 00090 exe.exit(); 00091 } 00092 } 00093 */ 00094 00095 /* 00096 void test3(void) 00097 { 00098 execute exe; 00099 00100 exe.fork(); 00101 if (exe.is_parent()) { 00102 char *msg_to_child = "Message from parent"; 00103 char msg_from_child[4096] = { 0 }; 00104 char msg_from_err[4096] = { 0 }; 00105 char extra_msg[4096] = { 0 }; 00106 int extra_msg_length = 0; 00107 int i; 00108 00109 assert(exe.child_running()); 00110 assert(!exe.child_exited()); 00111 assert(!exe.child_exited_normally()); 00112 assert(!exe.child_signaled()); 00113 assert(exe.child_exit_code() == 0); 00114 assert(exe.child_signal_no() == 0); 00115 00116 assert(exe.in_ready()); 00117 assert(!exe.out_ready()); 00118 assert(!exe.err_ready()); 00119 00120 sleep(1); 00121 00122 assert(exe.in_ready()); 00123 assert(!exe.out_ready()); 00124 assert(!exe.err_ready()); 00125 00126 if (write(exe.in_fd(), msg_to_child, strlen(msg_to_child)) 00127 != (int)strlen(msg_to_child)) 00128 throw(ERROR(errno,"Error writing to child's input pipe")); 00129 00130 sleep(1); 00131 00132 assert(exe.in_ready()); 00133 assert(exe.out_ready()); 00134 assert(exe.err_ready()); 00135 00136 if (read(exe.out_fd(), msg_from_child, 4096) == 0) 00137 throw(ERROR(errno,"Error reading from child's output pipe")); 00138 00139 sleep(1); 00140 00141 assert(exe.in_ready()); 00142 assert(exe.out_ready()); 00143 assert(exe.err_ready()); 00144 00145 if (read(exe.err_fd(), msg_from_err, 4096) == 0) 00146 throw(ERROR(errno,"Error reading from child's error pipe")); 00147 00148 sleep(1); 00149 00150 assert(exe.in_ready()); 00151 assert(exe.out_ready()); 00152 assert(exe.err_ready()); 00153 00154 if (exe.out_ready()) { 00155 for (i = 0; i < 4096; extra_msg[i++] = 0); 00156 extra_msg_length = read(exe.out_fd(), extra_msg, 4096); 00157 } 00158 assert(extra_msg_length == 0); 00159 if (exe.err_ready()) { 00160 for (i = 0; i < 4096; extra_msg[i++] = 0); 00161 extra_msg_length = read(exe.err_fd(), extra_msg, 4096); 00162 } 00163 assert(extra_msg_length == 0); 00164 00165 exe.wait(); 00166 00167 assert(static_cast<std::string>(msg_from_child) == "Message from child"); 00168 assert(static_cast<std::string>(msg_from_err) == "Message from child err"); 00169 assert(!exe.child_running()); 00170 assert(exe.child_exited()); 00171 assert(exe.child_exited_normally()); 00172 assert(!exe.child_signaled()); 00173 assert(exe.child_exit_code() == 0); 00174 assert(exe.child_signal_no() == 0); 00175 } 00176 if (exe.is_child()) { 00177 char msg_from_parent[4096] = { 0 }; 00178 char *msg_to_parent = "Message from child"; 00179 char *msg_to_err = "Message from child err"; 00180 00181 if (read(exe.in_fd(), msg_from_parent, 4096) == 0) 00182 throw(ERROR(errno,"Error reading input from parent")); 00183 if (write(exe.out_fd(), msg_to_parent, strlen(msg_to_parent)) 00184 != (int)strlen(msg_to_parent)) 00185 throw(ERROR(errno,"Error writing output to parent")); 00186 if (write(exe.err_fd(), msg_to_err, strlen(msg_to_err)) 00187 != (int)strlen(msg_to_err)) 00188 throw(ERROR(errno,"Error writing error to parent")); 00189 00190 assert(static_cast<std::string>(msg_from_parent) == "Message from parent"); 00191 00192 exe.exit(); 00193 } 00194 } 00195 */ 00196 00197 /* 00198 void test4(void) 00199 { 00200 execute exe; 00201 00202 exe.fork(); 00203 if (exe.is_parent()) { 00204 assert(exe.child_running()); 00205 assert(!exe.child_exited()); 00206 assert(!exe.child_exited_normally()); 00207 assert(!exe.child_signaled()); 00208 assert(exe.child_exit_code() == 0); 00209 assert(exe.child_signal_no() == 0); 00210 00211 exe.wait(); 00212 00213 assert(!exe.child_running()); 00214 assert(exe.child_exited()); 00215 assert(exe.child_exited_normally()); 00216 assert(!exe.child_signaled()); 00217 assert(exe.child_exit_code() == 5); 00218 assert(exe.child_signal_no() == 0); 00219 } 00220 else { 00221 sleep(1); 00222 exe.exit(5); 00223 } 00224 } 00225 */ 00226 00227 /* 00228 void test5(void) 00229 { 00230 execute exe; 00231 00232 exe.fork(); 00233 if (exe.is_parent()) { 00234 assert(exe.child_running()); 00235 assert(!exe.child_exited()); 00236 assert(!exe.child_exited_normally()); 00237 assert(!exe.child_signaled()); 00238 assert(exe.child_exit_code() == 0); 00239 assert(exe.child_signal_no() == 0); 00240 00241 exe.signal_child(SIGINT); 00242 exe.wait(); 00243 00244 assert(!exe.child_running()); 00245 assert(exe.child_exited()); 00246 assert(!exe.child_exited_normally()); 00247 assert(exe.child_signaled()); 00248 assert(exe.child_exit_code() == 0); 00249 assert(exe.child_signal_no() == SIGINT); 00250 } 00251 else { 00252 sleep(5); 00253 exe.exit(5); 00254 } 00255 } 00256 */ 00257 00258 /* 00259 void test6(void) 00260 { 00261 execute exe; 00262 std::string command = "/bin/ls -1 ./test-exec.cc"; 00263 char buffer[4096] = { 0 }; 00264 int num_bytes; 00265 00266 exe.exec(command); 00267 00268 assert(exe.child_running()); 00269 assert(!exe.child_exited()); 00270 assert(!exe.child_exited_normally()); 00271 assert(!exe.child_signaled()); 00272 assert(exe.child_exit_code() == 0); 00273 assert(exe.child_signal_no() == 0); 00274 assert(exe.in_ready()); 00275 assert(!exe.out_ready()); 00276 assert(!exe.err_ready()); 00277 00278 for (num_bytes = 0; num_bytes < 4096; buffer[num_bytes++] = 0); 00279 num_bytes = read(exe.out_fd(), buffer, 4096); 00280 assert(num_bytes = 15); 00281 assert(static_cast<std::string>(buffer) == static_cast<std::string>("./test-exec.cc\n")); 00282 00283 for (num_bytes = 0; num_bytes < 4096; buffer[num_bytes++] = 0); 00284 num_bytes = read(exe.err_fd(), buffer, 4096); 00285 assert(num_bytes == 0); 00286 assert(static_cast<std::string>(buffer).size() == 0); 00287 00288 exe.wait(); 00289 00290 assert(!exe.child_running()); 00291 assert(exe.child_exited()); 00292 assert(exe.child_exited_normally()); 00293 assert(!exe.child_signaled()); 00294 assert(exe.child_exit_code() == 0); 00295 assert(exe.child_signal_no() == 0); 00296 assert(exe.in_ready()); 00297 assert(exe.out_ready()); 00298 assert(exe.err_ready()); 00299 } 00300 */ 00301 00302 /* 00303 void test7(void) 00304 { 00305 execute exe; 00306 ofdstream fdout; 00307 00308 exe.fork(); 00309 if (exe.is_parent()) { 00310 char *msg_to_child = "Message from parent"; 00311 char msg_from_child[4096] = { 0 }; 00312 char msg_from_err[4096] = { 0 }; 00313 00314 assert(exe.child_running()); 00315 assert(!exe.child_exited()); 00316 assert(!exe.child_exited_normally()); 00317 assert(!exe.child_signaled()); 00318 assert(exe.child_exit_code() == 0); 00319 assert(exe.child_signal_no() == 0); 00320 assert(fdout.good()); 00321 00322 fdout.attach(exe.in_fd()); 00323 fdout << msg_to_child; 00324 fdout.flush(); 00325 00326 assert(fdout.good()); 00327 00328 if (read(exe.out_fd(), msg_from_child, 4096) == 0) 00329 throw(ERROR(errno,"Error reading from child's output pipe")); 00330 if (read(exe.err_fd(), msg_from_err, 4096) == 0) 00331 throw(ERROR(errno,"Error reading from child's error pipe")); 00332 00333 exe.wait(); 00334 00335 assert(fdout.good()); 00336 00337 assert(static_cast<std::string>(msg_from_child) == "Message from child"); 00338 assert(static_cast<std::string>(msg_from_err) == "Message from child err"); 00339 assert(!exe.child_running()); 00340 assert(exe.child_exited()); 00341 assert(exe.child_exited_normally()); 00342 assert(!exe.child_signaled()); 00343 assert(exe.child_exit_code() == 0); 00344 assert(exe.child_signal_no() == 0); 00345 } 00346 else { 00347 char msg_from_parent[4096] = { 0 }; 00348 char *msg_to_parent = "Message from child"; 00349 char *msg_to_err = "Message from child err"; 00350 00351 if (read(exe.in_fd(), msg_from_parent, 4096) == 0) 00352 throw(ERROR(errno,"Error reading input from parent")); 00353 if (write(exe.out_fd(), msg_to_parent, strlen(msg_to_parent)) 00354 != (int)strlen(msg_to_parent)) 00355 throw(ERROR(errno,"Error writing output to parent")); 00356 if (write(exe.err_fd(), msg_to_err, strlen(msg_to_err)) 00357 != (int)strlen(msg_to_err)) 00358 throw(ERROR(errno,"Error writing error to parent")); 00359 00360 assert(static_cast<std::string>(msg_from_parent) == "Message from parent"); 00361 00362 exe.exit(); 00363 } 00364 } 00365 */ 00366 00367 /* 00368 void test8(void) 00369 { 00370 execute exe; 00371 ofdstream fdout; 00372 ifdstream fdin; 00373 00374 exe.fork(); 00375 if (exe.is_parent()) { 00376 char *msg_to_child = "Message from parent"; 00377 char msg_from_child[4096] = { 0 }; 00378 char msg_from_err[4096] = { 0 }; 00379 00380 assert(exe.child_running()); 00381 assert(!exe.child_exited()); 00382 assert(!exe.child_exited_normally()); 00383 assert(!exe.child_signaled()); 00384 assert(exe.child_exit_code() == 0); 00385 assert(exe.child_signal_no() == 0); 00386 00387 fdout.attach(exe.in_fd()); 00388 fdout << msg_to_child; 00389 fdout.flush(); 00390 00391 fdin.attach(exe.out_fd()); 00392 fdin.get(msg_from_child,4096); 00393 00394 if (read(exe.err_fd(), msg_from_err, 4096) == 0) 00395 throw(ERROR(errno,"Error reading from child's error pipe")); 00396 00397 exe.wait(); 00398 00399 assert(static_cast<std::string>(msg_from_child) == "Message from child"); 00400 assert(static_cast<std::string>(msg_from_err) == "Message from child err"); 00401 assert(!exe.child_running()); 00402 assert(exe.child_exited()); 00403 assert(exe.child_exited_normally()); 00404 assert(!exe.child_signaled()); 00405 assert(exe.child_exit_code() == 0); 00406 assert(exe.child_signal_no() == 0); 00407 } 00408 else { 00409 char msg_from_parent[4096] = { 0 }; 00410 char *msg_to_parent = "Message from child"; 00411 char *msg_to_err = "Message from child err"; 00412 00413 if (read(exe.in_fd(), msg_from_parent, 4096) == 0) 00414 throw(ERROR(errno,"Error reading input from parent")); 00415 if (write(exe.out_fd(), msg_to_parent, strlen(msg_to_parent)) 00416 != (int)strlen(msg_to_parent)) 00417 throw(ERROR(errno,"Error writing output to parent")); 00418 if (write(exe.err_fd(), msg_to_err, strlen(msg_to_err)) 00419 != (int)strlen(msg_to_err)) 00420 throw(ERROR(errno,"Error writing error to parent")); 00421 00422 assert(static_cast<std::string>(msg_from_parent) == "Message from parent"); 00423 00424 exe.exit(); 00425 } 00426 } 00427 */ 00428 00429 /* 00430 void test9(void) 00431 { 00432 execute exe; 00433 ofdstream fdout; 00434 ifdstream fdin; 00435 00436 exe.fork(); 00437 if (exe.is_parent()) { 00438 char *msg_to_child = "Message from parent"; 00439 char msg_from_child[4096] = { 0 }; 00440 char msg_from_err[4096] = { 0 }; 00441 00442 assert(exe.child_running()); 00443 assert(!exe.child_exited()); 00444 assert(!exe.child_exited_normally()); 00445 assert(!exe.child_signaled()); 00446 assert(exe.child_exit_code() == 0); 00447 assert(exe.child_signal_no() == 0); 00448 00449 fdout.attach(exe.in_fd()); 00450 // fdout << msg_to_child; 00451 // fdout.flush(); 00452 if (write(exe.in_fd(), msg_to_child, strlen(msg_to_child)) 00453 != (int)strlen(msg_to_child)) 00454 throw(ERROR(errno,"Error writing to child's input pipe")); 00455 00456 fdin.attach(exe.out_fd()); 00457 // fdin.get(msg_from_child,4096); 00458 if (read(exe.out_fd(), msg_from_child, 4096) == 0) 00459 throw(ERROR(errno,"Error reading from child's output pipe")); 00460 00461 if (read(exe.err_fd(), msg_from_err, 4096) == 0) 00462 throw(ERROR(errno,"Error reading from child's error pipe")); 00463 00464 exe.wait(); 00465 00466 assert(static_cast<std::string>(msg_from_child) == "Message from child"); 00467 assert(static_cast<std::string>(msg_from_err) == "Message from child err"); 00468 assert(!exe.child_running()); 00469 assert(exe.child_exited()); 00470 assert(exe.child_exited_normally()); 00471 assert(!exe.child_signaled()); 00472 assert(exe.child_exit_code() == 0); 00473 assert(exe.child_signal_no() == 0); 00474 } 00475 else { 00476 char msg_from_parent[4096] = { 0 }; 00477 char *msg_to_parent = "Message from child"; 00478 char *msg_to_err = "Message from child err"; 00479 00480 if (read(exe.in_fd(), msg_from_parent, 4096) == 0) 00481 throw(ERROR(errno,"Error reading input from parent")); 00482 if (write(exe.out_fd(), msg_to_parent, strlen(msg_to_parent)) 00483 != (int)strlen(msg_to_parent)) 00484 throw(ERROR(errno,"Error writing output to parent")); 00485 if (write(exe.err_fd(), msg_to_err, strlen(msg_to_err)) 00486 != (int)strlen(msg_to_err)) 00487 throw(ERROR(errno,"Error writing error to parent")); 00488 00489 assert(static_cast<std::string>(msg_from_parent) == "Message from parent"); 00490 00491 exe.exit(); 00492 } 00493 } 00494 */ 00495 00496 void test10(void) 00497 { 00498 execute exe; 00499 00500 exe.fork(); 00501 if (exe.is_parent()) { 00502 char *msg_to_child = "Message from parent"; 00503 char msg_from_child[4096] = { 0 }; 00504 char msg_from_err[4096] = { 0 }; 00505 00506 assert(exe.child_running()); 00507 assert(!exe.child_exited()); 00508 assert(!exe.child_exited_normally()); 00509 assert(!exe.child_signaled()); 00510 assert(exe.child_exit_code() == 0); 00511 assert(exe.child_signal_no() == 0); 00512 00513 assert(exe.in_ready()); 00514 assert(!exe.out_ready()); 00515 assert(!exe.err_ready()); 00516 assert(!exe.in_eof()); 00517 assert(!exe.out_eof()); 00518 assert(!exe.err_eof()); 00519 00520 if (exe.in_write(msg_to_child, strlen(msg_to_child)) 00521 != (int)strlen(msg_to_child)) 00522 throw(ERROR(errno,"Error writing to child's input pipe")); 00523 00524 // Wait until input is ready from child 00525 while (!exe.out_ready() && !exe.err_ready()); 00526 00527 assert(exe.in_ready()); 00528 assert(exe.out_ready()); 00529 assert(exe.err_ready()); 00530 assert(!exe.in_eof()); 00531 assert(!exe.out_eof()); 00532 assert(!exe.err_eof()); 00533 00534 if (exe.out_read(msg_from_child, 4096) == 0) 00535 throw(ERROR(errno,"Error reading from child's output pipe")); 00536 00537 assert(exe.in_ready()); 00538 00539 assert(!exe.out_ready() || !exe.child_running()); 00540 assert(exe.err_ready()); 00541 assert(!exe.in_eof()); 00542 assert(!exe.out_eof()); 00543 assert(!exe.err_eof()); 00544 00545 if (exe.err_read(msg_from_err, 4096) == 0) 00546 throw(ERROR(errno,"Error reading from child's error pipe")); 00547 00548 while (!exe.out_ready() && !exe.err_ready()); 00549 00550 assert(exe.in_ready()); 00551 assert(exe.out_ready()); 00552 assert(exe.err_ready()); 00553 assert(!exe.in_eof()); 00554 assert(!exe.out_eof()); 00555 assert(!exe.err_eof()); 00556 00557 exe.wait(); 00558 00559 assert(exe.in_ready()); 00560 assert(exe.out_ready()); 00561 assert(exe.err_ready()); 00562 assert(!exe.in_eof()); 00563 assert(!exe.out_eof()); 00564 assert(!exe.err_eof()); 00565 00566 assert(static_cast<std::string>(msg_from_child) == "Message from child"); 00567 assert(static_cast<std::string>(msg_from_err) == "Message from child err"); 00568 00569 assert(exe.out_read(msg_from_child, 4096) == 0); 00570 assert(exe.in_ready()); 00571 assert(exe.out_ready()); 00572 assert(exe.err_ready()); 00573 assert(!exe.in_eof()); 00574 assert(exe.out_eof()); 00575 assert(!exe.err_eof()); 00576 00577 assert(!exe.child_running()); 00578 assert(exe.child_exited()); 00579 assert(exe.child_exited_normally()); 00580 assert(!exe.child_signaled()); 00581 assert(exe.child_exit_code() == 0); 00582 assert(exe.child_signal_no() == 0); 00583 } 00584 if (exe.is_child()) { 00585 char msg_from_parent[4096] = { 0 }; 00586 char *msg_to_parent = "Message from child"; 00587 char *msg_to_err = "Message from child err"; 00588 00589 if (read(exe.in_fd(), msg_from_parent, 4096) == 0) 00590 throw(ERROR(errno,"Error reading input from parent")); 00591 if (write(exe.out_fd(), msg_to_parent, strlen(msg_to_parent)) 00592 != (int)strlen(msg_to_parent)) 00593 throw(ERROR(errno,"Error writing output to parent")); 00594 if (write(exe.err_fd(), msg_to_err, strlen(msg_to_err)) 00595 != (int)strlen(msg_to_err)) 00596 throw(ERROR(errno,"Error writing error to parent")); 00597 00598 assert(static_cast<std::string>(msg_from_parent) == "Message from parent"); 00599 00600 sleep(5); 00601 exe.exit(); 00602 } 00603 } 00604 00605 int main(int argc, char *argv[]) 00606 { 00607 try { 00608 /* 00609 test1(); 00610 test2(); 00611 test3(); 00612 test4(); 00613 test5(); 00614 test6(); 00615 test7(); 00616 test8(); 00617 test9(); 00618 */ 00619 test10(); 00620 } 00621 catch(error e) { 00622 std::cerr << e; 00623 assert(0); 00624 } 00625 catch(...) { 00626 std::cerr << err_unknown; 00627 assert(0); 00628 } 00629 return(0); 00630 } 00631