[PATCH 2/2] lua: fix error handling in getpwall and getgrall

Vladimir Davydov vdavydov.dev at gmail.com
Mon Dec 3 11:33:24 MSK 2018


On Sun, Dec 02, 2018 at 06:57:32PM +0300, Alexander Turenko wrote:
> This commit fixes app-tap/pwd.test.lua test. It seems that the problem
> appears after updating to glibc-2.28.
> 
> Related to #3766.
> ---
>  src/lua/pwd.lua | 43 +++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 39 insertions(+), 4 deletions(-)
> 
> diff --git a/src/lua/pwd.lua b/src/lua/pwd.lua
> index 8f17951df..0a6b73395 100644
> --- a/src/lua/pwd.lua
> +++ b/src/lua/pwd.lua
> @@ -158,22 +158,52 @@ local function getpw(uid)
>      return user
>  end
>  
> +-- It seems glibc developers threat POSIX in the following way.

s/threat/treat

> +-- {set,get,end}pwent() and {set,get,end}grent() functions can set
> +-- errno to non-zero value that is not listed in the standard in
> +-- case of success. Errno should be checked after get{pw,gr}ent
> +-- only when it returns a non-NULL value.

Why do you need to check for specific error codes then?

> +--
> +-- https://sourceware.org/bugzilla/show_bug.cgi?id=1969
> +-- https://sourceware.org/bugzilla/show_bug.cgi?id=23737
> +
> +local pwent_grent_errno_list = {
> +    errno.EINTR,
> +    errno.EIO,
> +    errno.EMFILE,
> +    errno.ENFILE,
> +}
> +
> +local function is_pwent_grent_errno(e)
> +    for _, v in ipairs(pwent_grent_errno_list) do
> +        if e == v then
> +            return true
> +        end
> +    end
> +    return false
> +end
> +
>  local function getpwall()
>      errno(0)
>      ffi.C.setpwent()
> -    if errno() ~= 0 then
> +    if is_pwent_grent_errno(errno()) then

According to the manual setpwent never fails in any visible to the user
way so why check errno here?

>          return nil
>      end
>      local pws = {}
>      while true do
> +        errno(0)
>          local pw = ffi.C.getpwent()
>          if pw == nil then
> +            if is_pwent_grent_errno(errno()) then
> +                return nil
> +            end
>              break
>          end
>          table.insert(pws, getpw(pw.pw_uid))
>      end
> +    errno(0)
>      ffi.C.endpwent()
> -    if errno() ~= 0 then
> +    if is_pwent_grent_errno(errno()) then

Again, endpwent never fails. May be, remove this check altogether?

Same concerns setgrent and endgrent.

>          return nil
>      end
>      return pws
> @@ -182,19 +212,24 @@ end
>  local function getgrall()
>      errno(0)
>      ffi.C.setgrent()
> -    if errno() ~= 0 then
> +    if is_pwent_grent_errno(errno()) then
>          return nil
>      end
>      local grs = {}
>      while true do
> +        errno(0)
>          local gr = ffi.C.getgrent()
>          if gr == nil then
> +            if is_pwent_grent_errno(errno()) then
> +                return nil
> +            end
>              break
>          end
>          table.insert(grs, getpw(gr.gr_gid))
>      end
> +    errno(0)
>      ffi.C.endgrent()
> -    if errno() ~= 0 then
> +    if is_pwent_grent_errno(errno()) then
>          return nil
>      end
>      return grs



More information about the Tarantool-patches mailing list