gnulib attacks this problem by defining a macro PROMOTED_MODE_T that expands to 'int' on platforms where mode_t is narrower than int, and to 'mode_t' otherwise. This supports 'mode = va_arg (ap, PROMOTED_MODE_T);'. glibc could do something similar.