Skip to content
This repository was archived by the owner on Apr 12, 2019. It is now read-only.

Commit c232329

Browse files
committed
restart open_cloexec manually
to deal with EINTR (interrupted system call) on `open`
1 parent 9c1d1b8 commit c232329

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

src/support/ios.c

+18-4
Original file line numberDiff line numberDiff line change
@@ -874,19 +874,30 @@ static void _ios_init(ios_t *s)
874874
/* stream object initializers. we do no allocation. */
875875

876876
#if !defined(_OS_WINDOWS_)
877+
/*
878+
* NOTE: we do not handle system call restart in this function,
879+
* please do it manually:
880+
*
881+
* do
882+
* open_cloexec(...)
883+
* while (-1 == fd && _enonfatal(errno))
884+
*/
877885
static int open_cloexec(const char *path, int flags, mode_t mode)
878886
{
879887
#ifdef O_CLOEXEC
880-
static int no_cloexec=0;
888+
static int no_cloexec = 0;
881889

882890
if (!no_cloexec) {
883891
set_io_wait_begin(1);
884892
int fd = open(path, flags | O_CLOEXEC, mode);
885893
set_io_wait_begin(0);
894+
886895
if (fd != -1)
887896
return fd;
888897
if (errno != EINVAL)
889898
return -1;
899+
900+
/* O_CLOEXEC not supported. */
890901
no_cloexec = 1;
891902
}
892903
#endif
@@ -918,12 +929,15 @@ ios_t *ios_file(ios_t *s, const char *fname, int rd, int wr, int create, int tru
918929
#else
919930
// The mode of the created file is (mode & ~umask), which resolves with
920931
// default umask to u=rw,g=r,o=r
921-
fd = open_cloexec(fname, flags,
922-
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
932+
do
933+
fd = open_cloexec(fname, flags,
934+
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
935+
while (-1 == fd && _enonfatal(errno));
923936
#endif
924-
s = ios_fd(s, fd, 1, 1);
925937
if (fd == -1)
926938
goto open_file_err;
939+
940+
s = ios_fd(s, fd, 1, 1);
927941
if (!rd)
928942
s->readable = 0;
929943
if (!wr)

test/file.jl

+22
Original file line numberDiff line numberDiff line change
@@ -1134,3 +1134,25 @@ end
11341134
test_13559()
11351135
end
11361136
@test_throws ArgumentError mkpath("fakepath",-1)
1137+
1138+
# issue #22566
1139+
if !Sys.iswindows()
1140+
function test_22566()
1141+
fn = tempname()
1142+
run(`mkfifo $fn`)
1143+
1144+
script = "x = open(\"$fn\", \"w\"); close(x)"
1145+
cmd = `$(Base.julia_cmd()) --startup-file=no -e $script`
1146+
open(pipeline(cmd, stderr=STDERR))
1147+
1148+
r = open(fn, "r")
1149+
close(r)
1150+
1151+
rm(fn)
1152+
end
1153+
1154+
# repeat opening/closing fifo file, ensure no EINTR popped out
1155+
for i 1:50
1156+
test_22566()
1157+
end
1158+
end # !Sys.iswindows

0 commit comments

Comments
 (0)