[ts-gen] Hooking into shim directly via C/C++
Nils Gebhardt
mail at ngebhardt.de
Thu Aug 27 13:40:15 EDT 2009
On Thu, 2009-08-27 at 09:05 +0900, Ken Feng wrote:
> Hi Nils,
>
> I am glad to hear that you were able to get this to work!
>
> Would you care to share your code/invocations or at least show us some
> pseudo-code of what you did? Did you popen() and then fork() your
> process? What did you do to resynchronize the two processes, if you
> needed to wait for a process to complete?
>
> Any hints would be greatly appreciated.
Hi Ken,
when this wunderful order journaling - what I find really useful - came
out I was wondering what is the best way to invoke shim.
Since I need the shim process up and running to catch status messages,
I couldn't have a shim process per task but rather some sort of shim
'server' accepting new commands any time while still listening for tws
on the other hand.
I choose a select loop on a fifo/named pipe instead of opening a port,
because it allows me to do the simple things from simple bash/awk
scripts - I just echo all commands into the fifo.
So I did
1) "mkfifo shimpipe"
2) a small C programm with something like
shim = popen("/pathto/shim --risk file save", "w");
int fd = open("shimpipe", O_RDONLY | O_NONBLOCK );
//int fd = open(FIFO_PATHNAME, O_RDWR );
fd_set rfds;
int rc;
struct timeval tv;
for(;;){
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
rc = select(fd + 1, &rfds, NULL, NULL, &tv);
if (FD_ISSET(fd, &rfds)){
if (rc > 0) {
char buf[255];
ssize_t got = read(fd, buf, sizeof(buf));
if (got < 0) {
perror("read");
return 1;
}
else if (got == 0) {
close(fd);
fd = open("shimpipe", O_RDONLY );
}
else {
buf[got]='\0';
fprintf (shim, buf);
fflush(shim);
}
}
}
}
pclose(shim);
----%------
3) echo "select acct;" > shimpipe
or whatever you want
select() behaves a bit strange on fifos, since it doesn't listen on the
fifo once it is marked as EOF.
Therefore I close and reopen it. Better might be to open it as writer as
well. On the other hand, EOF ensures here that each command is passed
immediately and the chance to loose data between close/reopen
and returning into the select loop should be zero for my very low volume
traffic...
I have no further concurrency problems. No need to call fork(), all
messages are written immediately,
output is not delivered exclusivly to the caller, but has to be greped
(or piped through some awk scripts)
from the log. Might be copied to a fifo as well if necessary.
This is all really a bit simplicistic and probably not the solution to
your problems. As said above, this approach
helps me to:
- simultanously listening to and passing asynchronous commands and tws
messages
- still have a scripting access to shim
regards
Nils
More information about the ts-general
mailing list