Project

General

Profile

io-advise.patch

IO#advise - runpaint (Run Paint Run Run), 11/06/2010 03:59 AM

View differences:

configure.in
1266 1266
fi
1267 1267
AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot getcwd eaccess\
1268 1268
	      truncate ftruncate chsize times utimes utimensat fcntl lockf lstat\
1269
	      link symlink readlink readdir_r fsync fdatasync fchown\
1269
	      link symlink readlink readdir_r fsync fdatasync fchown posix_fadvise\
1270 1270
	      setitimer setruid seteuid setreuid setresuid setproctitle socketpair\
1271 1271
	      setrgid setegid setregid setresgid issetugid pause lchown lchmod\
1272 1272
	      getpgrp setpgrp getpgid setpgid initgroups getgroups setgroups\
io.c
1

  
1 2
/**********************************************************************
2 3

  
3 4
  io.c -
......
1413 1414
#define rb_io_fdatasync rb_f_notimplement
1414 1415
#endif
1415 1416

  
1417
#ifdef HAVE_POSIX_FADVISE
1418
/*
1419
 *  call-seq:
1420
 *     ios.advise(advice, offset=0, len=0) -> nil
1421
 *
1422
 *  Announce an intention to access data from the current file in a specific
1423
 *  pattern. This method is implemented in terms of <em>posix_fadvise(2)</em>,
1424
 *  so on systems that do not support this system call, a
1425
 *  <code>NotImplementedError</code> is raised.
1426

  
1427
 * _advice_ is one of the following constants:
1428
 *  
1429
 *  * File::POSIX_FADV_NORMAL - No advice to give; the default assumption for 
1430
 *    an open file.
1431
 *  * File::POSIX_FADV_SEQUENTIAL - The data will be accessed sequentially: 
1432
 *    with lower offsets read before higher ones.
1433
 *  * File::POSIX_FADV_RANDOM - The data will be accessed in random order.
1434
 *  * File::POSIX_FADV_WILLNEED - The data will be accessed in the near future.
1435
 *  * FILE::POSIX_FADV_DONTNEED - The data will not be accessed in the near 
1436
 *    future.
1437
 *  * File::POSIX_FADV_NOREUSE - The data will only be accessed once.
1438
 *
1439
 *  The term _data_ means the region of the current file that begins
1440
 *  at _offset_ and extends for _len_ bytes. By default, both _offset_
1441
 *  and _len_ are 0, meaning that the advice applies to the entire
1442
 *  file.
1443
 *
1444
 *  If an error occurs one of the following exceptions will be raised:
1445
 *
1446
 *  * <code>IOError</code> - The <code>IO</code> stream is closed.
1447
 *  * <code>Errno::EBADF</code> - The file descriptor of the current file is
1448
 *  * invalid.  
1449
 *  * <code>Errno::EINVAL</code> - An invalid value for _advice_ was
1450
 *  * given.
1451
 *  * <code>Errno::ESPIPE</code> - The file descriptor of the current
1452
 *  * file refers to a FIFO or pipe. (Linux raises <code>Errno::EINVAL</code>
1453
 *  * in this case).
1454
 *  * <code>TypeError</code> - One of the arguments given was
1455
 *  * not an <code>Integer</code>.
1456
 *  * <code>RangeError</code> - One of the arguments given was too big/small.
1457
 *  * <code>NotImplementedError</code> - The underlying operating system does
1458
 *  * not support <em>posix_fadvise(2)</em>.
1459
 */
1460

  
1461
static VALUE
1462
rb_io_advise(int argc, VALUE *argv, VALUE io)
1463
{
1464
  off_t offset, len;
1465
  int advice, rv;
1466
  VALUE initadvice, initoffset, initlen;
1467
  rb_io_t *fptr;
1468

  
1469
  rb_scan_args(argc, argv, "12", &initadvice, &initoffset, &initlen);
1470
  advice = NUM2INT(initadvice);
1471
  offset = NIL_P(initoffset) ? 0 : NUM2OFFT(initoffset);
1472
  len    = NIL_P(initlen)    ? 0 : NUM2OFFT(initlen);
1473

  
1474
  io = GetWriteIO(io);
1475
  GetOpenFile(io, fptr);
1476

  
1477
  if (rv = posix_fadvise(fptr->fd, offset, len, advice)) {
1478
    /* posix_fadvise(2) doesn't set errno. On success it returns 0; otherwise
1479
       it returns the error code. */
1480
    errno = rv;
1481
    rb_sys_fail_path(fptr->pathv);
1482
  }
1483
  return Qnil;
1484
}
1485
#else
1486
#define rb_io_fadvise rb_f_notimplement
1487
#endif
1488

  
1416 1489
/*
1417 1490
 *  call-seq:
1418 1491
 *     ios.fileno    -> fixnum
......
10048 10121
    rb_define_method(rb_cIO, "binmode",  rb_io_binmode_m, 0);
10049 10122
    rb_define_method(rb_cIO, "binmode?", rb_io_binmode_p, 0);
10050 10123
    rb_define_method(rb_cIO, "sysseek", rb_io_sysseek, -1);
10124
    rb_define_method(rb_cIO, "advise", rb_io_advise, -1);
10051 10125

  
10052 10126
    rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1);
10053 10127
    rb_define_method(rb_cIO, "fcntl", rb_io_fcntl, -1);
......
10206 10280
    /* do not change atime */
10207 10281
    rb_file_const("NOATIME", INT2FIX(O_NOATIME)); /* Linux */
10208 10282
#endif
10283
#ifdef POSIX_FADV_NORMAL
10284
    rb_file_const("POSIX_FADV_NORMAL", INT2FIX(POSIX_FADV_NORMAL));
10285
#endif
10286
#ifdef POSIX_FADV_SEQUENTIAL
10287
    rb_file_const("POSIX_FADV_SEQUENTIAL", INT2FIX(POSIX_FADV_SEQUENTIAL));
10288
#endif
10289
#ifdef POSIX_FADV_RANDOM
10290
    rb_file_const("POSIX_FADV_RANDOM", INT2FIX(POSIX_FADV_RANDOM));
10291
#endif
10292
#ifdef POSIX_FADV_WILLNEED
10293
    rb_file_const("POSIX_FADV_WILLNEED", INT2FIX(POSIX_FADV_WILLNEED));
10294
#endif
10295
#ifdef POSIX_FADV_DONTNEED
10296
    rb_file_const("POSIX_FADV_DONTNEED", INT2FIX(POSIX_FADV_DONTNEED));
10297
#endif
10298
#ifdef POSIX_FADV_NOREUSE
10299
    rb_file_const("POSIX_FADV_NOREUSE", INT2FIX(POSIX_FADV_NOREUSE));
10300
#endif
10209 10301

  
10210 10302
    sym_mode = ID2SYM(rb_intern("mode"));
10211 10303
    sym_perm = ID2SYM(rb_intern("perm"));