In linux client, Added code to detect capability to run 64-bit binaries

from 32-bit BOINC client, and capability to run 32-bit binaries on a 64-bit 
linux system.


svn path=/trunk/boinc/; revision=17617
This commit is contained in:
Eric J. Korpela 2009-03-17 18:41:35 +00:00
parent e5017daf0f
commit 9d2e79d468
2 changed files with 109 additions and 2 deletions

View File

@ -3076,4 +3076,11 @@ Charlie 17 Mar 2009
mac_build/
boinc.xcodeproj/
project.pbxproj
Eric K 17 Mar 2009
- Linux: client: Added code to detect capability to run 64-bit binaries
from 32-bit BOINC client, and capability to run 32-bit binaries on
a 64-bit linux system.
client/
cs_platforms.cpp

View File

@ -46,6 +46,7 @@ LPFN_ISWOW64PROCESS fnIsWow64Process;
#include "client_state.h"
#include "error_numbers.h"
#include "log_flags.h"
#include "filesys.h"
#include "str_util.h"
#include "util.h"
@ -103,6 +104,105 @@ void CLIENT_STATE::detect_platforms() {
// Supported on all 3 Mac architectures
add_platform("powerpc-apple-darwin");
#elif defined(__linux__) && ( defined(__i386__) || defined(__x86_64__) )
// Let's try to support both 32 and 64 bit applications in one client
// regardless of whether it is a 32 or 64 bit client
const char *uname[]={"/bin/uname","/usr/bin/uname",0};
int eno=0, support64=0, support32=0;
FILE *f;
char cmdline[256];
cmdline[0]=0;
// find the 'uname' executable
do {
if (boinc_file_exists(uname[eno])) break;
} while (uname[++eno] != 0);
// run it and check the kernel machine architecture.
if ( uname[eno] != 0 ) {
strlcpy(cmdline,uname[eno],256);
strlcat(cmdline," -m",256);
if ((f=popen(cmdline,"r"))) {
while (!std::feof(f)) {
fgets(cmdline,256,f);
if (strstr(cmdline,"x86_64")) support64=1;
}
pclose(f);
}
if (!support64) {
// we're running on a 32 bit kernel, so we will assume
// we are i686-pc-linux-gnu only.
support32=1;
} else {
// we're running on a 64 bit kernel.
// Now comes the hard part. How to tell whether we can run
// 32-bit binaries.
#if defined(__i386__) && !defined(__x86_64__)
// If we're a 32 bit binary, then we obviously can.
support32=1;
#else
// If we're a 64 bit binary, the check is a bit harder.
// We'll use the file command to check installation of
// 32 bit libraries or executables.
const char *file[]={"/usr/bin/file","/bin/file",0};
const char *libdir[]={"/lib","/lib32","/lib/32","/usr/lib","/usr/lib32","/usr/lib/32"};
const int nlibdirs=sizeof(libdir)/sizeof(char *);
// find 'file'
eno=0;
do {
if (boinc_file_exists(file[eno])) break;
} while (file[++eno] != 0);
// now try to find a 32-bit C library.
if (file[eno] != 0) {
int i;
for (i=0;i<nlibdirs;i++) {
struct dirent *entry;
DIR *a=opendir(libdir[i]);
// if dir doesn't exist, do to the next one
if ( a == 0 ) continue;
// dir exists. read each entry until you find a 32bit lib
while ((support32 == 0) && ((entry=readdir(a)) != 0)) {
strlcpy(cmdline,file[eno],256);
strlcat(cmdline," -L ",256);
strlcat(cmdline,libdir[i],256);
strlcat(cmdline,"/",256);
strlcat(cmdline,entry->d_name,256);
if ((f=popen(cmdline,"r"))) {
while (!std::feof(f)) {
fgets(cmdline,256,f);
// If the library is 32-bit ELF, then we're
// golden.
if (strstr(cmdline,"ELF") &&
strstr(cmdline,"32-bit")) support32=1;
}
pclose(f);
}
}
closedir(a);
if (support32) break;
}
}
#endif
}
}
if (support64) {
add_platform("x86_64-pc-linux-gnu");
}
if (support32) {
add_platform("i686-pc-linux-gnu");
}
if (!(support64 || support32)) {
// Something went wrong. Assume HOSTTYPE and HOSTTYPEALT
// are correct
add_platform(HOSTTYPE);
#ifdef HOSTTYPEALT
add_platform(HOSTTYPEALT);
#endif
}
#elif defined(sun)
// Check if we can run 64-bit binaries...
// this assumes there isn't a 64-bit only solaris. (Every 64-bit solaris can run 32 bit binaries)
@ -169,7 +269,7 @@ void CLIENT_STATE::detect_platforms() {
#endif // !defined(UNKNOWN_SOLARIS_PROCESSOR)
#else // defined(sun)
#else
// Any other platform, fall back to the previous method
add_platform(HOSTTYPE);
#ifdef HOSTTYPEALT