about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/tst-getpid1.c
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2017-08-11 09:43:59 -0400
committerZack Weinberg <zackw@panix.com>2017-08-23 07:42:53 -0400
commit38395be6ca77ffd3a1c09d68db6110333775dfdc (patch)
treef90d61997f4e0dee4b1727082d026a3121262ddf /sysdeps/unix/sysv/linux/tst-getpid1.c
parent5a706f649de3952271930a8340db4ca8aa50f485 (diff)
downloadglibc-zack/anon-unions.tar.gz
glibc-zack/anon-unions.tar.xz
glibc-zack/anon-unions.zip
RFC: Use anonymous union for siginfo_t zack/anon-unions
C2011 officially includes an 'anonymous union' feature, and GCC has
supported it for many years.  It makes sub-fields of a union that's a
struct field appear to be fields of the parent struct.  If we use this
in the definition of siginfo_t, we don't need to define lots of
innocuous-looking identifiers like 'si_pid' as macros expanding to
chains of field accessors.  The catch, however, is that the compiler
used to compile *programs that use glibc* - not just glibc itself -
must accept the use of this feature (in system headers) even when
running in an older conformance mode.

This patch only touches siginfo_t, but if people like the idea, we
could also do it for several other types:

netinet/in.h (in6_addr)
sys/stat.h (stat)
utmp.h (utmp)
signal.h (sigaction, sigevent_t)
ucontext.h (ucontext_t)

and maybe also - these use names in the user namespace for the fields
that would be removed:

net/if.h (ifaddr)
ifaddrs.h (ifaddrs)
netinet/in6.h (ip6_hdr) (really should be bitfields instead)
netinet/icmp6.h (many)
net/if_ppp.h (ifpppstatsreq, ifpppcstatsreq)
net/if_shaper.h (shaperconf)
a.out.h (exec) (only some versions)
sys/quota.h (dqblk?) (the dq_* macros refer to a field that doesn't exist?!)

There are still more hits in sunrpc and nis, but since hopefully that
code is going to go away, I don't propose to mess with them.  And
there may be even more that aren't caught by grepping for
'#define IDENT IDENT.IDENT'.

As a side note (and this could be split for commit if felt
appropriate), the siginfo_t field aliases 'si_int' and 'si_ptr' are
not in POSIX.  There are a few uses of these within glibc itself, and
a handful more in third-party software (not glibc, not uclibc, and not
linux) so I have preserved them, but put them under __USE_MISC and
added a deprecation warning.

This passes the glibc testsuite on x86-64-linux, which probably
*doesn't* test the case where someone is compiling a program in
an older conformance mode that uses siginfo_t
(-std=c99 -D_XOPEN_SOURCE=600, perhaps).

What do you think?

zw

	* sysdeps/unix/sysv/linux/bits/types/siginfo_t.h (siginfo_t):
	Use C2011 anonymous union and anonymous struct-in-union features
	to define this type.  Rename some public fields with their
	official names.
	(si_pid, si_uid, si_timerid, si_overrun, si_status, si_utime)
	(si_stime, si_value, si_addr, si_addr_lsb, si_lower, si_upper)
	(si_pkey, si_band, si_fd, si_call_addr, si_syscall, si_arch):
	Do not define as macros.
	(si_int, si_ptr): Define only when __USE_MISC, with deprecation
	warnings.
	* sysdeps/unix/sysv/linux/ia64/bits/siginfo-arch.h
	* sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h
	* sysdeps/unix/sysv/linux/tile/bits/siginfo-arch.h
	(__SI_SIGFAULT_ADDL): Define all fields with their public names
	when __USE_GNU, or with impl-namespace names otherwise.
	(si_imm, si_segvflags, si_isr, si_trapno): Do not define as macros.

	* sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread)
	Use si_value.sival_ptr instead of si_ptr.
	* sysdeps/unix/sysv/linux/tst-getpid1.c (do_test):
	Use si_value.sival_int instead of si_int.
Diffstat (limited to 'sysdeps/unix/sysv/linux/tst-getpid1.c')
-rw-r--r--sysdeps/unix/sysv/linux/tst-getpid1.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/sysdeps/unix/sysv/linux/tst-getpid1.c b/sysdeps/unix/sysv/linux/tst-getpid1.c
index 253ebf2e15..f24faf35e1 100644
--- a/sysdeps/unix/sysv/linux/tst-getpid1.c
+++ b/sysdeps/unix/sysv/linux/tst-getpid1.c
@@ -95,9 +95,10 @@ do_test (void)
       return 1;
     }
 
-  if (si.si_int != (int) p)
+  if (si.si_value.sival_int != (int) p)
     {
-      printf ("expected PID %d, got si_int %d\n", (int) p, si.si_int);
+      printf ("expected PID %d, got si_int %d\n",
+	      (int) p, si.si_value.sival_int);
       kill (p, SIGKILL);
       return 1;
     }