Add PBD API to hard-link files
[ardour.git] / libs / pbd / transmitter.cc
1 /*
2  * Copyright (C) 1998-2015 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19
20 #include <cstdlib>
21 #include <signal.h>
22 #include <string>
23
24 #include "pbd/transmitter.h"
25 #include "pbd/error.h"
26
27 using std::string;
28 using std::ios;
29
30 Transmitter::Transmitter (Channel c)
31 {
32         channel = c;
33         switch (c) {
34         case Error:
35                 send = &error;
36                 break;
37         case Warning:
38                 send = &warning;
39                 break;
40         case Info:
41                 send = &info;
42                 break;
43         case Fatal:
44                 send = &fatal;
45                 break;
46         case Throw:
47                 /* we should never call Transmitter::deliver
48                    for thrown messages (because its overridden in the
49                    class heirarchy). force a segv if we do.
50                 */
51                 send = 0;
52                 break;
53         }
54 }
55
56 void
57 Transmitter::deliver ()
58
59 {
60         string foo;
61
62         /* NOTE: this is just a default action for a Transmitter or a
63            derived class. Any class can override this to produce some
64            other action when deliver() is called.
65         */
66
67         *this << '\0';
68
69         /* send the SigC++ signal */
70
71         foo = str();
72         (*send) (channel, foo.c_str());
73
74         /* XXX when or how can we delete this ? */
75         // delete foo;
76
77         /* return to a pristine state */
78
79         clear ();
80         seekp (0, ios::beg);
81         seekg (0, ios::beg);
82
83         /* do the right thing if this should not return */
84
85         if (does_not_return()) {
86 #ifndef PLATFORM_WINDOWS
87 // TODO !!!! Commented out temporarily (for Windows)
88                 sigset_t mask;
89
90                 sigemptyset (&mask);
91                 sigsuspend (&mask);
92                 /*NOTREACHED*/
93                 exit (EXIT_FAILURE);
94 /* JE - From what I can tell, the above code suspends
95  * program execution until (any) signal occurs. Not
96  * sure at the moment what this achieves, unless it
97  * provides some time for the user to see the message.
98  */
99 #endif
100         }
101 }
102
103 bool
104 Transmitter::does_not_return ()
105
106 {
107         if (channel == Fatal || channel == Throw) {
108                 return true;
109         } else {
110                 return false;
111         }
112 }
113
114
115 extern "C" {
116   void pbd_c_error (const char *str)
117
118   {
119         PBD::error << str << endmsg;
120   }
121 }