| #include <pthread.h> | 
 | #include <sys/types.h> | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <unistd.h> | 
 | #include <errno.h> | 
 |  | 
 | #define handle_error_en(en, msg) \ | 
 | 		  do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) | 
 |  | 
 | static volatile int done = 0; | 
 | static volatile int cleanup_pop_arg = 0; | 
 | static volatile int cnt = 0; | 
 |  | 
 | static void cleanup_handler(void *arg) | 
 | { | 
 | 	printf("Running Cleanup Handler\n"); | 
 | } | 
 |  | 
 | static void *thread_start(void *arg) | 
 | { | 
 | 	time_t start, curr; | 
 |  | 
 | 	printf("Pushing Cleanup Handler\n"); | 
 | 	pthread_cleanup_push(cleanup_handler, NULL); | 
 | 	while (!done) | 
 | 		cnt++; | 
 | 	printf("Popping Cleanup Handler: %d\n", cleanup_pop_arg); | 
 | 	pthread_cleanup_pop(cleanup_pop_arg); | 
 | 	return NULL; | 
 | } | 
 |  | 
 | int main(int argc, char *argv[]) | 
 | { | 
 | 	pthread_t thr; | 
 | 	int s; | 
 | 	void *res; | 
 |  | 
 | 	if (argc == 2) { | 
 | 		cleanup_pop_arg = atoi(argv[1]); | 
 | 	} else { | 
 | 		printf("You must supply either 0 or 1 as an argument to " | 
 | 		       "run the pop handler or not.\n"); | 
 | 		exit(EXIT_FAILURE); | 
 | 	} | 
 |  | 
 | 	/* Start a new thread. */ | 
 | 	s = pthread_create(&thr, NULL, thread_start, NULL); | 
 | 	if (s != 0) | 
 | 		handle_error_en(s, "pthread_create"); | 
 |  | 
 | 	/* Allow new thread to run a while, then signal done. */ | 
 | 	uthread_sleep(2); | 
 | 	done = 1; | 
 |  | 
 | 	s = pthread_join(thr, &res); | 
 | 	if (s != 0) | 
 | 		handle_error_en(s, "pthread_join"); | 
 |  | 
 | 	printf("Thread terminated normally; cnt = %d\n", cnt); | 
 | 	exit(EXIT_SUCCESS); | 
 | } |