zeek/src/Flare.cc
Jon Siwek 3996a54302 Merge branch 'noreturn' of https://github.com/MaxKellermann/zeek
Minor formatting change in merge so [[noreturn]] is consistently
on same line as function declarations.

* 'noreturn' of https://github.com/MaxKellermann/zeek:
  threading/MsgThread: add [[noreturn]] to InternalError()
  Flare: add [[noreturn]] to bad_pipe_op()
  Obj: add [[noreturn]] attributes to Internal(),  bad_ref()
  Reporter: add [[noreturn]] attribute to several methods
2020-02-21 15:37:33 -08:00

90 lines
1.5 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "Flare.h"
#include "Reporter.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
using namespace bro;
Flare::Flare()
: pipe(FD_CLOEXEC, FD_CLOEXEC, O_NONBLOCK, O_NONBLOCK)
{
}
[[noreturn]] static void bad_pipe_op(const char* which, bool signal_safe)
{
if ( signal_safe )
abort();
char buf[256];
bro_strerror_r(errno, buf, sizeof(buf));
if ( reporter )
reporter->FatalErrorWithCore("unexpected pipe %s failure: %s", which, buf);
else
{
fprintf(stderr, "unexpected pipe %s failure: %s", which, buf);
abort();
}
}
void Flare::Fire(bool signal_safe)
{
char tmp = 0;
for ( ; ; )
{
int n = write(pipe.WriteFD(), &tmp, 1);
if ( n > 0 )
// Success -- wrote a byte to pipe.
break;
if ( n < 0 )
{
if ( errno == EAGAIN )
// Success: pipe is full and just need at least one byte in it.
break;
if ( errno == EINTR )
// Interrupted: try again.
continue;
bad_pipe_op("write", signal_safe);
}
// No error, but didn't write a byte: try again.
}
}
int Flare::Extinguish(bool signal_safe)
{
int rval = 0;
char tmp[256];
for ( ; ; )
{
int n = read(pipe.ReadFD(), &tmp, sizeof(tmp));
if ( n >= 0 )
{
rval += n;
// Pipe may not be empty yet: try again.
continue;
}
if ( errno == EAGAIN )
// Success: pipe is now empty.
break;
if ( errno == EINTR )
// Interrupted: try again.
continue;
bad_pipe_op("read", signal_safe);
}
return rval;
}