Hello ruby-core developers. Please apologize for the noise, but dunno if the bugs created at rubyforge tracker are being 'tracked' by someone. Basically, this ticket [1] exposes a problem that annoys and add cross-platform inoperativeness to Ruby. It start with the assumption that an extensionless file have priority over a true windows executable (.exe, com, bat, cmd) and try to use it instead when issue system or any way that calls back into the OS. To workaround this several projects need to include RUBY_PLATFORM =~ /mswin/ around stuff like 'rake.bat', 'gem.bat', 'spec.bat' 'rails.bat' and the list can go on... Fixing this not only will get rid of the RUBY_PLATFORM regexp, but also suppress the need to fix all these utilities to allow MinGW builds of Ruby work properly. It was suggested that RubyGems replace the current script+stub implementation for 1 wrapped file, like built-in MRI scripts does. This will be good for future, but will not solve the false premise we are based on. Since there a huge qty of projects that already fire 'rake' directly, is silly provides patches for all those instead of fixing the true root of the problem. Please, let me know your comments, I could be wrong (like usual) but I'll gladly provide a patch for 1.9 and 1.8.x series. Regards and thanks in advance for reading all this. [1] http://rubyforge.org/tracker/?func=detail&aid=19733&group_id=426&atid=1698 -- Luis Lavena Multimedia systems - Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so. Douglas Adams
RFC: #19733 - dln_find_1 prioritizes posix naming conventions over Operating System naming conventio
on 23.04.2008 19:32
Re: RFC: #19733 - dln_find_1 prioritizes posix naming conventions over Operating System naming conve
on 24.04.2008 06:17
Hi, At Thu, 24 Apr 2008 02:32:05 +0900, Luis Lavena wrote in [ruby-core:16517]: > Basically, this ticket [1] exposes a problem that annoys and add > cross-platform inoperativeness to Ruby. It start with the assumption > that an extensionless file have priority over a true windows > executable (.exe, com, bat, cmd) and try to use it instead when issue > system or any way that calls back into the OS. Do you consider files sans extensions shouldn't be returned? Index: dln.c =================================================================== --- dln.c (revision 16174) +++ dln.c (working copy) @@ -1695,24 +1695,7 @@ dln_find_1(const char *fname, const char memcpy(bp, fname, i + 1); -#ifndef __MACOS__ - if (stat(fbuf, &st) == 0) { - if (exe_flag == 0) return fbuf; - /* looking for executable */ - if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0) - return fbuf; - } -#else - if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) { - if (exe_flag == 0) return mac_fullpath; - /* looking for executable */ - if (stat(mac_fullpath, &st) == 0) { - if (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0) - return mac_fullpath; - } - } -#endif #if defined(DOSISH) if (exe_flag) { - static const char *const extension[] = { + static const char const extension[][5] = { #if defined(MSDOS) ".com", ".exe", ".bat", @@ -1748,7 +1731,26 @@ dln_find_1(const char *fname, const char #endif } + goto next; } #endif /* MSDOS or _WIN32 or __human68k__ or __EMX__ */ +#ifndef __MACOS__ + if (stat(fbuf, &st) == 0) { + if (exe_flag == 0) return fbuf; + /* looking for executable */ + if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0) + return fbuf; + } +#else + if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) { + if (exe_flag == 0) return mac_fullpath; + /* looking for executable */ + if (stat(mac_fullpath, &st) == 0) { + if (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0) + return mac_fullpath; + } + } +#endif + next: /* if not, and no other alternatives, life is bleak */
Re: RFC: #19733 - dln_find_1 prioritizes posix naming conventions over Operating System naming conve
on 24.04.2008 06:27
Hi, At Thu, 24 Apr 2008 13:17:03 +0900, Nobuyoshi Nakada wrote in [ruby-core:16548]: > > Basically, this ticket [1] exposes a problem that annoys and add > > cross-platform inoperativeness to Ruby. It start with the assumption > > that an extensionless file have priority over a true windows > > executable (.exe, com, bat, cmd) and try to use it instead when issue > > system or any way that calls back into the OS. > > Do you consider files sans extensions shouldn't be returned? And, rather I want to remove static fbuf in dln.c. Index: dln.h =================================================================== --- dln.h (revision 16174) +++ dln.h (working copy) @@ -31,4 +31,6 @@ char *dln_find_exe(const char*,const char*); char *dln_find_file(const char*,const char*); +char *dln_find2_exe(const char*,const char*,char*,int); +char *dln_find2_file(const char*,const char*,char*,int); #ifdef USE_DLN_A_OUT Index: dln.c =================================================================== --- dln.c (revision 16174) +++ dln.c (working copy) @@ -1569,8 +1569,8 @@ dln_load(const char *file) } -static char *dln_find_1(const char *fname, const char *path, int exe_flag); +static char *dln_find_1(const char *fname, const char *path, char *buf, int size, int exe_flag); char * -dln_find_exe(const char *fname, const char *path) +dln_find_exe2(const char *fname, const char *path, char *buf, int size) { if (!path) { @@ -1585,16 +1585,16 @@ dln_find_exe(const char *fname, const ch #endif } - return dln_find_1(fname, path, 1); + return dln_find_1(fname, path, buf, size, 1); } char * -dln_find_file(const char *fname, const char *path) +dln_find_file2(const char *fname, const char *path, char *buf, int size) { #ifndef __MACOS__ if (!path) path = "."; - return dln_find_1(fname, path, 0); + return dln_find_1(fname, path, buf, size, 0); #else if (!path) path = "."; - return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, 0)); + return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, buf, size, 0)); #endif } @@ -1602,6 +1602,19 @@ dln_find_file(const char *fname, const c static char fbuf[MAXPATHLEN]; +char * +dln_find_exe(const char *fname, const char *path) +{ + return dln_find_exe2(fname, path, fbuf, sizeof(fbuf)); +} + +char * +dln_find_file(const char *fname, const char *path) +{ + return dln_find_file2(fname, path, fbuf, sizeof(fbuf)); +} + static char * -dln_find_1(const char *fname, const char *path, int exe_flag /* non 0 if looking for executable. */) +dln_find_1(const char *fname, const char *path, char *fbuf, int size, + int exe_flag /* non 0 if looking for executable. */) { register const char *dp; @@ -1643,5 +1656,5 @@ dln_find_1(const char *fname, const char l = ep - dp; bp = fbuf; - fspace = sizeof fbuf - 2; + fspace = size - 2; if (l > 0) { /* Index: file.c =================================================================== --- file.c (revision 16174) +++ file.c (working copy) @@ -4335,9 +4381,10 @@ rb_find_file_ext(VALUE *filep, const cha for (i=0;i<RARRAY_LEN(rb_load_path);i++) { VALUE str = RARRAY_PTR(rb_load_path)[i]; + char fbuf[MAXPATHLEN]; FilePathValue(str); if (RSTRING_LEN(str) == 0) continue; path = RSTRING_PTR(str); - found = dln_find_file(StringValueCStr(fname), path); + found = dln_find_file2(StringValueCStr(fname), path, fbuf, sizeof(fbuf)); if (found && file_load_ok(found)) { *filep = rb_str_new2(found); @@ -4355,4 +4402,5 @@ rb_find_file(VALUE path) char *f = StringValueCStr(path); char *lpath; + char fbuf[MAXPATHLEN]; if (f[0] == '~') { @@ -4412,5 +4460,5 @@ rb_find_file(VALUE path) return 0; /* no path, no load */ } - if (!(f = dln_find_file(f, lpath))) { + if (!(f = dln_find_file2(f, lpath, fbuf, sizeof(fbuf)))) { return 0; } Index: process.c =================================================================== --- process.c (revision 16174) +++ process.c (working copy) @@ -949,5 +950,5 @@ void rb_thread_reset_timer_thread(void); (rb_thread_start_timer_thread(), rb_disable_interrupt()) -extern char *dln_find_exe(const char *fname, const char *path); +#include "dln.h" static void @@ -964,7 +965,9 @@ static int proc_exec_v(char **argv, const char *prog) { + char fbuf[MAXPATHLEN]; + if (!prog) prog = argv[0]; - prog = dln_find_exe(prog, 0); + prog = dln_find_exe2(prog, 0, fbuf, sizeof(fbuf)); if (!prog) { errno = ENOENT; @@ -1001,5 +1004,5 @@ proc_exec_v(char **argv, const char *pro new_argv[0] = COMMAND; argv = new_argv; - prog = dln_find_exe(argv[0], 0); + prog = dln_find_exe2(argv[0], 0, fbuf, sizeof(fbuf)); if (!prog) { errno = ENOENT; @@ -1065,5 +1079,6 @@ rb_proc_exec(const char *str) exit(status); #elif defined(__human68k__) || defined(__CYGWIN32__) || defined(__EMX__) - char *shell = dln_find_exe("sh", 0); + char fbuf[MAXPATHLEN]; + char *shell = dln_find_exe2("sh", 0, fbuf, sizeof(fbuf)); int status = -1; before_exec(); @@ -1112,4 +1127,5 @@ static rb_pid_t proc_spawn_v(char **argv, char *prog) { + char fbuf[MAXPATHLEN]; char *extension; rb_pid_t status; @@ -1118,5 +1134,5 @@ proc_spawn_v(char **argv, char *prog) prog = argv[0]; security(prog); - prog = dln_find_exe(prog, 0); + prog = dln_find_exe2(prog, 0, fbuf, sizeof(fbuf)); if (!prog) return -1; @@ -1139,5 +1155,5 @@ proc_spawn_v(char **argv, char *prog) new_argv[0] = COMMAND; argv = new_argv; - prog = dln_find_exe(argv[0], 0); + prog = dln_find_exe2(argv[0], 0, fbuf, sizeof(fbuf)); if (!prog) { errno = ENOENT; @@ -1176,4 +1192,5 @@ static rb_pid_t proc_spawn(char *str) { + char fbuf[MAXPATHLEN]; char *s, *t; char **argv, **a; @@ -1182,5 +1199,5 @@ proc_spawn(char *str) for (s = str; *s; s++) { if (*s != ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) { - char *shell = dln_find_exe("sh", 0); + char *shell = dln_find_exe2("sh", 0, fbuf, sizeof(fbuf)); before_exec(); status = shell?spawnl(P_WAIT,shell,"sh","-c",str,(char*)NULL):system(str); @@ -949,6 +984,7 @@ process_options(VALUE arg) NODE *tree = 0; VALUE parser; rb_encoding *enc; const char *s; + char fbuf[MAXPATHLEN]; int i = proc_options(argc, argv, opt); @@ -1031,8 +1067,8 @@ process_options(VALUE arg) opt->script = 0; if (path) { - opt->script = dln_find_file(argv[0], path); + opt->script = dln_find_file2(argv[0], path, fbuf, sizeof(fbuf)); } if (!opt->script) { - opt->script = dln_find_file(argv[0], getenv(PATH_ENV)); + opt->script = dln_find_file(argv[0], getenv(PATH_ENV), fbuf, sizeof(fbuf)); } if (!opt->script)
Re: RFC: #19733 - dln_find_1 prioritizes posix naming conventions over Operating System naming conve
on 24.04.2008 07:30
On Thu, Apr 24, 2008 at 1:26 AM, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote: > > > > Do you consider files sans extensions shouldn't be returned? > Not in Windows. These shouldn't be the first option, since they are not executables "as-is". > And, rather I want to remove static fbuf in dln.c. > Tried to apply the patch to trunk but failed to apply file.c and process.c diffs. I'll work on porting what you exposed here for 1.8 and get back on the ticket. Thank you again for your time Nobu. -- Luis Lavena Multimedia systems - Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so. Douglas Adams