mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* process.c (security): always give warning for insecure PATH.
* dir.c (my_getcwd): do not rely on MAXPATHLEN. * file.c (rb_file_s_readlink): ditto. * file.c (path_check_1): ditto. * eval.c (rb_yield_0): should not call rb_f_block_given_p(). * string.c (rb_str_chomp_bang): should terminate string by NUL. * eval.c (rb_yield_0): better error message. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1816 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ab827130d3
commit
dc98adf839
17 changed files with 201 additions and 109 deletions
|
@ -249,7 +249,7 @@ dmyext.@OBJEXT@: dmyext.c
|
|||
enum.@OBJEXT@: enum.c ruby.h config.h defines.h intern.h node.h
|
||||
error.@OBJEXT@: error.c ruby.h config.h defines.h intern.h env.h version.h
|
||||
eval.@OBJEXT@: eval.c ruby.h config.h defines.h intern.h node.h env.h rubysig.h st.h dln.h
|
||||
file.@OBJEXT@: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h dln.h
|
||||
file.@OBJEXT@: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h dln.h util.h
|
||||
gc.@OBJEXT@: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
|
||||
hash.@OBJEXT@: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h util.h
|
||||
inits.@OBJEXT@: inits.c ruby.h config.h defines.h intern.h
|
||||
|
|
13
bignum.c
13
bignum.c
|
@ -609,6 +609,17 @@ rb_big_eq(x, y)
|
|||
return Qtrue;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_big_eql(x, y)
|
||||
VALUE x, y;
|
||||
{
|
||||
if (TYPE(y) != T_BIGNUM) return Qfalse;
|
||||
if (RBIGNUM(x)->sign != RBIGNUM(y)->sign) return Qfalse;
|
||||
if (RBIGNUM(x)->len != RBIGNUM(y)->len) return Qfalse;
|
||||
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM(y)->len) != 0) return Qfalse;
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_big_uminus(x)
|
||||
VALUE x;
|
||||
|
@ -1454,7 +1465,7 @@ Init_Bignum()
|
|||
rb_define_method(rb_cBignum, "<=>", rb_big_cmp, 1);
|
||||
rb_define_method(rb_cBignum, "==", rb_big_eq, 1);
|
||||
rb_define_method(rb_cBignum, "===", rb_big_eq, 1);
|
||||
rb_define_method(rb_cBignum, "eql?", rb_big_eq, 1);
|
||||
rb_define_method(rb_cBignum, "eql?", rb_big_eql, 1);
|
||||
rb_define_method(rb_cBignum, "hash", rb_big_hash, 0);
|
||||
rb_define_method(rb_cBignum, "to_f", rb_big_to_f, 0);
|
||||
rb_define_method(rb_cBignum, "abs", rb_big_abs, 0);
|
||||
|
|
|
@ -293,7 +293,7 @@ AC_FUNC_MEMCMP
|
|||
AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strncasecmp strerror strftime\
|
||||
strchr strstr strtoul crypt flock vsnprintf\
|
||||
isinf isnan finite hypot)
|
||||
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd chroot\
|
||||
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall chroot\
|
||||
truncate chsize times utimes fcntl lockf lstat symlink readlink\
|
||||
setitimer setruid seteuid setreuid setresuid setproctitle\
|
||||
setrgid setegid setregid setresgid pause lchown lchmod\
|
||||
|
@ -581,7 +581,7 @@ if test "$with_dln_a_out" != yes; then
|
|||
LDFLAGS="-Wl,-E"
|
||||
rb_cv_dlopen=yes;;
|
||||
solaris*) if test "$GCC" = yes; then
|
||||
LDSHARED='$(CC) -Wl,-G'
|
||||
LDSHARED='$(CC) -Wl,-G -shared'
|
||||
`$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E"
|
||||
else
|
||||
LDSHARED='ld -G'
|
||||
|
|
22
dir.c
22
dir.c
|
@ -61,6 +61,8 @@ char *strchr _((char*,char));
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#ifndef HAVE_LSTAT
|
||||
#define lstat(path,st) stat(path,st)
|
||||
#endif
|
||||
|
@ -430,21 +432,16 @@ static VALUE chdir_thread = Qnil;
|
|||
|
||||
static VALUE
|
||||
chdir_restore(path)
|
||||
const char *path;
|
||||
char *path;
|
||||
{
|
||||
chdir_blocking--;
|
||||
if (chdir_blocking == 0)
|
||||
chdir_thread = Qnil;
|
||||
dir_chdir(path);
|
||||
free(path);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETCWD
|
||||
#define GETCWD(path) if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path)
|
||||
#else
|
||||
#define GETCWD(path) if (getwd(path) == 0) rb_sys_fail(path)
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
dir_s_chdir(argc, argv, obj)
|
||||
int argc;
|
||||
|
@ -473,9 +470,7 @@ dir_s_chdir(argc, argv, obj)
|
|||
}
|
||||
|
||||
if (rb_block_given_p()) {
|
||||
char cwd[MAXPATHLEN];
|
||||
|
||||
GETCWD(cwd);
|
||||
char *cwd = my_getcwd();
|
||||
chdir_blocking++;
|
||||
if (chdir_thread == Qnil)
|
||||
chdir_thread = rb_thread_current();
|
||||
|
@ -491,10 +486,11 @@ static VALUE
|
|||
dir_s_getwd(dir)
|
||||
VALUE dir;
|
||||
{
|
||||
char path[MAXPATHLEN];
|
||||
char *path = my_getcwd();
|
||||
VALUE cwd = rb_tainted_str_new2(path);
|
||||
|
||||
GETCWD(path);
|
||||
return rb_tainted_str_new2(path);
|
||||
free(path);
|
||||
return cwd;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
33
doc/NEWS
33
doc/NEWS
|
@ -1,3 +1,36 @@
|
|||
: String#chomp
|
||||
|
||||
if $/ == '\n', chops off last newlines (any of \n, \r, \r\n).
|
||||
|
||||
: IO#puts
|
||||
|
||||
do not treat Array specially.
|
||||
|
||||
: Module::new/Class::new
|
||||
|
||||
takes block.
|
||||
|
||||
: allocation framework
|
||||
|
||||
any instance of class can be allocated by class.allocate,
|
||||
(except a few classes).
|
||||
|
||||
: String#[]
|
||||
|
||||
starting offset can be specified as optional second parameter.
|
||||
|
||||
: String/Array methods
|
||||
|
||||
returns an instance of receivers class.
|
||||
|
||||
: String::new
|
||||
|
||||
returns "".
|
||||
|
||||
: Dir#path
|
||||
|
||||
Added.
|
||||
|
||||
: Enum#sort_by
|
||||
|
||||
Added.
|
||||
|
|
4
eval.c
4
eval.c
|
@ -3645,8 +3645,8 @@ rb_yield_0(val, self, klass, pcall)
|
|||
int state;
|
||||
static unsigned serial = 1;
|
||||
|
||||
if (!(rb_block_given_p() || rb_f_block_given_p())) {
|
||||
rb_raise(rb_eLocalJumpError, "yield called out of block");
|
||||
if (!rb_block_given_p()) {
|
||||
rb_raise(rb_eLocalJumpError, "no block given");
|
||||
}
|
||||
|
||||
PUSH_VARS();
|
||||
|
|
78
file.c
78
file.c
|
@ -19,6 +19,7 @@
|
|||
#include "ruby.h"
|
||||
#include "rubyio.h"
|
||||
#include "rubysig.h"
|
||||
#include "util.h"
|
||||
#include "dln.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
|
@ -1225,14 +1226,22 @@ rb_file_s_readlink(klass, path)
|
|||
VALUE klass, path;
|
||||
{
|
||||
#ifdef HAVE_READLINK
|
||||
char buf[MAXPATHLEN];
|
||||
int cc;
|
||||
char *buf;
|
||||
int size = 100;
|
||||
int rv;
|
||||
VALUE v;
|
||||
|
||||
SafeStringValue(path);
|
||||
if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0)
|
||||
rb_sys_fail(RSTRING(path)->ptr);
|
||||
buf = xmalloc(size);
|
||||
if ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) {
|
||||
size *= 2;
|
||||
buf = xrealloc(buf, size);
|
||||
}
|
||||
if (rv < 0) rb_sys_fail(RSTRING(path)->ptr);
|
||||
v = rb_tainted_str_new(buf, rv);
|
||||
free(buf);
|
||||
|
||||
return rb_tainted_str_new(buf, cc);
|
||||
return v;
|
||||
#else
|
||||
rb_notimplement();
|
||||
return Qnil; /* not reached */
|
||||
|
@ -1297,10 +1306,6 @@ rb_file_s_umask(argc, argv)
|
|||
return INT2FIX(omask);
|
||||
}
|
||||
|
||||
#ifndef HAVE_GETCWD
|
||||
#define getcwd(buf, len) ((void)(len), getwd(buf))
|
||||
#endif
|
||||
|
||||
#if defined DOSISH
|
||||
#define isdirsep(x) ((x) == '/' || (x) == '\\')
|
||||
#else
|
||||
|
@ -2228,29 +2233,31 @@ is_absolute_path(path)
|
|||
|
||||
static int
|
||||
path_check_1(path)
|
||||
char *path;
|
||||
VALUE path;
|
||||
{
|
||||
struct stat st;
|
||||
char *p = 0;
|
||||
char *s;
|
||||
char *p0 = RSTRING(path)->ptr;
|
||||
char *p, *s;
|
||||
|
||||
if (!is_absolute_path(path)) {
|
||||
char buf[MAXPATHLEN+1];
|
||||
if (!is_absolute_path(p0)) {
|
||||
char *buf = my_getcwd();
|
||||
VALUE newpath;
|
||||
|
||||
if (getcwd(buf, MAXPATHLEN) == 0) return 0;
|
||||
strncat(buf, "/", MAXPATHLEN);
|
||||
strncat(buf, path, MAXPATHLEN);
|
||||
buf[MAXPATHLEN] = '\0';
|
||||
return path_check_1(buf);
|
||||
newpath = rb_str_new2(buf);
|
||||
free(buf);
|
||||
|
||||
rb_str_cat2(newpath, "/");
|
||||
rb_str_cat2(newpath, p0);
|
||||
return path_check_1(newpath);
|
||||
}
|
||||
for (;;) {
|
||||
if (stat(path, &st) == 0 && (st.st_mode & 002)) {
|
||||
if (stat(p0, &st) == 0 && (st.st_mode & 002)) {
|
||||
if (p) *p = '/';
|
||||
return 0;
|
||||
}
|
||||
s = strrdirsep(path);
|
||||
s = strrdirsep(p0);
|
||||
if (p) *p = '/';
|
||||
if (!s || s == path) return 1;
|
||||
if (!s || s == p0) return 1;
|
||||
p = s;
|
||||
*p = '\0';
|
||||
}
|
||||
|
@ -2260,27 +2267,24 @@ int
|
|||
rb_path_check(path)
|
||||
char *path;
|
||||
{
|
||||
char *p, *pend;
|
||||
char *p0, *p, *pend;
|
||||
const char sep = PATH_SEP_CHAR;
|
||||
|
||||
if (!path) return 1;
|
||||
|
||||
p = path;
|
||||
pend = strchr(path, sep);
|
||||
pend = path + strlen(path);
|
||||
p0 = path;
|
||||
p = strchr(path, sep);
|
||||
if (!p) p = pend;
|
||||
|
||||
for (;;) {
|
||||
int safe;
|
||||
|
||||
if (pend) *pend = '\0';
|
||||
safe = path_check_1(p);
|
||||
if (!safe) {
|
||||
if (pend) *pend = sep;
|
||||
return 0;
|
||||
}
|
||||
if (!pend) break;
|
||||
*pend = sep;
|
||||
p = pend + 1;
|
||||
pend = strchr(p, sep);
|
||||
if (!path_check_1(rb_str_new(p0, p - p0))) {
|
||||
return 0; /* not safe */
|
||||
}
|
||||
if (p0 > pend) break;
|
||||
p0 = p + 1;
|
||||
p = strchr(p0, sep);
|
||||
if (!p) p = pend;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ DNS stub resolver.
|
|||
|
||||
--- Resolv::DNS#getresource(name, typeclass)
|
||||
--- Resolv::DNS#getresources(name, typeclass)
|
||||
--- Resolv::DNS#each_resources(name, typeclass) {|resource| ...}
|
||||
--- Resolv::DNS#each_resource(name, typeclass) {|resource| ...}
|
||||
They lookup DNS resources of ((|name|)).
|
||||
((|name|)) must be a instance of Resolv::Name or String.
|
||||
|
||||
|
@ -370,7 +370,7 @@ class Resolv
|
|||
end
|
||||
|
||||
def each_address(name)
|
||||
each_resources(name, Resource::IN::A) {|resource| yield resource.address}
|
||||
each_resource(name, Resource::IN::A) {|resource| yield resource.address}
|
||||
end
|
||||
|
||||
def getname(address)
|
||||
|
@ -395,21 +395,21 @@ class Resolv
|
|||
else
|
||||
raise ResolvError.new("cannot interpret as address: #{address}")
|
||||
end
|
||||
each_resources(ptr, Resource::IN::PTR) {|resource| yield resource.name}
|
||||
each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
|
||||
end
|
||||
|
||||
def getresource(name, typeclass)
|
||||
each_resources(name, typeclass) {|resource| return resource}
|
||||
each_resource(name, typeclass) {|resource| return resource}
|
||||
raise ResolvError.new("DNS result has no information for #{name}")
|
||||
end
|
||||
|
||||
def getresources(name, typeclass)
|
||||
ret = []
|
||||
each_resources(name, typeclass) {|resource| ret << resource}
|
||||
each_resource(name, typeclass) {|resource| ret << resource}
|
||||
return ret
|
||||
end
|
||||
|
||||
def each_resources(name, typeclass, &proc)
|
||||
def each_resource(name, typeclass, &proc)
|
||||
lazy_initialize
|
||||
q = Queue.new
|
||||
senders = {}
|
||||
|
@ -1594,7 +1594,7 @@ class Resolv
|
|||
|
||||
def initialize(address)
|
||||
unless address.kind_of?(String) && address.length == 16
|
||||
raise ArgumentError.new('IPv4 address muse be 16 bytes')
|
||||
raise ArgumentError.new('IPv6 address muse be 16 bytes')
|
||||
end
|
||||
@address = address
|
||||
end
|
||||
|
|
|
@ -60,7 +60,11 @@ class WeakRef<Delegator
|
|||
unless ID_MAP[@__id]
|
||||
raise RefError, "Illegal Reference - probably recycled", caller(2)
|
||||
end
|
||||
ObjectSpace._id2ref(@__id)
|
||||
begin
|
||||
ObjectSpace._id2ref(@__id)
|
||||
rescue RangeError
|
||||
raise RefError, "Illegal Reference - probably recycled", caller(2)
|
||||
end
|
||||
end
|
||||
|
||||
def weakref_alive?
|
||||
|
|
66
parse.y
66
parse.y
|
@ -428,24 +428,29 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
|
|||
| variable tOP_ASGN command_call
|
||||
{
|
||||
NODE *n = assignable($1, 0);
|
||||
if ($2 == tOROP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_OR(gettable($1), n);
|
||||
if (is_instance_id($1)) {
|
||||
$$->nd_aid = $1;
|
||||
if (n) {
|
||||
if ($2 == tOROP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_OR(gettable($1), n);
|
||||
if (is_instance_id($1)) {
|
||||
$$->nd_aid = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($2 == tANDOP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_AND(gettable($1), n);
|
||||
else if ($2 == tANDOP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_AND(gettable($1), n);
|
||||
}
|
||||
else {
|
||||
$$ = n;
|
||||
if ($$) {
|
||||
$$->nd_value = call_op(gettable($1),$2,1,$3);
|
||||
}
|
||||
}
|
||||
fixpos($$, $3);
|
||||
}
|
||||
else {
|
||||
$$ = n;
|
||||
if ($$) {
|
||||
$$->nd_value = call_op(gettable($1),$2,1,$3);
|
||||
}
|
||||
$$ = 0;
|
||||
}
|
||||
fixpos($$, $3);
|
||||
}
|
||||
| primary '[' aref_args ']' tOP_ASGN command_call
|
||||
{
|
||||
|
@ -770,24 +775,29 @@ arg : lhs '=' arg
|
|||
| variable tOP_ASGN arg
|
||||
{
|
||||
NODE *n = assignable($1, 0);
|
||||
if ($2 == tOROP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_OR(gettable($1), n);
|
||||
if (is_instance_id($1)) {
|
||||
$$->nd_aid = $1;
|
||||
if (n) {
|
||||
if ($2 == tOROP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_OR(gettable($1), n);
|
||||
if (is_instance_id($1)) {
|
||||
$$->nd_aid = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($2 == tANDOP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_AND(gettable($1), n);
|
||||
else if ($2 == tANDOP) {
|
||||
n->nd_value = $3;
|
||||
$$ = NEW_OP_ASGN_AND(gettable($1), n);
|
||||
}
|
||||
else {
|
||||
$$ = n;
|
||||
if ($$) {
|
||||
$$->nd_value = call_op(gettable($1),$2,1,$3);
|
||||
}
|
||||
}
|
||||
fixpos($$, $3);
|
||||
}
|
||||
else {
|
||||
$$ = n;
|
||||
if ($$) {
|
||||
$$->nd_value = call_op(gettable($1),$2,1,$3);
|
||||
}
|
||||
$$ = 0;
|
||||
}
|
||||
fixpos($$, $3);
|
||||
}
|
||||
| primary '[' aref_args ']' tOP_ASGN arg
|
||||
{
|
||||
|
|
|
@ -422,10 +422,13 @@ static void
|
|||
security(str)
|
||||
char *str;
|
||||
{
|
||||
if (rb_safe_level() > 0) {
|
||||
if (rb_env_path_tainted()) {
|
||||
if (rb_env_path_tainted()) {
|
||||
if (rb_safe_level() > 0) {
|
||||
rb_raise(rb_eSecurityError, "Insecure PATH - %s", str);
|
||||
}
|
||||
else {
|
||||
rb_warn("Insecure PATH - %s", str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,8 +524,6 @@ rb_proc_exec(str)
|
|||
char *ss, *t;
|
||||
char **argv, **a;
|
||||
|
||||
security(str);
|
||||
|
||||
while (*str && ISSPACE(*str))
|
||||
str++;
|
||||
|
||||
|
|
17
ruby.h
17
ruby.h
|
@ -35,15 +35,16 @@ extern "C" {
|
|||
#include <stdio.h>
|
||||
|
||||
/* need to include <ctype.h> to use these macros */
|
||||
#define ISASCII(c) isascii((unsigned char)(c))
|
||||
#undef ISPRINT
|
||||
#define ISPRINT(c) isprint((unsigned char)(c))
|
||||
#define ISSPACE(c) isspace((unsigned char)(c))
|
||||
#define ISUPPER(c) isupper((unsigned char)(c))
|
||||
#define ISLOWER(c) islower((unsigned char)(c))
|
||||
#define ISALNUM(c) isalnum((unsigned char)(c))
|
||||
#define ISALPHA(c) isalpha((unsigned char)(c))
|
||||
#define ISDIGIT(c) isdigit((unsigned char)(c))
|
||||
#define ISXDIGIT(c) isxdigit((unsigned char)(c))
|
||||
#define ISPRINT(c) (ISASCII(c) && isprint((unsigned char)(c)))
|
||||
#define ISSPACE(c) (ISASCII(c) && isspace((unsigned char)(c)))
|
||||
#define ISUPPER(c) (ISASCII(c) && isupper((unsigned char)(c)))
|
||||
#define ISLOWER(c) (ISASCII(c) && islower((unsigned char)(c)))
|
||||
#define ISALNUM(c) (ISASCII(c) && isalnum((unsigned char)(c)))
|
||||
#define ISALPHA(c) (ISASCII(c) && isalpha((unsigned char)(c)))
|
||||
#define ISDIGIT(c) (ISASCII(c) && isdigit((unsigned char)(c)))
|
||||
#define ISXDIGIT(c) (ISASCII(c) && isxdigit((unsigned char)(c)))
|
||||
|
||||
#if !defined(__STDC__) && !defined(_MSC_VER)
|
||||
# define volatile
|
||||
|
|
|
@ -1329,6 +1329,16 @@ begin
|
|||
rescue
|
||||
test_ok false
|
||||
end
|
||||
class S
|
||||
def initialize(a)
|
||||
@a = a
|
||||
end
|
||||
end
|
||||
l=nil
|
||||
100000.times {
|
||||
l = S.new(l)
|
||||
}
|
||||
test_ok true # reach here or dumps core
|
||||
|
||||
if $failed > 0
|
||||
printf "test: %d failed %d\n", $ntest, $failed
|
||||
|
|
10
string.c
10
string.c
|
@ -291,6 +291,8 @@ rb_str_dup(str)
|
|||
}
|
||||
else if (RSTRING(str)->orig) {
|
||||
str2 = rb_str_new3(RSTRING(str)->orig);
|
||||
FL_UNSET(str2, FL_TAINT);
|
||||
OBJ_INFECT(str2, str);
|
||||
}
|
||||
else {
|
||||
str2 = rb_str_new3(rb_str_new4(str));
|
||||
|
@ -2673,13 +2675,15 @@ rb_str_chomp_bang(argc, argv, str)
|
|||
RSTRING(str)->ptr[RSTRING(str)->len-1] == '\r') {
|
||||
RSTRING(str)->len--;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
else if (RSTRING(str)->ptr[len-1] == '\r') {
|
||||
RSTRING(str)->len--;
|
||||
return str;
|
||||
}
|
||||
return Qnil;
|
||||
else {
|
||||
return Qnil;
|
||||
}
|
||||
RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
|
||||
return str;
|
||||
}
|
||||
}
|
||||
if (NIL_P(rs)) return Qnil;
|
||||
|
|
15
util.c
15
util.c
|
@ -11,6 +11,7 @@
|
|||
**********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef NT
|
||||
#include "missing/file.h"
|
||||
|
@ -628,3 +629,17 @@ ruby_strdup(str)
|
|||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *
|
||||
ruby_getcwd()
|
||||
{
|
||||
int size = 200;
|
||||
char *buf = xmalloc(size);
|
||||
|
||||
while (!getcwd(buf, size)) {
|
||||
if (errno != ERANGE) rb_sys_fail(buf);
|
||||
size *= 2;
|
||||
buf = xrealloc(buf, size);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
|
3
util.h
3
util.h
|
@ -50,4 +50,7 @@ char *ruby_strdup _((const char*));
|
|||
#undef strdup
|
||||
#define strdup(s) ruby_strdup((s))
|
||||
|
||||
char *ruby_getcwd _((void));
|
||||
#define my_getcwd() ruby_getcwd()
|
||||
|
||||
#endif /* UTIL_H */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define RUBY_VERSION "1.7.2"
|
||||
#define RUBY_RELEASE_DATE "2001-11-02"
|
||||
#define RUBY_RELEASE_DATE "2001-11-08"
|
||||
#define RUBY_VERSION_CODE 172
|
||||
#define RUBY_RELEASE_CODE 20011102
|
||||
#define RUBY_RELEASE_CODE 20011108
|
||||
|
|
Loading…
Add table
Reference in a new issue