Eli Green [mailto:eli.green / codedogs.ca] wrote: > I've been trying to get Ruby to compile/run under QNX's > RTOS (the free > download one), and it's remarkable how easy it's been so far... =) > The interpreter itself works just fine: Did you try "make test"? > However, the minute > I try and load a .so: > > manhattan ~% ruby > require 'socket' > unknown symbol: rb_eSecurityError > unknown symbol: rb_cSymbol > ... it goes on like this for a while ... I ported ruby to QNX a while ago (using QNX 6.0B, I'll give the new 6.1 a try in a few days), applying only some minor changes. I'm using this version of ruby for nearly two months now without problems. Matz: Could you please have a look at the change notes at the end of this message and include them in the next release? Thanks in advance... Roland ================================ Changes to ruby-1.6.4 (2001-06-04) config.guess/config.sub: Updated with a more recent version (the ones supplied with QNX RTP). dir.c: fnmatch already defined in C library (fnmatch.h). Renamed static function fnmatch to _rb_fnmatch. Maybe the version from the C library can be used instead. It has the same signature, but there may be subtle differences. io.c: Added (somewhere at the top): #ifdef __QNXNTO__ #include "unix.h" #endif This is needed to define NOFILES. signal.c: Signal handlers are not properly set if SA_RESTART is used ("make test" fails). Added at line 296: #ifdef SA_RESTART #ifndef __QNXNTO__ sigact.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ #endif #endif eval.c: somewhere at the beginning (around line 100) added: #ifdef __QNXNTO__ #include <time.h> #include <sys/siginfo.h> #endif defines.h line 76: add ||defined(__QNXNTO__): #if defined(DJGPP) || defined(__BOW__) || defined(__QNXNTO__) #undef HAVE_SETITIMER #endif setitimer() only supports ITIMER_REAL in QNX 6.0, which cannot be used. I tried to simulate ITIMER_VIRTUAL with POSIX timers (see below), but this does not work reliably. ext/socket.c line 1517: #if !defined(NT) && !defined(__BEOS__) && !defined(__EMX__) && !defined(__QNXNTO__) Up to now socketpair() is not support in QNX 6 (although it might be soon). configure: line 4674: added: nto-qnx*) DLDFLAGS="-L/lib -L/usr/lib -L/usr/local/lib" LDSHARED='ld -Bshareable -x' LDFLAGS="-L/lib -L/usr/lib -L/usr/local/lib" rb_cv_dlopen=yes;; Note: This change should really go into configure.in, but I don't know enough about autoconf to mess with that file. lib/irb/locale.rb line 132: Change tmp_base = path.tr("./:", "___") to tmp_base = path.tr("./:", "___")[1..30] This is necessary because the QNX filesystem only supports filenames with up to 48 characters. ===================== Here is my try to simulate ITIMER_VIRTUAL to make thread switching more efficient. This seems to work on principle, but can make blocking system calls return prematurely (with EINTR result). Ruby doesn't like this... eval.c: around lines 8110 / 8122: (rb_thread_start_timer and rb_thread_stop_timer) Only TIMER_REAL is supported by setitimer on QNX RTP, so the ITIMER functionality has to be simulated by using POSIX timers. Change thread_start_timer / thread_stop_timer like this: #if defined(HAVE_SETITIMER) static int thread_init = 0; #ifdef __QNXNTO__ static timer_t thread_qnx6_timer_id = 0; #endif void rb_thread_start_timer() { #ifdef __QNXNTO__ struct sigevent sigevt; struct itimerspec tval; if (!thread_init) return; if (!thread_qnx6_timer_id) { SIGEV_SIGNAL_INIT (&sigevt, SIGVTALRM); timer_create (CLOCK_REALTIME, &sigevt, &thread_qnx6_timer_id); } tval.it_interval.tv_sec = 0; tval.it_interval.tv_nsec = 10000000; tval.it_value = tval.it_interval; timer_settime (thread_qnx6_timer_id, 0, &tval, NULL); #else struct itimerval tval; if (!thread_init) return; tval.it_interval.tv_sec = 0; tval.it_interval.tv_usec = 10000; tval.it_value = tval.it_interval; setitimer(ITIMER_VIRTUAL, &tval, NULL); #endif } void rb_thread_stop_timer() { #ifdef __QNXNTO__ struct itimerspec tval; if (!thread_init) return; if (!thread_qnx6_timer_id) return; tval.it_interval.tv_sec = 0; tval.it_interval.tv_nsec = 0; tval.it_value = tval.it_interval; timer_settime (thread_qnx6_timer_id, 0, &tval, NULL); #else struct itimerval tval; if (!thread_init) return; tval.it_interval.tv_sec = 0; tval.it_interval.tv_usec = 0; tval.it_value = tval.it_interval; setitimer(ITIMER_VIRTUAL, &tval, NULL); #endif } #endif