mirror of
https://github.com/tstack/lnav
synced 2024-11-17 15:29:40 +00:00
Merge pull request #228 from sureshsundriyal/wip4
[pretty] Don't wait indefinitely for reverse IP lookups.
This commit is contained in:
commit
43104ed687
@ -141,6 +141,7 @@ noinst_HEADERS = \
|
||||
textfile_sub_source.hh \
|
||||
textview_curses.hh \
|
||||
time_T.hh \
|
||||
timer.hh \
|
||||
top_status_source.hh \
|
||||
view_curses.hh \
|
||||
vt52_curses.hh \
|
||||
@ -203,6 +204,7 @@ libdiag_a_SOURCES = \
|
||||
sqlite-extension-func.c \
|
||||
statusview_curses.cc \
|
||||
string-extension-functions.cc \
|
||||
timer.cc \
|
||||
pcrepp.cc \
|
||||
piper_proc.cc \
|
||||
sql_util.cc \
|
||||
|
@ -30,18 +30,32 @@
|
||||
#ifndef __pretty_printer_hh
|
||||
#define __pretty_printer_hh
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <stack>
|
||||
#include <deque>
|
||||
#include <sstream>
|
||||
|
||||
#include "timer.hh"
|
||||
#include "ansi_scrubber.hh"
|
||||
#include "data_scanner.hh"
|
||||
|
||||
static sig_atomic_t reverse_lookup_enabled = 1;
|
||||
|
||||
void sigalrm_handler(int sig)
|
||||
{
|
||||
if (sig == SIGALRM)
|
||||
{
|
||||
reverse_lookup_enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class pretty_printer {
|
||||
|
||||
public:
|
||||
@ -149,14 +163,26 @@ private:
|
||||
require(0);
|
||||
break;
|
||||
}
|
||||
if (rc == 1) {
|
||||
while ((rc = getnameinfo((struct sockaddr *)&sa, socklen,
|
||||
buffer, sizeof(buffer), NULL, 0,
|
||||
NI_NAMEREQD)) == EAI_AGAIN) {
|
||||
usleep(1000);
|
||||
if (rc == 1 && reverse_lookup_enabled) {
|
||||
const struct timeval timeout = {3, 0};
|
||||
|
||||
{
|
||||
timer::interrupt_timer t(timeout, sigalrm_handler);
|
||||
if (t.arm_timer() == 0) {
|
||||
rc = getnameinfo((struct sockaddr *)&sa, socklen,
|
||||
buffer, sizeof(buffer), NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
if (rc == 0) {
|
||||
result = buffer;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_error("Unable to set timer, disabling reverse lookup");
|
||||
reverse_lookup_enabled = 0;
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
result = buffer;
|
||||
if (!reverse_lookup_enabled) {
|
||||
log_info("Reverse lookup in pretty-print view disabled");
|
||||
}
|
||||
}
|
||||
this->pp_stream << " " << ANSI_UNDERLINE_START <<
|
||||
|
112
src/timer.cc
Normal file
112
src/timer.cc
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (c) 2015, Suresh Sundriyal
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "timer.hh"
|
||||
#include "lnav_log.hh"
|
||||
|
||||
const struct itimerval disable = {
|
||||
{ 0, 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
timer::error::error(int err):e_err(err) { }
|
||||
|
||||
timer::interrupt_timer::interrupt_timer(struct timeval t,
|
||||
sighandler_t_ sighandler=SIG_IGN) : new_handler(sighandler),
|
||||
old_handler(NULL), new_val((struct itimerval){{0,0},t}),
|
||||
old_val(disable), armed(false) { }
|
||||
|
||||
int timer::interrupt_timer::arm_timer() {
|
||||
// Disable the interval timer before setting the handler and arming the
|
||||
// interval timer or else we will have a race-condition where the timer
|
||||
// might fire and the appropriate handler might not be set.
|
||||
if (setitimer(ITIMER_REAL, &disable, &this->old_val) != 0) {
|
||||
log_error("Unable to disable the timer: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
this->old_handler = signal(SIGALRM, this->new_handler);
|
||||
if (this->old_handler == SIG_ERR) {
|
||||
log_error("Unable to set the signal handler: %s",
|
||||
strerror(errno));
|
||||
if (setitimer(ITIMER_REAL, &this->old_val, NULL) != 0) {
|
||||
log_error("Unable to reset the interrupt timer: %s",
|
||||
strerror(errno));
|
||||
throw timer::error(errno);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setitimer(ITIMER_REAL, &this->new_val, NULL) != 0) {
|
||||
if(signal(SIGALRM, this->old_handler) == SIG_ERR) {
|
||||
log_error("Unable to reset the signal handler: %s",
|
||||
strerror(errno));
|
||||
throw timer::error(errno);
|
||||
}
|
||||
log_error("Unable to set the timer: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
this->armed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool timer::interrupt_timer::is_armed() {
|
||||
return this->armed;
|
||||
}
|
||||
|
||||
void timer::interrupt_timer::disarm_timer() {
|
||||
if (this->armed) {
|
||||
// Disable the interval timer before resetting the handler and rearming
|
||||
// the previous interval timer or else we will have a race-condition
|
||||
// where the timer might fire and the appropriate handler might not be
|
||||
// set.
|
||||
if (setitimer(ITIMER_REAL, &disable, NULL) != 0) {
|
||||
log_error("Failed to disable the timer: %s",
|
||||
strerror(errno));
|
||||
throw timer::error(errno);
|
||||
}
|
||||
if (signal(SIGALRM, this->old_handler) == SIG_ERR) {
|
||||
log_error("Failed to reinstall previous SIGALRM handler: %s",
|
||||
strerror(errno));
|
||||
throw timer::error(errno);
|
||||
}
|
||||
if (setitimer(ITIMER_REAL, &this->old_val, NULL) != 0) {
|
||||
log_error("Failed to reset the timer to previous value: %s",
|
||||
strerror(errno));
|
||||
throw timer::error(errno);
|
||||
}
|
||||
this->armed = false;
|
||||
this->old_val = disable;
|
||||
this->old_handler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
timer::interrupt_timer::~interrupt_timer() {
|
||||
this->disarm_timer();
|
||||
}
|
64
src/timer.hh
Normal file
64
src/timer.hh
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2015, Suresh Sundriyal
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef timer_hh
|
||||
#define timer_hh
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <exception>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// Linux and BSD seem to name the function pointer to signal handler differently.
|
||||
// Linux names it 'sighandler_t' and BSD names it 'sig_t'. Instead of depending
|
||||
// on configure scripts to find out the type name, typedef it right here.
|
||||
typedef void (*sighandler_t_)(int);
|
||||
|
||||
namespace timer{
|
||||
class error : public std::exception {
|
||||
public:
|
||||
error(int err);
|
||||
int e_err;
|
||||
};
|
||||
|
||||
class interrupt_timer {
|
||||
public:
|
||||
interrupt_timer(struct timeval, sighandler_t_);
|
||||
int arm_timer();
|
||||
void disarm_timer();
|
||||
bool is_armed();
|
||||
~interrupt_timer();
|
||||
private:
|
||||
sighandler_t_ new_handler, old_handler;
|
||||
struct itimerval new_val, old_val;
|
||||
bool armed;
|
||||
};
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user