About the format type specifiers

Maxim Dounin mdounin at mdounin.ru
Tue Jul 24 10:44:49 UTC 2012


Hello!

On Tue, Jul 24, 2012 at 03:34:39PM +0800, 姚伟斌 wrote:

> 1. The type of 'ngx_msec_int_t', from the source code, It's defined like this:
> 
> typedef ngx_int_t   ngx_rbtree_key_int_t;
> typedef ngx_rbtree_key_int_t  ngx_msec_int_t;
> 
> So It should be an ngx_int_t.
> 
> In the file of ngx_http_log_module.c, It appears like this:
> 
> static u_char *
> ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
>     ngx_http_log_op_t *op)
> {
>     ngx_time_t      *tp;
>     ngx_msec_int_t   ms;
> 
>     tp = ngx_timeofday();
> 
>     ms = (ngx_msec_int_t)
>              ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
>     ms = ngx_max(ms, 0);
> 
>     return ngx_sprintf(buf, "%T.%03M", ms / 1000, ms % 1000);
> }

In case of ngx_msec_int_t it's almost always possible to use %M 
which has identical size, as it's only used for intermediate 
computations and ensured to be non-negative.  (Note the 
ngx_max(ms, 0) call in the code above.)

> 2. The type of '' ngx_gid_t" and "ngx_uid_t", from the source code.
> They are defined like this:
> 
>  typedef uid_t  ngx_uid_t;
>  typedef gid_t  ngx_gid_t;
> 
> And I googled [1][2] about the types of uid_t and gid_t and They seem
> to unsigned integer.

Just a side note: no, POSIX doesn't define signedness of 
uid_t/gid_t.  It only says they should be "integer types", see
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html.

> 
> In the file of ngx_process_cycle.c, it appears like this:
> 
>     if (geteuid() == 0) {
>         if (setgid(ccf->group) == -1) {
>             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
>                           "setgid(%d) failed", ccf->group);
>             /* fatal */
>             exit(2);
>         }
> 
>         if (initgroups(ccf->username, ccf->group) == -1) {
>             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
>                           "initgroups(%s, %d) failed",
>                           ccf->username, ccf->group);
>         }
> 
>         if (setuid(ccf->user) == -1) {
>             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
>                           "setuid(%d) failed", ccf->user);
>             /* fatal */
>             exit(2);
>         }
>     }
> 
> I want to know the correct format specifiers with ngx_msec_int_t,
> uid_t and gid_t. I'm a little confused with above codes.

See above for ngx_msec_int_t.  Most safe way to print 
ngx_uint_t/ngx_gid_t is probably to do so with intermediate cast 
to some defined big-enough type.

Strictly speaking the above code isn't correct and might print 
garbage on some platforms.  It probably worth adding explicit 
casts to int.

Maxim Dounin



More information about the nginx-devel mailing list