On Mon, 2025-10-27 at 15:10 +0200, Álvaro Herrera wrote:
> Hmm, interesting idea.  I think the most difficult part is obtaining
> the
> source strings: we need to run your errno_translation.c program on
> _all_
> platforms,

I have attached .po files for the standard set of errnos (those
recognized by strerror.c:get_errno_symbol()) on linux+glibc,
linux+musl, freebsd, and mac.

Windows and solaris/illumos are missing, and perhaps some other
variations too (e.g. the other BSDs).

If we need to merge the files, let me know what format you have in mind
for the resulting file. I was thinking something like:

   #. EIO (linux+glibc, freebsd, mac)
   msgid "Input/output error"
   msgstr "Input/output error"

   #. EIO (linux+musl)
   msgid "I/O error"
   msgstr "I/O error"

We might not want to get too detailed with the comments, but it would
be nice to have a hint of where it might have come from.

>  merge the output files together, and then create a single
> errstrings.po file with all the variations, to reside on our source
> tree, which would be given to translators.
> 
> Also we need a separate step to create the final postgres.po by
> catenating the existing postgres.po with the new errstrings.po; this
> should not occur in the source tree but rather at install time,
> because
> of course pg_dump.po is going to have to do the same, and we don't
> need
> to make translators responsible for propagating translations from one
> file to others; that occurs already to a very small scale with the
> src/common files and I hate it, so I wouldn't want to see it
> happening
> with this much larger set of strings.

I'm not familiar with the tooling in this area, but I can take a look
into it. Would it affect packagers?

> BTW looking at the output of that program I realized that with
> _GNU_SOURCE, there's strerrorname_np() which can be helpful to
> generate
> the new file in a way that doesn't require you to have all these E
> constants in the program.

I just borrowed get_errno_symbol from strerror.c. It doesn't have the
nonstandard errnos, though, so I used strerrorname_np() to generate
only the nonstandard errnos and attached the result in errstrings-
linux-glibc-np.po.

I included that file so we can see if there are nonstandard errnos that
we really want to translate.

> the (null) bit should perhaps be avoided anyhow.

Done.

> (I think the exit condition of that loop should be "i <= max_err",
> otherwise it's confusing.)

Done. The the new C file also uses tab-delimited lines, to make it
easier to sort by the symbolic name before creating the .po file.

> > One downside is that there are more messages to translate -- one
> > per
> > errno that Postgres might plausibly encounter,
> 
> It's not all that many messages, and they only have to be translated
> once, so I think this shouldn't be too much of an issue.

Great, thank you.

Also, do you think it's fine to use the static variable (as in the
patch) for newlocale() in any NLS-enabled binary? I think it should be
fine because it's only done for platforms with HAVE_USELOCALE.

Regards,
        Jeff Davis

#. 0
msgid "No error: 0"
msgstr "No error: 0"

#. E2BIG
msgid "Argument list too long"
msgstr "Argument list too long"

#. EACCES
msgid "Permission denied"
msgstr "Permission denied"

#. EADDRINUSE
msgid "Address already in use"
msgstr "Address already in use"

#. EADDRNOTAVAIL
msgid "Can't assign requested address"
msgstr "Can't assign requested address"

#. EAFNOSUPPORT
msgid "Address family not supported by protocol family"
msgstr "Address family not supported by protocol family"

#. EAGAIN
msgid "Resource temporarily unavailable"
msgstr "Resource temporarily unavailable"

#. EALREADY
msgid "Operation already in progress"
msgstr "Operation already in progress"

#. EBADF
msgid "Bad file descriptor"
msgstr "Bad file descriptor"

#. EBADMSG
msgid "Bad message"
msgstr "Bad message"

#. EBUSY
msgid "Device busy"
msgstr "Device busy"

#. ECHILD
msgid "No child processes"
msgstr "No child processes"

#. ECONNABORTED
msgid "Software caused connection abort"
msgstr "Software caused connection abort"

#. ECONNREFUSED
msgid "Connection refused"
msgstr "Connection refused"

#. ECONNRESET
msgid "Connection reset by peer"
msgstr "Connection reset by peer"

#. EDEADLK
msgid "Resource deadlock avoided"
msgstr "Resource deadlock avoided"

#. EDOM
msgid "Numerical argument out of domain"
msgstr "Numerical argument out of domain"

#. EEXIST
msgid "File exists"
msgstr "File exists"

#. EFAULT
msgid "Bad address"
msgstr "Bad address"

#. EFBIG
msgid "File too large"
msgstr "File too large"

#. EHOSTDOWN
msgid "Host is down"
msgstr "Host is down"

#. EHOSTUNREACH
msgid "No route to host"
msgstr "No route to host"

#. EIDRM
msgid "Identifier removed"
msgstr "Identifier removed"

#. EINPROGRESS
msgid "Operation now in progress"
msgstr "Operation now in progress"

#. EINTR
msgid "Interrupted system call"
msgstr "Interrupted system call"

#. EINVAL
msgid "Invalid argument"
msgstr "Invalid argument"

#. EIO
msgid "Input/output error"
msgstr "Input/output error"

#. EISCONN
msgid "Socket is already connected"
msgstr "Socket is already connected"

#. EISDIR
msgid "Is a directory"
msgstr "Is a directory"

#. ELOOP
msgid "Too many levels of symbolic links"
msgstr "Too many levels of symbolic links"

#. EMFILE
msgid "Too many open files"
msgstr "Too many open files"

#. EMLINK
msgid "Too many links"
msgstr "Too many links"

#. EMSGSIZE
msgid "Message too long"
msgstr "Message too long"

#. ENAMETOOLONG
msgid "File name too long"
msgstr "File name too long"

#. ENETDOWN
msgid "Network is down"
msgstr "Network is down"

#. ENETRESET
msgid "Network dropped connection on reset"
msgstr "Network dropped connection on reset"

#. ENETUNREACH
msgid "Network is unreachable"
msgstr "Network is unreachable"

#. ENFILE
msgid "Too many open files in system"
msgstr "Too many open files in system"

#. ENOBUFS
msgid "No buffer space available"
msgstr "No buffer space available"

#. ENODEV
msgid "Operation not supported by device"
msgstr "Operation not supported by device"

#. ENOENT
msgid "No such file or directory"
msgstr "No such file or directory"

#. ENOEXEC
msgid "Exec format error"
msgstr "Exec format error"

#. ENOMEM
msgid "Cannot allocate memory"
msgstr "Cannot allocate memory"

#. ENOSPC
msgid "No space left on device"
msgstr "No space left on device"

#. ENOSYS
msgid "Function not implemented"
msgstr "Function not implemented"

#. ENOTCONN
msgid "Socket is not connected"
msgstr "Socket is not connected"

#. ENOTDIR
msgid "Not a directory"
msgstr "Not a directory"

#. ENOTEMPTY
msgid "Directory not empty"
msgstr "Directory not empty"

#. ENOTSOCK
msgid "Socket operation on non-socket"
msgstr "Socket operation on non-socket"

#. ENOTSUP
msgid "Operation not supported"
msgstr "Operation not supported"

#. ENOTTY
msgid "Inappropriate ioctl for device"
msgstr "Inappropriate ioctl for device"

#. ENXIO
msgid "Device not configured"
msgstr "Device not configured"

#. EOVERFLOW
msgid "Value too large to be stored in data type"
msgstr "Value too large to be stored in data type"

#. EPERM
msgid "Operation not permitted"
msgstr "Operation not permitted"

#. EPIPE
msgid "Broken pipe"
msgstr "Broken pipe"

#. EPROTONOSUPPORT
msgid "Protocol not supported"
msgstr "Protocol not supported"

#. ERANGE
msgid "Result too large"
msgstr "Result too large"

#. EROFS
msgid "Read-only file system"
msgstr "Read-only file system"

#. ESRCH
msgid "No such process"
msgstr "No such process"

#. ETIMEDOUT
msgid "Operation timed out"
msgstr "Operation timed out"

#. ETXTBSY
msgid "Text file busy"
msgstr "Text file busy"

#. EXDEV
msgid "Cross-device link"
msgstr "Cross-device link"

#. 0
msgid "Success"
msgstr "Success"

#. E2BIG
msgid "Argument list too long"
msgstr "Argument list too long"

#. EACCES
msgid "Permission denied"
msgstr "Permission denied"

#. EADDRINUSE
msgid "Address already in use"
msgstr "Address already in use"

#. EADDRNOTAVAIL
msgid "Cannot assign requested address"
msgstr "Cannot assign requested address"

#. EAFNOSUPPORT
msgid "Address family not supported by protocol"
msgstr "Address family not supported by protocol"

#. EAGAIN
msgid "Resource temporarily unavailable"
msgstr "Resource temporarily unavailable"

#. EALREADY
msgid "Operation already in progress"
msgstr "Operation already in progress"

#. EBADF
msgid "Bad file descriptor"
msgstr "Bad file descriptor"

#. EBADMSG
msgid "Bad message"
msgstr "Bad message"

#. EBUSY
msgid "Device or resource busy"
msgstr "Device or resource busy"

#. ECHILD
msgid "No child processes"
msgstr "No child processes"

#. ECONNABORTED
msgid "Software caused connection abort"
msgstr "Software caused connection abort"

#. ECONNREFUSED
msgid "Connection refused"
msgstr "Connection refused"

#. ECONNRESET
msgid "Connection reset by peer"
msgstr "Connection reset by peer"

#. EDEADLK
msgid "Resource deadlock avoided"
msgstr "Resource deadlock avoided"

#. EDOM
msgid "Numerical argument out of domain"
msgstr "Numerical argument out of domain"

#. EEXIST
msgid "File exists"
msgstr "File exists"

#. EFAULT
msgid "Bad address"
msgstr "Bad address"

#. EFBIG
msgid "File too large"
msgstr "File too large"

#. EHOSTDOWN
msgid "Host is down"
msgstr "Host is down"

#. EHOSTUNREACH
msgid "No route to host"
msgstr "No route to host"

#. EIDRM
msgid "Identifier removed"
msgstr "Identifier removed"

#. EINPROGRESS
msgid "Operation now in progress"
msgstr "Operation now in progress"

#. EINTR
msgid "Interrupted system call"
msgstr "Interrupted system call"

#. EINVAL
msgid "Invalid argument"
msgstr "Invalid argument"

#. EIO
msgid "Input/output error"
msgstr "Input/output error"

#. EISCONN
msgid "Transport endpoint is already connected"
msgstr "Transport endpoint is already connected"

#. EISDIR
msgid "Is a directory"
msgstr "Is a directory"

#. ELOOP
msgid "Too many levels of symbolic links"
msgstr "Too many levels of symbolic links"

#. EMFILE
msgid "Too many open files"
msgstr "Too many open files"

#. EMLINK
msgid "Too many links"
msgstr "Too many links"

#. EMSGSIZE
msgid "Message too long"
msgstr "Message too long"

#. ENAMETOOLONG
msgid "File name too long"
msgstr "File name too long"

#. ENETDOWN
msgid "Network is down"
msgstr "Network is down"

#. ENETRESET
msgid "Network dropped connection on reset"
msgstr "Network dropped connection on reset"

#. ENETUNREACH
msgid "Network is unreachable"
msgstr "Network is unreachable"

#. ENFILE
msgid "Too many open files in system"
msgstr "Too many open files in system"

#. ENOBUFS
msgid "No buffer space available"
msgstr "No buffer space available"

#. ENODEV
msgid "No such device"
msgstr "No such device"

#. ENOENT
msgid "No such file or directory"
msgstr "No such file or directory"

#. ENOEXEC
msgid "Exec format error"
msgstr "Exec format error"

#. ENOMEM
msgid "Cannot allocate memory"
msgstr "Cannot allocate memory"

#. ENOSPC
msgid "No space left on device"
msgstr "No space left on device"

#. ENOSYS
msgid "Function not implemented"
msgstr "Function not implemented"

#. ENOTCONN
msgid "Transport endpoint is not connected"
msgstr "Transport endpoint is not connected"

#. ENOTDIR
msgid "Not a directory"
msgstr "Not a directory"

#. ENOTEMPTY
msgid "Directory not empty"
msgstr "Directory not empty"

#. ENOTSOCK
msgid "Socket operation on non-socket"
msgstr "Socket operation on non-socket"

#. ENOTSUP
msgid "Operation not supported"
msgstr "Operation not supported"

#. ENOTTY
msgid "Inappropriate ioctl for device"
msgstr "Inappropriate ioctl for device"

#. ENXIO
msgid "No such device or address"
msgstr "No such device or address"

#. EOVERFLOW
msgid "Value too large for defined data type"
msgstr "Value too large for defined data type"

#. EPERM
msgid "Operation not permitted"
msgstr "Operation not permitted"

#. EPIPE
msgid "Broken pipe"
msgstr "Broken pipe"

#. EPROTONOSUPPORT
msgid "Protocol not supported"
msgstr "Protocol not supported"

#. ERANGE
msgid "Numerical result out of range"
msgstr "Numerical result out of range"

#. EROFS
msgid "Read-only file system"
msgstr "Read-only file system"

#. ESRCH
msgid "No such process"
msgstr "No such process"

#. ETIMEDOUT
msgid "Connection timed out"
msgstr "Connection timed out"

#. ETXTBSY
msgid "Text file busy"
msgstr "Text file busy"

#. EXDEV
msgid "Invalid cross-device link"
msgstr "Invalid cross-device link"

#. EADV
msgid "Advertise error"
msgstr "Advertise error"

#. EBADE
msgid "Invalid exchange"
msgstr "Invalid exchange"

#. EBADFD
msgid "File descriptor in bad state"
msgstr "File descriptor in bad state"

#. EBADR
msgid "Invalid request descriptor"
msgstr "Invalid request descriptor"

#. EBADRQC
msgid "Invalid request code"
msgstr "Invalid request code"

#. EBADSLT
msgid "Invalid slot"
msgstr "Invalid slot"

#. EBFONT
msgid "Bad font file format"
msgstr "Bad font file format"

#. ECANCELED
msgid "Operation canceled"
msgstr "Operation canceled"

#. ECHRNG
msgid "Channel number out of range"
msgstr "Channel number out of range"

#. ECOMM
msgid "Communication error on send"
msgstr "Communication error on send"

#. EDESTADDRREQ
msgid "Destination address required"
msgstr "Destination address required"

#. EDOTDOT
msgid "RFS specific error"
msgstr "RFS specific error"

#. EDQUOT
msgid "Disk quota exceeded"
msgstr "Disk quota exceeded"

#. EHWPOISON
msgid "Memory page has hardware error"
msgstr "Memory page has hardware error"

#. EILSEQ
msgid "Invalid or incomplete multibyte or wide character"
msgstr "Invalid or incomplete multibyte or wide character"

#. EISNAM
msgid "Is a named type file"
msgstr "Is a named type file"

#. EKEYEXPIRED
msgid "Key has expired"
msgstr "Key has expired"

#. EKEYREJECTED
msgid "Key was rejected by service"
msgstr "Key was rejected by service"

#. EKEYREVOKED
msgid "Key has been revoked"
msgstr "Key has been revoked"

#. EL2HLT
msgid "Level 2 halted"
msgstr "Level 2 halted"

#. EL2NSYNC
msgid "Level 2 not synchronized"
msgstr "Level 2 not synchronized"

#. EL3HLT
msgid "Level 3 halted"
msgstr "Level 3 halted"

#. EL3RST
msgid "Level 3 reset"
msgstr "Level 3 reset"

#. ELIBACC
msgid "Can not access a needed shared library"
msgstr "Can not access a needed shared library"

#. ELIBBAD
msgid "Accessing a corrupted shared library"
msgstr "Accessing a corrupted shared library"

#. ELIBEXEC
msgid "Cannot exec a shared library directly"
msgstr "Cannot exec a shared library directly"

#. ELIBMAX
msgid "Attempting to link in too many shared libraries"
msgstr "Attempting to link in too many shared libraries"

#. ELIBSCN
msgid ".lib section in a.out corrupted"
msgstr ".lib section in a.out corrupted"

#. ELNRNG
msgid "Link number out of range"
msgstr "Link number out of range"

#. EMEDIUMTYPE
msgid "Wrong medium type"
msgstr "Wrong medium type"

#. EMULTIHOP
msgid "Multihop attempted"
msgstr "Multihop attempted"

#. ENAVAIL
msgid "No XENIX semaphores available"
msgstr "No XENIX semaphores available"

#. ENOANO
msgid "No anode"
msgstr "No anode"

#. ENOCSI
msgid "No CSI structure available"
msgstr "No CSI structure available"

#. ENODATA
msgid "No data available"
msgstr "No data available"

#. ENOKEY
msgid "Required key not available"
msgstr "Required key not available"

#. ENOLCK
msgid "No locks available"
msgstr "No locks available"

#. ENOLINK
msgid "Link has been severed"
msgstr "Link has been severed"

#. ENOMEDIUM
msgid "No medium found"
msgstr "No medium found"

#. ENOMSG
msgid "No message of desired type"
msgstr "No message of desired type"

#. ENONET
msgid "Machine is not on the network"
msgstr "Machine is not on the network"

#. ENOPKG
msgid "Package not installed"
msgstr "Package not installed"

#. ENOPROTOOPT
msgid "Protocol not available"
msgstr "Protocol not available"

#. ENOSR
msgid "Out of streams resources"
msgstr "Out of streams resources"

#. ENOSTR
msgid "Device not a stream"
msgstr "Device not a stream"

#. ENOTBLK
msgid "Block device required"
msgstr "Block device required"

#. ENOTNAM
msgid "Not a XENIX named type file"
msgstr "Not a XENIX named type file"

#. ENOTRECOVERABLE
msgid "State not recoverable"
msgstr "State not recoverable"

#. ENOTUNIQ
msgid "Name not unique on network"
msgstr "Name not unique on network"

#. EOWNERDEAD
msgid "Owner died"
msgstr "Owner died"

#. EPFNOSUPPORT
msgid "Protocol family not supported"
msgstr "Protocol family not supported"

#. EPROTO
msgid "Protocol error"
msgstr "Protocol error"

#. EPROTOTYPE
msgid "Protocol wrong type for socket"
msgstr "Protocol wrong type for socket"

#. EREMCHG
msgid "Remote address changed"
msgstr "Remote address changed"

#. EREMOTEIO
msgid "Remote I/O error"
msgstr "Remote I/O error"

#. EREMOTE
msgid "Object is remote"
msgstr "Object is remote"

#. ERESTART
msgid "Interrupted system call should be restarted"
msgstr "Interrupted system call should be restarted"

#. ERFKILL
msgid "Operation not possible due to RF-kill"
msgstr "Operation not possible due to RF-kill"

#. ESHUTDOWN
msgid "Cannot send after transport endpoint shutdown"
msgstr "Cannot send after transport endpoint shutdown"

#. ESOCKTNOSUPPORT
msgid "Socket type not supported"
msgstr "Socket type not supported"

#. ESPIPE
msgid "Illegal seek"
msgstr "Illegal seek"

#. ESRMNT
msgid "Srmount error"
msgstr "Srmount error"

#. ESTALE
msgid "Stale file handle"
msgstr "Stale file handle"

#. ESTRPIPE
msgid "Streams pipe error"
msgstr "Streams pipe error"

#. ETIME
msgid "Timer expired"
msgstr "Timer expired"

#. ETOOMANYREFS
msgid "Too many references: cannot splice"
msgstr "Too many references: cannot splice"

#. EUCLEAN
msgid "Structure needs cleaning"
msgstr "Structure needs cleaning"

#. EUNATCH
msgid "Protocol driver not attached"
msgstr "Protocol driver not attached"

#. EUSERS
msgid "Too many users"
msgstr "Too many users"

#. EXFULL
msgid "Exchange full"
msgstr "Exchange full"

#. 0
msgid "No error information"
msgstr "No error information"

#. E2BIG
msgid "Argument list too long"
msgstr "Argument list too long"

#. EACCES
msgid "Permission denied"
msgstr "Permission denied"

#. EADDRINUSE
msgid "Address in use"
msgstr "Address in use"

#. EADDRNOTAVAIL
msgid "Address not available"
msgstr "Address not available"

#. EAFNOSUPPORT
msgid "Address family not supported by protocol"
msgstr "Address family not supported by protocol"

#. EAGAIN
msgid "Resource temporarily unavailable"
msgstr "Resource temporarily unavailable"

#. EALREADY
msgid "Operation already in progress"
msgstr "Operation already in progress"

#. EBADF
msgid "Bad file descriptor"
msgstr "Bad file descriptor"

#. EBADMSG
msgid "Bad message"
msgstr "Bad message"

#. EBUSY
msgid "Resource busy"
msgstr "Resource busy"

#. ECHILD
msgid "No child process"
msgstr "No child process"

#. ECONNABORTED
msgid "Connection aborted"
msgstr "Connection aborted"

#. ECONNREFUSED
msgid "Connection refused"
msgstr "Connection refused"

#. ECONNRESET
msgid "Connection reset by peer"
msgstr "Connection reset by peer"

#. EDEADLK
msgid "Resource deadlock would occur"
msgstr "Resource deadlock would occur"

#. EDOM
msgid "Domain error"
msgstr "Domain error"

#. EEXIST
msgid "File exists"
msgstr "File exists"

#. EFAULT
msgid "Bad address"
msgstr "Bad address"

#. EFBIG
msgid "File too large"
msgstr "File too large"

#. EHOSTDOWN
msgid "Host is down"
msgstr "Host is down"

#. EHOSTUNREACH
msgid "Host is unreachable"
msgstr "Host is unreachable"

#. EIDRM
msgid "Identifier removed"
msgstr "Identifier removed"

#. EINPROGRESS
msgid "Operation in progress"
msgstr "Operation in progress"

#. EINTR
msgid "Interrupted system call"
msgstr "Interrupted system call"

#. EINVAL
msgid "Invalid argument"
msgstr "Invalid argument"

#. EIO
msgid "I/O error"
msgstr "I/O error"

#. EISCONN
msgid "Socket is connected"
msgstr "Socket is connected"

#. EISDIR
msgid "Is a directory"
msgstr "Is a directory"

#. ELOOP
msgid "Symbolic link loop"
msgstr "Symbolic link loop"

#. EMFILE
msgid "No file descriptors available"
msgstr "No file descriptors available"

#. EMLINK
msgid "Too many links"
msgstr "Too many links"

#. EMSGSIZE
msgid "Message too large"
msgstr "Message too large"

#. ENAMETOOLONG
msgid "Filename too long"
msgstr "Filename too long"

#. ENETDOWN
msgid "Network is down"
msgstr "Network is down"

#. ENETRESET
msgid "Connection reset by network"
msgstr "Connection reset by network"

#. ENETUNREACH
msgid "Network unreachable"
msgstr "Network unreachable"

#. ENFILE
msgid "Too many open files in system"
msgstr "Too many open files in system"

#. ENOBUFS
msgid "No buffer space available"
msgstr "No buffer space available"

#. ENODEV
msgid "No such device"
msgstr "No such device"

#. ENOENT
msgid "No such file or directory"
msgstr "No such file or directory"

#. ENOEXEC
msgid "Exec format error"
msgstr "Exec format error"

#. ENOMEM
msgid "Out of memory"
msgstr "Out of memory"

#. ENOSPC
msgid "No space left on device"
msgstr "No space left on device"

#. ENOSYS
msgid "Function not implemented"
msgstr "Function not implemented"

#. ENOTCONN
msgid "Socket not connected"
msgstr "Socket not connected"

#. ENOTDIR
msgid "Not a directory"
msgstr "Not a directory"

#. ENOTEMPTY
msgid "Directory not empty"
msgstr "Directory not empty"

#. ENOTSOCK
msgid "Not a socket"
msgstr "Not a socket"

#. ENOTSUP
msgid "Not supported"
msgstr "Not supported"

#. ENOTTY
msgid "Not a tty"
msgstr "Not a tty"

#. ENXIO
msgid "No such device or address"
msgstr "No such device or address"

#. EOVERFLOW
msgid "Value too large for data type"
msgstr "Value too large for data type"

#. EPERM
msgid "Operation not permitted"
msgstr "Operation not permitted"

#. EPIPE
msgid "Broken pipe"
msgstr "Broken pipe"

#. EPROTONOSUPPORT
msgid "Protocol not supported"
msgstr "Protocol not supported"

#. ERANGE
msgid "Result not representable"
msgstr "Result not representable"

#. EROFS
msgid "Read-only file system"
msgstr "Read-only file system"

#. ESRCH
msgid "No such process"
msgstr "No such process"

#. ETIMEDOUT
msgid "Operation timed out"
msgstr "Operation timed out"

#. ETXTBSY
msgid "Text file busy"
msgstr "Text file busy"

#. EXDEV
msgid "Cross-device link"
msgstr "Cross-device link"

#. 0
msgid "Undefined error: 0"
msgstr "Undefined error: 0"

#. E2BIG
msgid "Argument list too long"
msgstr "Argument list too long"

#. EACCES
msgid "Permission denied"
msgstr "Permission denied"

#. EADDRINUSE
msgid "Address already in use"
msgstr "Address already in use"

#. EADDRNOTAVAIL
msgid "Can't assign requested address"
msgstr "Can't assign requested address"

#. EAFNOSUPPORT
msgid "Address family not supported by protocol family"
msgstr "Address family not supported by protocol family"

#. EAGAIN
msgid "Resource temporarily unavailable"
msgstr "Resource temporarily unavailable"

#. EALREADY
msgid "Operation already in progress"
msgstr "Operation already in progress"

#. EBADF
msgid "Bad file descriptor"
msgstr "Bad file descriptor"

#. EBADMSG
msgid "Bad message"
msgstr "Bad message"

#. EBUSY
msgid "Resource busy"
msgstr "Resource busy"

#. ECHILD
msgid "No child processes"
msgstr "No child processes"

#. ECONNABORTED
msgid "Software caused connection abort"
msgstr "Software caused connection abort"

#. ECONNREFUSED
msgid "Connection refused"
msgstr "Connection refused"

#. ECONNRESET
msgid "Connection reset by peer"
msgstr "Connection reset by peer"

#. EDEADLK
msgid "Resource deadlock avoided"
msgstr "Resource deadlock avoided"

#. EDOM
msgid "Numerical argument out of domain"
msgstr "Numerical argument out of domain"

#. EEXIST
msgid "File exists"
msgstr "File exists"

#. EFAULT
msgid "Bad address"
msgstr "Bad address"

#. EFBIG
msgid "File too large"
msgstr "File too large"

#. EHOSTDOWN
msgid "Host is down"
msgstr "Host is down"

#. EHOSTUNREACH
msgid "No route to host"
msgstr "No route to host"

#. EIDRM
msgid "Identifier removed"
msgstr "Identifier removed"

#. EINPROGRESS
msgid "Operation now in progress"
msgstr "Operation now in progress"

#. EINTR
msgid "Interrupted system call"
msgstr "Interrupted system call"

#. EINVAL
msgid "Invalid argument"
msgstr "Invalid argument"

#. EIO
msgid "Input/output error"
msgstr "Input/output error"

#. EISCONN
msgid "Socket is already connected"
msgstr "Socket is already connected"

#. EISDIR
msgid "Is a directory"
msgstr "Is a directory"

#. ELOOP
msgid "Too many levels of symbolic links"
msgstr "Too many levels of symbolic links"

#. EMFILE
msgid "Too many open files"
msgstr "Too many open files"

#. EMLINK
msgid "Too many links"
msgstr "Too many links"

#. EMSGSIZE
msgid "Message too long"
msgstr "Message too long"

#. ENAMETOOLONG
msgid "File name too long"
msgstr "File name too long"

#. ENETDOWN
msgid "Network is down"
msgstr "Network is down"

#. ENETRESET
msgid "Network dropped connection on reset"
msgstr "Network dropped connection on reset"

#. ENETUNREACH
msgid "Network is unreachable"
msgstr "Network is unreachable"

#. ENFILE
msgid "Too many open files in system"
msgstr "Too many open files in system"

#. ENOBUFS
msgid "No buffer space available"
msgstr "No buffer space available"

#. ENODEV
msgid "Operation not supported by device"
msgstr "Operation not supported by device"

#. ENOENT
msgid "No such file or directory"
msgstr "No such file or directory"

#. ENOEXEC
msgid "Exec format error"
msgstr "Exec format error"

#. ENOMEM
msgid "Cannot allocate memory"
msgstr "Cannot allocate memory"

#. ENOSPC
msgid "No space left on device"
msgstr "No space left on device"

#. ENOSYS
msgid "Function not implemented"
msgstr "Function not implemented"

#. ENOTCONN
msgid "Socket is not connected"
msgstr "Socket is not connected"

#. ENOTDIR
msgid "Not a directory"
msgstr "Not a directory"

#. ENOTEMPTY
msgid "Directory not empty"
msgstr "Directory not empty"

#. ENOTSOCK
msgid "Socket operation on non-socket"
msgstr "Socket operation on non-socket"

#. ENOTSUP
msgid "Operation not supported"
msgstr "Operation not supported"

#. ENOTTY
msgid "Inappropriate ioctl for device"
msgstr "Inappropriate ioctl for device"

#. ENXIO
msgid "Device not configured"
msgstr "Device not configured"

#. EOPNOTSUPP
msgid "Operation not supported on socket"
msgstr "Operation not supported on socket"

#. EOVERFLOW
msgid "Value too large to be stored in data type"
msgstr "Value too large to be stored in data type"

#. EPERM
msgid "Operation not permitted"
msgstr "Operation not permitted"

#. EPIPE
msgid "Broken pipe"
msgstr "Broken pipe"

#. EPROTONOSUPPORT
msgid "Protocol not supported"
msgstr "Protocol not supported"

#. ERANGE
msgid "Result too large"
msgstr "Result too large"

#. EROFS
msgid "Read-only file system"
msgstr "Read-only file system"

#. ESRCH
msgid "No such process"
msgstr "No such process"

#. ETIMEDOUT
msgid "Operation timed out"
msgstr "Operation timed out"

#. ETXTBSY
msgid "Text file busy"
msgstr "Text file busy"

#. EXDEV
msgid "Cross-device link"
msgstr "Cross-device link"

#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void translate(locale_t loc, int err);
static char *get_errno_symbol(int errnum);

int
main(int argc, char **argv)
{
	const char	*localename;
	int			 min_err;
	int			 max_err;
	locale_t	 c_loc;

	setlocale(LC_CTYPE, "");
	setlocale(LC_MESSAGES, "");

	if (argc != 3)
    {
		fprintf(stderr, "usage:\n\terrno_translation min_errno max_errno\n");
		exit(1);
    }

	min_err = atoi(argv[1]);
	max_err = atoi(argv[2]);

	if (min_err >= max_err)
    {
		fprintf(stderr, "min_err must be less than max_err\n");
		exit(1);
    }

	c_loc = newlocale(LC_ALL_MASK, "C", NULL);
	if (!c_loc)
    {
		fprintf(stderr, "can't create locale: C\n");
		exit(1);
    }

	for (int i = min_err; i <= max_err; i++)
		translate(c_loc, i);  
}

static void
translate(locale_t c_loc, int err)
{
	const char	*errorname = get_errno_symbol(err);
	const char	*msgid;
	const char	*msgstr;
	locale_t	 save_loc;

	if (!errorname && err == 0)
		errorname = "0";

	if (!errorname)
		return;

	printf("#. %s\t", errorname);
  
	save_loc = uselocale(c_loc);
	msgid = strerror(err);
	uselocale(save_loc);

	printf("msgid \"%s\"\t", msgid);
  
	msgstr = strerror(err);
	printf("msgstr \"%s\"\t\n", msgstr);
}

/*
 * Returns a symbol (e.g. "ENOENT") for an errno code.
 * Returns NULL if the code is unrecognized.
 */
static char *
get_errno_symbol(int errnum)
{
	switch (errnum)
	{
		case E2BIG:
			return "E2BIG";
		case EACCES:
			return "EACCES";
		case EADDRINUSE:
			return "EADDRINUSE";
		case EADDRNOTAVAIL:
			return "EADDRNOTAVAIL";
		case EAFNOSUPPORT:
			return "EAFNOSUPPORT";
#ifdef EAGAIN
		case EAGAIN:
			return "EAGAIN";
#endif
#ifdef EALREADY
		case EALREADY:
			return "EALREADY";
#endif
		case EBADF:
			return "EBADF";
#ifdef EBADMSG
		case EBADMSG:
			return "EBADMSG";
#endif
		case EBUSY:
			return "EBUSY";
		case ECHILD:
			return "ECHILD";
		case ECONNABORTED:
			return "ECONNABORTED";
		case ECONNREFUSED:
			return "ECONNREFUSED";
		case ECONNRESET:
			return "ECONNRESET";
		case EDEADLK:
			return "EDEADLK";
		case EDOM:
			return "EDOM";
		case EEXIST:
			return "EEXIST";
		case EFAULT:
			return "EFAULT";
		case EFBIG:
			return "EFBIG";
		case EHOSTDOWN:
			return "EHOSTDOWN";
		case EHOSTUNREACH:
			return "EHOSTUNREACH";
		case EIDRM:
			return "EIDRM";
		case EINPROGRESS:
			return "EINPROGRESS";
		case EINTR:
			return "EINTR";
		case EINVAL:
			return "EINVAL";
		case EIO:
			return "EIO";
		case EISCONN:
			return "EISCONN";
		case EISDIR:
			return "EISDIR";
#ifdef ELOOP
		case ELOOP:
			return "ELOOP";
#endif
		case EMFILE:
			return "EMFILE";
		case EMLINK:
			return "EMLINK";
		case EMSGSIZE:
			return "EMSGSIZE";
		case ENAMETOOLONG:
			return "ENAMETOOLONG";
		case ENETDOWN:
			return "ENETDOWN";
		case ENETRESET:
			return "ENETRESET";
		case ENETUNREACH:
			return "ENETUNREACH";
		case ENFILE:
			return "ENFILE";
		case ENOBUFS:
			return "ENOBUFS";
		case ENODEV:
			return "ENODEV";
		case ENOENT:
			return "ENOENT";
		case ENOEXEC:
			return "ENOEXEC";
		case ENOMEM:
			return "ENOMEM";
		case ENOSPC:
			return "ENOSPC";
		case ENOSYS:
			return "ENOSYS";
		case ENOTCONN:
			return "ENOTCONN";
		case ENOTDIR:
			return "ENOTDIR";
		case ENOTEMPTY:
			return "ENOTEMPTY";
		case ENOTSOCK:
			return "ENOTSOCK";
#ifdef ENOTSUP
		case ENOTSUP:
			return "ENOTSUP";
#endif
		case ENOTTY:
			return "ENOTTY";
		case ENXIO:
			return "ENXIO";
#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (EOPNOTSUPP != ENOTSUP))
		case EOPNOTSUPP:
			return "EOPNOTSUPP";
#endif
#ifdef EOVERFLOW
		case EOVERFLOW:
			return "EOVERFLOW";
#endif
		case EPERM:
			return "EPERM";
		case EPIPE:
			return "EPIPE";
		case EPROTONOSUPPORT:
			return "EPROTONOSUPPORT";
		case ERANGE:
			return "ERANGE";
#ifdef EROFS
		case EROFS:
			return "EROFS";
#endif
		case ESRCH:
			return "ESRCH";
		case ETIMEDOUT:
			return "ETIMEDOUT";
#ifdef ETXTBSY
		case ETXTBSY:
			return "ETXTBSY";
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
		case EWOULDBLOCK:
			return "EWOULDBLOCK";
#endif
		case EXDEV:
			return "EXDEV";
	}

	return NULL;
}

Reply via email to