Changeset 1817
- Timestamp:
- 2000-12-20T11:30:34+13:00 (23 years ago)
- Location:
- trunk/gsdl
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gsdl/lib/gsdltools.cpp
r1793 r1817 53 53 } 54 54 55 // gsdl_system spawns a completely separate program (i.e. the calling 56 // program continues and terminates normally). Arguments containing special 57 // characters (e.g. '&') should be quoted with "" 55 // gsdl_system creates a new process for the cmd command (which 56 // may contain arguments). 57 // cmd should contain the full path of the program to run. 58 // The child process inherits the environment of the calling 59 // process. 60 // If sync is true a synchronous call will be made, otherwise 61 // an asyncronous call. 62 // If sync is true the return value will be the exit code of 63 // the child process or -1 if the child process wasn't started. 64 // If sync is false the return value will be 0 if the process 65 // was started ok or -1 if it failed. 66 int gsdl_system (const text_t &cmd, bool sync, ostream &logout) { 67 if (cmd.empty()) return -1; 68 char *cmd_c = cmd.getcstr(); 58 69 59 70 #if defined (__WIN32__) 60 void gsdl_system (char *cmd, ostream &logout) { 61 71 // the windows version - this is implemented this way 72 // to prevent windows popping up all over the place when 73 // we call a console application (like perl) 62 74 STARTUPINFO ps = {sizeof(STARTUPINFO), NULL, NULL, NULL, 63 75 0, 0, 0, 0, 0, 0, 64 0, 0,65 0, 0, NULL,76 0, STARTF_USESHOWWINDOW, 77 SW_HIDE, 0, NULL, 66 78 NULL, NULL, NULL}; 67 79 PROCESS_INFORMATION pi; 68 80 BOOL res = CreateProcess(NULL, 69 cmd ,81 cmd_c, 70 82 NULL, 71 83 NULL, 72 84 FALSE, 73 DETACHED_PROCESS,85 NULL, 74 86 NULL, 75 87 NULL, … … 77 89 &pi); 78 90 if (!res) { 79 logout << "Failed to start " << cmd << " process, error code " << GetLastError(); 91 logout << "gsdl_system failed to start " << cmd_c 92 << " process, error code " << GetLastError(); 93 delete cmd_c; 94 return -1; 80 95 } 96 97 DWORD ret = 0; 98 if (sync) { // synchronous system call 99 // wait until child process exits. 100 WaitForSingleObject(pi.hProcess, INFINITE); 101 // set ret to exit code of child process 102 GetExitCodeProcess(pi.hProcess, &ret); 103 } 81 104 82 105 CloseHandle(pi.hProcess); 83 106 CloseHandle(pi.hThread); 84 }85 107 86 108 #else 87 void gsdl_system (char *cmd, ostream &logout) { 109 // the unix version 110 int ret = 0; 111 if (sync) { // synchronous system call 112 // make sure the command interpreter is found 113 if (system (NULL) == 0) { 114 logout << "gsdl_system failed to start " << cmd_c 115 << " process, command interpreter not found\n"; 116 delete cmd_c; 117 return -1; 118 } 119 ret = system (cmd_c); 88 120 89 if (cmd == NULL) return; 90 int pid = fork(); 91 if (pid == -1) return; 92 if (pid == 0) { 93 // child process 94 char *argv[4]; 95 argv[0] = "sh"; 96 argv[1] = "-c"; 97 argv[2] = cmd; 98 argv[3] = 0; 99 execv("/bin/sh", argv); 100 // exit(127); 121 } else { // asynchronous system call 122 int pid = fork(); 123 if (pid == -1) { 124 delete cmd_c; 125 return -1; 126 } 127 if (pid == 0) { 128 // child process 129 char *argv[4]; 130 argv[0] = "sh"; 131 argv[1] = "-c"; 132 argv[2] = cmd; 133 argv[3] = 0; 134 execv("/bin/sh", argv); 135 } 101 136 } 102 }103 137 #endif 104 138 105 106 // gsdl_call_perl executes the perl script perl_cmd, passing it all the 107 // arguments provided. 108 109 // Arguments should be char*'s, the last argument should be NULL 110 111 // perl_cmd shouldn't contain the path to the script as we use "perl -S" 112 // to find it. This means that the PATH environment variable of the calling 113 // process should contain the directory where the perl_cmd script lives. 114 115 // Uses a standard system() call on unix and a synchronous _spawn() on windows. 116 // We use the _spawn() because windows 9* doesn't seem to pass the 117 // environment of the calling process to the new process when using 118 // system (which we need to do). 119 120 // all arguments will be quoted with double quotes [""] so they should be unquoted 121 // when passed in. 122 123 // returns the exit status of the called process (-1 if system() or _spawn() failed) 124 125 int gsdl_call_perl (char *perl_cmd, ...) { 126 127 va_list argn; 128 char *thisarg = perl_cmd; 129 130 #if defined(__WIN32__) && !defined (__GNUC__) 131 int i = 2; 132 #define GSDL_MAX_ARGS 20 133 char *args[GSDL_MAX_ARGS]; 134 args[0] = "perl"; 135 args[1] = "-S"; 136 #else 137 text_t cmd = "perl -S"; 138 #endif 139 140 // get arguments 141 va_start(argn, perl_cmd); 142 while(thisarg != NULL) { 143 #if defined(__WIN32__) && !defined (__GNUC__) 144 if (i >= GSDL_MAX_ARGS) break; 145 text_t tmp = thisarg; 146 tmp = "\"" + tmp + "\""; 147 args[i] = tmp.getcstr(); 148 i++; 149 #else 150 cmd += " \""; 151 cmd += thisarg; 152 cmd.push_back ('"'); 153 #endif 154 thisarg = va_arg(argn, char *); 155 } 156 va_end(argn); 157 158 #if defined(__WIN32__) && !defined (__GNUC__) 159 args[i] = NULL; 160 int rv = _spawnvp (_P_WAIT, "perl", args); 161 while (--i > 2) delete (args[i]); 162 #else 163 char *cmdc = cmd.getcstr(); 164 int rv = system (cmdc); 165 delete (cmdc); 166 #endif 167 return rv; 139 delete cmd_c; 140 return ret; 168 141 } 169 142 170 143 // attempts to work out if perl is functional 171 bool perl_ok ( ) {144 bool perl_ok (ostream &logout) { 172 145 #if defined(__WIN32__) 173 int i = gsdl_call_perl ("-e", "exit 1", NULL); 146 text_t cmd = "perl -e \"exit 1\""; 147 #else 148 text_t cmd = "perl -e \"'exit 1'\""; 149 #endif; 150 int i = gsdl_system (cmd, true, logout); 174 151 return (i == 1); 175 #else176 int i = gsdl_call_perl ("-e", "'exit 0'", NULL);177 return (i == 0);178 #endif179 152 } -
trunk/gsdl/lib/gsdltools.h
r1783 r1817 36 36 bool littleEndian(); 37 37 38 39 38 // escapes '\' and '_' characters with '\' 40 39 // note that single '\' characters occurring … … 43 42 text_t dm_safe (const text_t &instring); 44 43 44 // gsdl_system creates a new process for the cmd command (which 45 // may contain arguments). 46 // cmd should contain the full path of the program to run. 47 // The child process inherits the environment of the calling 48 // process. 49 // If sync is true a synchronous call will be made, otherwise 50 // an asyncronous call. 51 // If sync is true the return value will be the exit code of 52 // the child process or -1 if the child process wasn't started. 53 // If sync is false the return value will be 0 if the process 54 // was started ok or -1 if it failed. 55 int gsdl_system (const text_t &cmd, bool sync, ostream &logout); 45 56 46 // gsdl_system spawns a completely separate program (i.e. the calling47 // program continues and terminates normally). Arguments containing special 48 // characters (e.g. '&') should be quoted with "" 49 void gsdl_system (char *cmd, ostream &logout); 57 // attempts to work out if perl is functional 58 bool perl_ok (ostream &logout); 59 60 #endif 50 61 51 62 52 // gsdl_call_perl executes the perl script perl_cmd, passing it all the53 // arguments provided.54 63 55 // Arguments should be text_t's, the last argument should be an empty text_t.56 64 57 // perl_cmd shouldn't contain the path to the script as we use "perl -S"58 // to find it. This means that the PATH environment variable of the calling59 // process should contain the directory where the perl_cmd script lives.60 65 61 // Uses a standard system() call on unix and a synchronous _spawn() on windows.62 // We use the _spawn() because windows 9* doesn't seem to pass the63 // environment of the calling process to the new process when using64 // system (which we need to do).65 66 66 // all arguments will be quoted with double quotes [""] so they should be unquoted67 // when passed in.68 67 69 // returns the exit status of the called process (-1 if system() or _spawn() failed)70 int gsdl_call_perl (char *perl_cmd, ...);71 72 // attempts to work out if perl is functional73 bool perl_ok ();74 75 #endif -
trunk/gsdl/src/recpt/collectoraction.cpp
r1796 r1817 309 309 // clean up any old builds left laying about in the tmp directory 310 310 // (note that it's possible this could take some time if there's a huge 311 // partially built collection laying about -- may need to think about doing312 // this in the background).313 gsdl_ call_perl ("cleantmp.pl", NULL);311 // partially built collection laying about so we'll make it an asynchronous 312 // system call) 313 gsdl_system ("perl -S cleantmp.pl", false, logout); 314 314 } 315 315 … … 1007 1007 text_t &collection = args["bc1dirname"]; 1008 1008 1009 // make sure we have perl (we'll only do this when entering 1010 // the intro page to minimise the number of annoying console 1011 // windows that get popped up on windows -- this should be ok 1012 // for now as the intro page is the only access point into the 1013 // collector) 1014 if (collector_page == "intro" && !perl_ok()) { 1009 // make sure we have perl (we won't bother with this check for the 1010 // building status pages to avoid slowing things down unneccessarily) 1011 if (collector_page != "bildstatus" && collector_page != "bildframe1" && !perl_ok(logout)) { 1015 1012 textout << outconvert 1016 1013 << "<html>\n" … … 1086 1083 remove_colservr (collection, logout); 1087 1084 1088 1089 char *collectionc = collection.getcstr(); 1090 int rv = gsdl_call_perl ("delcol.pl", "-f", collectionc, NULL); 1091 delete collectionc; 1085 text_t delete_cmd = "perl -S delcol.pl -f " + collection; 1086 int rv = gsdl_system (delete_cmd, true, logout); 1092 1087 if (rv != 0) { 1093 1088 // deletion failed -- permissions? … … 1134 1129 char *tmpmailfilec = tmpmailfile.getcstr(); 1135 1130 ofstream tmpfile (tmpmailfilec); 1131 delete tmpmailfilec; 1136 1132 if (tmpfile) { 1137 1133 tmpfile << outconvert << "[Collector Event]\n" … … 1155 1151 to += colmaintainer; 1156 1152 } 1157 char *to_c = to.getcstr(); 1158 char *from_c = rcinfo.maintainer.getcstr(); 1159 char *smtp_c = rcinfo.MailServer.getcstr(); 1160 gsdl_call_perl ("sendmail.pl", "-to", to_c, "-from", from_c, "-smtp", smtp_c, 1161 "-subject", "Greenstone Collector Event", "-msgfile", tmpmailfilec, NULL); 1162 delete (to_c); 1163 delete (from_c); 1164 delete (smtp_c); 1153 text_t sendmail_cmd = "perl -S sendmail.pl -to \"" + to + "\" -from \"" + rcinfo.maintainer; 1154 sendmail_cmd += "\" -smtp \"" + rcinfo.MailServer + "\" -subject \"Greenstone Collector Event\""; 1155 sendmail_cmd += " -msgfile \"" + tmpmailfile + "\""; 1156 1157 gsdl_system (sendmail_cmd, false, logout); 1165 1158 1166 1159 } else { … … 1346 1339 text_t optionfile = filename_cat (tmpdir, "mkcol.opt"); 1347 1340 char *optionfilec = optionfile.getcstr(); 1341 delete optionfilec; 1348 1342 ofstream ofile_out (optionfilec); 1349 1343 if (!ofile_out) { … … 1356 1350 ofile_out.close(); 1357 1351 1358 char *collectionc = collection.getcstr(); 1359 1360 // this is just an ordinary system call running in the foreground. we're assuming (hoping??) 1361 // that mkcol.pl will run through fast enough that nothing more elaborate is required. 1362 gsdl_call_perl ("mkcol.pl", "-optionfile", optionfilec, collectionc, NULL); 1363 1364 delete optionfilec; 1365 delete collectionc; 1352 // run mkcol.pl 1353 text_t mkcol_cmd = "perl -S mkcol.pl -optionfile \"" + optionfile; 1354 mkcol_cmd += "\" " + collection; 1355 gsdl_system (mkcol_cmd, true, logout); 1366 1356 1367 1357 // make sure it went ok … … 1481 1471 1482 1472 // set up the build command 1483 // Can't seem to get "perl -S" to work properly here on windows 95... 1484 //text_t build_cmd = "perl -S build -optionfile \"" + optionfile + "\" " + collection; 1485 text_t build_cmd = "perl \"" + filename_cat(gsdlhome, "bin", "script", "build") + 1486 "\" -optionfile \"" + optionfile + "\" " + collection; 1487 char *build_cmdc = build_cmd.getcstr(); 1488 // run build command in background 1489 gsdl_system (build_cmdc, logout); 1490 delete build_cmdc; 1473 text_t build_cmd = "perl -S build -optionfile \"" + optionfile + "\" " + collection; 1474 // run build command in background (i.e. asynchronously) 1475 gsdl_system (build_cmd, false, logout); 1491 1476 } 1492 1477 … … 1495 1480 // c++ code. I ran into some problems though (like how do you write a portable 1496 1481 // "rm -r" in c++?). One day I'll spend some time sorting it out ... maybe. 1497 text_t collectdir = filename_cat (gsdlhome, "tmp", args["bc1tmp"]); 1498 char *collectdirc = collectdir.getcstr(); 1499 char *collectionc = args["bc1dirname"].getcstr(); 1500 1501 gsdl_call_perl ("cancel_build.pl", "-collectdir", collectdirc, collectionc, NULL); 1502 delete (collectdirc); 1503 delete (collectionc); 1482 text_t cancel_cmd = "perl -S cancel_build.pl -collectdir \""; 1483 cancel_cmd += filename_cat (gsdlhome, "tmp", args["bc1tmp"]) + "\" "; 1484 cancel_cmd += args["bc1dirname"]; 1485 // To be on the safe side we'll make this a synchronous call 1486 // so that all tidying up is done before the user has a chance 1487 // to do anything else (like start rebuilding their collection). 1488 // This means that for a big collection where there's lots of 1489 // stuff to delete etc. it might take a while before the "build 1490 // cancelled" page appears. 1491 gsdl_system (cancel_cmd, true, logout); 1504 1492 } 1505 1493
Note:
See TracChangeset
for help on using the changeset viewer.