Skip to content

Commit

Permalink
Fix using System.retry_with_buffer with stack buffer (crystal-lang#…
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota committed May 29, 2024
1 parent db612c1 commit 6244f33
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
13 changes: 8 additions & 5 deletions src/crystal/system/unix/group.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ module Crystal::System::Group
grp = uninitialized LibC::Group
grp_pointer = pointerof(grp)
System.retry_with_buffer("getgrnam_r", GETGR_R_SIZE_MAX) do |buf|
LibC.getgrnam_r(groupname, grp_pointer, buf, buf.size, pointerof(grp_pointer))
LibC.getgrnam_r(groupname, grp_pointer, buf, buf.size, pointerof(grp_pointer)).tap do
# It's not necessary to check success with `ret == 0` because `grp_pointer` will be NULL on failure
return from_struct(grp) if grp_pointer
end
end

from_struct(grp) if grp_pointer
end

private def from_id?(groupid : String)
Expand All @@ -27,8 +28,10 @@ module Crystal::System::Group
grp = uninitialized LibC::Group
grp_pointer = pointerof(grp)
System.retry_with_buffer("getgrgid_r", GETGR_R_SIZE_MAX) do |buf|
LibC.getgrgid_r(groupid, grp_pointer, buf, buf.size, pointerof(grp_pointer))
LibC.getgrgid_r(groupid, grp_pointer, buf, buf.size, pointerof(grp_pointer)).tap do
# It's not necessary to check success with `ret == 0` because `grp_pointer` will be NULL on failure
return from_struct(grp) if grp_pointer
end
end
from_struct(grp) if grp_pointer
end
end
11 changes: 5 additions & 6 deletions src/crystal/system/unix/path.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ module Crystal::System::Path
pwd_pointer = pointerof(pwd)
ret = nil
System.retry_with_buffer("getpwuid_r", User::GETPW_R_SIZE_MAX) do |buf|
ret = LibC.getpwuid_r(id, pwd_pointer, buf, buf.size, pointerof(pwd_pointer))
ret = LibC.getpwuid_r(id, pwd_pointer, buf, buf.size, pointerof(pwd_pointer)).tap do
# It's not necessary to check success with `ret == 0` because `pwd_pointer` will be NULL on failure
return String.new(pwd.pw_dir) if pwd_pointer
end
end

if pwd_pointer
String.new(pwd.pw_dir)
else
raise RuntimeError.from_os_error("getpwuid_r", Errno.new(ret.not_nil!))
end
raise RuntimeError.from_os_error("getpwuid_r", Errno.new(ret.not_nil!))
end
end
end
14 changes: 8 additions & 6 deletions src/crystal/system/unix/user.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ module Crystal::System::User
pwd = uninitialized LibC::Passwd
pwd_pointer = pointerof(pwd)
System.retry_with_buffer("getpwnam_r", GETPW_R_SIZE_MAX) do |buf|
LibC.getpwnam_r(username, pwd_pointer, buf, buf.size, pointerof(pwd_pointer))
LibC.getpwnam_r(username, pwd_pointer, buf, buf.size, pointerof(pwd_pointer)).tap do
# It's not necessary to check success with `ret == 0` because `pwd_pointer` will be NULL on failure
return from_struct(pwd) if pwd_pointer
end
end

from_struct(pwd) if pwd_pointer
end

private def from_id?(id : String)
Expand All @@ -30,9 +31,10 @@ module Crystal::System::User
pwd = uninitialized LibC::Passwd
pwd_pointer = pointerof(pwd)
System.retry_with_buffer("getpwuid_r", GETPW_R_SIZE_MAX) do |buf|
LibC.getpwuid_r(id, pwd_pointer, buf, buf.size, pointerof(pwd_pointer))
LibC.getpwuid_r(id, pwd_pointer, buf, buf.size, pointerof(pwd_pointer)).tap do
# It's not necessary to check success with `ret == 0` because `pwd_pointer` will be NULL on failure
return from_struct(pwd) if pwd_pointer
end
end

from_struct(pwd) if pwd_pointer
end
end

0 comments on commit 6244f33

Please sign in to comment.