This is Unofficial EPICS BASE Doxygen Site
pvinfo.cpp
Go to the documentation of this file.
1 /*
2  * Copyright information and license terms for this software can be
3  * found in the file LICENSE that is included with the distribution
4  */
5 #include <iostream>
6 #include <pva/client.h>
7 #include <pv/caProvider.h>
8 
9 #include <stdio.h>
10 #include <epicsStdlib.h>
11 #include <epicsGetopt.h>
12 #include <epicsThread.h>
13 #include <pv/logger.h>
14 #include <pv/lock.h>
15 
16 #include <vector>
17 #include <string>
18 #include <sstream>
19 
20 #include <pv/event.h>
21 #include <epicsExit.h>
22 
23 #include "pvutils.h"
24 
25 namespace pvd = epics::pvData;
26 namespace pva = epics::pvAccess;
27 
28 namespace {
29 
30 void usage (void)
31 {
32  fprintf (stderr, "\nUsage: pvinfo [options] <PV name>...\n\n"
33  "\noptions:\n"
34  " -h: Help: Print this message\n"
35  " -V: Print version and exit\n"
36  " -w <sec>: Wait time, specifies timeout, default is %f second(s)\n"
37  " -p <provider>: Set default provider name, default is '%s'\n"
38  " -d: Enable debug output\n"
39  " -c: Wait for clean shutdown and report used instance count (for expert users)"
40  "\nExample: pvinfo double01\n\n"
41  , timeout, defaultProvider.c_str());
42 }
43 
44 int haderror;
45 
46 struct GetInfo : public pvac::ClientChannel::InfoCallback,
48  public Tracker
49 {
52 
53  std::string peerName;
54 
55  explicit GetInfo(pvac::ClientChannel& chan)
56  :chan(chan)
57  {
58  chan.addConnectListener(this);
59  }
60  virtual ~GetInfo()
61  {
62  chan.removeConnectListener(this);
63  }
64 
65  virtual void connectEvent(const pvac::ConnectEvent& evt) OVERRIDE FINAL
66  {
67  if(evt.connected) {
68  Guard G(doneLock);
69  peerName = evt.peerName;
70  }
71  }
72 
73  virtual void infoDone(const pvac::InfoEvent& evt) OVERRIDE FINAL
74  {
75  std::string pname;
76  {
77  Guard G(doneLock);
78  pname = peerName;
79  }
80 
81  switch(evt.event) {
82  case pvac::InfoEvent::Cancel: break;
84  std::cerr<<op.name()<<" Error: "<<evt.message<<"\n";
85  haderror = 1;
86  break;
88  std::cout<<op.name()<<"\n"
89  "Server: "<<pname<<"\n"
90  "Type:\n";
91  pvd::format::indent_scope I(std::cout);
92  std::cout<<evt.type<<"\n";
93  }
94  }
95  done();
96  std::cout.flush();
97  }
98 };
99 
100 } // namespace
101 
102 
103 int main (int argc, char *argv[])
104 {
105  int opt; /* getopt() current option */
106  bool debug = false;
107 
108  setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */
109 
110  while ((opt = getopt(argc, argv, ":hVw:p:dc")) != -1) {
111  switch (opt) {
112  case 'h': /* Print usage */
113  usage();
114  return 0;
115  case 'V': /* Print version */
116  {
117  fprintf(stdout, "pvAccess %u.%u.%u%s\n",
118  EPICS_PVA_MAJOR_VERSION,
119  EPICS_PVA_MINOR_VERSION,
120  EPICS_PVA_MAINTENANCE_VERSION,
121  (EPICS_PVA_DEVELOPMENT_FLAG)?"-SNAPSHOT":"");
122  fprintf(stdout, "pvData %u.%u.%u%s\n",
123  EPICS_PVD_MAJOR_VERSION,
124  EPICS_PVD_MINOR_VERSION,
125  EPICS_PVD_MAINTENANCE_VERSION,
126  (EPICS_PVD_DEVELOPMENT_FLAG)?"-SNAPSHOT":"");
127  fprintf(stdout, "Base %s\n", EPICS_VERSION_FULL);
128  return 0;
129  }
130  case 'w': /* Set PVA timeout value */
131  {
132  double temp;
133  if((epicsScanDouble(optarg, &temp)) != 1 || timeout <= 0.0)
134  {
135  fprintf(stderr, "'%s' is not a valid timeout value "
136  "- ignored. ('pvget -h' for help.)\n", optarg);
137  } else {
138  timeout = temp;
139  }
140  }
141  break;
142  case 'p': /* Set default provider */
144  break;
145  case 'd': /* Debug log level */
146  debug = true;
147  break;
148  case 'c': /* Clean-up and report used instance count */
149  break;
150  case '?':
151  fprintf(stderr,
152  "Unrecognized option: '-%c'. ('pvinfo -h' for help.)\n",
153  optopt);
154  return 1;
155  case ':':
156  fprintf(stderr,
157  "Option '-%c' requires an argument. ('pvinfo -h' for help.)\n",
158  optopt);
159  return 1;
160  default :
161  usage();
162  return 1;
163  }
164  }
165 
166  if (argc == optind)
167  {
168  fprintf(stderr, "No pv name(s) specified. ('pvinfo -h' for help.)\n");
169  return 1;
170  }
171 
173 
174  std::vector<std::tr1::shared_ptr<GetInfo> > infos;
175 
176  pva::ca::CAClientFactory::start();
177 
178  {
180 
181  for(int i = optind; i<argc; i++) {
182  pvac::ClientChannel chan(prov.connect(argv[i]));
183  std::tr1::shared_ptr<GetInfo> info(new GetInfo(chan));
184  info->op = chan.info(info.get());
185  infos.push_back(info);
186  }
187 
188  Tracker::prepare(); // install signal handler
189 
190  {
192  while(Tracker::inprog.size() && !Tracker::abort) {
193  UnGuard U(G);
194  if(timeout<=0)
195  Tracker::doneEvt.wait();
196  else if(!Tracker::doneEvt.wait(timeout)) {
197  haderror = 1;
198  std::cerr<<"Timeout\n";
199  break;
200  }
201  }
202  }
203  }
204 
205  return haderror ? 1 : 0;
206 }
double timeout
Definition: pvutils.cpp:25
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: epicsGetopt.c:65
static epicsMutex doneLock
Definition: pvutils.h:47
int i
Definition: scan.c:967
int main(int argc, char *argv[])
Definition: pvinfo.cpp:103
int optind
Definition: epicsGetopt.c:50
std::string name() const
Channel name.
Definition: client.cpp:131
static void prepare()
Definition: pvutils.cpp:49
#define SET_LOG_LEVEL(level)
Definition: logger.h:50
static epicsEvent doneEvt
Definition: pvutils.h:48
#define NULL
Definition: catime.c:38
#define epicsScanDouble(str, to)
Definition: epicsStdlib.h:78
#define OVERRIDE
Definition: pvAccess.h:55
Handle for in-progress get/put/rpc operation.
Definition: client.h:50
int optopt
Definition: epicsGetopt.c:50
Holds all PVA related.
Definition: pvif.h:34
pvData
Definition: monitor.h:428
static inprog_t inprog
Definition: pvutils.h:50
Connection state change CB.
Definition: client.h:448
Extended replacement for the Posix exit and atexit routines.
information on connect/disconnect
Definition: client.h:237
#define stdout
Definition: epicsStdio.h:30
Central client context.
Definition: client.h:517
request cancelled before completion
Definition: client.h:92
ClientChannel connect(const std::string &name, const ClientChannel::Options &conf=ClientChannel::Options())
Definition: client.cpp:295
request ends in failure. Check message
Definition: client.h:91
void done(int k)
Definition: antelope.c:77
Operation info(InfoCallback *cb, const std::string &subfld=std::string())
Definition: clientInfo.cpp:99
#define stderr
Definition: epicsStdio.h:32
ChannelPut::shared_pointer op
Definition: pvAccess.cpp:132
const std::string pname
C++ and C descriptions for a thread.
std::string defaultProvider
char * optarg
Definition: epicsGetopt.c:55
static bool abort
Definition: pvutils.h:51
void removeConnectListener(ConnectCallback *)
Remove from list of listeners.
Definition: client.cpp:185
void usage(void)
Definition: cainfo.c:36
It worked!
Definition: client.h:93
#define FINAL
Definition: pvAccess.h:48
void addConnectListener(ConnectCallback *)
Definition: client.cpp:163