chiark / gitweb /
Merge branch 'ijackson'
[ypp-sc-tools.web-live.git] / yarrg / 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 "convert.h"
29 #include "ocr.h"
30
31 static FILE *resolver;
32 static pid_t resolver_pid;
33 static int resolver_done;
34
35 FILE *resolve_start(void) {
36   int jobpipe[2],donepipe[2];
37
38   if (!o_resolver) return 0;
39
40   if (!resolver) {
41     sysassert(! pipe(jobpipe) );
42     sysassert(! pipe(donepipe) );
43     resolver_pid= fork();
44     sysassert(resolver_pid!=-1);
45     if (!resolver_pid) {
46       sysassert( dup2(jobpipe[0],0) ==0 );
47       sysassert(! close(jobpipe[1]) );
48       sysassert(! close(donepipe[0]) );
49       /* we know donepipe[1] is >= 4 and we have dealt with all the others
50        * so we aren't in any danger of overwriting some other fd 4: */
51       sysassert( dup2(donepipe[1],4) ==4 );
52       EXECLP_HELPER("dictionary-manager",
53         DEBUGP(callout)                 ? "--debug"       : "--noop-arg",
54         DEBUGP(callout) && DEBUGP(rect) ? "--debug-rect"  : "--noop-arg",
55                     o_quiet ? "--quiet" : "--noop-arg",
56                     "--automatic-1",
57                     (char*)0);
58       sysassert(!"execlp dictionary-manager --automatic failed");
59     }
60     sysassert(! close(jobpipe[0]) );
61     sysassert(! close(donepipe[1]) );
62     resolver= fdopen(jobpipe[1],"w"); sysassert(resolver);
63     resolver_done= donepipe[0];
64   }
65
66   progress("");
67   return resolver;
68 }
69
70 void resolve_finish(void) {
71   char cb;
72   
73   sysassert(!ferror(resolver));
74   sysassert(!fflush(resolver));
75
76   sysassert(resolver);
77
78   int r;
79   for (;;) {
80     r= read(resolver_done,&cb,1);
81     if (r==-1) { sysassert(errno==EINTR); continue; }
82     break;
83   }
84
85   if (r==0) {
86     waitpid_check_exitstatus(resolver_pid, "dictionary-manager", 0);
87     fclose(resolver);
88     close(resolver_done);
89     resolver= 0;
90   } else {
91     assert(r==1);
92     sysassert(cb==0);
93   }
94 }