Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
6c4d3941
Commit
6c4d3941
authored
Aug 26, 2015
by
Tomoyuki Sahara
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #30 from ksss/cloexec
Opened fd should be set FD_CLOEXEC by default
parents
042e4a43
e61c4697
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
82 additions
and
31 deletions
+82
-31
src/io.c
src/io.c
+73
-23
test/io.rb
test/io.rb
+9
-8
No files found.
src/io.c
View file @
6c4d3941
...
@@ -125,6 +125,30 @@ mrb_io_flags_to_modenum(mrb_state *mrb, int flags)
...
@@ -125,6 +125,30 @@ mrb_io_flags_to_modenum(mrb_state *mrb, int flags)
return
modenum
;
return
modenum
;
}
}
void
mrb_fd_cloexec
(
mrb_state
*
mrb
,
int
fd
)
{
int
flags
,
flags2
;
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
flags
=
fcntl
(
fd
,
F_GETFD
);
if
(
flags
==
-
1
)
{
mrb_sys_fail
(
mrb
,
"fcntl"
);
}
if
(
fd
<=
2
)
{
flags2
=
flags
&
~
FD_CLOEXEC
;
/* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */
}
else
{
flags2
=
flags
|
FD_CLOEXEC
;
/* Set CLOEXEC for non-standard file descriptors: 3, 4, 5, ... */
}
if
(
flags
!=
flags2
)
{
if
(
fcntl
(
fd
,
F_SETFD
,
flags2
)
==
-
1
)
{
mrb_sys_fail
(
mrb
,
"fcntl"
);
}
}
#endif
}
#ifndef _WIN32
#ifndef _WIN32
static
int
static
int
mrb_proc_exec
(
const
char
*
pname
)
mrb_proc_exec
(
const
char
*
pname
)
...
@@ -199,13 +223,22 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
...
@@ -199,13 +223,22 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
doexec
=
(
strcmp
(
"-"
,
pname
)
!=
0
);
doexec
=
(
strcmp
(
"-"
,
pname
)
!=
0
);
if
((
flags
&
FMODE_READABLE
)
&&
pipe
(
pr
)
==
-
1
)
{
if
(
flags
&
FMODE_READABLE
)
{
mrb_sys_fail
(
mrb
,
"pipe"
);
if
(
pipe
(
pr
)
==
-
1
)
{
mrb_sys_fail
(
mrb
,
"pipe"
);
}
mrb_fd_cloexec
(
mrb
,
pr
[
0
]);
mrb_fd_cloexec
(
mrb
,
pr
[
1
]);
}
}
if
((
flags
&
FMODE_WRITABLE
)
&&
pipe
(
pw
)
==
-
1
)
{
if
(
pr
[
0
]
!=
-
1
)
close
(
pr
[
0
]);
if
(
flags
&
FMODE_WRITABLE
)
{
if
(
pr
[
1
]
!=
-
1
)
close
(
pr
[
1
]);
if
(
pipe
(
pw
)
==
-
1
)
{
mrb_sys_fail
(
mrb
,
"pipe"
);
if
(
pr
[
0
]
!=
-
1
)
close
(
pr
[
0
]);
if
(
pr
[
1
]
!=
-
1
)
close
(
pr
[
1
]);
mrb_sys_fail
(
mrb
,
"pipe"
);
}
mrb_fd_cloexec
(
mrb
,
pw
[
0
]);
mrb_fd_cloexec
(
mrb
,
pw
[
1
]);
}
}
if
(
!
doexec
)
{
if
(
!
doexec
)
{
...
@@ -389,6 +422,38 @@ mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
...
@@ -389,6 +422,38 @@ mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
return
mrb_fixnum_value
(
0
);
return
mrb_fixnum_value
(
0
);
}
}
int
mrb_cloexec_open
(
mrb_state
*
mrb
,
const
char
*
pathname
,
mrb_int
flags
,
mrb_int
mode
)
{
int
fd
,
retry
=
FALSE
;
#ifdef O_CLOEXEC
/* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */
flags
|=
O_CLOEXEC
;
#elif defined O_NOINHERIT
flags
|=
O_NOINHERIT
;
#endif
reopen:
fd
=
open
(
pathname
,
flags
,
mode
);
if
(
fd
==
-
1
)
{
if
(
!
retry
)
{
switch
(
errno
)
{
case
ENFILE
:
case
EMFILE
:
mrb_garbage_collect
(
mrb
);
retry
=
TRUE
;
goto
reopen
;
}
}
mrb_sys_fail
(
mrb
,
"open"
);
}
if
(
fd
<=
2
)
{
mrb_fd_cloexec
(
mrb
,
fd
);
}
return
fd
;
}
mrb_value
mrb_value
mrb_io_s_sysopen
(
mrb_state
*
mrb
,
mrb_value
klass
)
mrb_io_s_sysopen
(
mrb_state
*
mrb
,
mrb_value
klass
)
{
{
...
@@ -396,7 +461,7 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
...
@@ -396,7 +461,7 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
mrb_value
mode
=
mrb_nil_value
();
mrb_value
mode
=
mrb_nil_value
();
mrb_int
fd
,
flags
,
perm
=
-
1
;
mrb_int
fd
,
flags
,
perm
=
-
1
;
const
char
*
pat
;
const
char
*
pat
;
int
modenum
,
retry
=
FALSE
;
int
modenum
;
mrb_get_args
(
mrb
,
"S|Si"
,
&
path
,
&
mode
,
&
perm
);
mrb_get_args
(
mrb
,
"S|Si"
,
&
path
,
&
mode
,
&
perm
);
if
(
mrb_nil_p
(
mode
))
{
if
(
mrb_nil_p
(
mode
))
{
...
@@ -409,22 +474,7 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
...
@@ -409,22 +474,7 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
pat
=
mrb_string_value_cstr
(
mrb
,
&
path
);
pat
=
mrb_string_value_cstr
(
mrb
,
&
path
);
flags
=
mrb_io_modestr_to_flags
(
mrb
,
mrb_string_value_cstr
(
mrb
,
&
mode
));
flags
=
mrb_io_modestr_to_flags
(
mrb
,
mrb_string_value_cstr
(
mrb
,
&
mode
));
modenum
=
mrb_io_flags_to_modenum
(
mrb
,
flags
);
modenum
=
mrb_io_flags_to_modenum
(
mrb
,
flags
);
fd
=
mrb_cloexec_open
(
mrb
,
pat
,
modenum
,
perm
);
reopen:
fd
=
open
(
pat
,
modenum
,
perm
);
if
(
fd
==
-
1
)
{
if
(
!
retry
)
{
switch
(
errno
)
{
case
ENFILE
:
case
EMFILE
:
mrb_garbage_collect
(
mrb
);
retry
=
TRUE
;
goto
reopen
;
}
}
mrb_sys_fail
(
mrb
,
pat
);
}
return
mrb_fixnum_value
(
fd
);
return
mrb_fixnum_value
(
fd
);
}
}
...
...
test/io.rb
View file @
6c4d3941
...
@@ -321,6 +321,7 @@ end
...
@@ -321,6 +321,7 @@ end
assert
(
'IO.popen'
)
do
assert
(
'IO.popen'
)
do
io
=
IO
.
popen
(
"ls"
)
io
=
IO
.
popen
(
"ls"
)
assert_true
io
.
close_on_exec?
assert_equal
Fixnum
,
io
.
pid
.
class
assert_equal
Fixnum
,
io
.
pid
.
class
ls
=
io
.
read
ls
=
io
.
read
assert_equal
ls
.
class
,
String
assert_equal
ls
.
class
,
String
...
@@ -362,28 +363,28 @@ assert('IO#fileno') do
...
@@ -362,28 +363,28 @@ assert('IO#fileno') do
io
.
closed?
io
.
closed?
end
end
assert
(
'IO#close_on_exec'
)
do
assert
(
'IO#close_on_exec'
)
do
fd
=
IO
.
sysopen
$mrbtest_io_wfname
,
"w"
fd
=
IO
.
sysopen
$mrbtest_io_wfname
,
"w"
io
=
IO
.
new
fd
,
"w"
io
=
IO
.
new
fd
,
"w"
begin
begin
# IO.sysopen opens a file descripter with
out
O_CLOEXEC flag.
# IO.sysopen opens a file descripter with O_CLOEXEC flag.
assert_
equal
(
false
,
io
.
close_on_exec?
)
assert_
true
io
.
close_on_exec?
rescue
ScriptError
rescue
ScriptError
skip
"IO
\#
close_on_exec is not implemented."
skip
"IO
\#
close_on_exec is not implemented."
end
end
io
.
close_on_exec
=
true
assert_equal
(
true
,
io
.
close_on_exec?
)
io
.
close_on_exec
=
false
io
.
close_on_exec
=
false
assert_equal
(
false
,
io
.
close_on_exec?
)
assert_equal
(
false
,
io
.
close_on_exec?
)
io
.
close_on_exec
=
true
io
.
close_on_exec
=
true
assert_equal
(
true
,
io
.
close_on_exec?
)
assert_equal
(
true
,
io
.
close_on_exec?
)
io
.
close_on_exec
=
false
assert_equal
(
false
,
io
.
close_on_exec?
)
io
.
close
io
.
close
io
.
closed?
io
.
closed?
# # Use below when IO.pipe is implemented.
# # Use below when IO.pipe is implemented.
# begin
# begin
# r, w = IO.pipe
# r, w = IO.pipe
# assert_equal(false, r.close_on_exec?)
# assert_equal(false, r.close_on_exec?)
# r.close_on_exec = true
# r.close_on_exec = true
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment