13

I know that the standard doesn't say anything about the signedness of uid_t or gid_t.

Inconsistency:

Page http://www.gnu.org/software/libc/manual/html_node/Reading-Persona.html says:

In the GNU C Library, this is an alias for unsigned int.

But man setreuid says:

Supplying a value of -1 for either the real or effective user ID forces the system to leave that ID unchanged.

Questions:

  1. So, is uid_t signed or unsigned in the GNU Library?

  2. How can I supply -1 if uid_t and gid_t are unsigned (-1 will be converted to 0xFFFFFFFF)?

Community
  • 1
  • 1
Antonio Rizzo
  • 748
  • 1
  • 8
  • 17
  • Not the same question, but yours is answered [here](http://stackoverflow.com/questions/2984258/printing-uid-of-a-file-on-linux-system). – AntonH Jan 26 '14 at 22:28

2 Answers2

11

POSIX says explicitly that pid_t is a signed integer type used for representing process and process group IDs.

It says that ino_t is an unsigned integer type used for file serial numbers.

For both uid_t and gid_t, it says that the type is an integer type (no mention of signed or unsigned) used for user IDs and group IDS.

Thus, the standard clearly states that the type of uid_t and gid_t can be signed or unsigned depending on the platform. It is very reasonable to suppose that this indeterminacy arose because actual implementations used both signed and unsigned types, and the standard was designed not to invalidate existing implementations.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Could `int` just be assumed to be signed by default unless defined otherwise? From using `c99` and `c11`, I noticed the compiler would complain whenever using any other value (I usually try to use strict guidelines when compiling). –  Sep 13 '17 at 04:30
  • @jargonjunkie: `int` is 'always' a signed type — unless you're mucking around with bit-fields, it is *always* a signed type. But I'm not sure how that's germane to the Q&A, so I suspect I'm missing what you're trying to ask. – Jonathan Leffler Sep 13 '17 at 04:33
  • According to your answer and source, it's defined as an integer which in C is an `int`. It's default is to assume a `signed` value. You could explicitly declare it as `signed int` or `unsigned int` as superfluous as it may be. Other than bit-fields, I can't think of another instance in which it would be affected. It was more a matter of explicit clarity; aside from being implied. If `uid_t` is an integer value, than it would make sense that it would be an `int` and not `unsigned int` unless `typedef` or `define` defined/aliased it as another "type" or value. –  Sep 13 '17 at 04:50
  • When I use "strict" options in `gcc` and compare `int` to `unsigned`, the compiler usually complains about the comparison. To me, this further implies that `uid_t` is type `int`. So when it's defined in the header as `uid_t` it's defined as something. I haven't looked at the source, but that's what I'm assuming. –  Sep 13 '17 at 04:55
  • 1
    You appear to misunderstand the term 'an integer type'. There's a difference between `int`, 'a signed integer type', 'an unsigned integer type', and 'an integer type'. While `int` is an integer type, it is very far being the only integer type. Some integer types are signed (and `int` is one such integer type); some integer types are unsigned (but `int` is not one of those integer types). When the standards use the term 'an integer type', it means 'some integer type that might be signed or unsigned' (but it explicitly excludes floating point types, or arrays or structures or pointers, etc.). – Jonathan Leffler Sep 13 '17 at 04:59
4

uid_t is (after some typedefs/defines) defined as __U32_TYPE which is defined as unsigned int (that is on my Gentoo Linux system).

However, just because -1 has a special meaning it does not mean that UIDs are restricted to the numbers that fit in a signed int. It just means that the highest value (i.e. (unsigned int)-1) is not a valid UID. The code in setreuid probably uses the reverse form of that cast ((signed int)ruid) to compare against -1 cleanly although it accepts an uid_t.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636