You need to group the disjoint clauses:
find "$path" -type f \( -iname "*.c" -o -iname "*.h" \) -exec ls {} \;
Without that, find interprets your command as two disjoint sets of clauses: -type f -iname "*.c" on one hand, and -iname "*.h" -exec ls {} \; on the other. That’s why you only see *.h matches.
Incidentally, there’s not much point in running ls like that; you might as well use
find "$path" -type f \( -iname "*.c" -o -iname "*.h" \) -print
(but perhaps ls is a placeholder).
You can also simplify your command by combining the two globs:
find "$path" -type f -iname "*.[ch]"
(relying on the default -print action).
-iname "*.[ch]"? – steeldriver Aug 31 '23 at 13:14.Cand.Hthat they need to handle, or they could just switch to-name. – Kusalananda Aug 31 '23 at 13:31-name '*.[chCH]'– Tavian Barnes Aug 31 '23 at 16:10