-
Notifications
You must be signed in to change notification settings - Fork 0
/
cancel.c
79 lines (70 loc) · 1.43 KB
/
cancel.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <assert.h>
#include <netdb.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define NAMESZ 10
struct args {
socklen_t addrlen;
const struct sockaddr *addr;
char name[NAMESZ];
};
static void handler(void *ign) {
(void) ign;
close(STDERR_FILENO + 1);
}
static void *thread(void *arg) {
struct args *args = arg;
pthread_cleanup_push(handler, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
getnameinfo(args->addr, args->addrlen, args->name, NAMESZ, NULL, 0, 0);
pthread_cleanup_pop(false);
return NULL;
}
int main(void) {
struct addrinfo *ai;
getaddrinfo("127.0.0.1", NULL, NULL, &ai);
struct sockaddr_storage sa;
socklen_t salen = ai->ai_addrlen;
memcpy(&sa, ai->ai_addr, salen);
freeaddrinfo(ai);
ai = NULL;
struct args args = {
.addrlen = salen,
.addr = (struct sockaddr *) &sa,
};
char acter = '|';
unsigned canceled = 0;
while(true) {
printf("%c\b", acter);
fflush(stdout);
switch(acter) {
case '|':
acter = '/';
break;
case '/':
acter = '-';
break;
case '-':
acter = '\\';
break;
case '\\':
acter = '|';
break;
}
pthread_t tid;
pthread_create(&tid, NULL, thread, &args);
pthread_cancel(tid);
void *res;
pthread_join(tid, &res);
if(res != PTHREAD_CANCELED) {
printf("%d ", canceled);
puts(args.name);
assert(!strcmp(args.name, "localhost"));
} else
++canceled;
}
return 0;
}