diff --git a/.gitignore b/.gitignore index 5706c86ae3fa50..2893f50c71d8f7 100644 --- a/.gitignore +++ b/.gitignore @@ -72,7 +72,6 @@ lcov*.info /ChangeLog /Doxyfile /GNUmakefile -/README.atheos /README.fat-patch /README.v6 /TAGS @@ -80,7 +79,6 @@ lcov*.info /autom4te*.cache /automake /benchmark/benchmark-driver -/beos /bmlog-* /breakpoints.gdb /config.cache @@ -128,7 +126,6 @@ lcov*.info /revision.h /revision.tmp /ripper.tmp.y -/riscos /rubicon /ruby /ruby-runner diff --git a/NEWS.md b/NEWS.md index 061223cc3b11b6..37ee9353086b39 100644 --- a/NEWS.md +++ b/NEWS.md @@ -302,6 +302,20 @@ Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for det * Interix (Windows Services for UNIX) * SunOS 4 (Solaris, i.e. SunOS 5, is unaffected) * BSD/OS (BSDi) + * NeXTSTEP, OpenStep and Rhapsody + +* Support code for the following platforms has also been removed. None + of them has a platform maintainer. + + * AmigaOS + * AtheOS + * ESIX + * HI-UX/MPP + * IRIX + * OSF/1 (Tru64 UNIX) + * QNX Neutrino + * System V Release 4 + * UX/PDS * Windows 10 1703 or later no longer needs the `LongPathsEnabled` registry value to use paths longer than 260 characters. This applies to any process diff --git a/configure.ac b/configure.ac index 24fe2b690790f9..fea206e2b87468 100644 --- a/configure.ac +++ b/configure.ac @@ -575,8 +575,7 @@ AS_CASE(["$target_os"], ]) rb_cv_binary_elf=no : ${enable_shared=yes} - ], -[hiuxmpp*], [AC_DEFINE(__HIUX_MPP__)]) # by TOYODA Eizi + ]) AC_PROG_LN_S AC_PROG_MAKE_SET @@ -1149,9 +1148,6 @@ AC_SUBST(POSTLINK) cleanlibs= AC_SUBST(cleanlibs) AS_CASE(["$target_os"], -[nextstep*], [ ], -[openstep*], [ ], -[rhapsody*], [ ], [darwin*], [ ORIG_LIBS="$LIBS" RUBY_PREPEND_OPTION(LIBS, -lobjc) @@ -1958,8 +1954,6 @@ AS_CASE(["$target_cpu"], [alpha*|sh4|sh4el|sh4eb], [AS_CASE(["$target_os"::"$GCC"], [*::yes], # gcc [CFLAGS="-mieee $CFLAGS"], - [osf*], # ccc - [CFLAGS="-ieee $CFLAGS"], )], [sparc*], [AC_LIBOBJ([sparc])]) @@ -3171,9 +3165,8 @@ STATIC= RUBY_APPEND_OPTION(CCDLFLAGS, -fPIC)]) ], [ AS_CASE(["$target_os"], - [solaris*|irix*], [CCDLFLAGS="$CCDLFLAGS -KPIC"], - [esix*|uxpds*], [CCDLFLAGS="$CCDLFLAGS -KPIC"], - [: ${CCDLFLAGS=""}]) + [solaris*], [CCDLFLAGS="$CCDLFLAGS -KPIC"], + [: ${CCDLFLAGS=""}]) ]) } @@ -3212,16 +3205,6 @@ AC_SUBST(PROGRAM_EXTS, [${EXTSTATIC:+exts}]) : ${PRELOADENV=LD_PRELOAD_32} ]) rb_cv_dlopen=yes], - [irix*], [ : ${LDSHARED='$(LD) -shared'} - rb_cv_dlopen=yes], - [sysv4*], [ : ${LDSHARED='$(LD) -G'} - rb_cv_dlopen=yes], - [nto-qnx*], [ : ${LDSHARED='$(CC) -shared'} - rb_cv_dlopen=yes], - [esix*|uxpds*], [ : ${LDSHARED='$(LD) -G'} - rb_cv_dlopen=yes], - [osf*], [ : ${LDSHARED='$(LD) -shared -expect_unresolved "*"'} - rb_cv_dlopen=yes], [linux* | gnu* | k*bsd*-gnu | netbsd* | kopensolaris*-gnu | haiku*], [ : ${LDSHARED='$(CC) -shared'} AS_IF([test "$rb_cv_binary_elf" = yes], [ @@ -3270,10 +3253,6 @@ AC_SUBST(PROGRAM_EXTS, [${EXTSTATIC:+exts}]) : ${LIBPATHENV=LIBPATH} : ${PRELOADENV=LDR_PRELOAD} rb_cv_dlopen=yes], - [nto-qnx*], [ DLDFLAGS="$DLDFLAGS -L/lib -L/usr/lib -L/usr/local/lib" - : ${LDSHARED='$(LD) -Bshareable -x'} - LDFLAGS="$LDFLAGS -L/lib -L/usr/lib -L/usr/local/lib" - rb_cv_dlopen=yes], [cygwin*|msys*|mingw*], [ : ${LDSHARED='$(CC) -shared'} XLDFLAGS="$XLDFLAGS -Wl,--stack,0x00200000,--enable-auto-import" @@ -3281,9 +3260,6 @@ AC_SUBST(PROGRAM_EXTS, [${EXTSTATIC:+exts}]) : ${LIBPATHENV=PATH} : ${PRELOADENV=""} rb_cv_dlopen=yes], - [hiuxmpp], [ : ${LDSHARED='$(LD) -r'}], - [atheos*], [ : ${LDSHARED='$(CC) -shared'} - rb_cv_dlopen=yes], [wasi*], [ : ${LDSHARED='$(LD) -shared -Xlinker --export-dynamic'}], [ : ${LDSHARED='$(LD)'}]) AC_MSG_RESULT($rb_cv_dlopen) @@ -3441,7 +3417,7 @@ AS_IF([test x$with_valgrind != xno], [darwin*], [ SOEXT=dylib DLEXT=bundle], - [cygwin*|msys*|mingw*|*djgpp*], [ + [cygwin*|msys*|mingw*], [ LOAD_RELATIVE=1 SOEXT=dll DLEXT=so], @@ -3679,7 +3655,7 @@ AS_CASE("$enable_shared", [yes], [ relative_libprefix="/../${multiarch+../}${libdir_basename}" AS_CASE(["$target_os"], - [linux* | gnu* | k*bsd*-gnu | atheos* | kopensolaris*-gnu | haiku*], [ + [linux* | gnu* | k*bsd*-gnu | kopensolaris*-gnu | haiku*], [ RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,$(LIBRUBY_SONAME)' "$LDFLAGS_OPTDIR"]) LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)' AS_IF([test "$load_relative" = yes], [ @@ -4242,21 +4218,6 @@ enum { RUBY_APPEND_OPTION(XLDFLAGS, [-framework CoreFoundation]) RUBY_APPEND_OPTION(LIBRUBYARG_STATIC, [-framework CoreFoundation]) ], - [osf*], [ - AS_IF([test "$GCC" != "yes" ], [ - # compile something small: taint.c is fine for this. - # the main point is the '-v' flag of 'cc'. - AS_CASE(["`cc -v -I. -c main.c -o /tmp/main.o 2>&1`"], - [*/gemc_cc*], [ # we have the new DEC GEM CC - CFLAGS="$CFLAGS -oldc" - ], - [ # we have the old MIPS CC - ]) - # cleanup - rm -f /tmp/main.o - CFLAGS="$CFLAGS -std" - ]) - ], [cygwin*|msys*|mingw*], [ LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' -Wl,--out-implib=$(LIBRUBY)' AS_CASE(["$target_os"], diff --git a/dir.c b/dir.c index 890372d18d007b..b1a7a3b8519446 100644 --- a/dir.c +++ b/dir.c @@ -1813,12 +1813,21 @@ nogvl_rmdir(void *ptr) } /* + * :markup: markdown + * * call-seq: + * Dir.delete(dirpath) -> 0 * Dir.rmdir(dirpath) -> 0 + * Dir.unlink(dirpath) -> 0 * - * Removes the directory at +dirpath+ from the underlying file system: + * Removes the directory entry ([hard link](rdoc-ref:file/hard_links.md)) at `dirpath`, + * along with its associated inode: * - * Dir.rmdir('foo') # => 0 + * ```ruby + * dirpath = '/tmp/tmpdir' + * Dir.mkdir(dirpath) + * Dir.rmdir(dirpath) # => 0 + * ``` * * Raises an exception if the directory is not empty. */ diff --git a/doc/file/hard_links.md b/doc/file/hard_links.md new file mode 100644 index 00000000000000..f2e56d5ac7bd3c --- /dev/null +++ b/doc/file/hard_links.md @@ -0,0 +1,65 @@ +# Hard Links + +A _hard link_ is a filesystem entry pointing to +an [inode](https://en.wikipedia.org/wiki/Inode) in the filesystem; +in effect, the hard link is a name for the inode. + +An inode is one of these types (see File.ftype): + +- Regular file. +- Directory. +- Symbolic link. +- FIFO. +- \Socket. +- Block-special device. +- Character-special device. + +When an inode is created, it initially has one hard link -- its original "name": + +```ruby +path0 = '/tmp/t0.tmp' +File.write(path0, 'foo') +stat0 = File.stat(path0) +stat0.ino # => 26345482 # Inode identifier; unique within filesystem. +stat0.nlink # => 1 # Count of hard link to the inode. +``` + +## Multiple Hard Links + +The inode may have more than one hard link: + +```ruby +path1 = '/tmp/t1.tmp' +File.link(path0, path1) +stat1 = File.stat(path1) +stat1.ino # => 26345482 +stat1.nlink # => 2 +``` + +Multiple hard links to the same inode are in effect multiple names for that inode: + +```ruby +File.read(path0) # => "foo" +File.read(path1) # => "foo" +``` + +When an inode has more than one hard link, all its hard links are "equal"; +the original hard link is no more "valid" or "important" than the others. + +## Unlinking + +Unlinking (removing) one hard link does not remove the inode: + +```ruby +File.unlink(path1) +File.exist?(path1) # => false # Hard link path1 was removed. +File.exist?(path0) # => true # Hard link path0 still exists. +File.stat(path0).nlink # => 1 # Now has only one hard link. +``` + +But removing the last hard link does remove the inode: + +```ruby +File.unlink(path0) +File.exist?(path0) # => false # And the inode was removed. +``` diff --git a/ext/etc/extconf.rb b/ext/etc/extconf.rb index 497303a4fa51f7..418147b466f093 100644 --- a/ext/etc/extconf.rb +++ b/ext/etc/extconf.rb @@ -7,7 +7,6 @@ headers << h end } -have_library("sun", "getpwnam") # NIS (== YP) interface for IRIX 4 have_func("uname((struct utsname *)NULL)", headers) have_func("getlogin") if have_func("getpwent") diff --git a/ext/pty/extconf.rb b/ext/pty/extconf.rb index ae2cb45d3cabc9..d88d977d932029 100644 --- a/ext/pty/extconf.rb +++ b/ext/pty/extconf.rb @@ -3,7 +3,7 @@ $INCFLAGS << " -I$(topdir) -I$(top_srcdir)" -if /mswin|mingw|bccwin/ !~ RUBY_PLATFORM +if /mswin|mingw/ !~ RUBY_PLATFORM have_header("sys/stropts.h") have_func("setresuid") have_header("libutil.h") @@ -19,7 +19,6 @@ end if openpt or (util or have_func("openpty")) or - have_func("_getpty") or have_func("ioctl") have_macro("HAVE_FCHMOD") or have_func("fchmod") have_macro("HAVE_FCHOWN") or have_func("fchown") diff --git a/ext/pty/pty.c b/ext/pty/pty.c index 3d5977707fcae4..0ffefd0a07e5b1 100644 --- a/ext/pty/pty.c +++ b/ext/pty/pty.c @@ -395,23 +395,6 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, return 0; -#elif defined HAVE__GETPTY - /* SGI IRIX */ - char *name; - mode_t mode = nomesg ? 0600 : 0622; - - if (!(name = _getpty(master, O_RDWR, mode, 0))) { - if (!fail) return -1; - rb_raise(rb_eRuntimeError, "_getpty() failed"); - } - rb_fd_fix_cloexec(*master); - - *slave = rb_cloexec_open(name, O_RDWR, 0); - /* error check? */ - rb_update_max_fd(*slave); - strlcpy(SlaveName, name, DEVICELEN); - - return 0; #elif defined(HAVE_PTSNAME) /* System V */ int masterfd = -1, slavefd = -1; diff --git a/ext/zlib/extconf.rb b/ext/zlib/extconf.rb index 2187ed1e7aac23..a4053177e978dd 100644 --- a/ext/zlib/extconf.rb +++ b/ext/zlib/extconf.rb @@ -82,9 +82,7 @@ Logging::message 'checking for kind of operating system... ' os_code = with_config('os-code') || case RUBY_PLATFORM.split('-',2)[1] - when 'amigaos' then - os_code = 'AMIGA' - when /mswin|mingw|bccwin/ then + when /mswin|mingw/ then # NOTE: cygwin should be regarded as Unix. os_code = 'WIN32' else diff --git a/file.c b/file.c index 600cffcea0ae55..ed51562de1071e 100644 --- a/file.c +++ b/file.c @@ -2188,19 +2188,28 @@ rb_file_readable_real_p(VALUE obj, VALUE fname) #endif /* + * :markup: markdown + * * call-seq: - * File.world_readable?(file_name) -> integer or nil + * File.world_readable?(object) -> integer or nil * - * If file_name is readable by others, returns an integer - * representing the file permission bits of file_name. Returns - * +nil+ otherwise. The meaning of the bits is platform dependent; on - * Unix systems, see stat(2). + * If the the given `object` exists and is readable by others, + * returns the integer [permissions](rdoc-ref:file/filesystem_modes.md@Permissions) + * for the entry; + * otherwise, returns `nil`: * - * _file_name_ can be an IO object. + * ```ruby + * filepath = '/tmp/t.tmp' + * File.world_readable?(filepath) # => nil # Non-existent. + * File.write(filepath, 'foo') # Create file. + * File.world_readable?(filepath).to_s(8) # => "664" # World-readable. + * File.chmod(0o000, filepath) # Change to unreadable. + * File.world_readable?(filepath) # => nil # Not world-readable. + * File.delete(filepath) # Clean up. + * File.world_readable?('.').to_s(8) # => "775" # Directory. + * File.world_readable?($stdin) # => nil # IO object. + * ``` * - * File.world_readable?("/etc/passwd") #=> 420 - * m = File.world_readable?("/etc/passwd") - * sprintf("%o", m) #=> "644" */ static VALUE @@ -2218,8 +2227,10 @@ rb_file_world_readable_p(VALUE obj, VALUE fname) } /* + * :markup: markdown + * * call-seq: - * File.writable?(file_name) -> true or false + * File.writable?(object) -> true or false * * Returns +true+ if the named file is writable by the effective user and * group id of this process. See eaccess(3). @@ -2235,14 +2246,16 @@ rb_file_writable_p(VALUE obj, VALUE fname) } /* + * :markup: markdown + * * call-seq: - * File.writable_real?(file_name) -> true or false + * File.writable_real?(object) -> true or false * - * Returns +true+ if the named file is writable by the real user and group id - * of this process. See access(3). + * Like File.writable?, but checks against the real owner and group + * instead of the effective owner and group. * - * Note that some OS-level security features may cause this to return true - * even though the file is not writable by the real user/group. + * Note that filesystem security features may cause this method to return `true` + * even when the object is not writable by the real owner and group. */ static VALUE @@ -2252,19 +2265,28 @@ rb_file_writable_real_p(VALUE obj, VALUE fname) } /* + * :markup: markdown + * * call-seq: - * File.world_writable?(file_name) -> integer or nil + * File.world_writable?(object) -> integer or nil * - * If file_name is writable by others, returns an integer - * representing the file permission bits of file_name. Returns - * +nil+ otherwise. The meaning of the bits is platform dependent; on - * Unix systems, see stat(2). + * If the given `object` exists and is writable by others, + * returns the integer [permissions](rdoc-ref:file/filesystem_modes.md@Permissions) + * for the entry; + * otherwise, returns `nil`: * - * _file_name_ can be an IO object. + * ```ruby + * filepath = '/tmp/t.tmp' + * File.world_writable?(filepath) # => nil # Non-existent. + * File.write(filepath, 'foo') # Create file. + * File.world_writable?(filepath) # => nil # Not world-writable. + * File.chmod(0o777, filepath) # Make world-writable. + * File.world_writable?(filepath).to_s(8) # => "777" # World-writable. + * File.delete(filepath) # Clean up. + * File.world_writable?('/tmp').to_s(8) # => "777" # Directory. + * File.world_writable?($stdin) # => nil # IO object. + * ``` * - * File.world_writable?("/tmp") #=> 511 - * m = File.world_writable?("/tmp") - * sprintf("%o", m) #=> "777" */ static VALUE @@ -4101,22 +4123,36 @@ unlink_internal(const char *path, void *arg) * File.delete(*paths) -> integer * File.unlink(*paths) -> integer * - * Removes the entry at each path in `paths`; - * returns the count of removed entries. + * Removes the entry ([hard link](rdoc-ref:file/hard_links.md)) at each path in `paths`; + * returns the count of removed entries: + * + * ```ruby + * filepath0 = '/tmp/t0.tmp' + * filepath1 = '/tmp/t1.tmp' + * File.write(filepath0, 'foo') + * File.write(filepath1, 'bar') + * File.unlink(filepath0, filepath1) # => 2 + * ``` + * + * If the removed hard link is the last one associated with the inode, + * also removes the inode; otherwise, not. + * See [Unlinking](rdoc-ref:file/hard_links.md@Unlinking). * * Does not follow [symbolic links](rdoc-ref:file/symbolic_links.md); - * if an entry is a symlink, the link itself is removed. + * if the entry is a symbolic link, removes the entry itself (not the link target). * * ```ruby - * File.write('t.tmp', 'foo') - * File.write('u.tmp', 'bar') - * File.delete('t.tmp', 'u.tmp') # => 2 - * File.symlink('README.md', 'foo') - * File.unlink('foo') # => 1 + * filepath = '/tmp/t.tmp' + * linkpath = '/tmp/link' + * File.write(filepath, 'foo') + * File.symlink(filepath, linkpath) + * File.unlink(linkpath) # => 1 + * File.exist?(filepath) # => true + * File.unlink(filepath) # => 1 * ``` * * Raises an exception on any error; - * some entries may have been deleted before the path causing the error. + * some entries may have been deleted before the error occurs. */ static VALUE @@ -7126,16 +7162,25 @@ rb_stat_R(VALUE obj) } /* + * :markup: markdown + * * call-seq: - * stat.world_readable? -> integer or nil + * world_readable? -> integer or nil * - * If stat is readable by others, returns an integer - * representing the file permission bits of stat. Returns +nil+ - * otherwise. The meaning of the bits is platform dependent; on Unix - * systems, see stat(2). + * If the entry in `self` exists and is readable by others, + * returns the integer [permissions](rdoc-ref:file/filesystem_modes.md@Permissions) + * for the entry; + * otherwise, returns `nil`: * - * m = File.stat("/etc/passwd").world_readable? #=> 420 - * sprintf("%o", m) #=> "644" + * ```ruby + * filepath = '/tmp/t.tmp' + * File.write(filepath, 'foo') + * File.stat(filepath).world_readable?.to_s(8) # => "664" # World-readable. + * File.chmod(0o000, filepath) # Make unreadable. + * File.stat(filepath).world_readable? # => nil # Not world-readable. + * File.delete(filepath) # Clean up. + * File.stat('.').world_readable?.to_s(8) # => "775" # Directory. + * ``` */ static VALUE @@ -7184,14 +7229,16 @@ rb_stat_w(VALUE obj) } /* - * call-seq: - * stat.writable_real? -> true or false + * :markup: markdown * - * Returns +true+ if stat is writable by the real user id of this - * process. + * call-seq: + * writable_real? -> true or false * - * File.stat("testfile").writable_real? #=> true + * Like File::Stat.writable?, but checks against the real owner and group + * instead of the effective owner and group. * + * Note that filesystem security features may cause this method to return `true` + * even when the entry in `self` is not writable by the real owner and group. */ static VALUE @@ -7217,16 +7264,26 @@ rb_stat_W(VALUE obj) } /* + * :markup: markdown + * call-seq: - * stat.world_writable? -> integer or nil + * world_writable? -> integer or nil * - * If stat is writable by others, returns an integer - * representing the file permission bits of stat. Returns +nil+ - * otherwise. The meaning of the bits is platform dependent; on Unix - * systems, see stat(2). + * If the entry in `self` exists and is writable by others, + * returns the integer [permissions](rdoc-ref:file/filesystem_modes.md@Permissions) + * for the entry; + * otherwise, returns `nil`: + * + * ```ruby + * filepath = '/tmp/t.tmp' + * File.write(filepath, 'foo') + * File.stat(filepath).world_writable? # => nil # Not world-writable. + * File.chmod(0o777, filepath) # Make world-writable. + * File.stat(filepath).world_writable?.to_s(8) # => "777" # World-writable. + * File.delete(filepath) # Clean up. + * File.stat('/tmp').world_writable?.to_s(8) # => "777" # Directory. + * ``` * - * m = File.stat("/tmp").world_writable? #=> 511 - * sprintf("%o", m) #=> "777" */ static VALUE @@ -7847,10 +7904,6 @@ rb_find_file(VALUE path) const char ruby_null_device[] = #if defined DOSISH "NUL" -#elif defined AMIGA || defined __amigaos__ - "NIL" -#elif defined __VMS - "NL:" #else "/dev/null" #endif diff --git a/io.c b/io.c index 90a2fcfa7824f5..9337dd2cc6e5a3 100644 --- a/io.c +++ b/io.c @@ -56,10 +56,6 @@ # define USE_SETVBUF #endif -#ifdef __QNXNTO__ -#include -#endif - #include #ifdef HAVE_SYS_IOCTL_H #include @@ -76,7 +72,7 @@ #include -#if defined(HAVE_SYS_PARAM_H) || defined(__HIUX_MPP__) +#if defined(HAVE_SYS_PARAM_H) # include #endif diff --git a/lib/bundler/constants.rb b/lib/bundler/constants.rb index 9564771e78afbb..4d86b1ac89b77a 100644 --- a/lib/bundler/constants.rb +++ b/lib/bundler/constants.rb @@ -3,7 +3,7 @@ require "rbconfig" module Bundler - WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/ + WINDOWS = RbConfig::CONFIG["host_os"] =~ /(mswin|mingw)/ deprecate_constant :WINDOWS FREEBSD = RbConfig::CONFIG["host_os"].to_s.include?("bsd") diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb index 192b7cb52e55dd..6eb8231c2c8c94 100644 --- a/lib/prism/ffi.rb +++ b/lib/prism/ffi.rb @@ -186,7 +186,7 @@ def self.with # pointer directly; for files it uses a pm_source_t under the hood. class PrismSource # :nodoc: PLATFORM_EXPECTS_UTF8 = - RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince|darwin/i) + RbConfig::CONFIG["host_os"].match?(/cygwin|mingw|mswin|darwin/i) attr_reader :pointer, :length diff --git a/lib/resolv.rb b/lib/resolv.rb index e1b7593ebac31f..72df381842e5d3 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -179,7 +179,7 @@ class ResolvTimeout < Timeout::Error; end # Resolv::Hosts is a hostname resolver that uses the system hosts file. class Hosts - if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM || ::RbConfig::CONFIG['host_os'] =~ /mswin/ + if /mswin|cygwin|mingw/ =~ RUBY_PLATFORM || ::RbConfig::CONFIG['host_os'] =~ /mswin/ begin require 'win32/resolv' unless defined?(Win32::Resolv) hosts = Win32::Resolv.get_hosts_path || IO::NULL diff --git a/lib/rubygems/win_platform.rb b/lib/rubygems/win_platform.rb index 10556871b2a68e..a5c6b7a037c19b 100644 --- a/lib/rubygems/win_platform.rb +++ b/lib/rubygems/win_platform.rb @@ -7,11 +7,8 @@ module Gem # An Array of Regexps that match windows Ruby platforms. WIN_PATTERNS = [ - /bccwin/i, - /djgpp/i, /mingw/i, /mswin/i, - /wince/i, ].freeze @@win_platform = nil diff --git a/man/erb.1 b/man/erb.1 index f518d86678e44b..c973b05afcdc32 100644 --- a/man/erb.1 +++ b/man/erb.1 @@ -1,5 +1,5 @@ .\"Ruby is copyrighted by Yukihiro Matsumoto . -.Dd July 10, 2026 +.Dd September 25, 2026 .Dt ERB 1 "Ruby Programmer's Reference Guide" .Os UNIX .Sh NAME diff --git a/man/goruby.1 b/man/goruby.1 index 7465c20f1f5904..611bc669a34a0f 100644 --- a/man/goruby.1 +++ b/man/goruby.1 @@ -1,5 +1,5 @@ .\"Ruby is copyrighted by Yukihiro Matsumoto . -.Dd May 24, 2026 +.Dd September 25, 2026 .Dt GORUBY 1 "Ruby Programmer's Reference Guide" .Os UNIX .Sh NAME diff --git a/man/ruby.1 b/man/ruby.1 index 84ec097dbf8ccd..9b46ca99b60598 100644 --- a/man/ruby.1 +++ b/man/ruby.1 @@ -1,5 +1,5 @@ .\"Ruby is copyrighted by Yukihiro Matsumoto . -.Dd July 10, 2026 +.Dd September 25, 2026 .Dt RUBY 1 "Ruby Programmer's Reference Guide" .Os UNIX .Sh NAME @@ -515,7 +515,7 @@ environment variable. .Pp .It Ev RUBYSHELL The path to the system shell command. This environment variable is -enabled for only mswin32, mingw32, and OS/2 platforms. If this +enabled for only mswin32 and mingw32 platforms. If this variable is not defined, Ruby refers to .Ev COMSPEC . .Pp diff --git a/pack.c b/pack.c index fb750b32fc8803..211432dcfa78ec 100644 --- a/pack.c +++ b/pack.c @@ -55,7 +55,7 @@ static const char endstr[] = "sSiIlLqQjJ"; #endif #ifdef DYNAMIC_ENDIAN -/* for universal binary of NEXTSTEP and MacOS X */ +/* for universal binary of MacOS X */ /* useless since autoconf 2.63? */ static int is_bigendian(void) diff --git a/pathname_builtin.rb b/pathname_builtin.rb index b373b9617fe548..834888250e6b66 100644 --- a/pathname_builtin.rb +++ b/pathname_builtin.rb @@ -2579,21 +2579,20 @@ def readable?() FileTest.readable?(@path) end # call-seq: # world_readable? -> integer or nil # - # If the entry at the path in `self` is readable by others, - # returns the integer permissions for the entry: + # If the entry at the path in `self` exists and is readable by others, + # returns the integer [permissions](rdoc-ref:file/filesystem_modes.md@Permissions) + # for the entry; + # otherwise, returns `nil`: # # ```ruby - # Pathname('/etc/passwd').world_readable?.to_s(8) # => "644" - # ``` - # - # Otherwise, returns `nil`: - # - # ```ruby - # pn = Pathname('doc/t.tmp') - # pn.write('foo') - # pn.chmod(0o0) - # pn.world_readable? # => nil - # pn.delete + # pn = Pathname('/tmp/t.tmp') + # pn.world_readable? # => nil # Does not exist. + # pn.write('foo') # Create file. + # pn.world_readable?.to_s(8) # => "664" # World-readable. + # pn.chmod(0o000) # Change to unreadable. + # pn.world_readable? # => nil # Not readable. + # pn.delete # Clean up. + # Pathname('.').world_readable?.to_s(8) # => "775" # Directory. # ``` # def world_readable?() File.world_readable?(@path) end @@ -2762,21 +2761,20 @@ def writable?() FileTest.writable?(@path) end # call-seq: # world_writable? -> integer or nil # - # If the entry at the path in `self` is writable by others, - # returns the integer permissions for the entry: - # - # ```ruby - # Pathname('/tmp').world_writable?.to_s(8) # => "777" - # ``` - # - # Otherwise, returns `nil`: + # If the entry at the path in `self` exists and is writable by others, + # returns the integer [permissions](rdoc-ref:file/filesystem_modes.md@Permissions) + # for the entry; + # otherwise, returns `nil`: # # ```ruby - # pn = Pathname('doc/t.tmp') - # pn.write('foo') - # pn.chmod(0o0) - # pn.world_writable? # => nil - # pn.delete + # pn = Pathname('/tmp/t.tmp') + # pn.world_writable? # => nil # Non-existent. + # pn.write('foo') # Create file. + # pn.world_writable? # => nil # Not world-writable. + # pn.chmod(0o777) # Make world-writable. + # pn.world_writable?.to_s(8) # => "511" # World-writable. + # pn.delete # Clean up. + # Pathname('/tmp').world_writable?.to_s(8) # => "777" # Directory. # ``` # def world_writable?() File.world_writable?(@path) end @@ -2786,8 +2784,11 @@ def world_writable?() File.world_writable?(@path) end # call-seq: # writable_real? -> true or false # - # Like #writable?, but checks against the real user and group ids - # instead of the effective ids. + # Like Pathname#writable?, but checks against the real owner and group + # instead of the effective owner and group. + # + # Note that filesystem security features may cause this method to return `true` + # even when the entry at the path in `self` is not writable by the real owner and group. def writable_real?() FileTest.writable_real?(@path) end # :markup: markdown @@ -2994,19 +2995,34 @@ class Pathname # * mixed * # call-seq: # unlink -> 0 or 1 # - # Removes the entry represented by `self`; - # returns `0` if a directory, `1` otherwise. + # Removes the entry ([hard link](rdoc-ref:file/hard_links.md)) + # at the path in `self`; + # returns `0` if a directory, `1` otherwise: + # + # ```ruby + # pn_file = Pathname('/tmp/t.txt') + # pn_file.write('foo') + # pn_file.unlink # => 1 + # pn_dir = Pathname('/tmp/foo') + # pn_dir.mkdir + # pn_dir.unlink # => 0 + # ``` + # + # If the removed hard link is the last one associated the inode, + # also removes the inode; otherwise, not. + # See [Unlinking](rdoc-ref:file/hard_links.md@Unlinking). # # Does not follow [symbolic links](rdoc-ref:file/symbolic_links.md); - # if the entry is a symlink, the link itself is removed. + # if the entry is a symbolic link, removes the entry itself (not the link target). # # ```ruby - # Pathname(Pathname.mktmpdir).unlink # => 0 - # Pathname(Tempfile.create).unlink # => 1 - # pn_target = Pathname('README.md') # => # - # pn_link = Pathname('foo') # => # - # pn_link.make_symlink(pn_target) - # pn_link.delete + # pn_file = Pathname('/tmp/t.txt') + # pn_link = Pathname('/tmp/link') + # pn_file.write('foo') + # pn_link.make_symlink(pn_file) + # pn_link.unlink # => 1 + # pn_file.exist? # => true # Link was not followed. + # pn_file.unlink # => 1 # ``` # def unlink() diff --git a/proc.c b/proc.c index ddb834e4645bf6..7e20f3872887f7 100644 --- a/proc.c +++ b/proc.c @@ -4614,10 +4614,11 @@ proc_curry(int argc, const VALUE *argv, VALUE self) arity = INT2FIX(min_arity); } else { - sarity = FIX2INT(arity); + sarity = NUM2INT(arity); if (rb_proc_lambda_p(self)) { rb_check_arity(sarity, min_arity, max_arity); } + arity = INT2FIX(sarity); } return make_curry_proc(self, rb_ary_new(), arity); diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock index 9e6c2fe23d7df6..81f0e2ffb51f21 100644 --- a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock +++ b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock @@ -11,7 +11,7 @@ GEM ostruct (0.6.3) rake (13.3.0) rexml (3.4.2) - rubyzip (3.3.0) + rubyzip (3.4.0) warbler (2.1.0) jruby-jars (>= 9.4, < 10.1) jruby-rack (>= 1.2.3, < 1.3) diff --git a/test/-ext-/thread/test_instrumentation_api.rb b/test/-ext-/thread/test_instrumentation_api.rb index 55c50a28b04acc..cefb91f8876fa0 100644 --- a/test/-ext-/thread/test_instrumentation_api.rb +++ b/test/-ext-/thread/test_instrumentation_api.rb @@ -6,7 +6,7 @@ class TestThreadInstrumentation < Test::Unit::TestCase include ThreadInstrumentation::TestHelper def setup - pend("No windows support") if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + pend("No windows support") if /mswin|mingw/ =~ RUBY_PLATFORM require '-test-/thread/instrumentation' @@ -14,7 +14,7 @@ def setup end def teardown - return if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + return if /mswin|mingw/ =~ RUBY_PLATFORM Bug::ThreadInstrumentation.unregister_callback cleanup_threads end diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb index dd2ba5db3ab41b..1a93c01a51b80c 100644 --- a/test/fileutils/test_fileutils.rb +++ b/test/fileutils/test_fileutils.rb @@ -34,11 +34,11 @@ def assert_output_lines(expected, fu = self, message=nil) m = Module.new do def have_drive_letter? - /mswin(?!ce)|mingw|bcc|emx/ =~ RUBY_PLATFORM + /mswin|mingw/ =~ RUBY_PLATFORM end def have_file_perm? - /mswin|mingw|bcc|emx/ !~ RUBY_PLATFORM + /mswin|mingw/ !~ RUBY_PLATFORM end @@assignable_groups = nil diff --git a/test/prism/test_helper.rb b/test/prism/test_helper.rb index 406582c0a5b1ec..9fea36476b9fb3 100644 --- a/test/prism/test_helper.rb +++ b/test/prism/test_helper.rb @@ -236,7 +236,7 @@ def self.each_encoding # True if the current platform is Windows. def self.windows? - RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince/i) + RbConfig::CONFIG["host_os"].match?(/cygwin|mingw|mswin/i) end # All versions that prism can parse diff --git a/test/ruby/test_argf.rb b/test/ruby/test_argf.rb index 0a09028a6e9a80..7d65a89320c49a 100644 --- a/test/ruby/test_argf.rb +++ b/test/ruby/test_argf.rb @@ -38,7 +38,7 @@ def ruby(*args, external_encoding: Encoding::UTF_8) end def no_safe_rename - /cygwin|mswin|mingw|bccwin/ =~ RUBY_PLATFORM + /cygwin|mswin|mingw/ =~ RUBY_PLATFORM end def assert_src_expected(src, args = nil, line: caller_locations(1, 1)[0].lineno+1) diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb index 3e928a5b52b9ac..cbdcb9cf9d8d48 100644 --- a/test/ruby/test_env.rb +++ b/test/ruby/test_env.rb @@ -2,7 +2,7 @@ require 'test/unit' class TestEnv < Test::Unit::TestCase - windows = /bccwin|mswin|mingw/ =~ RUBY_PLATFORM + windows = /mswin|mingw/ =~ RUBY_PLATFORM IGNORE_CASE = windows ENCODING = windows ? Encoding::UTF_8 : Encoding.find("locale") PATH_ENV = "PATH" @@ -1499,7 +1499,7 @@ def test_ivar_in_env_is_not_allowed RUBY end - if RUBY_PLATFORM =~ /bccwin|mswin|mingw/ + if RUBY_PLATFORM =~ /mswin|mingw/ def test_memory_leak_aset bug9977 = '[ruby-dev:48323] [Bug #9977]' assert_no_memory_leak([], <<-'end;', "5_000.times(&doit)", bug9977, limit: 2.0) diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb index a3d6221c0f924b..0f7034cf961736 100644 --- a/test/ruby/test_file.rb +++ b/test/ruby/test_file.rb @@ -16,7 +16,7 @@ def test_unlink_before_close w.close r = File.open(filename, "r") begin - if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + if /(mswin|mingw)/ =~ RUBY_PLATFORM assert_raise(Errno::EACCES) {File.unlink(filename)} else assert_nothing_raised {File.unlink(filename)} diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb index 9216194a65dde3..ce1263232964ce 100644 --- a/test/ruby/test_file_exhaustive.rb +++ b/test/ruby/test_file_exhaustive.rb @@ -8,8 +8,8 @@ class TestFileExhaustive < Test::Unit::TestCase ROOT_REGEXP = %r'\A(?:[a-z]:(?=(/))|//[^/]+/[^/]+)'i DRIVE = Dir.pwd[ROOT_REGEXP] - POSIX = /cygwin|mswin|bccwin|mingw|emx/ !~ RUBY_PLATFORM - NTFS = !(/mingw|mswin|bccwin/ !~ RUBY_PLATFORM) + POSIX = /cygwin|mswin|mingw/ !~ RUBY_PLATFORM + NTFS = !(/mingw|mswin/ !~ RUBY_PLATFORM) def assert_incompatible_encoding d = "\u{3042}\u{3044}".encode("utf-16le") @@ -258,7 +258,7 @@ def test_stat assert_integer_or_nil(fs1.rdev_minor) assert_integer(fs1.ino) assert_integer(fs1.mode) - unless /emx|mswin|mingw/ =~ RUBY_PLATFORM + unless /mswin|mingw/ =~ RUBY_PLATFORM # on Windows, nlink is always 1. but this behavior will be changed # in the future. assert_equal(hardlinkfile ? 2 : 1, fs1.nlink) diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb index 9f7a3c7f4b7ec4..8ebd9a048ccb68 100644 --- a/test/ruby/test_m17n.rb +++ b/test/ruby/test_m17n.rb @@ -1311,7 +1311,7 @@ def test_marshal end def test_env - if RUBY_PLATFORM =~ /bccwin|mswin|mingw/ + if RUBY_PLATFORM =~ /mswin|mingw/ env_encoding = Encoding::UTF_8 else env_encoding = Encoding.find("locale") diff --git a/test/ruby/test_path.rb b/test/ruby/test_path.rb index b35e942a2a037d..136e5d60203856 100644 --- a/test/ruby/test_path.rb +++ b/test/ruby/test_path.rb @@ -48,7 +48,7 @@ def test_path end def test_dirname - if /(bcc|ms)win\d|mingw|cygwin|emx/ =~ RUBY_PLATFORM + if /mswin\d|mingw|cygwin/ =~ RUBY_PLATFORM # DOSISH_DRIVE_LETTER assert_equal('C:.', File.dirname('C:')) assert_equal('C:.', File.dirname('C:a')) @@ -104,7 +104,7 @@ def test_dirname assert_equal('/', File.dirname('/a/')) assert_equal('/a', File.dirname('/a/b')) - if /(bcc|ms|cyg)win|mingw|emx/ =~ RUBY_PLATFORM + if /(ms|cyg)win|mingw/ =~ RUBY_PLATFORM # DOSISH_UNC assert_equal('//', File.dirname('//')) assert_equal('//a', File.dirname('//a')) @@ -138,7 +138,7 @@ def test_dirname end def test_basename - if /(bcc|ms)win\d|mingw|cygwin|emx/ =~ RUBY_PLATFORM + if /mswin\d|mingw|cygwin/ =~ RUBY_PLATFORM # DOSISH_DRIVE_LETTER assert_equal('', File.basename('C:')) assert_equal('a', File.basename('C:a')) @@ -194,7 +194,7 @@ def test_basename assert_equal("..", File.basename("..", ".*")) - if /(bcc|ms|cyg)win|mingw|emx/ =~ RUBY_PLATFORM + if /(ms|cyg)win|mingw/ =~ RUBY_PLATFORM # DOSISH_UNC assert_equal('/', File.basename('//')) assert_equal('/', File.basename('//a')) @@ -234,12 +234,12 @@ def test_extname assert_equal(ext, File.extname('.a.rb')) assert_equal(ext, File.extname('a/b/d/test.rb')) assert_equal(ext, File.extname('.a/b/d/test.rb')) - unless /mswin|bccwin|mingw/ =~ RUBY_PLATFORM + unless /mswin|mingw/ =~ RUBY_PLATFORM # trailing spaces and dots are ignored on NTFS. ext = '.' end assert_equal(ext, File.extname('a.rb.')) - if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM + if /mswin|mingw/ =~ RUBY_PLATFORM # trailing spaces and dots are ignored on NTFS. ext = '' end diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb index 6eba9735b17a64..246993d525c90e 100644 --- a/test/ruby/test_proc.rb +++ b/test/ruby/test_proc.rb @@ -447,6 +447,18 @@ def obj.foo(a, b=42); end assert_raise(ArgumentError) { ->(a, b=42){}.curry(3) } end + def test_curry_arity_to_int + bug22284 = '[Bug #22284]' + assert_equal(42, proc {|x, *y| x }.curry(1r)[42], bug22284) + assert_equal(42, lambda {|x, *y| x }.curry(1r)[42], bug22284) + + called = 0 + arity = Object.new + arity.define_singleton_method(:to_int) { called += 1; 2 } + assert_equal(3, proc {|x, y| x + y }.curry(arity)[1][2], bug22284) + assert_equal(1, called, bug22284) + end + def test_dup_clone # iseq backed proc b = proc {|x| x + "bar" } diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 29f1465b2f5a9e..c13b3e3cd9c61e 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -20,7 +20,7 @@ def windows? self.class.windows? end def self.windows? - return /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + return /mswin|mingw/ =~ RUBY_PLATFORM end def with_tmpchdir @@ -1285,7 +1285,7 @@ def test_exec_wordsplit with_tmpchdir {|d| File.write("script", <<-'End') File.open("result", "w") {|t| - if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM + if /mswin|mingw/ =~ RUBY_PLATFORM t << "hehe ppid=#{Process.ppid}" else t << "hehe pid=#{$$} ppid=#{Process.ppid}" diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index 71bd38af655a5e..25cf5dee509bdf 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -1415,8 +1415,8 @@ def util_clear_RUBY_VERSION end ## - # Returns whether or not we're on a version of Ruby built with VC++ (or - # Borland) versus Cygwin, Mingw, etc. + # Returns whether or not we're on a version of Ruby built with VC++ versus + # Cygwin, Mingw, etc. def self.vc_windows? RUBY_PLATFORM.match("mswin") @@ -1453,8 +1453,8 @@ def ruby_box_enabled? ## # Returns the make command for the current platform. For versions of Ruby - # built on MS Windows with VC++ or Borland it will return 'nmake'. On all - # other platforms, including Cygwin, it will return 'make'. + # built on MS Windows with VC++ it will return 'nmake'. On all other + # platforms, including Cygwin, it will return 'make'. def make_command ENV["make"] || ENV["MAKE"] || (vc_windows? ? "nmake" : "make") diff --git a/tool/fake.rb b/tool/fake.rb index a8d727db2150ee..c380a774df2433 100644 --- a/tool/fake.rb +++ b/tool/fake.rb @@ -2,7 +2,7 @@ # See common.mk and Makefile.in for details. class File - sep = ("\\" if RUBY_PLATFORM =~ /mswin|bccwin|mingw/) + sep = ("\\" if RUBY_PLATFORM =~ /mswin|mingw/) if sep != ALT_SEPARATOR remove_const :ALT_SEPARATOR ALT_SEPARATOR = sep diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb index 68d78a5ac7f516..6c47460094dc28 100755 --- a/tool/rbinstall.rb +++ b/tool/rbinstall.rb @@ -1126,7 +1126,7 @@ def (bins = []).add(name) prepare "common headers", rubyhdrdir noinst = [] - unless RUBY_PLATFORM =~ /mswin|mingw|bccwin/ + unless RUBY_PLATFORM =~ /mswin|mingw/ noinst << "win32.h" end noinst = nil if noinst.empty? diff --git a/vm_core.h b/vm_core.h index 0048cc7a47ac5b..40422f902c12a8 100644 --- a/vm_core.h +++ b/vm_core.h @@ -146,8 +146,6 @@ If `rb_vm_check_ints()` is called between the `RUBY_ASSERT_CRITICAL_SECTION_ENTE #elif defined(_SIG_MAXSIG) /* FreeBSD */ # undef NSIG # define NSIG _SIG_MAXSIG -#elif defined(_SIGMAX) /* QNX */ -# define NSIG (_SIGMAX + 1) #elif defined(NSIG) /* 99% of everything else */ # /* take it */ #else /* Last resort */ diff --git a/vsnprintf.c b/vsnprintf.c index ecd5573dd581fc..f974e808571de0 100644 --- a/vsnprintf.c +++ b/vsnprintf.c @@ -101,11 +101,6 @@ # endif #endif -#if defined(sgi) -#undef __const -#define __const -#endif /* People who don't like const sys_error */ - #include #ifndef NULL