[#15707] Schedule for the 1.8.7 release — "Akinori MUSHA" <knu@...>

Hi, developers,

21 messages 2008/03/01

[#15740] Copy-on-write friendly garbage collector — Hongli Lai <hongli@...99.net>

Hi.

31 messages 2008/03/03
[#15742] Re: Copy-on-write friendly garbage collector — Yukihiro Matsumoto <matz@...> 2008/03/03

Hi,

[#15829] Re: Copy-on-write friendly garbage collector — Daniel DeLorme <dan-ml@...42.com> 2008/03/08

Yukihiro Matsumoto wrote:

[#15756] embedding Ruby 1.9.0 inside pthread — "Suraj Kurapati" <sunaku@...>

Hello,

18 messages 2008/03/03
[#15759] Re: embedding Ruby 1.9.0 inside pthread — Nobuyoshi Nakada <nobu@...> 2008/03/04

Hi,

[#15760] Re: embedding Ruby 1.9.0 inside pthread — Yukihiro Matsumoto <matz@...> 2008/03/04

Hi,

[#15762] Re: embedding Ruby 1.9.0 inside pthread — "Suraj N. Kurapati" <sunaku@...> 2008/03/04

Yukihiro Matsumoto wrote:

[#15783] Adding startup and shutdown to Test::Unit — Daniel Berger <Daniel.Berger@...>

Hi all,

15 messages 2008/03/04

[#15835] TimeoutError in core, timeouts for ConditionVariable#wait — MenTaLguY <mental@...>

I've been reworking JRuby's stdlib to improve performance and fix

10 messages 2008/03/09

[#15990] Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...>

Hi,

35 messages 2008/03/23
[#15991] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/23

[#15993] Re: Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...> 2008/03/23

Hi Dave,

[#15997] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/23

[#16024] Re: Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...> 2008/03/26

Hi Dave,

[#16025] Re: Recent changes in Range#step behavior — Yukihiro Matsumoto <matz@...> 2008/03/26

Hi,

[#16026] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16027] Re: Recent changes in Range#step behavior — Yukihiro Matsumoto <matz@...> 2008/03/26

Hi,

[#16029] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16030] Re: Recent changes in Range#step behavior — Yukihiro Matsumoto <matz@...> 2008/03/26

Hi,

[#16031] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16032] Re: Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...> 2008/03/26

On Wed, Mar 26, 2008 at 7:01 PM, Dave Thomas <dave@pragprog.com> wrote:

[#16033] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16041] Re: Recent changes in Range#step behavior — David Flanagan <david@...> 2008/03/26

Dave Thomas wrote:

PATCH: mknod and mkfifo support [Was: Ruby does not support mkfifo]

From: Hongli Lai <hongli@...99.net>
Date: 2008-03-07 11:32:02 UTC
List: ruby-core #15822
In my last email, I mentioned that there was an old patch that 
implements mknod() and mkfifo() support. That patch no longer works. 
I've ported the patch to Ruby 1.9, improved its documentation, and wrote 
unit tests. Please review the attached patch.

Regards,
Hongli Lai

Attachments (1)

ruby-mkfifo-mknod.diff (6.36 KB, text/x-diff)
diff --git a/configure.in b/configure.in
index c178210..2df4f6c 100644
--- a/configure.in
+++ b/configure.in
@@ -661,7 +661,7 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd
 	      dlopen sigprocmask sigaction sigsetjmp _setjmp vsnprintf snprintf\
 	      setsid telldir seekdir fchmod cosh sinh tanh log2 round\
 	      setuid setgid daemon select_large_fdset setenv unsetenv\
-	      mktime timegm clock_gettime gettimeofday)
+	      mktime timegm clock_gettime gettimeofday mkfifo mknod)
 AC_ARG_ENABLE(setreuid,
        [  --enable-setreuid       use setreuid()/setregid() according to need even if obsolete.],
        [use_setreuid=$enableval])
diff --git a/file.c b/file.c
index c32afbc..df8d656 100644
--- a/file.c
+++ b/file.c
@@ -3509,6 +3509,114 @@ rb_f_test(int argc, VALUE *argv)
     return Qnil;		/* not reached */
 }
 
+/*
+ *  call-seq:
+ *     File.mknod(file_name, [type, [mode, [dev]]])  => 0
+ *  
+ * Create a filesystem node (file, device special file or named pipe)
+ * named _file_name_, specified by _mode_ and _dev_.
+ *
+ * _type_ and _mode_ specifies the type and the permissions of node to
+ * be created respectively.
+ *
+ * The permissions are modified by the process's umask in the usual
+ * way: the permissions of the created node are (mode & ~umask).
+ *
+ * _type_ should be one of:
+ * - +?f+ - normal file (which will be created empty)
+ * - +?c+ - character special file
+ * - +?b+ - block special file
+ * - +?p+ - FIFO (named pipe)
+ * - +nil+ - normal file
+ *
+ * Raises:
+ * - +ArgumentError+ - _type_ is unknown or not supported on the current platform.
+ * - +SystemCallError+ - Something went wrong during the creation of the node.
+ * - +NotImplementedError+ - This call is not supported on the current platform.
+ */
+
+static VALUE
+rb_file_s_mknod(argc, argv)
+    int argc;
+    VALUE *argv;
+{
+#ifdef HAVE_MKNOD
+    VALUE path, type, vmode, vdev;
+    int mode = 0666, dev = 0, t;
+
+    rb_secure(4);
+    switch (rb_scan_args(argc, argv, "13", &path, &type, &vmode, &vdev)) {
+      case 4:
+	dev = NUM2INT(vdev);
+      case 3:
+	mode = NUM2INT(vmode) & ~S_IFMT;
+    }
+    FilePathValue(path);
+    if (!NIL_P(type)) {
+	rb_check_safe_obj(type);
+	switch (t = NUM2CHR(type)) {
+	  case 'f': mode |= S_IFREG; break;
+	  case 'c': mode |= S_IFCHR; break;
+#ifdef S_IFBLK
+	  case 'b': mode |= S_IFBLK; break;
+#endif
+#ifdef S_IFIFO
+	  case 'p': mode |= S_IFIFO; break;
+#endif
+	  default:
+	    rb_raise(rb_eArgError, "unknown node type - %c", t);
+	}
+    }
+    if (mknod(StringValueCStr(path), mode, dev)) {
+	rb_sys_fail("mknod");
+    }
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(0);
+}
+
+/*
+ * call-seq:
+ *    File.mkfifo(file_name, mode)  => 0
+ * 
+ * Creates a FIFO special file (named pipe) with name _file_name_.  _mode_
+ * specifies the FIFO's permissions. It is modified by the process's
+ * umask in the usual way: the permissions of the created file are
+ * (mode & ~umask).
+ *
+ * Raises:
+ * - +SystemCallError+ - Something went wrong during the creation of the FIFO.
+ * - +NotImplementedError+ - This call is not supported on the current platform.
+ */
+
+static VALUE
+rb_file_s_mkfifo(argc, argv)
+    int argc;
+    VALUE *argv;
+{
+#if !defined HAVE_MKFIFO && defined HAVE_MKNOD && defined S_IFIFO
+    #define mkfifo(path, mode) mknod(path, (mode)&~S_IFMT|S_IFIFO, 0)
+    #define HAVE_MKFIFO
+#endif
+#ifdef HAVE_MKFIFO
+    VALUE path, vmode;
+    int mode = 0666;
+
+    rb_secure(4);
+    if (rb_scan_args(argc, argv, "11", &path, &vmode) > 1) {
+	mode = NUM2INT(vmode);
+    }
+    FilePathValue(path);
+    if (mkfifo(StringValueCStr(path), mode)) {
+	rb_sys_fail("mkfifo");
+    }
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(0);
+}
+
 
 
 /*
@@ -4512,6 +4620,8 @@ Init_File(void)
     rb_define_singleton_method(rb_cFile, "rename", rb_file_s_rename, 2);
     rb_define_singleton_method(rb_cFile, "umask", rb_file_s_umask, -1);
     rb_define_singleton_method(rb_cFile, "truncate", rb_file_s_truncate, 2);
+    rb_define_singleton_method(rb_cFile, "mknod", rb_file_s_mknod, -1);
+    rb_define_singleton_method(rb_cFile, "mkfifo", rb_file_s_mkfifo, -1);
     rb_define_singleton_method(rb_cFile, "expand_path", rb_file_s_expand_path, -1);
     rb_define_singleton_method(rb_cFile, "basename", rb_file_s_basename, -1);
     rb_define_singleton_method(rb_cFile, "dirname", rb_file_s_dirname, 1);
diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb
index d29253f..45b2981 100644
--- a/test/ruby/test_file_exhaustive.rb
+++ b/test/ruby/test_file_exhaustive.rb
@@ -8,12 +8,21 @@ class TestFileExhaustive < Test::Unit::TestCase
     @file = make_tmp_filename("file")
     @zerofile = make_tmp_filename("zerofile")
     @nofile = make_tmp_filename("nofile")
+    @fifofile_nod = make_tmp_filename("fifofile_nod")
+    @fifofile = make_tmp_filename("fifofile")
     @symlinkfile = make_tmp_filename("symlinkfile")
     @hardlinkfile = make_tmp_filename("hardlinkfile")
     make_file("foo", @file)
     make_file("", @zerofile)
     @time = Time.now
     begin
+      File.mkfifo(@fifofile, 0600)
+      File.mknod(@fifofile_nod, "p")
+    rescue NotImplementedError
+      @fifofile = nil
+      @fifofile_nod = nil
+    end
+    begin
       File.symlink(@file, @symlinkfile)
     rescue NotImplementedError
       @symlinkfile = nil
@@ -104,6 +113,7 @@ class TestFileExhaustive < Test::Unit::TestCase
     assert(!(File.pipe?(@dir)))
     assert(!(File.pipe?(@file)))
     assert(!(File.pipe?(@nofile)))
+    assert(File.pipe?(@fifofile)) if @fifofile
   end
 
   def test_symlink_p
@@ -265,6 +275,7 @@ class TestFileExhaustive < Test::Unit::TestCase
     assert_equal("file", File.ftype(@file))
     assert_equal("link", File.ftype(@symlinkfile)) if @symlinkfile
     assert_equal("file", File.ftype(@hardlinkfile)) if @hardlinkfile
+    assert_equal("fifo", File.ftype(@fifofile)) if @fifofile
     assert_raise(Errno::ENOENT) { File.ftype(@nofile) }
   end
 
@@ -321,6 +332,16 @@ class TestFileExhaustive < Test::Unit::TestCase
 
   def test_lchown ## xxx
   end
+  
+  def test_mkfifo_and_mknod
+    return unless @fifofile
+    assert_equal("fifo", File.ftype(@fifofile))
+    assert_equal("fifo", File.ftype(@fifofile_nod))
+    
+    nod_normal = make_tmp_filename("nod_normal")
+    File.mknod(nod_normal)
+    assert_equal("file", File.ftype(nod_normal))
+  end
 
   def test_symlink
     return unless @symlinkfile

In This Thread