-
Notifications
You must be signed in to change notification settings - Fork 2
/
nonreentrant.c
79 lines (68 loc) · 2.42 KB
/
nonreentrant.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
/*************************************************************************\
* Copyright (C) Michael Kerrisk, 2014. *
* *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU Affero General Public License as published *
* by the Free Software Foundation, either version 3 or (at your option) *
* any later version. This program is distributed without any warranty. *
* See the file COPYING.agpl-v3 for details. *
\*************************************************************************/
/* nonreentrant.c
Demonstrate the nonreentrant nature of some library functions, in this
example, crypt(3).
*/
#if ! defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600
#define _XOPEN_SOURCE 600
#endif
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include "tlpi_hdr.h"
static char *str2; /* Set from argv[2] */
static int handled = 0; /* Counts number of calls to handler */
static void
handler(int sig)
{
crypt(str2, "xx");
handled++;
}
int
main(int argc, char *argv[])
{
char *cr1;
int callNum, mismatch;
struct sigaction sa;
if (argc != 3)
usageErr("%s str1 str2\n", argv[0]);
str2 = argv[2]; /* Make argv[2] available to handler */
cr1 = strdup(crypt(argv[1], "xx")); /* Copy statically allocated string
to another buffer */
if (cr1 == NULL)
errExit("strdup");
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = handler;
if (sigaction(SIGINT, &sa, NULL) == -1)
errExit("sigaction");
/* Repeatedly call crypt() using argv[1]. If interrupted by a
signal handler, then the static storage returned by crypt()
will be overwritten by the results of encrypting argv[2], and
strcmp() will detect a mismatch with the value in 'cr1'. */
for (callNum = 1, mismatch = 0; ; callNum++) {
if (strcmp(crypt(argv[1], "xx"), cr1) != 0) {
mismatch++;
printf("Mismatch on call %d (mismatch=%d handled=%d)\n",
callNum, mismatch, handled);
}
}
}
/*
output:
gerryyang@mba:signals$./nonreentrant abc 123
^CMismatch on call 831882 (mismatch=1 handled=1)
^CMismatch on call 1732096 (mismatch=2 handled=2)
^CMismatch on call 2463718 (mismatch=3 handled=3)
^CMismatch on call 2667081 (mismatch=4 handled=4)
^CMismatch on call 2821579 (mismatch=5 handled=5)
^\Quit: 3
*/