From 57bc5eaf2f9b44ad8321fecf6dfa45d82a50c580 Mon Sep 17 00:00:00 2001 From: yugui Date: Sat, 11 Oct 2014 13:33:14 +0000 Subject: Fixes build failures on Portable Native Client. Note: Some of the fixes are for newlib in general but not NaCl-specific. * include/ruby/intern.h (rb_fd_select): declare struct timeval, or the struct gets local to the function in C99. * file.c (#include): add nacl/stat.h for PNaCl. (utimes): added a declaration for PNaCl. (stat_atimespec): stat::st_atimensec is long long but timespec::tv_nsec is long in PNaCl. (stat_mtimespec, stat_ctimespec): ditto. (rb_group_member): disable getgroups unless HAVE_GETGROUPS. (eaccess): unify the fallback to generic defined(USE_GETEUID). * io.c: include sys/time.h for struct timeval. (rb_close_before_exec): nothing we can do if F_GETFD is not available. (ioctl): pnacl newlib actually doesn't have ioctl. * process.c (maxgroups): it is used iff defined(_SC_NGROUPS_MAX) || defined(NGROUPS_MAX) but not defined(HAVE_GETGROUPS) || defined(HAVE_SETGROUPS). (obj2gid): fail unless the object is a Fixnum if getgrnam is not available. (disable_child_handler_fork_child): sigaction is not available in PNaCl newlib. * configure.in (warnflags, strict_warnflags): avoid -ansi for strlcpy. (rb_cv_gcc_atomic_builtins): also check __atomic_or_etch because it is used in ruby_atomic.h. (rb_cv_gcc_sync_builtins): ditto. (HAVE_GETGRNAM): added. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47882 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 41 +++++++++++++++++++++++++++++++++++++++++ configure.in | 6 +++++- file.c | 13 +++++++------ include/ruby/intern.h | 2 ++ io.c | 25 ++++++++++++++++++++----- nacl/README.nacl | 19 ++++++++++++++++++- process.c | 41 +++++++++++++++++++++++++++++++++++++++-- 7 files changed, 132 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 016dcb7a89..b49fec9d20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +Sat Oct 11 18:46:50 2014 Yuki Yugui Sonoda + + * include/ruby/intern.h (rb_fd_select): declare struct timeval, or the + struct gets local to the function in C99. + + * file.c (#include): add nacl/stat.h for PNaCl. + (utimes): added a declaration for PNaCl. + (stat_atimespec): stat::st_atimensec is long long but + timespec::tv_nsec is long in PNaCl. + (stat_mtimespec, stat_ctimespec): ditto. + (rb_group_member): disable getgroups unless HAVE_GETGROUPS. + (eaccess): unify the fallback to generic defined(USE_GETEUID). + + * io.c: include sys/time.h for struct timeval. + (rb_close_before_exec): nothing we can do if F_GETFD is not + available. + (ioctl): pnacl newlib actually doesn't have ioctl. + + * process.c (maxgroups): it is used iff + defined(_SC_NGROUPS_MAX) || defined(NGROUPS_MAX) but not + defined(HAVE_GETGROUPS) || defined(HAVE_SETGROUPS). + (obj2gid): fail unless the object is a Fixnum if getgrnam is not + available. + (disable_child_handler_fork_child): sigaction is not available in + PNaCl newlib. + + * configure.in (warnflags, strict_warnflags): avoid -ansi for strlcpy. + (rb_cv_gcc_atomic_builtins): also check + __atomic_or_etch because it is used in ruby_atomic.h. + (rb_cv_gcc_sync_builtins): ditto. + (HAVE_GETGRNAM): added. + Sat Oct 11 15:32:08 2014 Eric Wong * compile.c (iseq_build_from_ary_exception): move RB_GC_GUARD @@ -28,6 +60,7 @@ Sat Oct 11 11:27:14 2014 Yuki Yugui Sonoda * io.c: fix issues in the last two commits. don't disable cloexec for platforms other than NativeClient. + * ChangeLog: ditto. add entries for the last two commits. Sat Oct 11 11:12:00 2014 Yuki Yugui Sonoda @@ -38,21 +71,29 @@ Sat Oct 11 11:12:00 2014 Yuki Yugui Sonoda Sat Oct 11 11:11:53 2014 Yuki Yugui Sonoda * configure.in (RUBY_NACL and others): merge patch from naclports. Supports PNaCl. + * dln.c: ditto. replace the old hacky dynamic loading over HTTP with nacl_io. + * file.c: ditto. tenatively use access(2) instead of eaccess. (rb_file_load_ok): weaken with attribute but not by postprocess. + * io.c: ditto. (socket.h): now NaCl has socket.h (flock): disable here instead of nacl/ioctl.h + * nacl/GNUmakefile.in: ditto. (CC, LD, NM, AR, AS, RANLIB, OBJDUMP, OBJCOPY): respect path to them if they are absolute. This helps naclports to build ruby in their source tree. (PROGRAM_NMF, .SUFFIXES): support .pnexe for PNaCl. (ruby.o, file.o): move the hack to attributes in ruby.c and file.c + * nacl/ioctl.h: ditto. removed. move the hack to io.c. + * nacl/nacl-config.rb: ditto. support arm, pnacl and others. + * nacl/pepper_main.c: ditto. support build in a naclports tree. + * ruby.c (rb_load_file): ditto. weaken with attribute but not by postprocess. Sat Oct 11 09:32:00 2014 Zachary Scott diff --git a/configure.in b/configure.in index e430d8dcd7..4cc8afaea6 100644 --- a/configure.in +++ b/configure.in @@ -837,7 +837,7 @@ if test "$GCC" = yes; then # comments. We bypass ANSI C mode for them. Otherwise # extension libs cannot include those headers. ], - [cygwin*|darwin*|netbsd*], [ + [cygwin*|darwin*|netbsd*|nacl], [ # need lgamma_r(), finite() ], [haiku], [ @@ -1621,6 +1621,7 @@ if test "$GCC" = yes; then __atomic_exchange_n(&atomic_var, 1, __ATOMIC_SEQ_CST); __atomic_fetch_add(&atomic_var, 1, __ATOMIC_SEQ_CST); __atomic_fetch_sub(&atomic_var, 1, __ATOMIC_SEQ_CST); + __atomic_or_fetch(&atomic_var, 1, __ATOMIC_SEQ_CST); ], [rb_cv_gcc_atomic_builtins=yes], [rb_cv_gcc_atomic_builtins=no])]) @@ -1635,6 +1636,8 @@ if test "$GCC" = yes; then __sync_lock_test_and_set(&atomic_var, 1); __sync_fetch_and_add(&atomic_var, 1); __sync_fetch_and_sub(&atomic_var, 1); + __sync_or_and_fetch(&atomic_var, 1); + __sync_val_compare_and_swap(&atomic_var, 0, 1); ], [rb_cv_gcc_sync_builtins=yes], [rb_cv_gcc_sync_builtins=no])]) @@ -2006,6 +2009,7 @@ AC_CHECK_FUNCS(ftruncate) AC_CHECK_FUNCS(ftruncate64) # used for Win32 platform AC_CHECK_FUNCS(getcwd) AC_CHECK_FUNCS(getgidx) +AC_CHECK_FUNCS(getgrnam) AC_CHECK_FUNCS(getgrnam_r) AC_CHECK_FUNCS(getgroups) AC_CHECK_FUNCS(getpgid) diff --git a/file.c b/file.c index 3fdfa1444a..3a960d7c93 100644 --- a/file.c +++ b/file.c @@ -22,6 +22,7 @@ #ifdef __APPLE__ #include #endif +#include #include "ruby/ruby.h" #include "ruby/io.h" @@ -69,7 +70,6 @@ int flock(int, int); # include "nacl/unistd.h" #endif - #ifdef HAVE_SYS_MKDEV_H #include #endif @@ -720,7 +720,7 @@ stat_atimespec(struct stat *st) #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC) ts.tv_nsec = st->st_atimespec.tv_nsec; #elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC) - ts.tv_nsec = st->st_atimensec; + ts.tv_nsec = (long)st->st_atimensec; #else ts.tv_nsec = 0; #endif @@ -744,7 +744,7 @@ stat_mtimespec(struct stat *st) #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) ts.tv_nsec = st->st_mtimespec.tv_nsec; #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) - ts.tv_nsec = st->st_mtimensec; + ts.tv_nsec = (long)st->st_mtimensec; #else ts.tv_nsec = 0; #endif @@ -768,7 +768,7 @@ stat_ctimespec(struct stat *st) #elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC) ts.tv_nsec = st->st_ctimespec.tv_nsec; #elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC) - ts.tv_nsec = st->st_ctimensec; + ts.tv_nsec = (long)st->st_ctimensec; #else ts.tv_nsec = 0; #endif @@ -1138,7 +1138,7 @@ rb_file_lstat(VALUE obj) static int rb_group_member(GETGROUPS_T gid) { -#ifdef _WIN32 +#if defined(_WIN32) || !defined(HAVE_GETGROUPS) return FALSE; #else int rv = FALSE; @@ -1195,7 +1195,8 @@ rb_group_member(GETGROUPS_T gid) // overridden by nacl_io. // TODO(sbc): Remove this once eaccess() is wired up correctly // in NaCl. -#define eaccess access +# undef HAVE_EACCESS +# undef USE_GETEUID #endif #ifndef HAVE_EACCESS diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 41f256722e..591589ae16 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -316,6 +316,8 @@ void rb_fd_clr(int, rb_fdset_t *); int rb_fd_isset(int, const rb_fdset_t *); void rb_fd_copy(rb_fdset_t *, const fd_set *, int); void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src); + +struct timeval; int rb_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *); #define rb_fd_ptr(f) ((f)->fdset) diff --git a/io.c b/io.c index 61c87206d9..9548c439c5 100644 --- a/io.c +++ b/io.c @@ -68,6 +68,10 @@ # define PRI_OFF_T_PREFIX "" #endif +#ifdef HAVE_SYS_TIME_H +# include +#endif + #include /* EMX has sys/param.h, but.. */ @@ -127,7 +131,10 @@ off_t __syscall(quad_t number, ...); #endif #ifdef __native_client__ -# undef F_GETFD +# undef F_GETFD +# ifdef NACL_NEWLIB +# undef HAVE_IOCTL +# endif #endif #define IO_RBUF_CAPA_MIN 8192 @@ -5866,19 +5873,20 @@ linux_get_maxfd(void) void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds) { +#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) int fd, ret; int max = (int)max_file_descriptor; -#ifdef F_MAXFD +# ifdef F_MAXFD /* F_MAXFD is available since NetBSD 2.0. */ ret = fcntl(0, F_MAXFD); /* async-signal-safe */ if (ret != -1) maxhint = max = ret; -#elif defined(__linux__) +# elif defined(__linux__) ret = linux_get_maxfd(); if (maxhint < ret) maxhint = ret; /* maxhint = max = ret; if (ret == -1) abort(); // test */ -#endif +# endif if (max < maxhint) max = maxhint; for (fd = lowfd; fd <= max; fd++) { @@ -5889,12 +5897,13 @@ rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds) if (ret != -1 && !(ret & FD_CLOEXEC)) { fcntl(fd, F_SETFD, ret|FD_CLOEXEC); /* async-signal-safe */ } -#define CONTIGUOUS_CLOSED_FDS 20 +# define CONTIGUOUS_CLOSED_FDS 20 if (ret != -1) { if (max < fd + CONTIGUOUS_CLOSED_FDS) max = fd + CONTIGUOUS_CLOSED_FDS; } } +#endif } static int @@ -8864,6 +8873,7 @@ rb_f_select(int argc, VALUE *argv, VALUE obj) # define NUM2IOCTLREQ(num) NUM2INT(num) #endif +#ifdef HAVE_IOCTL struct ioctl_arg { int fd; ioctl_req_t cmd; @@ -8892,6 +8902,7 @@ do_ioctl(int fd, ioctl_req_t cmd, long narg) return retval; } +#endif #define DEFULT_IOCTL_NARG_LEN (256) @@ -9125,6 +9136,7 @@ setup_narg(ioctl_req_t cmd, VALUE *argp, int io_p) return narg; } +#ifdef HAVE_IOCTL static VALUE rb_ioctl(VALUE io, VALUE req, VALUE arg) { @@ -9168,6 +9180,9 @@ rb_io_ioctl(int argc, VALUE *argv, VALUE io) rb_scan_args(argc, argv, "11", &req, &arg); return rb_ioctl(io, req, arg); } +#else +#define rb_io_ioctl rb_f_notimplement +#endif #ifdef HAVE_FCNTL struct fcntl_arg { diff --git a/nacl/README.nacl b/nacl/README.nacl index ef2c3d1fa4..77140e0f75 100644 --- a/nacl/README.nacl +++ b/nacl/README.nacl @@ -15,7 +15,7 @@ You need to install the following things before building NaCl port of Ruby. (2) Set NACL_SDK_ROOT environment variable to the path to the Native Client SDK you installed: $ export NACL_SDK_ROOT=/home/yugui/src/nacl_sdk/pepper_37 (3) Configure - $ ./configure --prefix=/tmp/nacl-ruby --host=x86_64-nacl --with-baseruby=/path/to/ruby-1.9.3 + $ ./configure --prefix=/tmp/nacl-ruby --host=x86_64-nacl --with-baseruby=/path/to/ruby-1.9.3-or-later (4) Make $ make $ make package @@ -28,6 +28,23 @@ embeds Ruby", and libraries to $prefix. You can run it by the following steps: (6) Visit the example.html on the web server by a browser that implements Pepper 18 or later. -- e.g., Chrome 18 implements Pepper 18, Chrome 19 implements Pepper 19, ... +=== Example Configurations +* x86_32 Native Client + $ ./configure --prefix=/tmp/nacl-ruby \ + --host=i686-nacl \ + --with-baseruby=/path/to/ruby-1.9.3-or-later +* arm Native Client + $ ./configure --prefix=/tmp/nacl-ruby \ + --host=arm-nacl \ + --with-newlib \ + --with-baseruby=/path/to/ruby-1.9.3-or-later +* Portable Native Client + $ ./configure --prefix=/tmp/nacl-ruby \ + --host=le32-nacl \ + --with-newlib \ + --with-static-linked-ext \ + --with-baseruby=/path/to/ruby-1.9.3-or-later + = Copyright * Copyright 2012 Google Inc. All Rights Reserved. * Author: yugui@google.com (Yugui Sonoda) diff --git a/process.c b/process.c index f9bc01c5c3..301735d266 100644 --- a/process.c +++ b/process.c @@ -67,8 +67,11 @@ #include #if defined(__native_client__) && defined(NACL_NEWLIB) +# include # include "nacl/stat.h" # include "nacl/unistd.h" +# include "nacl/resource.h" +# undef HAVE_ISSETUGID #endif #ifdef HAVE_SYS_TIME_H @@ -3389,6 +3392,7 @@ disable_child_handler_before_fork(struct child_handler_disabler_state *old) int ret; sigset_t all; +#ifdef HAVE_PTHREAD_SIGMASK ret = sigfillset(&all); if (ret == -1) rb_sys_fail("sigfillset"); @@ -3398,6 +3402,9 @@ disable_child_handler_before_fork(struct child_handler_disabler_state *old) errno = ret; rb_sys_fail("pthread_sigmask"); } +#else +# pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous" +#endif #ifdef PTHREAD_CANCEL_DISABLE ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old->cancelstate); @@ -3421,11 +3428,15 @@ disable_child_handler_fork_parent(struct child_handler_disabler_state *old) } #endif +#ifdef HAVE_PTHREAD_SIGMASK ret = pthread_sigmask(SIG_SETMASK, &old->sigmask, NULL); /* not async-signal-safe */ if (ret != 0) { errno = ret; rb_sys_fail("pthread_sigmask"); } +#else +# pragma GCC warning "pthread_sigmask on fork is not available. potentially dangerous" +#endif } /* This function should be async-signal-safe. Actually it is. */ @@ -3434,6 +3445,7 @@ disable_child_handler_fork_child(struct child_handler_disabler_state *old, char { int sig; int ret; +#ifdef POSIX_SIGNAL struct sigaction act, oact; act.sa_handler = SIG_DFL; @@ -3443,6 +3455,9 @@ disable_child_handler_fork_child(struct child_handler_disabler_state *old, char ERRMSG("sigemptyset"); return -1; } +#else + sig_t handler; +#endif for (sig = 1; sig < NSIG; sig++) { int reset = 0; @@ -3451,6 +3466,7 @@ disable_child_handler_fork_child(struct child_handler_disabler_state *old, char reset = 1; #endif if (!reset) { +#ifdef POSIX_SIGNAL ret = sigaction(sig, NULL, &oact); /* async-signal-safe */ if (ret == -1 && errno == EINVAL) { continue; /* Ignore invalid signal number. */ @@ -3461,13 +3477,32 @@ disable_child_handler_fork_child(struct child_handler_disabler_state *old, char } reset = (oact.sa_flags & SA_SIGINFO) || (oact.sa_handler != SIG_IGN && oact.sa_handler != SIG_DFL); +#else + handler = signal(sig, SIG_DFL); + if (handler == SIG_ERR && errno == EINVAL) { + continue; /* Ignore invalid signal number */ + } + if (handler == SIG_ERR) { + ERRMSG("signal to obtain old action"); + return -1; + } + reset = (handler != SIG_IGN && handler != SIG_DFL); +#endif } if (reset) { +#ifdef POSIX_SIGNAL ret = sigaction(sig, &act, NULL); /* async-signal-safe */ if (ret == -1) { ERRMSG("sigaction to set default action"); return -1; } +#else + handler = signal(sig, handler); + if (handler == SIG_ERR) { + ERRMSG("signal to set default action"); + return -1; + } +#endif } } @@ -5036,8 +5071,10 @@ obj2gid(VALUE id getgr_buf = RSTRING_PTR(*getgr_tmp); getgr_buf_len = rb_str_capacity(*getgr_tmp); } -#else +#elif defined(HAVE_GETGRNAM) grptr = getgrnam(grpname); +#else + grptr = NULL; #endif if (!grptr) { #if !defined(USE_GETGRNAM_R) && defined(HAVE_ENDGRENT) @@ -5668,7 +5705,7 @@ proc_setgid(VALUE obj, VALUE id) #endif -#if defined(HAVE_SETGROUPS) || defined(HAVE_GETGROUPS) +#if defined(_SC_NGROUPS_MAX) || defined(NGROUPS_MAX) /* * Maximum supplementary groups are platform dependent. * FWIW, 65536 is enough big for our supported OSs. -- cgit v1.2.3