1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
--- network.cc.orig 2018-07-31 18:02:19 UTC
+++ network.cc
@@ -501,7 +501,7 @@ int IncomingConnection::createSocket() {
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(Port);
- if (bind(netsocket,(struct sockaddr *) &sin,sizeof(sin))==-1) {
+ if (::bind(netsocket,(struct sockaddr *) &sin,sizeof(sin))==-1) {
snprintf(errorMessage,128,_("Unable to bind on port %d."),Port);
return(-1);
}
@@ -604,6 +604,7 @@ PipeConnection::PipeConnection(int _pin,int _pout) {
strcpy(HostName,"local pipe");
snprintf(HostAddress,96,"pipe[%d,%d]",pin,pout);
Quiet=0;
+ use_execve=0;
MaxWaitTime = 60000.0; // 1 minute
}
@@ -615,6 +616,7 @@ void PipeConnection::init() {
strcpy(HostAddress,"unknown");
memset(HelperBin,0,512);
Quiet=0;
+ use_execve=0;
handshake.erase();
MaxWaitTime = 60000.0; // 1 minute
}
@@ -652,6 +654,25 @@ PipeConnection::PipeConnection(const char *host,int po
Port=port;
g_strlcpy(HostName,host,128);
+ // Special handling for timeseal on FreeBSD:
+ //
+ // On FreeBSD, the games/timeseal port provides an a.out timeseal
+ // binary. However, a.out support is disabled by default on FreeBSD
+ // >= 5.x. If the a.out kernel module is not loaded, or if a.out
+ // support is not compiled into the kernel, execvp()ing timeseal
+ // will not return (because it fallbacks to the shell when execve()
+ // returns NOEXEC): eboard will not notice the failure (in
+ // PipeConnection::open()) and will therefore not fallback to a
+ // direct connection.
+ //
+ // We solve the problem by executing timeseal with execve(), which
+ // will fail if a.out support is not available. Note that unlike
+ // execvp(), execve() does not search for the program in the path,
+ // but this is not a problem since eboard uses the absolute path to
+ // timeseal.
+ if (! strcmp(helperbin, "timeseal"))
+ use_execve = 1;
+
// build helper path
if (helpersuffix)
snprintf(z,256,"%s.%s",helperbin,helpersuffix);
@@ -768,7 +789,10 @@ int PipeConnection::open() {
dup2(1,2);
setpgid(getpid(),0); // to broadcast SIGKILL later
- execvp(HelperBin,arguments);
+ if (use_execve)
+ execve(HelperBin,arguments,NULL);
+ else
+ execvp(HelperBin,arguments);
write(1,"exec failed\n",12);
global.debug("exec failed",HelperBin);
_exit(2); // eek
|