Or just test the resource handles you opened, and only close them if they're valid. That way, you don't have to worry about doing a goto to the wrong label, or messing up the order of cleanup.
BOOL do_stuff_with_resources()
{
int success = FALSE;
char *memBuf = (char *) malloc(256 * 1024);
if (NULL == memBuf) goto cleanup;
if (randBomb()) goto cleanup;
FILE *fp = fopen("dummy-file.txt", "w");
if (NULL == fp) goto cleanup;
if (randBomb()) goto cleanup;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sock) goto cleanup;
if (randBomb()) goto cleanup;
int shmId = shmget(0x1234ABCD, 256*1024, IPC_CREAT);
if (-1 == shmId) goto cleanup;
shmRegion = (char *) shmat(shmId, NULL, 0);
if ((char *) -1 == shmRegion) goto cleanup;
if (randBomb()) goto cleanup;
sem_t st = -1;
if (-1 == sem_init(&st, 0, 1)) goto cleanup;
if (randBomb()) goto cleanup;
// TODO: Do stuff
success = TRUE;
cleanup:
if(-1 != st)
{
sem_destroy(&st);
}
if(-1 != shmId)
{
shmctl(shmId, IPC_RMID, NULL);
}
if(-1 != sock)
{
close(sock);
}
if(NULL != fp)
{
fclose(fp);
}
if(NULL != memBuf)
{
free(memBuf);
}
return success;
}