Skip to main content

sd1

Function sd1 

Source
pub unsafe extern "C" fn sd1(
    socket: I,
    function: extern "C" fn(I) -> K,
) -> K
Expand description

Register callback to the associated kdb+ socket.

use kdbplus::qtype;
use kdbplus::api::*;
use kdbplus::api::native::*;
use std::ffi::c_void;

// Send asynchronous query to the q process which sent a query to the caller of this function.
extern "C" fn counter(socket: I) -> K{
  let extra_query="show `$\"Counter_punch!!\"".as_bytes();
  let query_length=extra_query.len();
  // header (8) + list header (6) + data length
  let total_length=8+6+query_length;
  // Buffer
  let mut message: Vec<u8>=Vec::with_capacity(total_length);
  // Little endian, async, uncompress, reserved
  message.extend_from_slice(&[1_u8, 0, 0, 0]);
  // Total message length
  message.extend_from_slice(&(total_length as i32).to_le_bytes());
  // Data type, attribute
  message.extend_from_slice(&[10_u8, 0]);
  // Length of data
  message.extend_from_slice(&(query_length as i32).to_le_bytes());
  // Data
  message.extend_from_slice(extra_query);
  // Send
  unsafe{libc::send(socket, message.as_slice().as_ptr() as *const c_void, total_length, 0)};
  KNULL
}

#[no_mangle]
pub extern "C" fn enable_counter(socket: K) -> K{
  unsafe{
    let result=sd1(socket.get_int().expect("oh no"), counter);
    if result.get_type()== qtype::NULL || result.get_type()== qtype::ERROR{
      return krr(null_terminated_str_to_const_S("Failed to hook\0"));
    }
    else{
      KNULL
    }
  }
}
q)// process1
q)enable_counter: `libc_api_examples 2: (`enable_counter; 1)
q)\p 5000
q)// process2
q)h:hopen `:unix://5000
q)// process1
q).z.W
5|
q)enable_counter[5i]
q)// process2
q)h "1+2"
`Counter_punch!!
3
q)neg[h] "1+2"
`Counter_punch!!