Skip to content

Commit 782458c

Browse files
authored
Merge pull request JuliaLang#45638 from JuliaLang/sf/fix_musl_libgit2
Fix LibGit2 tests on `x86_64-linux-musl`
2 parents 7a1e404 + 22042be commit 782458c

File tree

6 files changed

+51
-12
lines changed

6 files changed

+51
-12
lines changed

base/secretbuffer.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,17 @@ function SecretBuffer!(d::Vector{UInt8})
7979
s
8080
end
8181

82-
unsafe_SecretBuffer!(s::Cstring) = unsafe_SecretBuffer!(convert(Ptr{UInt8}, s), Int(ccall(:strlen, Csize_t, (Cstring,), s)))
82+
function unsafe_SecretBuffer!(s::Cstring)
83+
if s == C_NULL
84+
throw(ArgumentError("cannot convert NULL to SecretBuffer"))
85+
end
86+
len = Int(ccall(:strlen, Csize_t, (Cstring,), s))
87+
unsafe_SecretBuffer!(convert(Ptr{UInt8}, s), len)
88+
end
8389
function unsafe_SecretBuffer!(p::Ptr{UInt8}, len=1)
90+
if p == C_NULL
91+
throw(ArgumentError("cannot convert NULL to SecretBuffer"))
92+
end
8493
s = SecretBuffer(sizehint=len)
8594
for i in 1:len
8695
write(s, unsafe_load(p, i))

base/util.jl

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -257,19 +257,19 @@ graphical interface.
257257
"""
258258
function getpass end
259259

260-
if Sys.iswindows()
260+
_getch() = UInt8(ccall(:jl_getch, Cint, ()))
261261
function getpass(input::TTY, output::IO, prompt::AbstractString)
262262
input === stdin || throw(ArgumentError("getpass only works for stdin"))
263263
print(output, prompt, ": ")
264264
flush(output)
265265
s = SecretBuffer()
266266
plen = 0
267267
while true
268-
c = UInt8(ccall(:_getch, Cint, ()))
269-
if c == 0xff || c == UInt8('\n') || c == UInt8('\r')
268+
c = _getch()
269+
if c == 0xff || c == UInt8('\n') || c == UInt8('\r') || c == 0x04
270270
break # EOF or return
271271
elseif c == 0x00 || c == 0xe0
272-
ccall(:_getch, Cint, ()) # ignore function/arrow keys
272+
_getch() # ignore function/arrow keys
273273
elseif c == UInt8('\b') && plen > 0
274274
plen -= 1 # delete last character on backspace
275275
elseif !iscntrl(Char(c)) && plen < 128
@@ -278,13 +278,6 @@ function getpass(input::TTY, output::IO, prompt::AbstractString)
278278
end
279279
return seekstart(s)
280280
end
281-
else
282-
function getpass(input::TTY, output::IO, prompt::AbstractString)
283-
(input === stdin && output === stdout) || throw(ArgumentError("getpass only works for stdin"))
284-
msg = string(prompt, ": ")
285-
unsafe_SecretBuffer!(ccall(:getpass, Cstring, (Cstring,), msg))
286-
end
287-
end
288281

289282
# allow new getpass methods to be defined if stdin has been
290283
# redirected to some custom stream, e.g. in IJulia.

src/jl_exported_funcs.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@
199199
XX(jl_generic_function_def) \
200200
XX(jl_gensym) \
201201
XX(jl_getallocationgranularity) \
202+
XX(jl_getch) \
202203
XX(jl_getnameinfo) \
203204
XX(jl_getpagesize) \
204205
XX(jl_get_ARCH) \

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,7 @@ extern JL_DLLEXPORT JL_STREAM *JL_STDERR;
20572057
JL_DLLEXPORT JL_STREAM *jl_stdout_stream(void);
20582058
JL_DLLEXPORT JL_STREAM *jl_stdin_stream(void);
20592059
JL_DLLEXPORT JL_STREAM *jl_stderr_stream(void);
2060+
JL_DLLEXPORT int jl_getch(void);
20602061

20612062
// showing and std streams
20622063
JL_DLLEXPORT void jl_flush_cstdio(void) JL_NOTSAFEPOINT;

src/sys.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include <sys/mman.h>
2828
#include <dlfcn.h>
2929
#include <grp.h>
30+
31+
// For `struct termios`
32+
#include <termios.h>
3033
#endif
3134

3235
#ifndef _OS_WINDOWS_
@@ -514,6 +517,31 @@ JL_DLLEXPORT JL_STREAM *jl_stdin_stream(void) { return JL_STDIN; }
514517
JL_DLLEXPORT JL_STREAM *jl_stdout_stream(void) { return JL_STDOUT; }
515518
JL_DLLEXPORT JL_STREAM *jl_stderr_stream(void) { return JL_STDERR; }
516519

520+
// terminal workarounds
521+
JL_DLLEXPORT int jl_getch(void) JL_NOTSAFEPOINT
522+
{
523+
#if defined(_OS_WINDOWS_)
524+
// Windows has an actual `_getch()`, use that:
525+
return _getch();
526+
#else
527+
// On all other platforms, we do the POSIX terminal manipulation dance
528+
char c;
529+
int r;
530+
struct termios old_termios = {0};
531+
struct termios new_termios = {0};
532+
if (tcgetattr(0, &old_termios) != 0)
533+
return -1;
534+
new_termios = old_termios;
535+
cfmakeraw(&new_termios);
536+
if (tcsetattr(0, TCSADRAIN, &new_termios) != 0)
537+
return -1;
538+
r = read(0, &c, 1);
539+
if (tcsetattr(0, TCSADRAIN, &old_termios) != 0)
540+
return -1;
541+
return r == 1 ? c : -1;
542+
#endif
543+
}
544+
517545
// -- processor native alignment information --
518546

519547
JL_DLLEXPORT void jl_native_alignment(uint_t *int8align, uint_t *int16align, uint_t *int32align,

test/secretbuffer.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,11 @@ using Test
122122
@test hash(sb1, UInt(5)) === hash(sb2, UInt(5))
123123
shred!(sb1); shred!(sb2)
124124
end
125+
@testset "NULL initialization" begin
126+
null_ptr = Cstring(C_NULL)
127+
@test_throws ArgumentError Base.unsafe_SecretBuffer!(null_ptr)
128+
null_ptr = Ptr{UInt8}(C_NULL)
129+
@test_throws ArgumentError Base.unsafe_SecretBuffer!(null_ptr)
130+
@test_throws ArgumentError Base.unsafe_SecretBuffer!(null_ptr, 0)
131+
end
125132
end

0 commit comments

Comments
 (0)