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
This commit is contained in:
yugui 2014-10-11 13:33:14 +00:00
parent 3fedb5128f
commit 57bc5eaf2f
7 changed files with 132 additions and 15 deletions

View File

@ -1,3 +1,35 @@
Sat Oct 11 18:46:50 2014 Yuki Yugui Sonoda <yugui@yugui.jp>
* 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 <e@80x24.org>
* 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 <yugui@yugui.jp>
* 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 <yugui@yugui.jp>
@ -38,21 +71,29 @@ Sat Oct 11 11:12:00 2014 Yuki Yugui Sonoda <yugui@yugui.jp>
Sat Oct 11 11:11:53 2014 Yuki Yugui Sonoda <yugui@yugui.jp>
* 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 <e@zzak.io>

View File

@ -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)

13
file.c
View File

@ -22,6 +22,7 @@
#ifdef __APPLE__
#include <CoreFoundation/CFString.h>
#endif
#include <sys/time.h>
#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 <sys/mkdev.h>
#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

View File

@ -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)

25
io.c
View File

@ -68,6 +68,10 @@
# define PRI_OFF_T_PREFIX ""
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/stat.h>
/* 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 {

View File

@ -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)

View File

@ -67,8 +67,11 @@
#include <sys/stat.h>
#if defined(__native_client__) && defined(NACL_NEWLIB)
# include <sys/unistd.h>
# 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.