Project

General

Profile

Feature #4038 » io-advise.patch

runpaint (Run Paint Run Run), 11/09/2010 10:27 AM

View differences:

configure.in
fi
AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot getcwd eaccess\
truncate ftruncate chsize times utimes utimensat fcntl lockf lstat\
link symlink readlink readdir_r fsync fdatasync fchown\
link symlink readlink readdir_r fsync fdatasync fchown posix_fadvise\
setitimer setruid seteuid setreuid setresuid setproctitle socketpair\
setrgid setegid setregid setresgid issetugid pause lchown lchmod\
getpgrp setpgrp getpgid setpgid initgroups getgroups setgroups\
io.c
/**********************************************************************
io.c -
......
#define rb_io_fdatasync rb_f_notimplement
#endif
static VALUE sym_normal, sym_sequential, sym_random,
sym_willneed, sym_dontneed, sym_noreuse;
/*
* call-seq:
* ios.advise(advice, offset=0, len=0) -> nil
*
* Announce an intention to access data from the current file in a
* specific pattern. On platforms that do not support the
* <em>posix_fadvise(2)</em> system call, this method is a no-op.
*
* _advice_ is one of the following symbols:
*
* * :normal - No advice to give; the default assumption for an open file.
* * :sequential - The data will be accessed sequentially:
* with lower offsets read before higher ones.
* * :random - The data will be accessed in random order.
* * :willneed - The data will be accessed in the near future.
* * :dontneed - The data will not be accessed in the near future.
* * :noreuse - The data will only be accessed once.
*
* "data" means the region of the current file that begins
* at _offset_ and extends for _len_ bytes. By default, both _offset_
* and _len_ are 0, meaning that the advice applies to the entire
* file.
*
* If an error occurs, one of the following exceptions will be raised:
*
* * <code>IOError</code> - The <code>IO</code> stream is closed.
* * <code>Errno::EBADF</code> - The file descriptor of the current file is
invalid.
* * <code>Errno::EINVAL</code> - An invalid value for _advice_ was given.
* * <code>Errno::ESPIPE</code> - The file descriptor of the current
* * file refers to a FIFO or pipe. (Linux raises <code>Errno::EINVAL</code>
* * in this case).
* * <code>TypeError</code> - Either _advice_ was not a Symbol, or one of the
other arguments was not an <code>Integer</code>.
* * <code>RangeError</code> - One of the arguments given was too big/small.
*/
static VALUE
rb_io_advise(int argc, VALUE *argv, VALUE io)
{
off_t offset, len;
int advice, rv;
VALUE initadvice, initoffset, initlen;
rb_io_t *fptr;
rb_scan_args(argc, argv, "12", &initadvice, &initoffset, &initlen);
if (TYPE(initadvice) != T_SYMBOL)
rb_raise(rb_eTypeError, "advice must be a Symbol");
offset = NIL_P(initoffset) ? 0 : NUM2OFFT(initoffset);
len = NIL_P(initlen) ? 0 : NUM2OFFT(initlen);
advice = 0;
if (initadvice == sym_normal) {
#ifdef POSIX_FADV_NORMAL
advice = POSIX_FADV_NORMAL;
#endif
}
else if (initadvice == sym_random) {
#ifdef POSIX_FADV_RANDOM
advice = POSIX_FADV_RANDOM;
#endif
}
else if (initadvice == sym_sequential) {
#ifdef POSIX_FADV_SEQUENTIAL
advice = POSIX_FADV_SEQUENTIAL;
#endif
}
else if (initadvice == sym_willneed) {
#ifdef POSIX_FADV_WILLNEED
advice = POSIX_FADV_WILLNEED;
#endif
}
else if (initadvice == sym_dontneed) {
#ifdef POSIX_FADV_DONTNEED
advice = POSIX_FADV_DONTNEED;
#endif
}
else if (initadvice == sym_noreuse) {
#ifdef POSIX_FADV_NOREUSE
advice = POSIX_FADV_NOREUSE;
#endif
}
else
rb_raise(rb_eArgError, "Invalid advice: :%s",
RSTRING_PTR(rb_id2str(SYM2ID(initadvice))));
#ifdef HAVE_POSIX_FADVISE
io = GetWriteIO(io);
GetOpenFile(io, fptr);
if (rv = posix_fadvise(fptr->fd, offset, len, advice)) {
/* posix_fadvise(2) doesn't set errno. On success it returns 0; otherwise
it returns the error code. */
errno = rv;
rb_sys_fail_path(fptr->pathv);
}
#endif
return Qnil;
}
/*
* call-seq:
* ios.fileno -> fixnum
......
rb_define_method(rb_cIO, "binmode", rb_io_binmode_m, 0);
rb_define_method(rb_cIO, "binmode?", rb_io_binmode_p, 0);
rb_define_method(rb_cIO, "sysseek", rb_io_sysseek, -1);
rb_define_method(rb_cIO, "advise", rb_io_advise, -1);
rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1);
rb_define_method(rb_cIO, "fcntl", rb_io_fcntl, -1);
......
sym_textmode = ID2SYM(rb_intern("textmode"));
sym_binmode = ID2SYM(rb_intern("binmode"));
sym_autoclose = ID2SYM(rb_intern("autoclose"));
sym_normal = ID2SYM(rb_intern("normal"));
sym_sequential = ID2SYM(rb_intern("sequential"));
sym_random = ID2SYM(rb_intern("random"));
sym_willneed = ID2SYM(rb_intern("willneed"));
sym_dontneed = ID2SYM(rb_intern("dontneed"));
sym_noreuse = ID2SYM(rb_intern("noreuse"));
}
(1-1/7)