# HG changeset patch # User pkienzle # Date 1056404072 0 # Node ID 69c8bde06b0e505ef70855e60f94b2cf182c6e08 # Parent 2aac9ad934a9bb5a7b331d1d929b791ef3cade42 Make debug a run time rather than compile time option. diff -r 2aac9ad934a9 -r 69c8bde06b0e main/miscellaneous/listen.cc --- a/main/miscellaneous/listen.cc Sat Jun 21 02:57:29 2003 +0000 +++ b/main/miscellaneous/listen.cc Mon Jun 23 21:34:32 2003 +0000 @@ -1,18 +1,12 @@ -#ifdef EBUG -#define STATUS(x) do { std::cout << x << std::endl << std::flush; } while (0) -#define DEBUG 1 -#else -#define STATUS(x) do {} while (0) -#define DEBUG 0 -#endif +#define STATUS(x) do { if (debug) std::cout << x << std::endl << std::flush; } while (0) #include -#include -#include +#include +#include #include -#include -#include +#include +// #include #include #include #include @@ -24,6 +18,16 @@ #include #include #include +#include + +static bool debug = false; + +// XXX FIXME XXX --- surely this is part of the standard library? +void +lowercase (std::string& s) +{ + for (std::string::iterator i=s.begin(); i != s.end(); i++) *i = tolower(*i); +} octave_value get_builtin_value (const std::string& nm) @@ -94,7 +98,13 @@ } -#if !DEBUG && !defined(__CYGWIN__) +#if defined(__CYGWIN__) + +// Don't daemonize on cygwin just yet. +inline void daemonize(void) {} + +#else + static RETSIGTYPE sigterm_handler(int /* sig */) { @@ -105,7 +115,9 @@ static void daemonize(void) { + if (debug) return; /* Don't daemonize if debugging */ if (fork()) exit(0); + std::cout << "Octave pid: " << octave_syscalls::getpid() << std::endl; signal(SIGTERM,sigterm_handler); signal(SIGQUIT,sigterm_handler); @@ -113,8 +125,7 @@ freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); } -#else -inline void daemonize(void) {} + #endif @@ -146,10 +157,8 @@ // STATUS("entering reads loop with size " << n); while (1) { int chunk = read(channel, buf, n); -#if DEBUG if (chunk == 0) STATUS("read socket returned 0"); if (chunk < 0) STATUS("read socket: " << strerror(errno)); -#endif if (chunk <= 0) return false; n -= chunk; // if (n == 0) STATUS("done reads loop"); @@ -163,10 +172,8 @@ // STATUS("entering writes loop"); while (1) { int chunk = write(channel, buf, n); -#if DEBUG if (chunk == 0) STATUS("write socket returned 0"); if (chunk < 0) STATUS("write socket: " << strerror(errno)); -#endif if (chunk <= 0) return false; n -= chunk; // if (n == 0) STATUS("done writes loop"); @@ -271,35 +278,35 @@ // write the matrix contents const double *v = m.data(); // data if (ok) ok = writes(channel,v,sizeof(double)*m.rows()*m.columns()); -#if DEBUG if (ok) STATUS("sent " << m.rows()*m.columns()); else STATUS("failed " << m.rows()*m.columns()); -#endif } break; case 'x': // silently execute the command { -#if DEBUG - if (len > 500) + if (debug) { - // XXX FIXME XXX can we limit the maximum output width for a - // string? The setprecision() io manipulator doesn't do it. - // In the meantime, a hack ... - char t = buffer[400]; buffer[400] = '\0'; - STATUS("evaluating (" << len << ") " - << buffer << std::endl - << "..." << std::endl - << buffer+len-100); - buffer[400] = t; + if (len > 500) + { + // XXX FIXME XXX can we limit the maximum output width for a + // string? The setprecision() io manipulator doesn't do it. + // In the meantime, a hack ... + char t = buffer[400]; buffer[400] = '\0'; + STATUS("evaluating (" << len << ") " + << buffer << std::endl + << "..." << std::endl + << buffer+len-100); + buffer[400] = t; + } + else + { + STATUS("evaluating (" << len << ") " << buffer); + } } - else - { - STATUS("evaluating (" << len << ") " << buffer); - } -#endif + int parse_status = 0; error_state = 0; eval_string(buffer, true, parse_status, 0); @@ -450,6 +457,10 @@ Listen for connections on the given port. Normally only accepts\n\ connections from localhost (127.0.0.1), but you can specify any\n\ dot-separated host name.\n\ +listen(...,debug|nodebug)\n\ + If debug, echo all commands sent across the connection. If nodebug,\n\ + detach the process and don't echo anything. You will need to use\n\ + kill directly to end the process. Nodebug is the default.\n\ ") { install_builtin_function (Fsend, "send", "builtin send doc", false); @@ -460,10 +471,9 @@ bool canfork = true; #endif - octave_value_list ret; int nargin = args.length(); - if (nargin < 1 || nargin > 2) + if (nargin < 1) { print_usage("listen"); return ret; @@ -472,6 +482,21 @@ int port = args(0).int_value(); if (error_state) return ret; + if (nargin >= 2) { + std::string lastarg(args(nargin-1).string_value()); + if (error_state) return ret; + lowercase(lastarg); + if (lastarg == "debug") { + debug = true; + nargin--; + } else if (lastarg == "nodebug") { + debug = false; + nargin--; + } else { + debug = false; + } + } + struct in_addr localhost; struct in_addr hostid; inet_aton("127.0.0.1",&localhost); @@ -536,7 +561,14 @@ STATUS("trying to accept"); if ((channel = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { - STATUS("failed to accept"); + // XXX FIXME XXX + // Linux is returning "Interrupted system call" when the + // child terminates. Until I figure out why, I can't use + // accept errors as a basis for breaking out of the listen + // loop, so instead print the octave PID so that I can kill + // it from another terminal. + STATUS("failed to accept" << std::endl + << "Octave pid: " << octave_syscalls::getpid() ); perror("accept"); #if defined(__CYGWIN__) || defined(_sgi) break; @@ -582,6 +614,7 @@ } STATUS("could not read commands; returning"); + close(sockfd); unwind_protect::run_frame("Flisten"); return ret; }