Project

General

Profile

Feature #6082 » patch.diff

Glass_saga (Masaki Matsushita), 02/25/2012 01:33 PM

View differences:

configure.in
setuid setgid daemon select_large_fdset setenv unsetenv\
mktime timegm gmtime_r clock_gettime gettimeofday poll ppoll\
pread sendfile shutdown sigaltstack dl_iterate_phdr\
dup3 pipe2 posix_memalign memalign)
dup3 pipe2 posix_memalign memalign writev)
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
[AC_TRY_COMPILE([
io.c
size_t capa;
};
#ifdef HAVE_WRITEV
struct io_internal_writev_struct {
int fd;
const struct iovec *iov;
int iovcnt;
};
#endif
static VALUE
internal_read_func(void *ptr)
{
......
return write(iis->fd, iis->buf, iis->capa);
}
#ifdef HAVE_WRITEV
static VALUE
internal_writev_func(void *ptr)
{
struct io_internal_writev_struct *iis = ptr;
return writev(iis->fd, iis->iov, iis->iovcnt);
}
#endif
static ssize_t
rb_read_internal(int fd, void *buf, size_t count)
{
......
return (ssize_t)rb_thread_io_blocking_region(internal_write_func, &iis, fd);
}
#ifdef HAVE_WRITEV
static ssize_t
rb_writev_internal(int fd, const struct iovec *iov, int iovcnt)
{
struct io_internal_writev_struct iis;
iis.fd = fd;
iis.iov = iov;
iis.iovcnt = iovcnt;
return (ssize_t)rb_thread_io_blocking_region(internal_writev_func, &iis, fd);
}
#endif
static long
io_writable_length(rb_io_t *fptr, long l)
{
......
int nosync;
};
#ifdef HAVE_WRITEV
static VALUE
io_binwritev_string(VALUE arg)
{
struct binwrite_arg *p = (struct binwrite_arg *)arg;
rb_io_t *fptr = p->fptr;
long r;
if (fptr->wbuf.len) {
struct iovec iov[2];
iov[0].iov_base = fptr->wbuf.ptr+fptr->wbuf.off;
iov[0].iov_len = fptr->wbuf.len;
iov[1].iov_base = (char *)p->ptr;
iov[1].iov_len = p->length;
r = rb_writev_internal(fptr->fd, iov, 2);
if (fptr->wbuf.len <= r) {
r -= fptr->wbuf.len;
fptr->wbuf.off = 0;
fptr->wbuf.len = 0;
}
else {
fptr->wbuf.off += (int)r;
fptr->wbuf.len -= (int)r;
r = 0L;
}
}
else {
long l = io_writable_length(fptr, p->length);
r = rb_write_internal(fptr->fd, p->ptr, l);
}
return r;
}
#else
static VALUE
io_binwrite_string(VALUE arg)
{
......
long l = io_writable_length(p->fptr, p->length);
return rb_write_internal(p->fptr->fd, p->ptr, l);
}
#endif
static long
io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
......
(fptr->wbuf.ptr && fptr->wbuf.capa <= fptr->wbuf.len + len)) {
struct binwrite_arg arg;
/* xxx: use writev to avoid double write if available */
arg.fptr = fptr;
arg.str = str;
#ifdef HAVE_WRITEV
retry:
arg.ptr = ptr + offset;
arg.length = n;
if (fptr->write_lock) {
r = rb_mutex_synchronize(fptr->write_lock, io_binwritev_string, (VALUE)&arg);
}
else {
r = io_binwritev_string((VALUE)&arg);
}
#else
if (fptr->wbuf.len && fptr->wbuf.len+len <= fptr->wbuf.capa) {
if (fptr->wbuf.capa < fptr->wbuf.off+fptr->wbuf.len+len) {
MEMMOVE(fptr->wbuf.ptr, fptr->wbuf.ptr+fptr->wbuf.off, char, fptr->wbuf.len);
......
if (fptr->stdio_file != stderr && !rb_thread_fd_writable(fptr->fd)) {
rb_io_check_closed(fptr);
}
arg.fptr = fptr;
arg.str = str;
retry:
arg.ptr = ptr + offset;
arg.length = n;
......
long l = io_writable_length(fptr, n);
r = rb_write_internal(fptr->fd, ptr+offset, l);
}
#endif
/* xxx: other threads may modify given string. */
if (r == n) return len;
if (0 <= r) {
(1-1/4)