Thanks for being patient with me.
Each line of data being written can have different piecs of data
<uniqueID> <GLIBC_OPERATION> <CONT><OPERATION-SPECIFC-ARGUMENTS-AS-JSON_OBJECT-STRING>.
where is * if the data is in that line is partial, because lib::PIPE_BUF was reached and will be continued in the next buffered write
So was looking for a simple convenient way/API to implement report_readlink(), report_execvp, report_symlink(), etc to be to written. I currently do this as
pub unsafe fn reportsymlink(self: &Self, target: *const libc::c_char, linkpath: *const libc::c_char) {
let args = (utils::ptr2str(target), pathgetabs(linkpath,AT_FDCWD));
write!(self.file, "{} SYMLINK {}", UUID&serde_json::to_string(&args).unwrap());
}
If I have to write each of the fields as an individual fields, the report*() code can become quite long
I also need buffered writing, where the buffer is thread local, so that when a multithreaded program invokes my LD_PRELOAD intercept, there is zero locking. I do buffering because, doing syscalls for individual seems expense. When I did a "linux perf" evaluation. So I want to buffer upto to libc::PIPE_BUF, before write in blocks of libc::PIPE_BUF
I started with BufferedWrite, but I read here that it has a single buffer. That means it cannot be shared by writes from multiple threads.
So I am doing my own implementation of BufferedWrite using thread_local!{} buffers. Trouble there is, I am yet to figure out how can I do thread local buffer fields within the BufferedWrite instance. So far I have seen thread_local examples of globals or BufferedWrite class level statics. Not how to make it threadlocal and specific to the instance Buffered Write. There are atleast 2 instances of BufferedWrite, for 2 destination files.
Thanks for this example. That shows me how to implement custom Display code for my structures/data.