Er, I knew my description would be not as good as it could be.
My aim was to catch all the printf and similar output from third-party code I have no control over, from stdout and redirect it to my own logger. This logger can then record and update the ncurses display with its own formatted output. Except the ncurses displays using stdout, so any re-direction caused ncurses to be logged. And no re-direction caused printf's to corrupt the display.
Thanks for answering though, because on the plus side, as always happens when you post and ask for help, writing the post seems to clarify things in your mind and after days of work and searching a solution presents itself...
For anyone else that needs this:
1. Instead of using initscr(), use newterm() with the default terminal file desciptor to start ncurses:
FILE *fd = fopen("/dev/tty", "r+");
SCREEN *scr = newterm(NULL, fd, fd);
This opens a new ncurses terminal bypassing stdin and stdout (I think). stdout can then by redirected wherever:
I then use setvbuf(stdout, NULL, _IONBF, 0) to make stdout unbuffered. This doesn't seem to automatically pass printf's with no "\n" through, so in an ncurses update function, I call fflush(stdout) every pass to punt through the messages. And hey presto I seem to be getting there!
Don't forget delscreen(scr) when you're done with ncurses.