goto是局部跳转,只能在一个函数内实施的跳转。
setjmp与longjmp是非局部跳转

#include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);

在希望返回的位置上调用setjmp,当在可能出现错误的位置上调用longjmp,函数返回就好像又回到了setjmp返回的地方。

static jmp_buf jmpbuf; 
static void sig_quit(int signo)
{
longjmp(jmpbuf, 1);
}
int main()
{
socket s;
singal(SIGIO, sig_quit);
...
bind(s);
...
if(setjmp(jmpbuf)) {
exit(0);
}
socket ns = accept();//即使堵在此也不怕了

...
}

第一次setjmp会返回0,而当SIGIO打断程序跳出accept之后,进入信号处理函数,里面调用longjmp,这时又回到了setjmp的地方,不过这时候setjmp返回的是1,返回的值是longjmp的第二个参数的值。