From e48ada68cb70acbf90a9e31c4a055a4d80fb2b33 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 29 Jan 2020 19:38:30 -0800 Subject: [PATCH 01/13] Add Libc.mkfifo --- base/libc.jl | 21 +++++++++++++++++++++ test/file.jl | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/base/libc.jl b/base/libc.jl index 379c76dfd8c60..0c17dba2aca5b 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -10,6 +10,9 @@ import Core.Intrinsics: bitcast export FILE, TmStruct, strftime, strptime, getpid, gethostname, free, malloc, calloc, realloc, errno, strerror, flush_cstdio, systemsleep, time, transcode +if Sys.isunix() + export mkfifo +end if Sys.iswindows() export GetLastError, FormatMessage end @@ -400,4 +403,22 @@ Interface to the C `srand(seed)` function. """ srand(seed=floor(Int, time()) % Cuint) = ccall(:srand, Cvoid, (Cuint,), seed) +if Sys.isunix() + @doc """ + mkfifo(path::AbstractString, [mode::Integer]) -> path + + Make a FIFO special file (a named pipe) at `path`. Return `path` as-is on success. + """ -> + function mkfifo( + path::AbstractString, + mode::Integer = Base.S_IRUSR | Base.S_IWUSR | Base.S_IRGRP | Base.S_IWGRP | + Base.S_IROTH | Base.S_IWOTH, + ) + # Default `mode` is compatible with `mkfifo` CLI in coreutils. + ret = ccall(:mkfifo, Cint, (Cstring, Base.Cmode_t), path, mode) + systemerror("mkfifo", ret == -1) + return path + end +end + end # module diff --git a/test/file.jl b/test/file.jl index 80e8d8d6445a6..ef9a3ae6bb120 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1477,3 +1477,19 @@ end end end end + +@testset "mkfifo" begin + mktempdir() do dir + path = Libc.mkfifo(joinpath(dir, "fifo")) + @sync begin + cat_exec = `$(Base.julia_cmd()) --startup-file=no -e "write(stdout, read(ARGS[1]))"` + reader = @async read(`$cat_exec $path`, String) + @async write(path, "hello") + @test fetch(reader) == "hello" + end + + existing_file = joinpath(dir, "existing") + write(existing_file, "") + @test_throws SystemError Libc.mkfifo(existing_file) + end +end From be3a4bbf0d962e3298ff4430d3a17a304442a394 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 29 Jan 2020 20:40:11 -0800 Subject: [PATCH 02/13] Simplify mkfifo test --- test/file.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/file.jl b/test/file.jl index ef9a3ae6bb120..8aa7304cd9788 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1482,10 +1482,9 @@ end mktempdir() do dir path = Libc.mkfifo(joinpath(dir, "fifo")) @sync begin - cat_exec = `$(Base.julia_cmd()) --startup-file=no -e "write(stdout, read(ARGS[1]))"` - reader = @async read(`$cat_exec $path`, String) @async write(path, "hello") - @test fetch(reader) == "hello" + cat_exec = `$(Base.julia_cmd()) --startup-file=no -e "write(stdout, read(ARGS[1]))"` + @test read(`$cat_exec $path`, String) == "hello" end existing_file = joinpath(dir, "existing") From 5f6367bae07961fc6872debb1b210e4b45695c19 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 29 Jan 2020 21:40:22 -0800 Subject: [PATCH 03/13] Run mkfifo tests only on Unix --- test/file.jl | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/test/file.jl b/test/file.jl index 8aa7304cd9788..8acec3cbe7a6b 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1478,17 +1478,19 @@ end end end -@testset "mkfifo" begin - mktempdir() do dir - path = Libc.mkfifo(joinpath(dir, "fifo")) - @sync begin - @async write(path, "hello") - cat_exec = `$(Base.julia_cmd()) --startup-file=no -e "write(stdout, read(ARGS[1]))"` - @test read(`$cat_exec $path`, String) == "hello" - end +if Sys.isunix() + @testset "mkfifo" begin + mktempdir() do dir + path = Libc.mkfifo(joinpath(dir, "fifo")) + @sync begin + @async write(path, "hello") + cat_exec = `$(Base.julia_cmd()) --startup-file=no -e "write(stdout, read(ARGS[1]))"` + @test read(`$cat_exec $path`, String) == "hello" + end - existing_file = joinpath(dir, "existing") - write(existing_file, "") - @test_throws SystemError Libc.mkfifo(existing_file) + existing_file = joinpath(dir, "existing") + write(existing_file, "") + @test_throws SystemError Libc.mkfifo(existing_file) + end end end From 01c16401e4e3ce691e2440e6c0c661b5c2ec9ec7 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 29 Jan 2020 21:48:01 -0800 Subject: [PATCH 04/13] Always define Libc.mkfifo docstring --- base/libc.jl | 15 ++++++++++----- doc/src/base/libc.md | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/base/libc.jl b/base/libc.jl index 0c17dba2aca5b..36d5582bd35e9 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -403,12 +403,17 @@ Interface to the C `srand(seed)` function. """ srand(seed=floor(Int, time()) % Cuint) = ccall(:srand, Cvoid, (Cuint,), seed) -if Sys.isunix() - @doc """ - mkfifo(path::AbstractString, [mode::Integer]) -> path +""" + mkfifo(path::AbstractString, [mode::Integer]) -> path + +Make a FIFO special file (a named pipe) at `path`. Return `path` as-is on success. - Make a FIFO special file (a named pipe) at `path`. Return `path` as-is on success. - """ -> +!!! compat "Julia 1.5" + `mkfifo` requires at least Julia 1.5. +""" +function mkfifo end + +if Sys.isunix() function mkfifo( path::AbstractString, mode::Integer = Base.S_IRUSR | Base.S_IWUSR | Base.S_IRGRP | Base.S_IWGRP | diff --git a/doc/src/base/libc.md b/doc/src/base/libc.md index 0af1b74a79a71..bdc0afb0ec709 100644 --- a/doc/src/base/libc.md +++ b/doc/src/base/libc.md @@ -15,4 +15,5 @@ Base.Libc.strptime Base.Libc.TmStruct Base.Libc.flush_cstdio Base.Libc.systemsleep +Base.Libc.mkfifo ``` From 4fa8055225dabd6619f6e70a10c1e36cb2282cc9 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 29 Jan 2020 21:48:35 -0800 Subject: [PATCH 05/13] Mention it in NEWS.md --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index b2f473e305232..022dc40bbec9c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -48,6 +48,7 @@ New library functions provide one-argument method that returns a closure. The old methods of `merge` and `merge!` are still available for backward compatibility ([#34296]). * The new `isdisjoint` function indicates whether two collections are disjoint ([#34427]). +* The new `Libc.mkfifo` function wraps `mkfifo` C function on Unix platforms ([#34587]). New library features -------------------- From 4e16f42fd94cae37ea2f808bcc71b5c775624927 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 30 Apr 2020 16:33:10 -0700 Subject: [PATCH 06/13] Define mkfifo in all platforms; a better error message than MethodError --- base/libc.jl | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/base/libc.jl b/base/libc.jl index 36d5582bd35e9..e04a05d89cf0a 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -8,11 +8,8 @@ Interface to libc, the C standard library. import Base: transcode, windowserror import Core.Intrinsics: bitcast -export FILE, TmStruct, strftime, strptime, getpid, gethostname, free, malloc, calloc, realloc, - errno, strerror, flush_cstdio, systemsleep, time, transcode -if Sys.isunix() - export mkfifo -end +export FILE, TmStruct, strftime, strptime, getpid, gethostname, free, malloc, mkfifo, + calloc, realloc, errno, strerror, flush_cstdio, systemsleep, time, transcode if Sys.iswindows() export GetLastError, FormatMessage end @@ -411,18 +408,18 @@ Make a FIFO special file (a named pipe) at `path`. Return `path` as-is on succe !!! compat "Julia 1.5" `mkfifo` requires at least Julia 1.5. """ -function mkfifo end - -if Sys.isunix() - function mkfifo( - path::AbstractString, - mode::Integer = Base.S_IRUSR | Base.S_IWUSR | Base.S_IRGRP | Base.S_IWGRP | - Base.S_IROTH | Base.S_IWOTH, - ) +function mkfifo( + path::AbstractString, + mode::Integer = Base.S_IRUSR | Base.S_IWUSR | Base.S_IRGRP | Base.S_IWGRP | + Base.S_IROTH | Base.S_IWOTH, +) + @static if Sys.isunix() # Default `mode` is compatible with `mkfifo` CLI in coreutils. ret = ccall(:mkfifo, Cint, (Cstring, Base.Cmode_t), path, mode) systemerror("mkfifo", ret == -1) return path + else + error("not supported on this platform") end end From d7447a1adc6c9ed155c9041ec429831ee80ff40b Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 30 Apr 2020 20:34:41 -0700 Subject: [PATCH 07/13] Add a test for Windows --- test/file.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/file.jl b/test/file.jl index b70f32d5137fd..0d97ebd5de388 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1526,4 +1526,9 @@ if Sys.isunix() @test_throws SystemError Libc.mkfifo(existing_file) end end +else + @test_throws( + ErrorException("not supported on this platform"), + Libc.mkfifo(joinpath(pwd(), "dummy_path")), + ) end From 1ff5cd7a9e9d7b023df5b04726e78d227032f23e Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 12 Nov 2021 17:48:58 -0800 Subject: [PATCH 08/13] Update base/libc.jl Co-authored-by: Jameson Nash --- base/libc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/libc.jl b/base/libc.jl index e04a05d89cf0a..1ca9ce2aecf51 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -419,7 +419,7 @@ function mkfifo( systemerror("mkfifo", ret == -1) return path else - error("not supported on this platform") + systemerror("mkfifo", ENOTSUP) end end From b08691563e6d9cb0b4dfd2cb9e5d2ce24719a221 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 12 Nov 2021 20:52:40 -0500 Subject: [PATCH 09/13] Update compat --- base/libc.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/libc.jl b/base/libc.jl index 3b52a30b901db..0c9f4a04b1e4b 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -407,8 +407,8 @@ srand(seed=floor(Int, time()) % Cuint) = ccall(:srand, Cvoid, (Cuint,), seed) Make a FIFO special file (a named pipe) at `path`. Return `path` as-is on success. -!!! compat "Julia 1.5" - `mkfifo` requires at least Julia 1.5. +!!! compat "Julia 1.8" + `mkfifo` requires at least Julia 1.8. """ function mkfifo( path::AbstractString, From 9d434693adc293929efcc20dff8340ec85fff5a2 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 12 Nov 2021 20:56:17 -0500 Subject: [PATCH 10/13] Mention that it is supported only in Unix --- base/libc.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/base/libc.jl b/base/libc.jl index 7be427c5ee2f5..b65c5dca63c16 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -407,6 +407,8 @@ srand(seed=floor(Int, time()) % Cuint) = ccall(:srand, Cvoid, (Cuint,), seed) Make a FIFO special file (a named pipe) at `path`. Return `path` as-is on success. +`mkfifo` is supported only in Unix platforms. + !!! compat "Julia 1.8" `mkfifo` requires at least Julia 1.8. """ From b32355ceb19fc45f0e36dff4bb1ff01307d82adf Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 12 Nov 2021 21:08:43 -0500 Subject: [PATCH 11/13] Update error message in test --- test/file.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/file.jl b/test/file.jl index 9a97f9ce2d36b..ff1fa72a6535a 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1633,7 +1633,7 @@ if Sys.isunix() end else @test_throws( - ErrorException("not supported on this platform"), + "mkfifo: Operation not supported", Libc.mkfifo(joinpath(pwd(), "dummy_path")), ) end From 51008b13dc184dd9fe8bf3f39b7e8be4f7c45797 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sat, 13 Nov 2021 20:28:34 -0500 Subject: [PATCH 12/13] Don't use ENOTSUP; Windows does not have it? It seems Windows prints it as "Unknown error": Error in testset file: Test Failed at C:\buildbot\worker-tabularasa\tester_win64\build\share\julia\test\file.jl:1635 Expression: Libc.mkfifo(joinpath(pwd(), "dummy_path")) Expected: "mkfifo: Operation not supported" Message: "SystemError: mkfifo: Unknown error" https://build.julialang.org/#/builders/65/builds/5360 This reverts commit 1ff5cd7a9e9d7b023df5b04726e78d227032f23e. --- base/libc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/libc.jl b/base/libc.jl index b65c5dca63c16..9e2ac7d6cead2 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -423,7 +423,7 @@ function mkfifo( systemerror("mkfifo", ret == -1) return path else - systemerror("mkfifo", ENOTSUP) + error("not supported on this platform") end end From 02961cc2b25031cb83628342f4471adbc55c9cf1 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sat, 13 Nov 2021 20:32:13 -0500 Subject: [PATCH 13/13] Use `error("mkfifo: Operation not supported")` --- base/libc.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/libc.jl b/base/libc.jl index 9e2ac7d6cead2..78c153303535d 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -423,7 +423,9 @@ function mkfifo( systemerror("mkfifo", ret == -1) return path else - error("not supported on this platform") + # Using normal `error` because `systemerror("mkfifo", ENOTSUP)` does not + # seem to work on Windows. + error("mkfifo: Operation not supported") end end