1157
1175
aix_loaderror(const char *pathname)
1159
char *message[1024], errbuf[1024];
1162
static const struct errtab {
1164
const char * errstr;
1166
{L_ERROR_TOOMANY, "too many errors, rest skipped."},
1167
{L_ERROR_NOLIB, "can't load library:"},
1168
{L_ERROR_UNDEF, "can't find symbol in library:"},
1170
"RLD index out of range or bad relocation type:"},
1171
{L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
1173
"file not an archive or does not contain requested member:"},
1174
{L_ERROR_TYPE, "symbol table mismatch:"},
1175
{L_ERROR_ALIGN, "text alignment in file is wrong."},
1176
{L_ERROR_SYSTEM, "System error:"},
1177
{L_ERROR_ERRNO, NULL}
1180
#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
1177
char *message[1024], errbuf[1024];
1181
1179
#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
1183
snprintf(errbuf, sizeof(errbuf), "load failed - %s ", pathname);
1186
if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message)))
1187
ERRBUF_APPEND(strerror(errno));
1188
for(i = 0; message[i] && *message[i]; i++) {
1189
int nerr = atoi(message[i]);
1190
for (j=0; j<LOAD_ERRTAB_LEN; j++) {
1191
if (nerr == load_errtab[j].errnum && load_errtab[j].errstr)
1192
ERRBUF_APPEND(load_errtab[j].errstr);
1194
while (isdigit(*message[i])) message[i]++;
1195
ERRBUF_APPEND(message[i]);
1196
ERRBUF_APPEND("\n");
1180
snprintf(errbuf, sizeof(errbuf), "load failed - %s. ", pathname);
1182
if (loadquery(L_GETMESSAGES, &message[0], sizeof(message)) != -1) {
1183
ERRBUF_APPEND("Please issue below command for detailed reasons:\n\t");
1184
ERRBUF_APPEND("/usr/sbin/execerror ruby ");
1185
for (i=0; message[i]; i++) {
1186
ERRBUF_APPEND("\"");
1187
ERRBUF_APPEND(message[i]);
1188
ERRBUF_APPEND("\" ");
1198
errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
1199
rb_loaderror("%s", errbuf);
1190
ERRBUF_APPEND("\n");
1192
ERRBUF_APPEND(strerror(errno));
1193
ERRBUF_APPEND("[loadquery failed]");
1195
dln_loaderror("%s", errbuf);
1204
#endif /* NO_DLN_LOAD */
1199
#if defined(DLN_NEEDS_ALT_SEPARATOR) && DLN_NEEDS_ALT_SEPARATOR
1200
#define translit_separator(src) do { \
1201
char *tmp = ALLOCA_N(char, strlen(src) + 1), *p = tmp, c; \
1203
*p++ = ((c = *file++) == '/') ? DLN_NEEDS_ALT_SEPARATOR : c; \
1208
#define translit_separator(str) (void)(str)
1207
1212
dln_load(const char *file)
1210
rb_raise(rb_eLoadError, "this executable file can't load extension libraries");
1213
1214
#if !defined(_AIX) && !defined(NeXT)
1214
1215
const char *error = 0;
1215
1216
#define DLN_ERROR() (error = dln_strerror(), strcpy(ALLOCA_N(char, strlen(error) + 1), error))
1351
1358
char *object_files[2] = {NULL, NULL};
1353
1360
void (*init_fct)();
1355
1362
object_files[0] = (char*)file;
1357
1364
s = NXOpenFile(2,NX_WRITEONLY);
1359
1366
/* Load object file, if return value ==0 , load failed*/
1360
1367
if(rld_load(s, NULL, object_files, NULL) == 0) {
1363
rb_loaderror("Failed to load %.200s", file);
1370
dln_loaderror("Failed to load %.200s", file);
1366
1373
/* lookup the initial function */
1367
1374
if(rld_lookup(s, buf, &init_address) == 0) {
1370
rb_loaderror("Failed to lookup Init function %.200s", file);
1377
dln_loaderror("Failed to lookup Init function %.200s", file);
1376
1383
/* Cannot call *init_address directory, so copy this value to
1378
1385
init_fct = (void(*)())init_address;
1380
1387
return (void*)init_address;
1444
1451
if ((B_BAD_IMAGE_ID == err_stat) || (B_BAD_INDEX == err_stat)) {
1445
1452
unload_add_on(img_id);
1446
rb_loaderror("Failed to lookup Init function %.200s", file);
1453
dln_loaderror("Failed to lookup Init function %.200s", file);
1448
1455
else if (B_NO_ERROR != err_stat) {
1449
1456
char errmsg[] = "Internal of BeOS version. %.200s (symbol_name = %s)";
1450
1457
unload_add_on(img_id);
1451
rb_loaderror(errmsg, strerror(err_stat), buf);
1458
dln_loaderror(errmsg, strerror(err_stat), buf);
1454
1461
/* call module initialize function. */
1456
1463
return (void*)img_id;
1458
#endif /* __BEOS__*/
1465
#endif /* __BEOS__ || __HAIKU__ */
1460
1467
#ifndef DLN_DEFINED
1464
1471
#endif /* USE_DLN_A_OUT */
1466
1473
#if !defined(_AIX) && !defined(NeXT)
1468
rb_loaderror("%s - %s", error, file);
1475
dln_loaderror("%s - %s", error, file);
1471
#endif /* NO_DLN_LOAD */
1472
1478
return 0; /* dummy return */
1475
static char *dln_find_1(const char *fname, const char *path, char *buf, int size, int exe_flag);
1478
dln_find_exe_r(const char *fname, const char *path, char *buf, int size)
1481
path = getenv(PATH_ENV);
1486
path = "/usr/local/bin;/usr/ucb;/usr/bin;/bin;.";
1488
path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
1491
return dln_find_1(fname, path, buf, size, 1);
1495
dln_find_file_r(const char *fname, const char *path, char *buf, int size)
1497
if (!path) path = ".";
1498
return dln_find_1(fname, path, buf, size, 0);
1501
static char fbuf[MAXPATHLEN];
1504
dln_find_exe(const char *fname, const char *path)
1506
return dln_find_exe_r(fname, path, fbuf, sizeof(fbuf));
1510
dln_find_file(const char *fname, const char *path)
1512
return dln_find_file_r(fname, path, fbuf, sizeof(fbuf));
1516
dln_find_1(const char *fname, const char *path, char *fbuf, int size,
1517
int exe_flag /* non 0 if looking for executable. */)
1519
register const char *dp;
1520
register const char *ep;
1525
static const char extension[][5] = {
1526
".exe", ".com", ".cmd", ".bat",
1529
int is_abs = 0, has_path = 0;
1530
const char *ext = 0;
1531
const char *p = fname;
1534
#define RETURN_IF(expr) if (expr) return (char *)fname;
1539
# define CharNext(p) ((p)+1)
1541
# ifdef DOSISH_DRIVE_LETTER
1542
if (((p[0] | 0x20) - 'a') < 26 && p[1] == ':') {
1548
case '/': case '\\':
1555
case '/': case '\\':
1569
for (j = 0; STRCASECMP(ext, extension[j]); ) {
1570
if (++j == sizeof(extension) / sizeof(extension[0])) {
1580
else if (has_path) {
1583
if (i + 1 > size) goto toolong;
1584
fspace = size - i - 1;
1587
memcpy(fbuf, fname, i + 1);
1588
goto needs_extension;
1592
RETURN_IF(fname[0] == '/');
1593
RETURN_IF(strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0);
1594
RETURN_IF(exe_flag && strchr(fname, '/'));
1598
for (dp = path;; dp = ++ep) {
1601
/* extract a component */
1602
ep = strchr(dp, PATH_SEP[0]);
1606
/* find the length of that component */
1612
** If the length of the component is zero length,
1613
** start from the current directory. If the
1614
** component begins with "~", start from the
1615
** user's $HOME environment variable. Otherwise
1616
** take the path literally.
1619
if (*dp == '~' && (l == 1 ||
1626
home = getenv("HOME");
1629
if ((fspace -= i) < 0)
1631
memcpy(bp, home, i);
1638
if ((fspace -= l) < 0)
1644
/* add a "/" between directory and filename */
1649
/* now append the file name */
1651
if ((fspace -= i) < 0) {
1653
fprintf(stderr, "openpath: pathname too long (ignored)\n");
1655
fprintf(stderr, "\tDirectory \"%s\"\n", fbuf);
1656
fprintf(stderr, "\tFile \"%s\"\n", fname);
1659
memcpy(bp, fname, i + 1);
1662
if (exe_flag && !ext) {
1664
for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) {
1665
if (fspace < strlen(extension[j])) {
1666
fprintf(stderr, "openpath: pathname too long (ignored)\n");
1667
fprintf(stderr, "\tDirectory \"%.*s\"\n", (int) (bp - fbuf), fbuf);
1668
fprintf(stderr, "\tFile \"%s%s\"\n", fname, extension[j]);
1671
strcpy(bp + i, extension[j]);
1672
if (stat(fbuf, &st) == 0)
1677
#endif /* _WIN32 or __EMX__ */
1679
if (stat(fbuf, &st) == 0) {
1680
if (exe_flag == 0) return fbuf;
1681
/* looking for executable */
1682
if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0)
1686
/* if not, and no other alternatives, life is bleak */
1691
/* otherwise try the next component in the search path */