"Fossies" - the Fresh Open Source Software Archive 
Member "pigz-2.8/try.c" (12 Apr 2021, 2616 Bytes) of package /linux/privat/pigz-2.8.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "try.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
2.6_vs_2.7.
1 /* try.c -- try / catch / throw exception handling for C99
2 * For copyright, version, and conditions of distribution and use, see try.h
3 */
4
5 /* See try.h for documentation. This source file provides the global pointer
6 and the functions needed by throw(). The pointer is thread-unique if
7 pthread.h is included in try.h. */
8
9 #include "try.h"
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdarg.h>
13
14 /* Set up the try stack with a global pointer to the next try block. The
15 global is thread-unique if pthread.h is included in try.h. */
16 #ifdef PTHREAD_ONCE_INIT
17 pthread_key_t try_key_;
18 static pthread_once_t try_once_ = PTHREAD_ONCE_INIT;
19 static void try_create_(void)
20 {
21 int ret = pthread_key_create(&try_key_, NULL);
22 assert(ret == 0 && "try: pthread_key_create() failed");
23 }
24 void try_setup_(void)
25 {
26 int ret = pthread_once(&try_once_, try_create_);
27 assert(ret == 0 && "try: pthread_once() failed");
28 }
29 #else /* !PTHREAD_ONCE_INIT */
30 try_t_ *try_stack_ = NULL;
31 #endif /* PTHREAD_ONCE_INIT */
32
33 /* Throw an exception. This must always have at least two arguments, where the
34 second argument can be a NULL. The throw() macro is permitted to have one
35 argument, since it appends a NULL argument in the call to this function. */
36 void try_throw_(int code, char *fmt, ...)
37 {
38 /* save the thrown information in the try stack before jumping */
39 try_setup_();
40 assert(try_stack_ != NULL && "try: naked throw");
41 try_stack_->ball.ret = 1;
42 try_stack_->ball.code = code;
43 try_stack_->ball.free = 0;
44 try_stack_->ball.why = fmt;
45
46 /* consider the second argument to be a string, and if it has formatting
47 commands, process them with the subsequent arguments of throw, saving
48 the result in allocated memory -- this if statement and clause must be
49 updated for a different interpretation of the throw() arguments and
50 different contents of the ball_t structure */
51 if (fmt != NULL && strchr(fmt, '%') != NULL) {
52 char *why, nul[1];
53 size_t len;
54 va_list ap1, ap2;
55
56 va_start(ap1, fmt);
57 va_copy(ap2, ap1);
58 len = vsnprintf(nul, 1, fmt, ap1);
59 va_end(ap1);
60 why = malloc(len + 1);
61 if (why == NULL)
62 try_stack_->ball.why = "try: out of memory";
63 else {
64 vsnprintf(why, len + 1, fmt, ap2);
65 va_end(ap2);
66 try_stack_->ball.free = 1;
67 try_stack_->ball.why = why;
68 }
69 }
70
71 /* jump to the end of the nearest enclosing try block */
72 longjmp(try_stack_->env, 1);
73 }