-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.cpp
157 lines (138 loc) · 4.02 KB
/
Main.cpp
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
#
# This software is Copyright by the Board of Trustees of Michigan
# State University (c) Copyright 2005.
#
# You may use this software under the terms of the GNU public license
# (GPL) ir the Tcl BSD derived license The terms of these licenses
# are described at:
#
# GPL: http://www.gnu.org/licenses/gpl.txt
# Tcl: http://www.tcl.tk/softare/tcltk/license.html
# Start with the second paragraph under the Tcl/Tk License terms
# as ownership is solely by Board of Trustees at Michigan State University.
#
# Author:
# Ron Fox
# NSCL
# Michigan State University
# East Lansing, MI 48824-1321
#
*/
/*!
\file Main.cpp
This file contains the unbound functions and the program entry point.
The inventory of functions includes:
- main - Program entry point.
- EpicsInit - Perform whatever initialization EPICS requires.
- startRepeater - Workaround to properly start/stop the caRepeater
process when it is not started by the system startup
scripts.
*/
#include <config.h>
#include "cmdline.h"
#include "CApplication.h"
#include <cadef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <CopyrightNotice.h>
#include <Iostream.h>
#include <string>
#include <Exception.h>
#ifdef HAVE_STD_NAMESPACE
using namespace std;
#endif
/*!
This function kludges around a problem with epics. It's supposed
to start up caRepeater, but evidently:
- It does that by forking and making caRepeater the parent process.
- the resulting caRepeater identifies to ps as us.
- After our process exits, the resulting caRepeater doesn't work quite
right but hangs around.
*/
void
startRepeater(int argc, char** argv)
{
string repeatername(EPICS_BIN);
repeatername += "/caRepeater";
int pid = fork();
if(pid < 0) { // Fork failed.
perror("Failed to fork in startRepeater()");
exit(errno);
}
else if (pid == 0) { // child process
if(daemon(0,0) < 0) {
perror("Child could not setsid");
exit(errno);
}
argv[0] = "caRepeater";
int stat = execlp(repeatername.c_str(),
repeatername.c_str(), NULL);
perror("Child: execlp failed!!");
exit(errno);
}
else { // Fork parent process..
usleep(1000); // Let it startup.
}
}
/*!
Initializes access to EPICS
\throw fatal exception caught by epics
on error.
*/
void EpicsInit(int argc, char** argv)
{
startRepeater(argc, argv);
int status = ca_task_initialize();
SEVCHK(status, "Initialization failed");
}
/*!
Actual program entry point. We parse the commands and, if that's
successful, creat an application object and invoke it.
*/
int
main(int argc, char** argv)
{
try {
gengetopt_args_info args;
cmdline_parser(argc, argv, &args); // exits on error.
// Ensure the user supplied a filename.
if(args.inputs_num != 1) {
cerr << "Missing channel input file.\n";
cmdline_parser_print_help();
exit(-1);
}
CopyrightNotice::Notice(cout, argv[0],
"1.0", "2004");
CopyrightNotice::AuthorCredit(cout, argv[0],
"Ron Fox", NULL);
EpicsInit(argc, argv);
CApplication app;
int status = app(args);
// In the future, maybe app can exit correctly... so...
if(status != 0) {
cerr << "Main application object exiting due to error\n";
}
return status;
}
catch (string message) {
cerr << "Main caught a string exception: " << message << endl;
cerr << "Exiting due to string exception " << endl;
}
catch (CException& failure) {
cerr << "Main caught an NSCL Exception object: " << failure.ReasonText()
<< endl;
cerr << "Exiting due to an NSCL Exception object\n";
}
catch (char* msg) {
cerr << "Main caught a char* exception: " << msg << endl;
cerr << "Exiting due to a char* exception " << endl;
}
catch (...) {
cerr << "Main caught an unanticipated exception type ... exiting \n";
}
exit(-1); // Exit due to exception.
}