std::string jevois::getPythonExceptionString(boost::python::error_already_set &)
{
  // Get some info from the python exception:
  PyObject *t, *v, *tb;

  try
  {
    PyErr_Fetch(&t, &v, &tb);
    PyErr_NormalizeException(&t, &v, &tb);
  }
  catch (...) { return "Internal error trying to fetch exception data from Python"; }
  
  try
  {
    boost::python::object objtype = ::ptr_to_obj(t);
    boost::python::object objvalue = ::ptr_to_obj(v);
    boost::python::object objtraceback = ::ptr_to_obj(tb);
  
    std::string const type = extract_exception_type(objtype);
    std::string const message = (type == "SyntaxError") ?
      make_syntax_error_message(objvalue) : extract_message(objvalue);
    traceback const traceback = extract_traceback(objtraceback);

    PyErr_Restore(t, v, tb);
    clear_exception();

    return generate_message(type, message, traceback);
  }
  catch (...)
  { PyErr_Restore(t, v, tb); clear_exception(); return "Internal error trying to fetch exception data from Python"; }
}
Example #2
0
/* -------------------------------------------------------------------------
   make_log_entry has 1 main flaws:
   The message in its entirity, must fit into the tempbuffer.
   So it must be shorter than MAXLOGSIZE
   ------------------------------------------------------------------------- */
void make_log_entry(enum loglevels loglevel, enum logtypes logtype,
                    const char *file, int line, char *message, ...)
{
    /* fn is not reentrant but is used in signal handler
     * with LOGGER it's a little late source name and line number
     * are already changed. */
    static int inlog = 0;
    int fd, len;
    char *user_message, *log_message;
    va_list args;

    if (inlog)
        return;

    inlog = 1;

    if (!log_config.inited) {
      log_init();
    }
    
    if (type_configs[logtype].syslog) {
        if (type_configs[logtype].level >= loglevel) {
            /* Initialise the Messages and send it to syslog */
            va_start(args, message);
            len = vasprintf(&user_message, message, args);
            va_end(args);
            if (len == -1) {
                return;
            }
            make_syslog_entry(loglevel, logtype, user_message);
            free(user_message);
        }
        inlog = 0;
        return;
    }

    /* logging to a file */

    log_src_filename = file;
    log_src_linenumber = line;

    /* Check if requested logtype is setup */
    if (type_configs[logtype].set) {
        /* Yes */
        fd = type_configs[logtype].fd;
    } else {
        /* No: use default */
        fd = type_configs[logtype_default].fd;
    }

    if (fd < 0) {
        /* no where to send the output, give up */
        goto exit;
    }

    /* Initialise the Messages */
    va_start(args, message);
    len = vasprintf(&user_message, message, args);
    if (len == -1) {
        goto exit;
    }
    va_end(args);

    len = generate_message(&log_message,
                           user_message,
                           type_configs[logtype].set ?
                           type_configs[logtype].display_options :
                           type_configs[logtype_default].display_options,
                           loglevel, logtype);
    if (len == -1) {
        goto exit;
    }
    write(fd, log_message, len);
    free(log_message);
    free(user_message);

exit:
    inlog = 0;
}
Example #3
0
int main(int argc, char* argv[])
{
signal( SIGTRAP, SIG_IGN );
params p = get_params( argc, argv );
unistd::addrinfo hint = addrinfo{ 0, AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 0, nullptr, nullptr, nullptr };
std::vector<unistd::addrinfo> addrs = unistd::getaddrinfo( p.hostname, p.port, hint );
const unistd::addrinfo& addr = addrs.at( 0 );
unistd::fd sock = unistd::socket( addr );
subscribe_events( sock );

if ( 0 != p.sndbuf )
    unistd::setsockopt( sock, SOL_SOCKET, SO_SNDBUF, p.sndbuf );

if ( 0 != p.mtu )
    {
    unistd::setsockopt( sock, IPPROTO_IPV6, IPV6_MTU_DISCOVER, IP_PMTUDISC_DONT );
    unistd::setsockopt( sock, IPPROTO_IPV6, IPV6_MTU, p.mtu );
    }

if ( p.nodelay )
    unistd::setsockopt( sock, SOL_SCTP, SCTP_NODELAY, 1 );

if ( 0 != p.max_burst )
    unistd::setsockopt( sock, SOL_SCTP, SCTP_MAX_BURST, p.max_burst );

if ( 0 != p.maxseg )
    unistd::setsockopt( sock, SOL_SCTP, SCTP_MAXSEG, p.maxseg );

int sndbuf = 0;
socklen_t len = sizeof(sndbuf);
getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len );
fprintf( stderr, "sndbuf: set=%d get=%d\n", p.sndbuf, sndbuf );

if ( 0 != p.rcvbuf )
    unistd::setsockopt( sock, SOL_SOCKET, SO_RCVBUF, p.rcvbuf );

sctp_initmsg init_params;
memset( &init_params, 0, sizeof(init_params) );
init_params.sinit_num_ostreams = 1;
init_params.sinit_max_instreams = 1;
init_params.sinit_max_attempts = 3;
init_params.sinit_max_init_timeo = 100;
unistd::setsockopt( sock, SOL_SCTP, SCTP_INITMSG, init_params );

unistd::connect( sock, addr );

sctp_assoc_t assoc_id = 0;
while ( assoc_id == 0 )
    {
    std::vector<char> cmsg_buff( CMSG_SPACE( sizeof( sctp_sndrcvinfo ) ) );
    std::vector<char> msg_buff( 8192 ); //TODO:

    struct iovec iov;
    memset( &iov, 0, sizeof(iov) );
    iov.iov_base = msg_buff.data();
    iov.iov_len = msg_buff.size();

    struct msghdr hdr;
    memset( &hdr, 0, sizeof(hdr) );
    hdr.msg_name = nullptr;
    hdr.msg_namelen = 0;
    hdr.msg_iov = &iov;
    hdr.msg_iovlen = 1;
    hdr.msg_control = cmsg_buff.data();
    hdr.msg_controllen = cmsg_buff.size();
    hdr.msg_flags = 0;

    ssize_t nrecv = 0;
    TEMP_FAILURE_RETRY( nrecv = recvmsg( sock, &hdr, 0 ) );
    if ( 0 == nrecv )
        raise( SIGTRAP );
    if ( -1 == nrecv )
        raise( SIGTRAP );
    if ( hdr.msg_flags & MSG_NOTIFICATION )
        {
        const sctp_notification& notify = *reinterpret_cast<const sctp_notification*>( hdr.msg_iov[0].iov_base );
        switch ( notify.sn_header.sn_type )
            {
            case SCTP_ASSOC_CHANGE:
                {
                const auto& sac = notify.sn_assoc_change;
        std::cout << " assoc_id=" << sac.sac_assoc_id << " error=" << sac.sac_error << " in=" << sac.sac_inbound_streams << " out=" << sac.sac_outbound_streams << std::endl;
                assoc_id = sac.sac_assoc_id;
                break;
                }
            case SCTP_REMOTE_ERROR:
                {
                const auto& sre = notify.sn_remote_error;
                printf( "^^^ remote_error: err=%hu len=%hu\n", ntohs(sre.sre_error), ntohs(sre.sre_length) );
                return EXIT_FAILURE;
                }
            case SCTP_SHUTDOWN_EVENT:
                {
                printf( "^^^ SCTP_SHUTDOWN_EVENT\n" );
                return EXIT_FAILURE;
                }
            }
        }
    }

//int flags = fcntl( sock, F_GETFL, 0 );
//fcntl( sock, F_SETFL, flags | O_NONBLOCK );

const std::vector<char> msg = generate_message( p.msgsize );
struct iovec iov;
iov.iov_base = const_cast<char*>( msg.data() );
iov.iov_len = msg.size();
std::vector<char> cmsg_buff( CMSG_SPACE( sizeof( sctp_sndrcvinfo ) ) );

struct mmsghdr mhdr;
memset( &mhdr, 0, sizeof(mhdr) );
struct msghdr& hdr = mhdr.msg_hdr;
hdr.msg_name = nullptr;
hdr.msg_namelen = 0;
hdr.msg_iov = &iov;
hdr.msg_iovlen = 1;
hdr.msg_flags = 0;
hdr.msg_control = cmsg_buff.data();
hdr.msg_controllen = cmsg_buff.size();

cmsghdr* cmsg = CMSG_FIRSTHDR( &hdr );
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN( sizeof( sctp_sndrcvinfo ) );
sctp_sndrcvinfo& cmsg_data = *reinterpret_cast<sctp_sndrcvinfo*>( CMSG_DATA( cmsg ) );
cmsg_data.sinfo_stream = 0;
cmsg_data.sinfo_ssn = 0; //ignored
cmsg_data.sinfo_flags = SCTP_UNORDERED;
cmsg_data.sinfo_ppid = 31337;
cmsg_data.sinfo_context = 123456;
cmsg_data.sinfo_timetolive = 0;
cmsg_data.sinfo_tsn = 0; //ignored
cmsg_data.sinfo_cumtsn = 0; //ignored
cmsg_data.sinfo_assoc_id = assoc_id;

std::vector<mmsghdr> mhdrs( p.batch, mhdr );

while ( p.count )
    {
    const ssize_t count = std::min<uint64_t>( p.batch, p.count );
    ssize_t nsend = 0;
    TEMP_FAILURE_RETRY( nsend = sendmmsg( sock, mhdrs.data(), count, 0 ) );
    if ( 0 == nsend )
        raise( SIGTRAP );
    if ( -1 == nsend )
        raise( SIGTRAP );
    if ( count != nsend )
        raise( SIGTRAP );
    p.count -= count;
    }

//raise( SIGTRAP );

sock.close();
return EXIT_SUCCESS;
}