mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 a3c23f0074
			
		
	
	
		a3c23f0074
		
	
	
	
	
		
			
			* goruby.c (goruby_options): fix potential FD leak. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57820 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			66 lines
		
	
	
	
		
			1.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
	
		
			1.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| void Init_golf(void);
 | |
| #define ruby_options goruby_options
 | |
| #define ruby_run_node goruby_run_node
 | |
| #include "main.c"
 | |
| #undef ruby_options
 | |
| #undef ruby_run_node
 | |
| 
 | |
| #if defined _WIN32
 | |
| #include <io.h>
 | |
| #include <fcntl.h>
 | |
| #define pipe(p) _pipe(p, 32L, _O_NOINHERIT)
 | |
| #elif defined HAVE_UNISTD_H
 | |
| #include <unistd.h>
 | |
| #endif
 | |
| 
 | |
| RUBY_EXTERN void *ruby_options(int argc, char **argv);
 | |
| RUBY_EXTERN int ruby_run_node(void*);
 | |
| RUBY_EXTERN void ruby_init_ext(const char *name, void (*init)(void));
 | |
| 
 | |
| static VALUE
 | |
| init_golf(VALUE arg)
 | |
| {
 | |
|     Init_golf();
 | |
|     rb_provide("golf.so");
 | |
|     return arg;
 | |
| }
 | |
| 
 | |
| void *
 | |
| goruby_options(int argc, char **argv)
 | |
| {
 | |
|     static const char cmd[] = "END{require 'irb';IRB.start}";
 | |
|     int rw[2], infd;
 | |
|     void *ret;
 | |
| 
 | |
|     if ((isatty(0) && isatty(1) && isatty(2)) && (pipe(rw) == 0)) {
 | |
| 	ssize_t n;
 | |
| 	infd = dup(0);
 | |
| 	if (infd < 0) {
 | |
| 	    close(rw[0]);
 | |
| 	    close(rw[1]);
 | |
| 	    goto no_irb;
 | |
| 	}
 | |
| 	dup2(rw[0], 0);
 | |
| 	close(rw[0]);
 | |
| 	n = write(rw[1], cmd, sizeof(cmd) - 1);
 | |
| 	close(rw[1]);
 | |
| 	ret = n > 0 ? ruby_options(argc, argv) : NULL;
 | |
| 	dup2(infd, 0);
 | |
| 	close(infd);
 | |
| 	return ret;
 | |
|     }
 | |
|     else {
 | |
|       no_irb:
 | |
| 	return ruby_options(argc, argv);
 | |
|     }
 | |
| }
 | |
| 
 | |
| int
 | |
| goruby_run_node(void *arg)
 | |
| {
 | |
|     int state;
 | |
|     if (NIL_P(rb_protect(init_golf, Qtrue, &state))) {
 | |
| 	return state == EXIT_SUCCESS ? EXIT_FAILURE : state;
 | |
|     }
 | |
|     return ruby_run_node(arg);
 | |
| }
 |