Use of ioctl() makes for nonportable programs. Use the POSIX interface described in termios(3) whenever possible.
stty -a prints the value of every flag in the struct termios in a human-readable format.
On Linux, an ioctl on a tty device with a "request" of TCGETS (defined in termios.h) takes a parameter that is a pointer to a struct termios, and copies the in-kernel settings for that tty to the provided struct.
So somewhere in libc, tcgetattr(fd, p) is just defined to do an ioctl(fd, TCGETS, p)