The use of goto in C for error and exception handling is good practice. It keeps the code easy to read, and also provides common code for error and/or exit handling. You'll see this paradigm used a lot in large open source C projects, such as the Linux kernel and QEMU.
In my experience, a lot of closed source C projects ban goto outright, in (IMO) an overly dogmatic adherence to the idea that all goto use is spaghetti code and therefore bad.