chiark / gitweb /
dictionary-update-receiver emails again
[ypp-sc-tools.db-test.git] / pctb / resolve.c
1 /*
2  * IPC to external resolver program
3  */
4 /*
5  *  This is part of ypp-sc-tools, a set of third-party tools for assisting
6  *  players of Yohoho Puzzle Pirates.
7  * 
8  *  Copyright (C) 2009 Ian Jackson <ijackson@chiark.greenend.org.uk>
9  * 
10  *  This program is free software: you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation, either version 3 of the License, or
13  *  (at your option) any later version.
14  * 
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  * 
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  * 
23  *  Yohoho and Puzzle Pirates are probably trademarks of Three Rings and
24  *  are used without permission.  This program is not endorsed or
25  *  sponsored by Three Rings.
26  */
27
28 #include "ocr.h"
29
30 static FILE *resolver;
31 static pid_t resolver_pid;
32 static int resolver_done;
33
34 FILE *resolve_start(void) {
35   int jobpipe[2],donepipe[2];
36
37   if (!o_resolver) return 0;
38
39   if (!resolver) {
40     sysassert(! pipe(jobpipe) );
41     sysassert(! pipe(donepipe) );
42     resolver_pid= fork();
43     sysassert(resolver_pid!=-1);
44     if (!resolver_pid) {
45       sysassert( dup2(jobpipe[0],0) ==0 );
46       sysassert(! close(jobpipe[1]) );
47       sysassert(! close(donepipe[0]) );
48       /* we know donepipe[1] is >= 4 and we have dealt with all the others
49        * so we aren't in any danger of overwriting some other fd 4: */
50       sysassert( dup2(donepipe[1],4) ==4 );
51       execlp(o_resolver, o_resolver,
52              DEBUGP(callout) ? "--debug" : "--noop-arg",
53              "--automatic-1",
54              (char*)0);
55       sysassert(!"execlp dictionary-manager failed");
56     }
57     sysassert(! close(jobpipe[0]) );
58     sysassert(! close(donepipe[1]) );
59     resolver= fdopen(jobpipe[1],"w"); sysassert(resolver);
60     resolver_done= donepipe[0];
61   }
62   return resolver;
63 }
64
65 void resolve_finish(void) {
66   char cb;
67   
68   sysassert(!ferror(resolver));
69   sysassert(!fflush(resolver));
70
71   sysassert(resolver);
72
73   int r;
74   for (;;) {
75     r= read(resolver_done,&cb,1);
76     if (r==-1) { sysassert(errno==EINTR); continue; }
77     break;
78   }
79
80   if (r==0) {
81     waitpid_check_exitstatus(resolver_pid, "dictionary manager");
82     fclose(resolver);
83     close(resolver_done);
84     resolver= 0;
85   } else {
86     assert(r==1);
87     sysassert(cb==0);
88   }
89 }