Compare commits

...

199 Commits

Author SHA1 Message Date
Janet B. Anderson
25a6340993 Added filio.h include for solaris build. 1995-11-13 16:55:03 +00:00
Jeff Hill
a3652fd54e improvents for better client reconnect 1995-11-08 23:48:26 +00:00
Jeff Hill
107ae2cee8 fixed log client reconnect problems 1995-11-08 23:46:27 +00:00
Jeff Hill
deb5e9c973 add log entries 1995-11-08 23:45:10 +00:00
Jeff Hill
196f2302a4 changes associated with fixing the log client 1995-11-08 23:44:41 +00:00
Jeff Hill
2a21b01b0e fixed bug occuring when diagnostic is printed and the env var cant be found 1995-11-08 23:43:51 +00:00
Jeff Hill
56465da07f log entries changed 1995-11-08 23:38:41 +00:00
Jeff Hill
ee9457970a changes froim chris T 1995-11-08 23:36:31 +00:00
Jeff Hill
89a3746869 changes from Chris T 1995-11-08 23:20:56 +00:00
Janet B. Anderson
5be8f4999d Removed "-s" compile option 1995-11-08 19:28:51 +00:00
Marty Kraimer
b278c803ce When calling db_post_event for argument fields ass DBE_LOG 1995-11-08 15:01:36 +00:00
Jeff Hill
50b8361078 more changes from Chris Timossi 1995-10-25 16:46:01 +00:00
Jeff Hill
2a121a4276 changes from Chris Timossi 1995-10-24 21:21:31 +00:00
Jeff Hill
7b03ab0182 Changes to avoid spurious ECONREFUSED returned from recvfrom() under linux 1995-10-22 22:27:47 +00:00
cvs2svn
73a224a6ce This commit was manufactured by cvs2svn to create tag 'R3.12.1.4'. 1995-10-20 20:21:33 +00:00
Marty Kraimer
f4af420e22 Changes to make stop work 1995-10-20 20:21:32 +00:00
Janet B. Anderson
b0177729b8 Sequencer V1.9.0(3.12.1) form lanl. 1995-10-19 21:35:38 +00:00
Jeff Hill
c7b5592846 make certain we dont use CPU while waiting for a flush to complete 1995-10-19 20:37:19 +00:00
Janet B. Anderson
2f5202a4e4 Assume no DST if tsMinWest is 600 (includes Hawaii and may be exclusively
Hawaii?). (WFL, 95/08/15)
1995-10-19 13:54:50 +00:00
Ned Arnold
ecb106fb71 WAIT Record Version 3.01, channel access dynamic links 1995-10-19 13:42:38 +00:00
Ned Arnold
b637c15e18 SCAN Record Version 3.00. Many changes. 1995-10-19 13:41:47 +00:00
Jeff Hill
d1102b06c0 recv task is now running at a lower priority than the send task under vxWorks 1995-10-18 16:49:23 +00:00
Jeff Hill
2fb23fd27b Use recast delay greater than one vxWorks tick 1995-10-18 16:45:40 +00:00
Jeff Hill
752b7e257e select time out must be greater than a vxWorks tick 1995-10-18 16:44:36 +00:00
John Quintana
025b13b977 *** empty log message *** 1995-10-12 20:50:36 +00:00
Jeff Hill
4c2822dd2e added SOLARIS ifdef around ioctl includes 1995-10-12 18:55:22 +00:00
Jeff Hill
9dcee4c068 removed unused variable 1995-10-12 18:54:41 +00:00
Janet B. Anderson
9bf802557e Updated for R3.12.1.3 1995-10-12 17:09:20 +00:00
Jeff Hill
2566ee1e26 If the IOC is out of memory allow them to connect if they stop
some of the clients.
1995-10-12 01:40:48 +00:00
Jeff Hill
5a16ba053b Changes from Bob Dalesio:
lrd     fix init to limit in overshoot check and retry post monitors
	   for mcw and mccw reprocess records if the setpoint changed
	   while they were moving
1995-10-12 01:38:41 +00:00
Jeff Hill
ad3e5a3272 New ca_flush_io() mechanism 1995-10-12 01:36:39 +00:00
Jeff Hill
17511136a1 Use of port is consistent unsigned short now 1995-10-12 01:36:13 +00:00
Jeff Hill
ffa22f89bd Moved cac_mux_io() to iocinf.c 1995-10-12 01:35:33 +00:00
Jeff Hill
2e7075bd31 Dont include filio.h and sockio.h. They are included by ioctl.h
and dont exist under linux.
1995-10-12 01:34:00 +00:00
Jeff Hill
278eaf84d7 Initial delay between search frames went from .1 to .01 sec,
Added flush pending flag, Make all usage of port be unsigned short.
1995-10-12 01:33:12 +00:00
Jeff Hill
d957aebbf4 make the use of unsigend short for a port consistent. Moved
cac_mux_io() out of os dependent code and into this module.
Added caSendMsgPending() routine.
1995-10-12 01:31:54 +00:00
Jeff Hill
5ac2a99686 improved the test 1995-10-12 01:30:28 +00:00
Jeff Hill
b782f63a7d new ca_flush_io() mechanism prevents deadlock when they call
ca_flush_io() from within an event routine. Also forces early
transmission of leading search UDP frames.
1995-10-12 01:30:10 +00:00
Marty Kraimer
e62f7d0ae2 cvtDoubleToString: honor precision for wierd numbers 1995-10-11 19:42:52 +00:00
Marty Kraimer
1ca96e0116 recGblGetAlarmDouble was not setting upper_warning_limit and lower_alarm_limit 1995-10-11 19:41:22 +00:00
Andrew Johnson
44d65d9477 Fixed main() for use as host tool - was *really* broken. 1995-10-04 20:42:05 +00:00
Andrew Johnson
dc3ba94fc8 Updated for Solaris Native mode compilation instructions. 1995-10-03 22:52:50 +00:00
Andrew Johnson
41ad7ae2ab Generating LIBOBJS automatically from SRCS.c 1995-10-03 21:18:50 +00:00
Andrew Johnson
017c55f9d9 Generating TARGETS automatically from SRCS.c 1995-10-03 21:13:45 +00:00
Andrew Johnson
196d7538c3 Generating LIBOBJS automatically from SRCS.c 1995-10-03 21:04:57 +00:00
Andrew Johnson
5ace66b609 Generating LIBOBJS automatically from SRCS.c 1995-10-03 20:59:44 +00:00
cvs2svn
0be218bed4 This commit was manufactured by cvs2svn to create tag 'R3.12.1.3'. 1995-10-03 15:42:27 +00:00
Janet B. Anderson
297f0b8c31 Added *COPYRIGHT* files to release tar file. 1995-10-03 15:42:26 +00:00
Jeff Hill
cc20412693 added locking for previous change 1995-09-29 22:53:38 +00:00
Jeff Hill
7021cd3589 use unsigned short for port 1995-09-29 22:18:53 +00:00
Jeff Hill
b7acf453c2 added arch independent type 1995-09-29 22:17:57 +00:00
Jeff Hill
c9abc2c82e ms windows changes 1995-09-29 22:17:13 +00:00
Jeff Hill
a7484494c4 changes from LBL 1995-09-29 22:15:26 +00:00
Jeff Hill
52cfbe92bf check for nill dbr pointer 1995-09-29 22:13:59 +00:00
Jeff Hill
75f0fb2b0c allow server to refuse to create a channel without a client disconnect 1995-09-29 22:13:05 +00:00
Jeff Hill
ed36723d6c ms windows changes 1995-09-29 21:58:16 +00:00
Jeff Hill
f7a5da9139 added minor version 6 which allows the server to refuse to create a channel
without disconnecting the client
1995-09-29 21:57:11 +00:00
Jeff Hill
254c5b1620 added func proto for cacDisconnectChannel() 1995-09-29 21:55:38 +00:00
Jeff Hill
c6aab85d79 MS windows changes and added cacDisconnectChannel() 1995-09-29 21:54:40 +00:00
Jeff Hill
d54724fce1 MS windows changes 1995-09-29 21:48:33 +00:00
Jeff Hill
60c0acab3c MS windows changes 1995-09-29 21:47:58 +00:00
Jeff Hill
69f33b9e23 alignment fix for SPARC IOC client and changes to prevent running of
access rights or connection handlers when the connection is lost just
after deleting a channel
1995-09-29 21:47:33 +00:00
Janet B. Anderson
9191863094 Added test for Linux. 1995-09-27 22:09:43 +00:00
Marty Kraimer
1beb157ab0 new database access has units as 16 char null terminated. old has 8 char null 1995-09-27 19:54:50 +00:00
Marty Kraimer
41ae285075 copy units string using DB_UNITS_SIZE 1995-09-27 19:52:45 +00:00
John Winans
222063ac53 Added code to send last byte of a RAC_RESET in pepTxTask(). It was left
out in a previous mod that modes the last byte transmission into a locked
region in order to prevent a TxTask/RxTask race condition.
1995-09-26 14:50:31 +00:00
Janet B. Anderson
3342ca120f Specified return type of functions. 1995-09-21 19:48:26 +00:00
cvs2svn
13b785e594 This commit was manufactured by cvs2svn to create tag 'R3.12.1.2'. 1995-09-13 18:27:49 +00:00
Jim Kowalkowski
6931273fef New utilities to list PVs on an IOC and loaded applications. 1995-09-13 18:27:48 +00:00
Jim Kowalkowski
8d52177933 Fixed the address of ioc by name in BSlib.c.
Added app list to the services of PVSvx.
Removed rdbls from PVSserver - made it a separate file.
1995-09-13 18:26:42 +00:00
Jim Kowalkowski
b64fa8bd87 Fixed bug in TSinit - Gives defaults to TSdirectTime() and TSdriverInit() if
event time disabled with TSconfigure().
1995-09-12 15:01:09 +00:00
Janet B. Anderson
34ce2ab6ac Added include for sockio and a cast for tsin in memset. 1995-09-08 14:56:30 +00:00
Jim Kowalkowski
43ef20b90c Completed first version of vx info server and workstation utility.
Removed the stupid program PVSget.
1995-09-07 21:25:59 +00:00
Jim Kowalkowski
818bc0d475 New library and PV dump programs for IOC and client workstation 1995-09-06 21:06:07 +00:00
Jim Kowalkowski
ca2f9aff52 Corrected a problem with building dbLoadTemplate/subtool.
Added the BS and PVS test functions
1995-09-06 21:05:09 +00:00
Jim Kowalkowski
64a93df872 Changed the error message 1995-09-06 21:04:22 +00:00
Jim Kowalkowski
ecc03e9ad9 Cleanup and addition of application() to db file 1995-09-06 21:03:07 +00:00
John Winans
db1b46e5f9 Added ability to change default clock speed from shell. 1995-09-01 14:36:35 +00:00
Marty Kraimer
d87295397e Still new 1995-09-01 14:35:27 +00:00
Marty Kraimer
7277c336f7 Fixed bug causing memory problem 1995-09-01 14:31:32 +00:00
Marty Kraimer
30ad5b1149 Added so that individual files dont have to have long notice 1995-09-01 12:47:28 +00:00
Marty Kraimer
c6bcd1a10b Still new 1995-08-30 21:31:43 +00:00
Marty Kraimer
f3cf369071 made separate from recDynLink 1995-08-30 21:18:29 +00:00
Marty Kraimer
adffe02a2d Still new 1995-08-30 21:17:46 +00:00
Marty Kraimer
e635080cef Fixed problems with freeing pvd 1995-08-30 17:43:19 +00:00
Jim Kowalkowski
be85da6a3a *** empty log message *** 1995-08-30 15:38:39 +00:00
Marty Kraimer
c16006f34d recDynLink is new 1995-08-29 17:55:20 +00:00
Janet B. Anderson
72491d8829 Added startup directory to release tar file 1995-08-28 15:49:54 +00:00
Marty Kraimer
cb78c5adb8 Changes so that function prototype for db_post_event defined 1995-08-28 14:50:32 +00:00
Jeff Hill
1a2cd5953d added log entries 1995-08-23 00:35:17 +00:00
Jeff Hill
5da79a5f56 fixed vxWorks specific SPARC data alignment problem 1995-08-23 00:34:06 +00:00
Jeff Hill
9f2d9587f0 additional parenthesis in macro to be safe 1995-08-23 00:31:13 +00:00
cvs2svn
74e405969a This commit was manufactured by cvs2svn to create tag 'R3.12.1.1'. 1995-08-22 12:23:38 +00:00
Marty Kraimer
89a6d17353 Added argument verbose to dbPvdDump 1995-08-22 12:23:37 +00:00
Jeff Hill
d9666a8f30 added cvs style mod log 1995-08-22 00:27:59 +00:00
Jeff Hill
7cb76ae9e4 dont recompute connection time outs if the time stamp doesnt change 1995-08-22 00:25:22 +00:00
Jeff Hill
46e00da251 recompute the current time variable after waiting in a semaphore
(instead of select)
1995-08-22 00:24:38 +00:00
Jeff Hill
39d98562fc dont recompute connection timers if the time stamp hasnt changed 1995-08-22 00:23:36 +00:00
Jeff Hill
8624be05d4 Dont wait for itsy bitsy delays to expire 1995-08-22 00:22:52 +00:00
Jeff Hill
c0da182217 Dont recompute connection timers if the time stamp hasnt changed 1995-08-22 00:22:07 +00:00
Jeff Hill
6dab97f8e7 added KLUDGE def of S_db_Pending 1995-08-22 00:20:27 +00:00
Jeff Hill
1abcc71e71 use current time var to init time stamp in a beacon hash entry 1995-08-22 00:19:21 +00:00
Jeff Hill
f8f17eeb33 comments changed 1995-08-22 00:17:11 +00:00
Jeff Hill
db50e1bdd7 Added test of the duration of ca_pend_event() 1995-08-22 00:16:34 +00:00
Jeff Hill
96605d4439 Use 1.0/USEC_PER_SEC and not 1.0e-6
Check for S_db_Pending when calling dbPutNotify()
1995-08-22 00:15:19 +00:00
Jeff Hill
593bc413bf *** empty log message *** 1995-08-22 00:12:07 +00:00
Marty Kraimer
3e20abece8 When initing new card wait yp to 3 seconds to read old values. 1995-08-18 17:59:09 +00:00
Marty Kraimer
79c01170e8 db_post_event had illegal arg for val field 1995-08-18 15:22:28 +00:00
Marty Kraimer
6c21758d23 fixed 2nd arg of db_post_event for clcv 1995-08-18 15:11:35 +00:00
Marty Kraimer
d2347c497c Changes for ansi c 1995-08-18 15:07:32 +00:00
Marty Kraimer
099f63fb20 Made changes for ansi c 1995-08-18 13:19:37 +00:00
Jeff Hill
665a5134d3 send flush message when we see a new client 1995-08-18 00:30:07 +00:00
Jim Kowalkowski
e1b04e69bb fixed all the -pendantic errors (pain) 1995-08-17 20:35:09 +00:00
Janet B. Anderson
8375a2cf18 Moved bldEnvData,blderrSymTbl, makeStatTbl to libCom dir 1995-08-17 20:22:13 +00:00
Janet B. Anderson
300f38584b Added base/tools scripts functionality to base/Makefile, removed scripts
Moved base/tools/MakeRelease to base dir.
1995-08-17 20:15:03 +00:00
Janet B. Anderson
b9a5acc88c Fixed comment that broke during previous commit 1995-08-17 19:49:52 +00:00
Jim Kowalkowski
2ff81c09f0 Completed the accurate time stamp change. event number 0 is current time
updated at 60HZ, event -1 is the best time that can be provided (1000Hz in
the APS event system).  The vxWorks time is now correct (1970 instead of
1900).
1995-08-17 19:43:04 +00:00
Janet B. Anderson
63eefd2ba8 Makefile now uses library build rule from RULES.Vx 1995-08-17 15:43:34 +00:00
Janet B. Anderson
f9f8e55035 Moved cvtBpt.c to db dir so libCom builds without record header dependancies 1995-08-17 15:39:10 +00:00
Janet B. Anderson
0f8f36c4bb Makefile now uses library build rule from RULES.Vx
Moved cvtBpt.c to db dir so libCom builds without record header dependancies
1995-08-17 15:38:03 +00:00
Janet B. Anderson
fd6e666256 Makefile now uses library build rule from RULES.Vx 1995-08-17 15:33:47 +00:00
Janet B. Anderson
d492d665fc Moved cvtBpt.c from libCom so libCom now has no record header dependancies 1995-08-17 15:31:42 +00:00
Janet B. Anderson
6b659e8404 Makefile now uses library build rule from RULES.Vx.
Moved cvtBpt.c from libCom so libCom now has no record header dependancies
1995-08-17 15:31:24 +00:00
Janet B. Anderson
43ecde53f3 Makefile now uses library build rule from RULES.Vx,removed redundant rules. 1995-08-17 15:28:32 +00:00
Janet B. Anderson
e6ffa71c54 Removed redundant rules. 1995-08-17 15:27:11 +00:00
Janet B. Anderson
be6ecdfe24 Makefile now uses library build rule from RULES.Vx 1995-08-17 15:25:45 +00:00
Marty Kraimer
e6bec6af38 mrk committed for dalesio 1995-08-17 14:51:53 +00:00
Marty Kraimer
59a2f10867 Initialize oval properly 1995-08-17 14:50:43 +00:00
Marty Kraimer
00abe6b876 Removed recSwitch 1995-08-17 14:50:17 +00:00
Marty Kraimer
b0e9cc9fba Made changes so that it doesnt call dbCalloc 1995-08-17 14:48:02 +00:00
Marty Kraimer
6eb04984bd Removed epicsSetEnvParams 1995-08-17 14:47:40 +00:00
Marty Kraimer
d9a05d6051 added abConfigScanListAscii and abConfigAuto 1995-08-17 14:45:57 +00:00
Marty Kraimer
d9233e4864 ansi changes 1995-08-17 14:43:49 +00:00
Marty Kraimer
34bd710ffa Removed INITHOOKafterSetEnvParams 1995-08-17 14:42:43 +00:00
Marty Kraimer
438f00a708 Changes to make more ansi compatible 1995-08-17 14:42:12 +00:00
Marty Kraimer
622a225308 Changed hash algorithm to allow larger table sizes 1995-08-17 14:41:05 +00:00
Marty Kraimer
1c14ac4941 post_event and scanOnce no longer give error message storms for ring buffer overflows.
Made changes so that casts are ANSI C compatible
1995-08-17 14:39:46 +00:00
Marty Kraimer
df2ce01069 Made change for new putNotify 1995-08-17 14:36:54 +00:00
Marty Kraimer
f7aa394524 Changed algorithm for computing lock sets.
No longer calls epicsSetEnvParams.
1995-08-17 14:36:29 +00:00
Marty Kraimer
ed6047ec51 Many changes. It should now work in all cases( I hope). 1995-08-17 14:35:47 +00:00
Marty Kraimer
a3573cd384 If record should be processed because of put and record is active and TPRO is true then print active message.
Fixed some casts so that they are ANSI compatible
putStringUshort converts to float first then to ushort
putStringUlong converts to double first then to unsigned long
1995-08-17 14:34:55 +00:00
Marty Kraimer
81deb4fceb Use new hash algorirthm. New variable dbPvdHashTableSize can be set after ld < iocCore 1995-08-17 14:33:55 +00:00
Marty Kraimer
b7378bbc62 Added -Wall -pedantic -ansi 1995-08-17 14:33:18 +00:00
Marty Kraimer
bdffdb0369 If asSetFilename is given NULL argument then next call to asInit turns off access security.
Allow character '-' in pvnames.
1995-08-17 14:31:52 +00:00
Ned Arnold
98809f8141 made QUEUE_SIZE a global variable so users could control mallocing 1995-08-16 20:53:26 +00:00
Jim Kowalkowski
8a0f66cb9b Corrected multiple card bug. 1995-08-16 19:15:07 +00:00
Jim Kowalkowski
0462aed01d Many updates. Added GPS ability and adjusted the printf's. 1995-08-16 19:03:21 +00:00
Jim Kowalkowski
ea279855da Allow for ~ in both pv name and value. 1995-08-16 18:16:43 +00:00
Jeff Hill
66210afed7 epicsAPI => epicsShareAPI 1995-08-14 19:26:15 +00:00
Jeff Hill
c13d342680 fixed compilation error 1995-08-14 16:08:08 +00:00
Jeff Hill
549a4ba978 func proto added 1995-08-12 01:20:36 +00:00
Jeff Hill
cf7fe3deb4 force double alignment of the protocol buffer 1995-08-12 01:18:28 +00:00
Jeff Hill
ef8abaa44f keep trying 1995-08-12 01:17:38 +00:00
Jeff Hill
5624aaefe1 fetch the server's port number 1995-08-12 01:16:26 +00:00
Jeff Hill
2b7e4ff84d dont quit if client unreachable 1995-08-12 01:15:08 +00:00
Jeff Hill
fb2c2f0925 dont reuse res id 1995-08-12 01:14:22 +00:00
Jeff Hill
55dae7db1c no dbg lib 1995-08-12 01:13:30 +00:00
Jeff Hill
524da0d2df doc 1995-08-12 01:12:37 +00:00
Jeff Hill
93c191ffe9 windows NT changes 1995-08-12 01:11:53 +00:00
Jeff Hill
0dc2be41d3 dont allow res id reuse 1995-08-12 01:10:57 +00:00
Jeff Hill
11af4456c7 dont return (and leak memory) 1995-08-12 01:10:25 +00:00
Jeff Hill
f232999d32 dont print if the format is NULL 1995-08-12 01:04:11 +00:00
Jeff Hill
ca13bfdff9 dont call vprintf if pformat is NULL 1995-08-12 01:03:17 +00:00
Jeff Hill
21cbea930a added casdef.h 1995-08-12 01:02:39 +00:00
Jeff Hill
8b06e22907 added return to print func 1995-08-12 01:02:11 +00:00
Jeff Hill
f3dcfd60bb dont allow reallocation of the same res id
use std EPICS status
1995-08-12 01:01:20 +00:00
Jeff Hill
1b33e449c6 use $log in header 1995-08-12 01:00:07 +00:00
Jeff Hill
afa208a5e1 use $log in header 1995-08-12 00:59:11 +00:00
Jeff Hill
5903ff0cdb use arch independent types 1995-08-12 00:48:21 +00:00
Jeff Hill
51d44c6200 use epicsApi 1995-08-12 00:44:13 +00:00
Jeff Hill
a362731044 use const in proto 1995-08-12 00:43:41 +00:00
Jeff Hill
0e225a4335 use epicsEntry 1995-08-12 00:42:23 +00:00
Jeff Hill
8c0527c25a dont allow res id reuse 1995-08-12 00:41:52 +00:00
Jeff Hill
92f91ee2cc allow multiple servers on one machine 1995-08-12 00:40:58 +00:00
Jeff Hill
1bd52dfef9 discover loss of client by connecting UDP sockets 1995-08-12 00:37:28 +00:00
Jeff Hill
c7005b4783 dont muck with signal handlers already installed 1995-08-12 00:31:37 +00:00
Jeff Hill
d9e3f09760 win NT changes 1995-08-12 00:30:24 +00:00
Jeff Hill
07a265d299 added const 1995-08-12 00:29:39 +00:00
Jeff Hill
feb73d85b3 bumbed CA minor version to 5 1995-08-12 00:28:58 +00:00
Jeff Hill
f18238a8b9 added shareLib.h and const to proto 1995-08-12 00:28:10 +00:00
Jeff Hill
8ff5572e6c linux changes 1995-08-12 00:27:24 +00:00
Jeff Hill
865e69d7d3 added const to func proto 1995-08-12 00:26:26 +00:00
Jeff Hill
38f82f342d new ca_pend_event() duration test 1995-08-12 00:25:34 +00:00
Jeff Hill
20fd27263a sped up ca_pend_event() poll 1995-08-12 00:24:58 +00:00
Jeff Hill
7760d16956 better fp test 1995-08-12 00:24:26 +00:00
Jeff Hill
3fab82780b check for res id in use, epicsEntry, dont wait for itsy bitsy delay
in ca_pend_event(), better clean up when monitor is deleted and
we are disconnected
1995-08-12 00:23:32 +00:00
Jeff Hill
fd679234dd doc 1995-08-12 00:18:59 +00:00
Ned Arnold
7f949f441b Corrected bug of not allocating space for .dola : Multiple records with DOLN's did not work. 1995-08-07 15:36:37 +00:00
John Winans
48640936f5 Changed the parameter table and associated support routines to support
buffer length specifications of size long instead of short.
1995-07-31 19:44:18 +00:00
John Winans
1e2d258c66 first release 1995-07-27 14:23:02 +00:00
John Winans
83d4ee2313 Changed the way send() is called to account for structure padding. 1995-05-30 14:45:44 +00:00
Jeff Hill
67324dc7b7 use DBR_STRING parameter instead of just zero 1995-05-23 20:45:08 +00:00
Jim Kowalkowski
47843d49a0 updates to allow direct read of time stamps from event systems 1995-05-22 15:21:39 +00:00
John Winans
d27f70a883 Aded logic to handle the new BdtEof protocol state. 1995-05-16 15:39:27 +00:00
Jim Kowalkowski
bcde03d0a0 new functions to support the bulk data transfer 1995-05-11 02:10:50 +00:00
Andrew Johnson
1887fbd7f8 Added CONFIG_SITE_ENV, changed envData to .c file 1995-05-04 09:49:18 +00:00
Andrew Johnson
f3e0f33d15 Fixed port4_5 / port6_7 swap in bo_driver 1995-05-01 17:16:23 +00:00
cvs2svn
09e1c40650 This commit was manufactured by cvs2svn to create tag 'R3.12.1'. 1995-04-26 14:17:01 +00:00
cvs2svn
0de34c3162 This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta13'. 1995-04-26 14:17:00 +00:00
177 changed files with 15152 additions and 7053 deletions

View File

@@ -0,0 +1,45 @@
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
AND IN ALL SOURCE LISTINGS OF THE CODE.
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
Argonne National Laboratory (ANL), with facilities in the States of
Illinois and Idaho, is owned by the United States Government, and
operated by the University of Chicago under provision of a contract
with the Department of Energy.
Portions of this material resulted from work developed under a U.S.
Government contract and are subject to the following license: For
a period of five years from March 30, 1993, the Government is
granted for itself and others acting on its behalf a paid-up,
nonexclusive, irrevocable worldwide license in this computer
software to reproduce, prepare derivative works, and perform
publicly and display publicly. With the approval of DOE, this
period may be renewed for two additional five year periods.
Following the expiration of this period or periods, the Government
is granted for itself and others acting on its behalf, a paid-up,
nonexclusive, irrevocable worldwide license in this computer
software to reproduce, prepare derivative works, distribute copies
to the public, perform publicly and display publicly, and to permit
others to do so.
*****************************************************************
DISCLAIMER
*****************************************************************
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
OWNED RIGHTS.
*****************************************************************
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).

140
MakeRelease Executable file
View File

@@ -0,0 +1,140 @@
#!/bin/sh
#
# $Id$
#
# Make Release - Creates an EPICS release
# By Matthew Needes and Bob Zieman
#
# MakeRelease [-b]
#
# [-b] - For fully built release
#
# $Log$
# Revision 1.2 1995/08/28 15:49:54 jba
# Added startup directory to release tar file
#
# Revision 1.1 1995/08/17 20:14:56 jba
# Added base/tools scripts functionality to base/Makefile, removed scripts
# Moved base/tools/MakeRelease to base dir.
#
# Revision 1.14 1994/12/19 18:42:08 tang
# Make the args length compatible for HP and SUN.
#
# Revision 1.13 1994/12/15 19:19:18 tang
# Replace -I opt by cat and xargs for tar for HP compatibility.
#
# Revision 1.12 1994/12/14 23:57:55 tang
# Take out \< and \> pair for hp compatible
#
# Revision 1.11 1994/10/31 21:44:17 jba
# Moved print stmnt, added cd $(EPICS)
#
# Revision 1.10 1994/10/05 18:29:34 jba
# Renamed version.h to epicsVersion.h
#
# Revision 1.9 1994/09/22 01:41:47 mcn
# MakeRelease - MAJOR bug fix. GetVar / MakeDirs - minor fix.
#
# Revision 1.8 1994/09/07 20:59:15 mcn
# Revamped GetVar, modified scripts for new GetVar.
#
# Revision 1.7 1994/09/02 20:58:00 mcn
# minor change.
#
# Revision 1.6 1994/08/21 00:56:41 mcn
# New Stuff
#
# Revision 1.5 1994/08/02 18:36:29 mcn
# Support new configuration.
#
# Revision 1.4 1994/07/14 22:13:32 mcn
# Now include SDR Makefile/Headers
#
#
EPICS=${1};
if [ ! -d include -o ! -d src ]; then
echo "Cannot find src or include, are you at the top of EPICS base ?"
exit 1
fi
cd $EPICS/base
FULLY_BUILT=NO
if [ "${2}" = "-b" ]; then
FULLY_BUILT=YES
shift
fi
# Retrieve EPICS release string from include/epicsVersion.h
grep EPICS_VERSION_STRING include/epicsVersion.h > /dev/null 2>&1 || ERR=1;
if [ "$ERR" = "1" ];
then
echo "TOP: Cannot retrieve release number from include/epicsVersion.h";
exit 1;
fi
RELS=`grep "EPICS_VERSION_STRING" include/epicsVersion.h \
| sed -e 's-.*Version--' \
-e 's-[ ][ ]*--g' \
-e 's-".*--' \
-e 's-\.0$--'`;
if [ -z "${RELS}" ];
then
echo "TOP: Cannot retrieve release number from include/epicsVersion.h";
exit 1;
fi
RELS="R${RELS}";
echo TOP: Creating ../${RELS}.Tar;
if [ -f ${RELS}.Tar* ];
then
echo "TOP: This release has already been created.";
echo "TOP: Remove Tar file or edit include/epicsVersion.h.";
exit 1;
fi
# Create list of files and dirs to include in Tar file
cd $EPICS
ls base/README* | xargs tar cvf ${RELS}.Tar
ls base/Makefile* > /tmp/make_release.out.$$;
ls base/*COPYRIGHT* >> /tmp/make_release.out.$$;
if [ -d startup ];
then
find startup -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
fi
find config base/include base/man base/tools -name CVS -prune -o \
! -type d -print >> /tmp/make_release.out.$$;
# binary / library / default.dctsdr / <rec>Record.h / etc.
if [ $FULLY_BUILT = "YES" ];
then
find base/bin -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
find base/lib -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
find base/rec -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
fi
find base/src -name CVS -prune -o -name SCCS -prune -o ! -type d -print \
| grep -v '/O\..*$' >> /tmp/make_release.out.$$
cat /tmp/make_release.out.$$ | xargs tar rvf ${RELS}.Tar
rm /tmp/make_release.out.$$

View File

@@ -12,6 +12,9 @@
# install because the release.% syntax is illegal.
#
# $Log$
# Revision 1.23 1995/02/13 15:00:09 jba
# Changed include file from CONFIG_SITE to CONFIG
#
# Revision 1.22 1994/11/14 23:12:17 tang
# Replace ARCH_TYPE with .
#
@@ -74,21 +77,27 @@ depends:
${MAKE} ${MFLAGS} $@.$$ARCH; \
done)
clean:
@(for ARCH in ${BUILD_ARCHS}; \
do \
ARCH_TYPE=$$ARCH \
${MAKE} ${MFLAGS} $@.$$ARCH; \
done)
uninstall:
@(for ARCH in ${BUILD_ARCHS}; \
do \
ARCH_TYPE=$$ARCH \
${MAKE} ${MFLAGS} $@.$$ARCH; \
done)
release:
@echo TOP: Creating Release...
@tools/MakeRelease
@./MakeRelease ${EPICS}
built_release: install
@echo TOP: Creating Fully Built Release...
@tools/MakeRelease -b
clean:
@echo "TOP: Cleaning"
@tools/Clean
uninstall:
rm -rf bin/* lib/* rec.bak
rm -f rec/default.dctsdr rec/default.sdrSum rec/*.h
@./MakeRelease ${EPICS} -b
# Notes for single architecture build rules:
# CheckArch only has to be run for dirs.% . That
@@ -107,20 +116,15 @@ uninstall:
# some things may be included on a per architecture
# basis.
dirs.%:
@tools/CheckArch $*
@echo $*: Creating Directories
@tools/MakeDirs $*
build.%: dirs.%
build.%:
@echo $*: Building
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs build
install.%: dirs.%
install.%:
@echo $*: Installing
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs install
depends.%: dirs.%
depends.%:
@echo $*: Performing Make Depends
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs depends
@@ -133,11 +137,10 @@ release.%:
@echo
uninstall.%:
@echo
@echo "The uninstall.arch syntax is not supported by this build."
@echo
@echo "TOP: Uninstalling $* "
@rm -rf ./bin/$* ./lib/$* rec.bak rec
clean.%:
@echo "$*: Cleaning"
@tools/Clean $*
@echo "TOP: Cleaning $* "
@find src -type d -name "O.$*" -prune -exec rm -rf {} \;

View File

@@ -5,6 +5,9 @@
# by Matthew Needes and Mike Bordua
#
# $Log$
# Revision 1.13 1994/09/09 17:32:29 jba
# Cleanup of files
#
# Revision 1.12 1994/09/08 17:25:41 mcn
# Changed clean to tools/Clean. Added "uninstall" dependency.
#
@@ -27,7 +30,7 @@ include $(EPICS)/config/CONFIG_BASE
all: build
build:
build: dirs
@(for DIR in ${DIRS}; \
do \
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
@@ -35,7 +38,7 @@ build:
cd $$TMP; \
done)
install:
install: dirs
@(for DIR in ${DIRS}; \
do \
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
@@ -43,7 +46,7 @@ install:
cd $$TMP; \
done)
depends:
depends: dirs
@(for DIR in ${DIRS}; \
do \
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
@@ -51,3 +54,23 @@ depends:
cd $$TMP; \
done)
dirs:
@echo ${T_A}: Creating Directories
@for DIR in ${DIRS}; \
do \
TMP=`pwd`; \
cd $$DIR ; \
if [ -f Makefile.${BUILD_TYPE} ] ; then \
test -d O.${T_A} || \
mkdir O.${T_A}; \
test -f O.${T_A}/Makefile || \
ln -s ../Makefile.${BUILD_TYPE} O.${T_A}/Makefile \
> /dev/null 2> /dev/null; \
test -f O.${T_A}/Target.include || \
echo "T_A=${T_A}" > O.${T_A}/Target.include; \
test -f O.${T_A}/.DEPENDS || \
touch O.${T_A}/.DEPENDS; \
fi ; \
cd $$TMP; \
done

74
README
View File

@@ -7,23 +7,13 @@ $Id$
Notes:
1. Before you can build or really use EPICS, you must set your
path properly:
set path = ( $path EPICS/base/tools EPICS/base/bin/HOST_ARCH \
EPICS/extensions/bin HOST_ARCH )
e.g.:
set path = ( $path /home/epics/base/tools /home/epics/base/bin/sun4 \
/home/epics/extensions/bin/sun4 )
1. Before you can build or really use EPICS, you must properly set the
environemnt variable HOST_ARCH. The epics/startup/HostArch script file
has been provided to set HOST_ARCH.
2. You must use GNU make (which is now THE supported make utility) for
the build. A script, gmake, exists in the base/tools directory to invoke
it with the --no-print-directory option. This option will turn off the
annoying messages GNU make produces upon entering a directory.
gmake
the build, gnumake. Set your path so that a recent version (e.g.
V3.70) of gnumake is available (as make) before any system supplied makes.
----------------------------------------------------------------------------
Part 1 - Configuring and Building EPICS Base
@@ -39,63 +29,63 @@ gmake
cd epics/config
cp CONFIG_ARCH.mv167 CONFIG_ARCH.YOUR_ARCH
edit CONFIG_ARCH.YOUR_ARCH - For compiler flags / etc.
edit CONFIG_ARCH.YOUR_ARCH - For compiler flags / etc.
cp CONFIG.Vx.68k CONFIG.Vx.YOUR_ARCH_CLASS
cp CONFIG_SITE.Vx.68k CONFIG_SITE.Vx.YOUR_ARCH_CLASS
- ONLY IF you are adding a new architecture class,
see note in Appendix A.
edit CONFIG_BASE - Add architecture to list.
edit CONFIG_BASE - Add architecture to list.
1.3 To build EPICS:
cd epics/base
gmake - To build and install EPICS.
gmake clean - To clean temporary object files. Clean will
gnumake - To build and install EPICS.
gnumake clean - To clean temporary object files. Clean will
remove files from ALL O.ARCH dirs, not
only those specified in BUILD_ARCHS.
1.4 To create an EPICS release:
edit base/include/version.h - ONLY IF you need to change the EPICS
version number.
edit base/include/version.h - ONLY IF you need to change the EPICS
version number.
gmake release - Will create Tar file
gnumake release - Will create Tar file
gmake built_release - Will create Tar file, after generating
dependencies, INCLUDING BINARIES.
gnumake built_release - Will create Tar file, after generating
dependencies, INCLUDING BINARIES.
1.5 "Partial" build commands:
gmake clean.sun4 - Cleans sun4 binaries in O.sun4 dirs only.
gmake install.sun4 - Builds sun4 only.
gmake install.mv167 - Builds mv167 only (a HOST_ARCH build must
be complete before this can be issued).
gnumake clean.sun4 - Cleans sun4 binaries in O.sun4 dirs only.
gnumake install.sun4 - Builds sun4 only.
gnumake install.mv167 - Builds mv167 only (a HOST_ARCH build must
be complete before this can be issued).
NOTES:
1. tools/MakeRelease will create tar files in the directory ABOVE
base. These tar files are then meant to be untarred at that level.
This release will include the "epics/config" directory.
1. base/MakeRelease will create tar files in the directory ABOVE
base. These tar files are then meant to be untarred at that level.
This release will include the "epics/config" directory.
2. EPICS binaries are kept in the bin/ARCH and lib/ARCH directories.
EPICS shellscripts are kept in the tools directory.
EPICS shellscripts are kept in the tools directory.
3. During a normal build (a "make" or "make install"), the "depends"
dependency will NOT be invoked. Only if "make depends" is run
explicitly, or a "make built_release" is performed will dependencies
be generated automatically.
dependency will NOT be invoked. Only if "make depends" is run
explicitly, or a "make built_release" is performed will dependencies
be generated automatically.
4. Temporary objects are stored in src/DIR/O.ARCH, This allows objects
for multiple architectures to be maintained at the same time.
While developing source for EPICS, merely cd src/DIR/O.ARCH, and
invoke "make":
for multiple architectures to be maintained at the same time.
While developing source for EPICS, merely cd src/DIR/O.ARCH, and
invoke "make":
cd epics/base/src/db/O.mv167
make dbAccess.o
cd epics/base/src/db/O.mv167
make dbAccess.o
The above example instructs make to build dbAccess.o for the
mv167 target.
The above example instructs make to build dbAccess.o for the
mv167 target.
----------------------------------------------------------------------------
Part 2 --- Configuration Files in epics/config

34
README.Linux Normal file
View File

@@ -0,0 +1,34 @@
Special Notes on Linux
1) The epics makefiles use GNU make which is the make that comes
with Linux. You need to make a link from make to gnumake and
have it in your path. After you have defined the EPICS environement
variable, you can use:
ln -s /usr/bin/make $EPICS/base/tools/gnumake
2) At this point, support for Linux only involves channel access
clients. Since Vxworks is not available for Linux, you must
use other platforms for developing server side code. As for
building databases with dct and gdct, this requires that the
$EPICS/base/tools/makesdr script works properly. Since makesdr
is slated to be removed from the EPICS distribution in a future
release, we didn't feel it was important to include this capability
now. Consequently, when you run make you will receive the error
gnumake[4]: *** [bldDefaultSdr] Error 127
and
gnumake[3]: *** [comsubs.o] Error 1
3) You MUST start caRepeater by hand before running a client.
Prior to running a client, you must run:
caRepeater &
---
jpq@nwu.edu

View File

@@ -4,42 +4,11 @@
# M. Anderson and J. Tang
- EPICS environment variable - set by hand prior to build
For EPICS builds on HP700 and Alpha OSF/1, set an environment variable "EPICS"
to the base of the EPICS directory to do builds in (the directory where
this file resides, for instance).
If you are currently in the base directory, then do the following:
% setenv EPICS $cwd
- set path to include gnu make and base/tools and base/bin/<arch>
Then set the path such that a recent version (e.g. V3.70) of gnumake
is available (as make) before any system supplied makes, and that
$EPICS/base/tools and $EPICS/base/bin/<arch> are included as well.
For example:
% set path=(/usr/local/bin $EPICS/base/tools $EPICS/base/bin/hp700 $path)
- to build multiple architectures in same tree
To build multiple architectures in the same directory tree, you
can avoid editing CONFIG_SITE by simply issuing make with HOST_ARCH=<arch>
For example:
% make HOST_ARCH=hp700
Also, directory permissions may not be correct across multiple machines,
so a
- Directory permissions may not be correct across multiple machines, so a
% chmod -R ugo+rw base extensions
might be necessary.
- bsdinstall is written to replace install for hp.
- epics/base/tools/bsdinstall was written to replace install for hp.

View File

@@ -1,29 +1,21 @@
----------------------------------------------------------------------------
EPICS R3.12 Notes for Solaris 2.3
EPICS R3.12.2 Notes for Solaris
- By Andrew Johnson
----------------------------------------------------------------------------
Notes:
1. In order to build and use EPICS under Solaris 2, you must include
various directories in your path in the order given below, in addition
to those named in base/README. Some of these directories may already be
included in your path from your .login script or .cshrc file, so be
careful that the ordering is correct.
1. In order to build EPICS under Solaris 2, you must ensure that the
solaris directory /usr/ccs/bin is in your search path.
setenv PATH /usr/ucb:/usr/bin:/usr/ccs/bin:$PATH
2. It is not possible to compile EPICS under Solaris 2 using only the
GNU gcc compiler -- you must have the Sun SPARCworks ANSI C compiler.
2. It is not possible to compile the whole of EPICS under Solaris 2
using only the GNU gcc compiler - some routines which are needed (for
example quiet_nan()) have been unbundled by Sun and are provided with
their ANSI C compiler. The path to the Sun compiler is explicitly set
using the SPARCWORKS definition in the file CONFIG_SITE.Unix.solaris
3. EPICS must be compiled and linked using the UCB compatability
libraries. The definitions UCB_LIB and UCB_INCLUDE are used here to
refer to these libraries and their header files, and the tools provided
within /usr/ucb must be used in preference to the System V ones, hence
the above path ordering.
3. EPICS under Solaris 2 no longer uses the UCB compatability
libraries. It does require the /usr/ucb/install program however. In
order to ensure that the /usr/ucblib files are not inherited, you
should ensure that your LD_LIBRARY_PATH environment variable does not
include /usr/ucblib when you build any of the host tools.
--
anj@mail.ast.cam.ac.uk
anj@ast.cam.ac.uk

View File

@@ -0,0 +1,10 @@
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
**********************************************************************/

View File

@@ -5,8 +5,8 @@ include $(EPICS)/config/CONFIG_BASE
USR_CFLAGS = -DACCESS_SECURITY -D_NO_PROTO
SRCS.c = ../asDbLib.c ../asCa.c asLib.c
OBJS = asDbLib.o asCa.o asLib.o
PROD = asLibrary
LIBOBJS = asDbLib.o asCa.o asLib.o
LIBNAME = asLibrary
include $(EPICS)/config/RULES.Vx
@@ -18,7 +18,4 @@ asLib.o: asLib_lex.c ../asLibRoutines.c
clean::
@$(RM) asLib_lex.c asLib.c
asLibrary : $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -148,13 +148,16 @@ static long asInitCommon(void)
long status;
char buffer[BUF_SIZE];
if(!pacf) return(0);
if(asLockInit) {
FASTLOCKINIT(&asLock);
asLockInit = FALSE;
}
FASTLOCK(&asLock);
if(asActive)asCaStop();
if(!pacf) {
asActive = FALSE;
return(0);
}
buffer[0] = 0;
my_buffer = buffer;
my_buffer_ptr = my_buffer;

View File

@@ -1,6 +1,6 @@
integer [0-9]
name [a-zA-Z0-9_\.]
pvname [a-zA-Z0-9_:\.\[\]<>;]
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
string [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$]
%{

18
src/bdt/Makefile Normal file
View File

@@ -0,0 +1,18 @@
#
# $Id$
#
# Base Lowest Level Directroy Makefile
# by Janet Anderson
#
# $Log$
# Revision 1.1 1994/09/07 19:26:22 jba
# New file
#
#
EPICS=../../..
include $(EPICS)/config/CONFIG_BASE
include $(EPICS)/config/RULES_ARCHS

10
src/bdt/Makefile.Unix Normal file
View File

@@ -0,0 +1,10 @@
EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
LIBOBJS += bdt.o
LIBNAME = libBdt.a
include $(EPICS)/config/RULES.Unix

21
src/bdt/Makefile.Vx Normal file
View File

@@ -0,0 +1,21 @@
EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
SRCS.c += ../bdt.c
SRCS.c += ../bdtServ.c
SRCS.c += ../bdtServName.c
SRCS.c += ../bdtServPv.c
OBJS += bdt.o
OBJS += bdtServ.o
OBJS += bdtServName.o
OBJS += bdtServPv.o
PROD = bdt
include $(EPICS)/config/RULES.Vx
$(PROD): $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

701
src/bdt/bdt.c Normal file
View File

@@ -0,0 +1,701 @@
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef linux
#include <sys/resource.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include <ioLib.h>
#include <selectLib.h>
#else
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include "bdt.h"
/* ---------------------------------------------------------------------- */
/* server mode functions */
#ifndef vxWorks /* server mode functions */
static char* filename=(char*)NULL;
/* ----------------------------- */
/* signal catcher for the server */
/* ----------------------------- */
static void catch_sig(int sig)
{
fprintf(stderr,"\nbdt server exiting\n");
unlink(filename);
exit(0);
}
/* -------------------------------- */
/* child reaper for the server mode */
/* -------------------------------- */
static void get_child(int sig)
{
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
#ifdef linux
signal(SIGCHLD,get_child); /* for reaping children */
#endif
}
/* ------------------------------- */
/* Clear the signals for a process */
/* ------------------------------- */
int BdtServerClearSignals()
{
signal(SIGCHLD,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
return 0;
}
/* ----------------------------------------------------- */
/* Make a unix process into a generic background process */
/* ----------------------------------------------------- */
int BdtMakeServer(char** argv)
{
FILE* fd;
if(filename) return -1;
/* set up signal handling for the server */
signal(SIGCHLD,get_child); /* for reaping children */
signal(SIGHUP,catch_sig);
signal(SIGINT,catch_sig);
signal(SIGTERM,catch_sig);
signal(SIGQUIT,catch_sig);
/* disconnect from parent */
switch(fork())
{
case -1: /* error */
perror("Cannot fork");
return -1;
case 0: /* child */
#ifdef linux
setpgrp();
#else
setpgrp(0,0);
#endif
setsid();
break;
default: /* parent goes away */
exit(0);
}
/* save process ID */
filename=(char*)malloc(strlen(argv[0])+10);
sprintf(filename,"%s.%d",argv[0],getpid());
fd=fopen(filename,"w");
fprintf(fd,"%d",getpid());
fprintf(stderr,"\npv server pid: %d\n",getpid());
fclose(fd);
return 0;
}
#endif /* server mode functions */
/* ------------------------------------------ */
/* unimplemented channel access open function */
/* ------------------------------------------ */
BDT* BdtPvOpen(char *IocName, char* PvName)
{
BDT *bdt;
if((bdt = BdtIpOpen(IocName, BDT_TCP_PORT)) == NULL)
{
fprintf(stderr,"open of address %s failed\n", IocName);
return(NULL);
}
if(BdtServiceConnect(bdt, BDT_SERVICE_PV, PvName) < 0)
{
fprintf(stderr,"connect to PV %s failed\n", PvName);
BdtClose(bdt);
return(NULL);
}
return(bdt);
}
/* --------------------------------------------------------------- */
/* open a bulk data socket to a server given the server IP address */
/* --------------------------------------------------------------- */
BDT* BdtIpOpen(char* address, int Port)
{
struct hostent *pHostent;
struct sockaddr_in tsin;
unsigned long addr;
int osoc;
BDT *bdt;
#ifndef vxWorks
/* Deal with the name -vs- IP number issue. */
if (isdigit(address[0]))
#endif
addr=inet_addr(address);
#ifndef vxWorks
else
{
if ((pHostent = gethostbyname (address)) == NULL)
return(NULL);
bcopy (pHostent->h_addr, (char *) &addr, sizeof(addr));
printf("Converting name >%s< to IP number %08.8X\n", address, addr);
}
#endif
tsin.sin_port=0;
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtIpOpen: create socket failed");
return (BDT*)NULL;
}
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtIpOpen: local address bind failed");
return (BDT*)NULL;
}
tsin.sin_port=htons(Port);
memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr));
if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0)
{
perror("BdtIpOpen: connect failed");
close(osoc);
return (BDT*)NULL;
}
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=osoc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtUnbound;
#ifndef vxWorks
{
int j;
j = fcntl(bdt->soc, F_GETFL, 0);
fcntl(bdt->soc, F_SETFL, j|O_NDELAY);
}
#endif
/* now connected to the bulk data socket on the IOC */
return bdt;
}
/* -------------------------------------- */
/* write size bytes from buffer to socket */
/* -------------------------------------- */
int BdtWrite(int soc,void* buffer,int size)
{
int rc;
int total;
unsigned char* data;
fd_set fds;
struct timeval to;
data=(unsigned char*)buffer;
total=size;
to.tv_sec = 5;
to.tv_usec = 0;
do
{
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, NULL, &fds, NULL, &to) != 1)
{
printf("BdtWrite: timeout waiting to write data\n");
return(-1);
}
/* send block of data */
if((rc=send(soc,&data[size-total],total,0))<0)
{
if(errno == EINTR)
rc = 0;
else
perror("BdtWrite: Send to remote failed");
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* --------------------------------------- */
/* send a message header down a BDT socket */
/* --------------------------------------- */
int BdtSendHeader(BDT* bdt,unsigned short verb,int size)
{
BdtMsgHead buf;
if(bdt->state!=BdtIdle)
{
fprintf(stderr,"BdtSendHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
buf.verb=htons(verb);
buf.size=htonl((unsigned long)size);
if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
/* don't wait for response if data must go out */
if(size)
{
bdt->remaining_send=size;
bdt->state=BdtSData;
}
return 0;
}
/* ------------------------------------------- */
/* send a message data chunk down a BDT socket */
/* ------------------------------------------- */
int BdtSendData(BDT* bdt,void* buffer,int size)
{
int len;
int remaining;
int rc;
if(bdt->state!=BdtSData)
{
fprintf(stderr,"BdtSendData: Interface not in send data mode\n");
bdt->state=BdtBad;
return -1;
}
remaining=bdt->remaining_send-size;
if(remaining<0)
{
fprintf(stderr,"WARNING -- BdtSendData: To much data to send\n");
len=bdt->remaining_send;
}
else
len=size;
if (BdtWrite(bdt->soc, buffer, len) < 0)
return -1;
bdt->remaining_send-=len;
if(bdt->remaining_send<0)
{
fprintf(stderr,"BdtSendData: To much data Sent\n");
bdt->remaining_send=0;
}
if(bdt->remaining_send==0)
bdt->state=BdtIdle;
return len;
}
int BdtFlushOutput(BDT* bdt)
{
#ifdef vxWorks
ioctl(bdt->soc, FIOWFLUSH, 0);
#endif
}
/* ------------------------------------- */
/* Read exactly size bytes from remote */
/* ------------------------------------- */
int BdtRead(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
fd_set fds;
struct timeval to;
to.tv_sec = 5;
to.tv_usec = 0;
data=(unsigned char*)buffer;
total=size;
do
{
#if 1
/* wait for data chunk */
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, &fds, NULL, NULL, &to) != 1)
{
printf("BdtRead: timeout waiting for data\n");
return(-1);
}
#endif
if((rc=recv(soc,&data[size-total],total,0))<0)
{
if(errno==EINTR)
{
printf("BdtRead: EINTR");
rc=0;
}
else
{
perror("BdtRead: Receive data chunk failed");
}
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* ------------------------------------- */
/* wait for a message header from remote */
/* ------------------------------------- */
int BdtReceiveHeader(BDT* bdt,int* verb,int* size)
{
BdtMsgHead buf;
/* can only receive header when in the idle state */
if (bdt->state == BdtEof)
return -1;
if(bdt->state != BdtIdle)
{
fprintf(stderr,"BdtReceiveHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
/* copy message data to user */
*verb=ntohs(buf.verb);
*size=ntohl(buf.size);
if(*size)
bdt->state=BdtRData;
bdt->remaining_recv=*size;
return 0;
}
/* ------------------------------------------------------------------------
Wait for a chunk of data from remote.
User can continually call this with a maximum size until it return 0.
------------------------------------------------------------------------ */
int BdtReceiveData(BDT* bdt,void* buffer,int size)
{
int rc;
/* can only receive data when in the receive data state */
switch(bdt->state)
{
case BdtRData: break;
case BdtIdle: return 0;
default:
fprintf(stderr,"BdtReceiveData: bad receive state\n");
bdt->state=BdtBad;
break;
}
if (bdt->remaining_recv < size)
size = bdt->remaining_recv;
if(BdtRead(bdt->soc,buffer,size)<0)
{
fprintf(stderr,"BdtReceiveData: Read failed\n");
bdt->state = BdtEof;
return -1;
}
bdt->remaining_recv-=size;
if(bdt->remaining_recv<0)
{
fprintf(stderr,"BdtReceiveData: To much data received\n");
bdt->remaining_recv=0;
}
if(bdt->remaining_recv==0)
bdt->state=BdtIdle;
return size;
}
/* ------------------------------------------------------ */
/* connect to a process variable, useful if raw open used */
/* ------------------------------------------------------ */
int BdtServiceConnect(BDT* bdt, char* Name, char *Args)
{
int len;
int rc;
int size;
int verb;
unsigned char NameLen;
unsigned char ArgLen;
if(bdt->state!=BdtUnbound)
{
fprintf(stderr,"BdtServiceConnect: can only bind to one service\n");
return -1;
}
bdt->state=BdtIdle;
NameLen = strlen(Name)+1;
if (Args != NULL)
ArgLen = strlen(Args)+1;
else
ArgLen = 0;
/* send out connect message */
if(BdtSendHeader(bdt, BDT_Connect, NameLen+ArgLen) < 0)
{
fprintf(stderr,"BdtServiceConnect: send of connect header failed\n");
bdt->state=BdtUnbound;
return -1;
}
NameLen--;
ArgLen--;
/* send out the process variable to connect to */
if((BdtSendData(bdt, &NameLen, 1) < 0) || (BdtSendData(bdt, Name, NameLen) < 0))
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
if (ArgLen > 0)
{
if ((BdtSendData(bdt, &ArgLen, 1) < 0) || (BdtSendData(bdt, Args, ArgLen) < 0))
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
}
rc=0;
/* wait for response from connect to process variable */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtServiceConnect: receive reponse failed\n");
bdt->state=BdtUnbound;
return -1;
}
/* check response */
switch(verb)
{
case BDT_Ok:
rc=0;
break;
case BDT_Error:
fprintf(stderr,"BdtServiceConnect: connection rejected\n");
bdt->state=BdtUnbound;
rc=-1;
break;
default:
fprintf(stderr,"BdtServiceConnect: unknown response from remote\n");
bdt->state=BdtUnbound;
rc=-1;
break;
}
return rc;
}
/* -------------------- */
/* close the connection */
/* -------------------- */
int BdtClose(BDT* bdt)
{
int verb,size,done;
/* send a close message out */
if(BdtSendHeader(bdt,BDT_Close,0)<0)
{
fprintf(stderr,"BdtClose: Cannot send close message\n");
return -1;
}
done=0;
do
{
/* check response */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtClose: Close message response error\n");
return -1;
}
switch(verb)
{
case BDT_Ok:
done=1;
break;
case BDT_Error:
fprintf(stderr,"BdtClose: Close rejected\n");
return -1;
break;
default: break;
}
}
while(done==0);
bdt->state=BdtUnbound;
free(bdt);
return 0;
}
/* --------------------------------------- */
/* make a listener socket for UDP - simple */
/* --------------------------------------- */
int BdtOpenListenerUDP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
tsin.sin_port=htons(Port);
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0)
{
perror("BdtOpenListenerUDP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerUDP: local bind failed");
close(nsoc);
return -1;
}
return nsoc;
}
/* --------------------------------------- */
/* make a listener socket for TCP - simple */
/* --------------------------------------- */
int BdtOpenListenerTCP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
memset (&tsin, 0, sizeof(struct sockaddr_in));
tsin.sin_port=htons(Port);
tsin.sin_family=htons(AF_INET);
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtOpenListenerTCP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerTCP: local bind failed");
close(nsoc);
return -1;
}
listen(nsoc,5);
return nsoc;
}
/* ------------------------------- */
/* make BDT from a socket - simple */
/* ------------------------------- */
BDT* BdtMakeBDT(int soc)
{
BDT* bdt;
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=soc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtIdle;
return bdt;
}
/* --------------------------- */
/* free a BDT and close socket */
/* --------------------------- */
int BdtFreeBDT(BDT* bdt)
{
close(bdt->soc);
free(bdt);
return 0;
}
int BdtPvPutArray(BDT *bdt, short DbrType, void *Buf, unsigned long NumElements,
unsigned long ElementSize)
{
int Verb;
int Size;
unsigned long BufSize;
BufSize = NumElements * ElementSize;
if (BdtSendHeader(bdt, BDT_Put, 6 + BufSize) != 0)
return(-1);
if (BdtSendData(bdt, &DbrType, 2) < 0)
return(-1);
if (BdtSendData(bdt, &NumElements, 4) < 0)
return(-1);
if (BdtSendData(bdt, Buf, BufSize) < 0)
return(-1);
if (BdtReceiveHeader(bdt, &Verb, &Size) != 0)
return(-1);
if (Verb != BDT_Ok)
return(-1);
return(0);
}

392
src/bdt/bdtServ.c Normal file
View File

@@ -0,0 +1,392 @@
/*
*
* Author: John Winans
* Date: 95-05-22
*
* $Log$
*/
/*****************************************************************************
*
* IOC listener task blocks on accept calls waiting for binders.
* If a bind arrives, a receiver task is spawned.
*
* IOC receiver task blocks on read calls waiting for transactions.
* When a transaction arrives it is serviced.
* At the end of a transaction service, a response is sent back.
* After the response is sent, a chack is made to see if a delta transmission
* was blocked by the transaction's use of the socket... if so, it is sent.
*
******************************************************************************/
#include <selectLib.h>
#include <stdio.h>
#include <signal.h>
#include <vxWorks.h>
#include <sys/socket.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include <sysSymTbl.h>
#include <string.h>
#include "bdt.h"
#define BDT_TASK_PRIO 200
#define BDT_TASK_OPTIONS VX_FP_TASK
#define BDT_TASK_STACK 5000
#define STATIC static
/* used for debugging */
STATIC char *BdtNames[] = {
"BDT_Ok",
"BDT_Connect",
"BDT_Error",
"BDT_Get",
"BDT_Put",
"BDT_Close",
"BDT_Monitor",
"BDT_Value",
"BDT_Delta",
"BDT_Add",
"BDT_Delete",
"BDT_Ping"
};
STATIC int HexDump(char *ReadBuffer, int rbytes);
/*****************************************************************************
*
* A debugging routine that hex-dumps a message to the console.
*
*****************************************************************************/
void BDT_DumpMessage(BDT *Bdt)
{
char Buf[16*4];
int RecvLen;
while(Bdt->remaining_recv)
{
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
return; /* Got EOF, (EOM handled by the while() */
HexDump(Buf, RecvLen);
}
}
/*****************************************************************************
*
* Throw away a message.
*
****************************************************************************/
void BDT_DiscardMessage(BDT *Bdt)
{
char Buf[16*4];
int RecvLen;
while(Bdt->remaining_recv)
{
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
return; /* Got EOF, (EOM handled by the while() */
}
}
/*****************************************************************************
*
* Process a single Connect message. And return a response.
*
******************************************************************************/
STATIC int BDT_ProcessConnect(BDT *Bdt)
{
SYM_TYPE Type;
unsigned char length;
char Buf[50];
char HandlerName[70];
if (Bdt->remaining_recv > sizeof(Buf))
{
printf("BDT_ProcessConnect Connect Message too long %d\n", Bdt->remaining_recv);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (Bdt->remaining_recv < 2)
{
printf("BDT_ProcessConnect Connect Message w/missing service name\n");
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, &length, 1);
if (length > sizeof(Buf))
{
printf("BDT_ProcessConnect Connect Message service name too long %d\n", length);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, Buf, length);
Buf[length] = '\0';
sprintf(HandlerName, "_BDT_ServiceHandler_%s", Buf);
printf("BDT_ProcessConnect NAME service (%s)\n", HandlerName);
/*Bdt->pHandlers = (BdthandlerFunc *)(&BDT_NameServicehandlers);*/
if (symFindByName(sysSymTbl, HandlerName, (char **)&(Bdt->pHandlers), &Type) != OK)
{
printf("BDT_ProcessConnect Connect to unknown service (%s)\n", Buf);
BdtSendHeader(Bdt, BDT_Error, 0);
}
else
{
Bdt->Name = (char *)malloc(strlen(Buf)+1);
strcpy(Bdt->Name, Buf);
if (Bdt->pHandlers[BDT_Connect] != NULL)
return((*(Bdt->pHandlers[BDT_Connect]))(Bdt));
else
{
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Ok, 0);
}
}
return(0);
}
/*****************************************************************************
*
* Process a single message. And return a response.
*
******************************************************************************/
STATIC int BDT_ProcMessage(BDT *Bdt, unsigned short Command)
{
int RecvLen;
if (Command > BDT_LAST_VERB)
{
printf("BDT: %s Invalid command %d, length = %d\n", Bdt->Name, Command, Bdt->remaining_recv);
BDT_DumpMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (Bdt->pHandlers == NULL)
{
if (Command == BDT_Connect)
BDT_ProcessConnect(Bdt);
else
{
printf("BDT_ProcMessage: %s got %s before connect\n", Bdt->Name, BdtNames[Command]);
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
}
return(0);
}
if (Bdt->pHandlers[Command] == NULL)
{
printf("BDT_ProcMessage: service %s got %s... invalid\n", Bdt->Name, BdtNames[Command]);
}
return((*(Bdt->pHandlers[Command]))(Bdt));
}
/*****************************************************************************
*
* Wait on a socket read for a message. When one arrives, read the header,
* decode it, and call the message handler routine to process and respond to it.
*
******************************************************************************/
STATIC void BDT_ReceiverTask(int Sock)
{
int Verb;
int Size;
BDT Bdt;
int MonitorLockTimeout = (BDT_PING_INTERVAL*sysClkRateGet())/2;
static char *NoBdtName = "(No Name)";
fd_set FdSet;
struct timeval TimeVal;
int PollStatus;
int SocketState;
Bdt.soc = Sock;
Bdt.pMonitor = NULL;
Bdt.WriteLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
Bdt.MonitorLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
Bdt.state = BdtIdle;
Bdt.pHandlers = NULL;
Bdt.Name = NoBdtName;
printf("BDT_ReceiverTask(%d) started\n", Sock);
TimeVal.tv_sec = BDT_CONENCTION_TIMEOUT;
TimeVal.tv_usec = 0;
FD_ZERO(&FdSet);
FD_SET(Bdt.soc, &FdSet);
SocketState = 0;
while (((PollStatus = select(FD_SETSIZE, &FdSet, NULL, NULL, &TimeVal)) > 0) && (BdtReceiveHeader(&Bdt, &Verb, &Size) == 0))
{
semTake(Bdt.WriteLock, WAIT_FOREVER);
SocketState = BDT_ProcMessage(&Bdt, Verb);
if (SocketState != 0)
break;
#if 0
if (semTake(Bdt.MonitorLock, MonitorLockTimeout) == OK)
{
/* Check for delta flag and send if so */
/* Change this to run thru a delta-message linked list */
if (Bdt.pMonitor != NULL)
{
/* Send delta notifier */
}
semGive(Bdt.WriteLock); /* Order important for BDT_SendDelta */
semGive(Bdt.MonitorLock);
}
else
{
printf("BDT_ReceiverTask timeout on monitor semaphore. Monitors are stuck!\n");
semGive(Bdt.WriteLock);
}
#else
semGive(Bdt.WriteLock);
#endif
BdtFlushOutput(&Bdt);
FD_ZERO(&FdSet);
FD_SET(Bdt.soc, &FdSet);
}
if (SocketState == 0)
{
if (PollStatus == 0)
printf("BDT_ReceiverTask(%d) exiting on client timeout\n", Sock);
else
printf("BDT_ReceiverTask(%d) exiting on I/O error talking to Client\n", Sock);
}
else
printf("BDT_ReceiverTask(%d) received close from client\n", Sock);
/* Free up resources */
if (Bdt.Name != NoBdtName)
free(Bdt.Name);
close(Sock);
semDelete(Bdt.WriteLock);
semDelete(Bdt.MonitorLock);
return;
}
/*****************************************************************************
*
******************************************************************************/
#if 0
int BDT_SendDelta(int Socket, char *Message)
{
semTake (DeltaFlagLock, WAIT_FOREVER);
if (if (semTake(SocketWriteLock, no wait) == failed)
{
/* Reader task is busy... Post message for future transmission */
Bdt.pending_delta = 1;
}
else
{
write(Message); /* This COULD block */
semGive(SocketWriteLock);
}
semGive(DeltaFlagLock);
return (0);
}
#endif
/*****************************************************************************
*
* This task listens on a port for new connections. When one is made, it
* spawns a task to manage it.
*
******************************************************************************/
void BDT_ListenerTask(int Port)
{
/* Open a socket to listen on */
struct sockaddr_in ListenerAddr;
struct sockaddr_in ClientAddr;
int ListenerSock;
int ClientSock;
int ClientAddrLen;
int SockAddrSize = sizeof(struct sockaddr_in);
if (Port == 0)
Port = BDT_TCP_PORT;
printf("BDT_Listener(%d) started\n", Port);
if ((ListenerSock = BdtOpenListenerTCP(Port)) < 0)
{
printf("BDT_ListenerTask(%d) can't start listener\n", Port);
return;
}
while (1)
{
ClientAddrLen = sizeof(ClientAddr);
if((ClientSock = accept(ListenerSock, (struct sockaddr*)&ClientAddr, &ClientAddrLen)) < 0)
{
if(errno!=EINTR)
{
printf("BDT_ListenerTask(%d) accept() failed\n", Port);
}
}
else
{
/* Spawn a task to handle the new connection */
printf("Accepted a connection\n");
taskSpawn("BDT", BDT_TASK_PRIO, BDT_TASK_OPTIONS, BDT_TASK_STACK, (FUNCPTR)BDT_ReceiverTask, ClientSock, 2,3,4,5,6,7,8,9,0);
}
}
/* Never reached */
}
/*****************************************************************************
*
* A handy routine to assist in debugging.
*
******************************************************************************/
STATIC int HexDump(char *ReadBuffer, int rbytes)
{
int c = 0;
int i = 0;
int firsttime;
char ascii[20]; /* To hold printable portion of string */
if (!rbytes)
return(0);
firsttime = 1;
while(c < rbytes)
{
if ((c % 16) == 0)
{
if (!firsttime)
{
ascii[i] = '\0';
printf(" *%s*\n", ascii);
}
firsttime=0;
i = 0;
}
printf(" %02.2X", ReadBuffer[c] & 0xff);
ascii[i] = ReadBuffer[c];
if (!isprint(ascii[i]))
ascii[i] = '.';
++i;
++c;
}
while (c%16)
{
fputs(" ", stdout);
++c;
}
ascii[i] = '\0';
printf(" *%s*\n", ascii);
return(0);
}

129
src/bdt/bdtServName.c Normal file
View File

@@ -0,0 +1,129 @@
/*****************************************************************************
*
* Author: John Winans
* Date: 95-06-05
*
* $Id$
*
* $Log$
*
*****************************************************************************/
#include <selectLib.h>
#include <stdio.h>
#include <signal.h>
/*****************************************************************************
*
* IOC listener task blocks on accept calls waiting for binders.
* If a bind arrives, a receiver task is spawned.
*
* IOC receiver task blocks on read calls waiting for transactions.
* When a transaction arrives it is serviced.
* At the end of a transaction service, a response is sent back.
* After the response is sent, a chack is made to see if a delta transmission
* was blocked by the transaction's use of the socket... if so, it is sent.
*
******************************************************************************/
#include <vxWorks.h>
#include <sys/socket.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#include "bdt.h"
#define STATIC static
/*****************************************************************************
*
*****************************************************************************/
STATIC int BDT_NameServiceOk(BDT *Bdt)
{
printf("BDT_NameServiceOk \n");
return(0);
}
/*****************************************************************************
*
*****************************************************************************/
STATIC int BDT_NameServiceConnect(BDT *Bdt)
{
printf("BDT_NameServiceConnect \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
STATIC int BDT_NameServiceError(BDT *Bdt)
{
printf("BDT_NameServiceError \n");
return(0);
}
STATIC int BDT_NameServiceGet(BDT *Bdt)
{
printf("BDT_NameServiceGet \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServicePut(BDT *Bdt)
{
printf("BDT_NameServicePut \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceClose(BDT *Bdt)
{
printf("BDT_NameServiceClose \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
STATIC int BDT_NameServiceMonitor(BDT *Bdt)
{
printf("BDT_NameServiceMonitor \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceValue(BDT *Bdt)
{
printf("BDT_NameServiceValue \n");
return(0);
}
STATIC int BDT_NameServiceDelta(BDT *Bdt)
{
printf("BDT_NameServiceDelta \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceAdd(BDT *Bdt)
{
printf("BDT_NameServiceAdd \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServiceDelete(BDT *Bdt)
{
printf("BDT_NameServiceDelete \n");
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
STATIC int BDT_NameServicePing(BDT *Bdt)
{
printf("BDT_NameServicePing \n");
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
BdtHandlers BDT_ServiceHandler_name =
{
BDT_NameServiceOk,
BDT_NameServiceConnect,
BDT_NameServiceError,
BDT_NameServiceGet,
BDT_NameServicePut,
BDT_NameServiceClose,
BDT_NameServiceMonitor,
BDT_NameServiceValue,
BDT_NameServiceDelta,
BDT_NameServiceAdd,
BDT_NameServiceDelete,
BDT_NameServicePing
};

377
src/bdt/bdtServPv.c Normal file
View File

@@ -0,0 +1,377 @@
/*****************************************************************************
*
* Author: John Winans
* Date: 95-06-05
*
* $Id$
*
* $Log$
*
******************************************************************************/
#include <vxWorks.h>
#include <semLib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <dbCommon.h>
#include <dbAccess.h>
#include "bdt.h"
#define STATIC static
#define MESSAGE_PREFIX "BDT PV server:"
/*****************************************************************************
*
* These conversion finctions take care of one of the most insane parts
* of dealing with database access... having two different interfaces that
* have the same named enumerators in two seperate header files... that
* therefore can not be both included in the same file.
*
* This is so bad, I wanted to vomit when typing it in.
*
******************************************************************************/
STATIC int DbrOld2New(int Old)
{
switch (Old)
{
case 0: return(DBR_STRING);
case 1: return(DBR_SHORT);
case 2: return(DBR_FLOAT);
case 3: return(DBR_ENUM);
case 4: return(DBR_CHAR);
case 5: return(DBR_LONG);
case 6: return(DBR_DOUBLE);
default:
return(-1);
}
}
STATIC int DbrNew2Old(int New)
{
switch (New)
{
case DBR_STRING: return(0);
case DBR_CHAR: return(4);
case DBR_UCHAR: return(4);
case DBR_SHORT: return(1);
case DBR_USHORT: return(1);
case DBR_LONG: return(5);
case DBR_ULONG: return(5);
case DBR_FLOAT: return(2);
case DBR_DOUBLE: return(6);
case DBR_ENUM: return(3);
default:
return(-1);
}
}
/*****************************************************************************
*
* Handle the receipt of an OK message.
*
* The OK message is received as a confirmation of the last operation. It is
* not normally responded to.
*
*****************************************************************************/
STATIC int BDT_ServiceOk(BDT *Bdt)
{
printf("%s got a Ok message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Connect message.
*
* The Connect is received when a new connection is first made.
* Any arguments left in the message body have not yet been read.
*
*****************************************************************************/
STATIC int BDT_ServiceConnect(BDT *Bdt)
{
unsigned char Length;
char Buf[100];
struct dbAddr *pDbAddr;
Buf[0] = '\0';
if (Bdt->remaining_recv > 0)
{
BdtReceiveData(Bdt, &Length, 1);
if (Length <= sizeof(Buf))
{
BdtReceiveData(Bdt, Buf, Length);
Buf[Length] = '\0';
}
else
{
printf("%s Connect message argument list too long\n", MESSAGE_PREFIX);
BDT_DiscardMessage(Bdt);
return(-1);
}
}
#ifdef DEBUG_VERBOSE
printf("%s got Connect >%s<\n", MESSAGE_PREFIX, Buf);
#endif
/* Find the PV in the database */
Bdt->pService = malloc(sizeof(struct dbAddr));
pDbAddr = (struct dbAddr *)(Bdt->pService);
if (dbNameToAddr(Buf, pDbAddr))
{
BdtSendHeader(Bdt, BDT_Error, 0);
free(Bdt->pService);
}
else
{
if (pDbAddr->dbr_field_type != pDbAddr->field_type)
{
BdtSendHeader(Bdt, BDT_Error, 0);
free(Bdt->pService);
}
else
BdtSendHeader(Bdt, BDT_Ok, 0);
}
return(0);
}
/*****************************************************************************
*
* Handle the receipt of an Error message.
*
*****************************************************************************/
STATIC int BDT_ServiceError(BDT *Bdt)
{
printf("%s got a Error message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Get message.
*
* The response to a Get message is either an Error or a Value:
*
* Value message body format:
* SHORT EPICS data type enumerator (in old format)
* LONG Number of elements
* CHAR[] Value image
*
*
*****************************************************************************/
STATIC int BDT_ServiceGet(BDT *Bdt)
{
void *Buf;
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
long NumElements;
long Size;
long l;
short OldType;
int stat;
#ifdef DEBUG_VERBOSE
printf("%s got a Get message\n", MESSAGE_PREFIX);
printf("field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
#endif
OldType = DbrNew2Old(pDbAddr->field_type);
if (OldType < 0)
{
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/* Allocate a buffer to hold the response message data */
Buf = malloc(pDbAddr->field_size * pDbAddr->no_elements);
if (Buf == NULL)
{
printf("Can't allocate %d-byte buffer for get request to %s\n",
pDbAddr->field_size * pDbAddr->no_elements,
pDbAddr->precord->name);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/* Get the response message data */
NumElements = pDbAddr->no_elements;
if (stat=dbGetField(pDbAddr, pDbAddr->field_type, Buf, 0, &NumElements, NULL))
{
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
#if 0
/* Test hack to transfer HUGE buffers */
NumElements = pDbAddr->no_elements;
#endif
/* Send the response message */
Size = NumElements * pDbAddr->field_size;
BdtSendHeader(Bdt, BDT_Value, Size + sizeof(long) + sizeof(short));
BdtSendData(Bdt, &OldType, sizeof(short));
BdtSendData(Bdt, &NumElements, sizeof(long));
if (Size)
BdtSendData(Bdt, Buf, Size);
free(Buf);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Put message.
*
* Put message body format:
* SHORT EPICS data type enumerator
* LONG Number of elements
* CHAR[] Value image
*
*****************************************************************************/
STATIC int BDT_ServicePut(BDT *Bdt)
{
long Size;
void *Buf;
short DbrType;
long NumElements;
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
#ifdef DEBUG_VERBOSE
printf("%s got a Put message\n", MESSAGE_PREFIX);
#endif
if (BdtGetResidualRead(Bdt) < 6)
{
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
if (BdtGetResidualRead(Bdt) == 6)
{ /* Do data contents, just toss it */
BDT_DiscardMessage(Bdt);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
Buf = malloc(BdtGetResidualRead(Bdt) - 6);
if (Buf == NULL)
{
printf("Can't allocate %d-byte buffer for put request to %s\n",
BdtGetResidualRead(Bdt), pDbAddr->precord->name);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
BdtReceiveData(Bdt, &DbrType, 2);
BdtReceiveData(Bdt, &NumElements, 4);
#ifdef DEBUG_VERBOSE
printf("record field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
printf("message field type=%d, field size=%d, elements=%d total %d\n", DbrType, pDbAddr->field_type ,NumElements, BdtGetResidualRead(Bdt));
#endif
BdtReceiveData(Bdt, Buf, BdtGetResidualRead(Bdt));
DbrType = DbrOld2New(DbrType);
if (DbrType < 0)
BdtSendHeader(Bdt, BDT_Error, 0);
else if (dbPutField(pDbAddr, DbrType, Buf, NumElements))
BdtSendHeader(Bdt, BDT_Error, 0);
else
BdtSendHeader(Bdt, BDT_Ok, 0);
free(Buf);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Close message.
*
*****************************************************************************/
STATIC int BDT_ServiceClose(BDT *Bdt)
{
printf("%s got a Close message\n", MESSAGE_PREFIX);
free(Bdt->pService);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(1);
}
/*****************************************************************************
*
* Handle the receipt of a Monitor message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceMonitor(BDT *Bdt)
{
printf("%s got a Monitor message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Value message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceValue(BDT *Bdt)
{
printf("%s got a Value message\n", MESSAGE_PREFIX);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Delta message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceDelta(BDT *Bdt)
{
printf("%s got a Delta message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of an Add message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceAdd(BDT *Bdt)
{
printf("%s got a Add message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Delete message.
*
* Not Supported.
*
*****************************************************************************/
STATIC int BDT_ServiceDelete(BDT *Bdt)
{
printf("%s got a Delete message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Error, 0);
return(0);
}
/*****************************************************************************
*
* Handle the receipt of a Ping message.
*
*****************************************************************************/
STATIC int BDT_ServicePing(BDT *Bdt)
{
printf("%s got a Ping message\n", MESSAGE_PREFIX);
BdtSendHeader(Bdt, BDT_Ok, 0);
return(0);
}
BdtHandlers BDT_ServiceHandler_pv =
{
BDT_ServiceOk,
BDT_ServiceConnect,
BDT_ServiceError,
BDT_ServiceGet,
BDT_ServicePut,
BDT_ServiceClose,
BDT_ServiceMonitor,
BDT_ServiceValue,
BDT_ServiceDelta,
BDT_ServiceAdd,
BDT_ServiceDelete,
BDT_ServicePing
};

View File

@@ -5,11 +5,10 @@ $!
$! Purpose : To build the CHANNEL_ACCESS library and test programs for
$! VAX/VMS. This procedure assumes the following:
$! - You have copied *.c and *.h from the Epics channel access
$! source directory (.../src/ca) into this VMS directory
$! - You have copied envSubr.c, ellLib.c, and bucketLib.c
$! from the Epics
$! source directory (base/src/ca) into this VMS directory
$! - You have copied *.c and *.h from the Epics
$! libCom directory into this VMS directory
$! - You have copied *.h from the /src/epicsH directory into this
$! - You have copied *.h from the base/include directory into this
$! VMS directory
$! - You are using Multinet for TCP/IP access. If not, the logical
$! name definitions below will need to be changed

View File

@@ -34,13 +34,7 @@ include $(EPICS)/config/RULES.Unix
acctst: acctst.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
acctst.o: ../acctst.c
$(COMPILE.c) $<
catime: catime.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
catime.o: ../catime.c
$(COMPILE.c) $<

View File

@@ -8,21 +8,11 @@ SRCS.c = \
../if_depen.c ../bsd_depen.c ../vxWorks_depen.c ../acctst.c \
../catime.c
OBJS = \
LIBOBJS = \
iocinf.o access.o test_event.o service.o flow_control.o \
repeater.o conn.o syncgrp.o if_depen.o bsd_depen.o vxWorks_depen.o
PROD = caLib
LIBNAME = caLib
include $(EPICS)/config/RULES.Vx
caLib: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)
acctst.o: ../acctst.c
$(COMPILE.c) $<
catime.o: ../catime.c
$(COMPILE.c) $<

View File

@@ -1,3 +1,4 @@
/* $Id$ */
/************************************************************************/
/* */
/* L O S A L A M O S */
@@ -92,7 +93,44 @@
/* 011394 joh fixed bucketLib level memory leak (vxWorks) */
/* 020494 joh Added user name protocol */
/* 022294 joh fixed recv task id verify at exit (vxWorks) */
/* */
/* 072895 joh fixed problem resulting from unsigned long */
/* tv_sec var in struct timeval in sys/time.h */
/* under HPUX */
/************************************************************************/
/*
* $Log$
* Revision 1.79 1995/10/12 01:30:10 jhill
* new ca_flush_io() mechanism prevents deadlock when they call
* ca_flush_io() from within an event routine. Also forces early
* transmission of leading search UDP frames.
*
* Revision 1.78 1995/09/29 21:47:33 jhill
* alignment fix for SPARC IOC client and changes to prevent running of
* access rights or connection handlers when the connection is lost just
* after deleting a channel
*
* Revision 1.77 1995/09/01 14:31:32 mrk
* Fixed bug causing memory problem
*
* Revision 1.76 1995/08/23 00:34:06 jhill
* fixed vxWorks specific SPARC data alignment problem
*
* Revision 1.75 1995/08/22 00:15:19 jhill
* Use 1.0/USEC_PER_SEC and not 1.0e-6
* Check for S_db_Pending when calling dbPutNotify()
*
* Revision 1.74 1995/08/22 00:12:07 jhill
* *** empty log message ***
*
* Revision 1.73 1995/08/14 19:26:10 jhill
* epicsAPI => epicsShareAPI
*
* Revision 1.72 1995/08/12 00:23:32 jhill
* check for res id in use, epicsEntry, dont wait for itsy bitsy delay
* in ca_pend_event(), better clean up when monitor is deleted and
* we are disconnected
*
*/
/*_begin */
/************************************************************************/
/* */
@@ -292,6 +330,22 @@ void *pext
while(TRUE){
struct timeval itimeout;
/*
* record the time if we end up blocking so that
* we can time out
*/
if (bytesAvailable>=msgsize){
piiu->sendPending = FALSE;
break;
}
else {
if (!piiu->sendPending) {
piiu->timeAtSendBlock =
ca_static->currentTime;
piiu->sendPending = TRUE;
}
}
/*
* if connection drops request
* cant be completed
@@ -311,21 +365,6 @@ void *pext
bytesAvailable = cacRingBufferWriteSize(
&piiu->send,
FALSE);
/*
* record the time if we end up blocking so that
* we can time out
*/
if (bytesAvailable>=extsize+sizeof(msg)) {
piiu->sendPending = FALSE;
break;
}
else {
if (!piiu->sendPending) {
piiu->timeAtSendBlock =
ca_static->currentTime;
piiu->sendPending = TRUE;
}
}
}
}
@@ -443,7 +482,7 @@ LOCAL void cac_add_msg (IIU *piiu)
/*
* CA_TASK_INITIALIZE
*/
int APIENTRY ca_task_initialize(void)
int epicsShareAPI ca_task_initialize(void)
{
int status;
struct ca_static *ca_temp;
@@ -548,6 +587,8 @@ int ca_os_independent_init (void)
ca_spawn_repeater();
}
ca_static->ca_flush_pending = FALSE;
return ECA_NORMAL;
}
@@ -566,6 +607,7 @@ LOCAL void create_udp_fd()
status = create_net_chan(
&ca_static->ca_piiuCast,
NULL,
ca_static->ca_server_port,
IPPROTO_UDP);
if (~status & CA_M_SUCCESS) {
ca_static->ca_piiuCast = NULL;
@@ -589,7 +631,7 @@ LOCAL void create_udp_fd()
status = taskSpawn(
name,
pri-1,
pri+1,
VX_FP_TASK,
4096,
(FUNCPTR)cac_recv_task,
@@ -620,7 +662,7 @@ LOCAL void create_udp_fd()
* Modify or override the default
* client host name.
*/
int APIENTRY ca_modify_host_name(char *pHostName)
int epicsShareAPI ca_modify_host_name(char *pHostName)
{
char *pTmp;
unsigned size;
@@ -675,7 +717,7 @@ int APIENTRY ca_modify_host_name(char *pHostName)
* Modify or override the default
* client user name.
*/
int APIENTRY ca_modify_user_name(char *pClientName)
int epicsShareAPI ca_modify_user_name(char *pClientName)
{
char *pTmp;
unsigned size;
@@ -730,7 +772,7 @@ int APIENTRY ca_modify_user_name(char *pClientName)
* call this routine if you wish to free resources prior to task
* exit- ca_task_exit() is also executed routinely at task exit.
*/
int APIENTRY ca_task_exit (void)
int epicsShareAPI ca_task_exit (void)
{
/*
* This indirectly calls ca_process_exit() below
@@ -858,10 +900,10 @@ void ca_process_exit()
/*
* free hash tables
*/
status = bucketFree(ca_static->ca_pSlowBucket);
assert(status == BUCKET_SUCCESS);
status = bucketFree(ca_static->ca_pFastBucket);
assert(status == BUCKET_SUCCESS);
status = bucketFree (ca_static->ca_pSlowBucket);
assert (status == S_bucket_success);
status = bucketFree (ca_static->ca_pFastBucket);
assert (status == S_bucket_success);
/*
* free beacon hash table
@@ -880,7 +922,7 @@ void ca_process_exit()
*
* backwards compatible entry point to ca_search_and_connect()
*/
int APIENTRY ca_build_and_connect
int epicsShareAPI ca_build_and_connect
(
char *name_str,
chtype get_type,
@@ -905,7 +947,7 @@ int APIENTRY ca_build_and_connect
*
*
*/
int APIENTRY ca_search_and_connect
int epicsShareAPI ca_search_and_connect
(
char *name_str,
chid *chixptr,
@@ -950,13 +992,14 @@ int APIENTRY ca_search_and_connect
* also allocate enough for the channel name & paddr
* block
*/
size = sizeof(*chix) + strcnt + sizeof(struct db_addr);
size = CA_MESSAGE_ALIGN(sizeof(*chix) + strcnt) +
sizeof(struct db_addr);
*chixptr = chix = (chid) calloc(1,size);
if (!chix){
return ECA_ALLOCMEM;
}
chix->id.paddr = (struct db_addr *)
(strcnt + (char *) (chix + 1));
(CA_MESSAGE_ALIGN(sizeof(*chix)+strcnt) + (char *)chix);
*chix->id.paddr = tmp_paddr;
chix->puser = puser;
chix->pConnFunc = conn_func;
@@ -1010,13 +1053,20 @@ int APIENTRY ca_search_and_connect
}
LOCK;
chix->cid = CLIENT_SLOW_ID_ALLOC;
status = bucketAddItemUnsignedId(pSlowBucket, &chix->cid, chix);
if(status != BUCKET_SUCCESS){
do {
chix->cid = CLIENT_SLOW_ID_ALLOC;
status = bucketAddItemUnsignedId (pSlowBucket,
&chix->cid, chix);
} while (status == S_bucket_idInUse);
if (status != S_bucket_success) {
*chixptr = (chid) NULL;
free((char *) chix);
UNLOCK;
return ECA_ALLOCMEM;
if (status == S_bucket_noMemory) {
return ECA_ALLOCMEM;
}
return ECA_INTERNAL;
}
chix->puser = puser;
@@ -1127,7 +1177,7 @@ int reply_type
*
*
*/
int APIENTRY ca_array_get
int epicsShareAPI ca_array_get
(
chtype type,
unsigned long count,
@@ -1195,8 +1245,10 @@ void *pvalue
}
else {
LOCK;
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
}
UNLOCK;
}
}
@@ -1212,7 +1264,7 @@ void *pvalue
/*
* CA_ARRAY_GET_CALLBACK()
*/
int APIENTRY ca_array_get_callback
int epicsShareAPI ca_array_get_callback
(
chtype type,
unsigned long count,
@@ -1273,8 +1325,10 @@ void *arg
status = issue_get_callback (monix, IOC_READ_NOTIFY);
if (status != ECA_NORMAL) {
LOCK;
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&pend_read_list, &monix->node);
caIOBlockFree (monix);
}
UNLOCK;
}
}
@@ -1305,12 +1359,15 @@ LOCAL evid caIOBlockCreate(void)
}
if (pIOBlock) {
pIOBlock->id = CLIENT_FAST_ID_ALLOC;
status = bucketAddItemUnsignedId(
pFastBucket,
&pIOBlock->id,
pIOBlock);
if(status != BUCKET_SUCCESS){
do {
pIOBlock->id = CLIENT_FAST_ID_ALLOC;
status = bucketAddItemUnsignedId(
pFastBucket,
&pIOBlock->id,
pIOBlock);
} while (status == S_bucket_idInUse);
if(status != S_bucket_success){
free(pIOBlock);
pIOBlock = NULL;
}
@@ -1333,7 +1390,7 @@ void caIOBlockFree(evid pIOBlock)
status = bucketRemoveItemUnsignedId(
ca_static->ca_pFastBucket,
&pIOBlock->id);
assert (status == BUCKET_SUCCESS);
assert (status == S_bucket_success);
pIOBlock->id = ~0U; /* this id always invalid */
ellAdd (&free_event_list, &pIOBlock->node);
UNLOCK;
@@ -1433,7 +1490,7 @@ LOCAL int issue_get_callback(evid monix, unsigned cmmd)
* CA_ARRAY_PUT_CALLBACK()
*
*/
int APIENTRY ca_array_put_callback
int epicsShareAPI ca_array_put_callback
(
chtype type,
unsigned long count,
@@ -1537,7 +1594,7 @@ void *usrarg
}
status = dbPutNotify(&ppn->dbPutNotify);
UNLOCK;
if(status){
if(status && status != S_db_Pending){
if(status==S_db_Blocked){
return ECA_PUTCBINPROG;
}
@@ -1577,8 +1634,10 @@ void *usrarg
pvalue);
if(status != ECA_NORMAL){
LOCK;
ellDelete (&pend_write_list, &monix->node);
caIOBlockFree(monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&pend_write_list, &monix->node);
caIOBlockFree(monix);
}
UNLOCK;
return status;
}
@@ -1642,7 +1701,7 @@ LOCAL void ca_put_notify_action(PUTNOTIFY *ppn)
*
*
*/
int APIENTRY ca_array_put (
int epicsShareAPI ca_array_put (
chtype type,
unsigned long count,
chid chix,
@@ -1883,7 +1942,7 @@ LOCAL void free_put_convert(void *pBuf)
* Specify an event subroutine to be run for connection events
*
*/
int APIENTRY ca_change_connection_event
int epicsShareAPI ca_change_connection_event
(
chid chix,
void (*pfunc)(struct connection_handler_args)
@@ -1915,7 +1974,7 @@ void (*pfunc)(struct connection_handler_args)
/*
* ca_replace_access_rights_event
*/
int APIENTRY ca_replace_access_rights_event(
int epicsShareAPI ca_replace_access_rights_event(
chid chan,
void (*pfunc)(struct access_rights_handler_args))
{
@@ -1929,7 +1988,7 @@ void (*pfunc)(struct access_rights_handler_args))
/*
* make certain that it runs at least once
*/
if(chan->state == cs_conn){
if(chan->state == cs_conn && chan->pAccessRightsFunc){
args.chid = chan;
args.ar = chan->ar;
(*chan->pAccessRightsFunc)(args);
@@ -1943,7 +2002,7 @@ void (*pfunc)(struct access_rights_handler_args))
* Specify an event subroutine to be run for asynch exceptions
*
*/
int APIENTRY ca_add_exception_event
int epicsShareAPI ca_add_exception_event
(
void (*pfunc)(struct exception_handler_args),
void *arg
@@ -1975,7 +2034,7 @@ void *arg
* Undocumented entry for the VAX OPI which may vanish in the future.
*
*/
int APIENTRY ca_add_io_event
int epicsShareAPI ca_add_io_event
(
void (*ast)(),
void *astarg
@@ -2010,7 +2069,7 @@ void *astarg
*
*
*/
int APIENTRY ca_add_masked_array_event
int epicsShareAPI ca_add_masked_array_event
(
chtype type,
unsigned long count,
@@ -2140,8 +2199,10 @@ long mask
status = ca_request_event(monix);
if (status != ECA_NORMAL) {
LOCK;
ellDelete (&chix->eventq, &monix->node);
caIOBlockFree(monix);
if (ca_state(chix)==cs_conn) {
ellDelete (&chix->eventq, &monix->node);
caIOBlockFree(monix);
}
UNLOCK
}
return status;
@@ -2373,7 +2434,7 @@ void *pfl
* after leaving this routine.
*
*/
int APIENTRY ca_clear_event (evid monix)
int epicsShareAPI ca_clear_event (evid monix)
{
int status;
chid chix = monix->chan;
@@ -2448,6 +2509,7 @@ int APIENTRY ca_clear_event (evid monix)
else{
LOCK;
ellDelete(&monix->chan->eventq, &monix->node);
caIOBlockFree(monix);
UNLOCK;
status = ECA_NORMAL;
}
@@ -2471,7 +2533,7 @@ int APIENTRY ca_clear_event (evid monix)
* (from this source) after leaving this routine.
*
*/
int APIENTRY ca_clear_channel (chid chix)
int epicsShareAPI ca_clear_channel (chid chix)
{
int status;
evid monix;
@@ -2485,6 +2547,8 @@ int APIENTRY ca_clear_channel (chid chix)
chix->type = TYPENOTINUSE;
old_chan_state = chix->state;
chix->state = cs_closed;
chix->pAccessRightsFunc = NULL;
chix->pConnFunc = NULL;
/* the while is only so I can break to the lock exit */
LOCK;
@@ -2614,7 +2678,7 @@ void clearChannelResources(unsigned id)
ellDelete (&piiu->chidlist, &chix->node);
status = bucketRemoveItemUnsignedId (
ca_static->ca_pSlowBucket, &chix->cid);
assert (status == BUCKET_SUCCESS);
assert (status == S_bucket_success);
free (chix);
if (piiu!=piiuCast && !piiu->chidlist.count){
TAG_CONN_DOWN(piiu);
@@ -2631,48 +2695,59 @@ void clearChannelResources(unsigned id)
/* if the argument early is specified TRUE then CA_NORMAL is */
/* returned early (prior to timeout experation) when outstanding */
/* IO completes. */
/* ca_flush_io() is called by this routine. */
/* Output buffers are flushed by this routine */
/************************************************************************/
int APIENTRY ca_pend(ca_real timeout, int early)
int epicsShareAPI ca_pend (ca_real timeout, int early)
{
struct timeval beg_time;
ca_real delay;
struct timeval tmo;
INITCHK;
if(timeout<0.0){
return ECA_TIMEOUT;
}
if(EVENTLOCKTEST){
return ECA_EVDISALLOW;
}
cac_gettimeval (&ca_static->currentTime);
/*
* Flush the send buffers
* (guarantees that we wait for all send buffer to be
* flushed even if this requires blocking)
*
* Also takes care of outstanding recvs
* for single threaded clients
*/
ca_flush_io();
ca_static->ca_flush_pending = TRUE;
if(pndrecvcnt<1 && early){
/*
* force the flush
*/
LD_CA_TIME (0.0, &tmo);
cac_mux_io(&tmo);
return ECA_NORMAL;
}
/*
* the current time set iderectly within ca_flush_io()
* above.
*/
if(timeout<0.0){
/*
* force the flush
*/
LD_CA_TIME (0.0, &tmo);
cac_mux_io(&tmo);
return ECA_TIMEOUT;
}
beg_time = ca_static->currentTime;
delay = 0.0;
while(TRUE){
ca_real remaining;
struct timeval tmo;
if (pndrecvcnt<1 && early) {
/*
* force the flush
*/
LD_CA_TIME (0.0, &tmo);
cac_mux_io(&tmo);
return ECA_NORMAL;
}
@@ -2681,29 +2756,48 @@ int APIENTRY ca_pend(ca_real timeout, int early)
}
else{
remaining = timeout-delay;
if(remaining<=0.0){
if(early){
ca_pend_io_cleanup();
}
ca_flush_io();
return ECA_TIMEOUT;
}
/*
* Allow for CA background labor
*/
remaining = min(SELECT_POLL, remaining);
}
tmo.tv_sec = (long) remaining;
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
cac_block_for_io_completion(&tmo);
/*
* the current time set within cac_block_for_io_completion()
* above.
* If we are no longer waiting any significant
* delay then return
* (dont wait forever for an itsy bitsy
* delay which will no be updated if
* select is called with no delay)
*
* current time is only updated by
* cac_select_io() if we specify
* at least 1 usec to wait
*
*/
if (remaining <= (1.0/USEC_PER_SEC)) {
if(early){
ca_pend_io_cleanup();
ca_static->ca_flush_pending = TRUE;
}
/*
* be certain that we processed
* recv backlog at least once
*/
/*
* force the flush
*/
LD_CA_TIME (0.0, &tmo);
cac_block_for_io_completion (&tmo);
return ECA_TIMEOUT;
}
tmo.tv_sec = (long) remaining;
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
cac_block_for_io_completion (&tmo);
if (timeout != 0.0) {
delay = cac_time_diff (&ca_static->currentTime, &beg_time);
delay = cac_time_diff (&ca_static->currentTime,
&beg_time);
}
}
}
@@ -2714,20 +2808,31 @@ int APIENTRY ca_pend(ca_real timeout, int early)
*/
ca_real cac_time_diff (ca_time *pTVA, ca_time *pTVB)
{
ca_real delay;
ca_real delay;
ca_real udelay;
if(pTVA->tv_usec>pTVB->tv_usec){
delay = pTVA->tv_sec - pTVB->tv_sec;
delay += (pTVA->tv_usec - pTVB->tv_usec) /
(ca_real)(USEC_PER_SEC);
}
else{
delay = pTVA->tv_sec - pTVB->tv_sec - 1L;
delay += (USEC_PER_SEC - pTVB->tv_usec + pTVA->tv_usec) /
(ca_real)(USEC_PER_SEC);
}
/*
* works with unsigned tv_sec in struct timeval
* under HPUX
*/
if (pTVA->tv_sec>pTVB->tv_sec) {
delay = pTVA->tv_sec - pTVB->tv_sec;
}
else {
delay = pTVB->tv_sec - pTVA->tv_sec;
delay = -delay;
}
return delay;
if(pTVA->tv_usec>pTVB->tv_usec){
udelay = pTVA->tv_usec - pTVB->tv_usec;
}
else{
delay -= 1.0;
udelay = (USEC_PER_SEC - pTVB->tv_usec) + pTVA->tv_usec;
}
delay += udelay / USEC_PER_SEC;
return delay;
}
@@ -2790,55 +2895,27 @@ LOCAL void ca_pend_io_cleanup()
/*
* CA_FLUSH_IO()
*
* Flush the send buffer
*
* reprocess connection state and
* flush the send buffer
*/
int APIENTRY ca_flush_io()
int epicsShareAPI ca_flush_io()
{
struct ioc_in_use *piiu;
struct timeval timeout;
int pending;
unsigned long bytesPending;
INITCHK;
pending = TRUE;
timeout.tv_usec = 0;
timeout.tv_sec = 0;
while(pending){
/*
* force early transmission of the first few search frames
*/
manage_conn(TRUE);
/*
* perform socket io
* and process recv backlog
*/
cac_mux_io(&timeout);
/*
* wait for all buffers to flush
*/
pending = FALSE;
LOCK;
for( piiu = (IIU *) iiuList.node.next;
piiu;
piiu = (IIU *) piiu->node.next){
if(piiu == piiuCast || piiu->conn_up == FALSE){
continue;
}
bytesPending = cacRingBufferReadSize(
&piiu->send,
FALSE);
if(bytesPending != 0){
pending = TRUE;
}
}
UNLOCK;
LD_CA_TIME (SELECT_POLL, &timeout);
}
/*
* Wait for all send buffers to be flushed
* while performing socket io and processing recv backlog
*/
ca_static->ca_flush_pending = TRUE;
LD_CA_TIME (0.0, &timeout);
cac_mux_io (&timeout);
return ECA_NORMAL;
}
@@ -2848,7 +2925,7 @@ int APIENTRY ca_flush_io()
* CA_TEST_IO ()
*
*/
int APIENTRY ca_test_io()
int epicsShareAPI ca_test_io()
{
if(pndrecvcnt<1){
return ECA_IODONE;
@@ -2864,7 +2941,7 @@ int APIENTRY ca_test_io()
*
*
*/
void APIENTRY ca_signal(long ca_status,char *message)
void epicsShareAPI ca_signal(long ca_status,char *message)
{
ca_signal_with_file_and_lineno(ca_status, message, NULL, 0);
}
@@ -2873,7 +2950,7 @@ void APIENTRY ca_signal(long ca_status,char *message)
/*
* ca_signal_with_file_and_lineno()
*/
void APIENTRY ca_signal_with_file_and_lineno(
void epicsShareAPI ca_signal_with_file_and_lineno(
long ca_status,
char *message,
char *pfilenm,
@@ -3236,7 +3313,7 @@ LOCAL void ca_default_exception_handler(struct exception_handler_args args)
* (for a manager of the select system call under UNIX)
*
*/
int APIENTRY ca_add_fd_registration(CAFDHANDLER *func, void *arg)
int epicsShareAPI ca_add_fd_registration(CAFDHANDLER *func, void *arg)
{
fd_register_func = func;
fd_register_arg = arg;
@@ -3267,7 +3344,7 @@ int ca_defunct()
* currently implemented as a function
* (may be implemented as a MACRO in the future)
*/
char * APIENTRY ca_host_name_function(chid chix)
char * epicsShareAPI ca_host_name_function(chid chix)
{
IIU *piiu;
@@ -3283,7 +3360,7 @@ char * APIENTRY ca_host_name_function(chid chix)
/*
* ca_v42_ok(chid chan)
*/
int APIENTRY ca_v42_ok(chid chan)
int epicsShareAPI ca_v42_ok(chid chan)
{
int v42;
IIU *piiu;
@@ -3360,10 +3437,12 @@ int ca_channel_status(int tid)
/*
* ca_replace_printf_handler ()
*/
int APIENTRY ca_replace_printf_handler (
int epicsShareAPI ca_replace_printf_handler (
int (*ca_printf_func)(const char *pformat, va_list args)
)
{
INITCHK;
if (ca_printf_func) {
ca_static->ca_printf_func = ca_printf_func;
}

View File

@@ -5,6 +5,16 @@
static char *sccsId = "@(#) $Id$";
/*
* $Log$
* Revision 1.30 1995/09/29 21:47:58 jhill
* MS windows changes
*
* Revision 1.29 1995/08/22 00:16:34 jhill
* Added test of the duration of ca_pend_event()
*
*/
#ifdef VMS
#include <LIB$ROUTINES.H>
#endif
@@ -19,7 +29,7 @@ static char *sccsId = "@(#) $Id$";
#include "os_depen.h"
#include <epicsAssert.h>
#include <assert.h>
#include <cadef.h>
#define EVENT_ROUTINE null_event
@@ -27,7 +37,11 @@ static char *sccsId = "@(#) $Id$";
#define NUM 1
int conn_get_cb_count;
int conn_cb_count;
#ifndef min
#define min(A,B) ((A)>(B)?(B):(A))
#endif
int doacctst(char *pname);
void test_sync_groups(chid chix);
@@ -35,9 +49,22 @@ void multiple_sg_requests(chid chix, CA_SYNC_GID gid);
void null_event(struct event_handler_args args);
void write_event(struct event_handler_args args);
void conn(struct connection_handler_args args);
void conn_cb(struct event_handler_args args);
void get_cb(struct event_handler_args args);
void accessSecurity_cb(struct access_rights_handler_args args);
void doubleTest(
chid chan,
dbr_double_t beginValue,
dbr_double_t increment,
dbr_double_t epsilon,
unsigned iterations);
void floatTest(
chid chan,
dbr_float_t beginValue,
dbr_float_t increment,
dbr_float_t epsilon,
unsigned iterations);
#ifdef vxWorks
int acctst(char *pname)
@@ -82,25 +109,45 @@ int doacctst(char *pname)
chid chix4;
struct dbr_gr_float *ptr = NULL;
struct dbr_gr_float *pgrfloat = NULL;
float *pfloat = NULL;
double *pdouble = NULL;
dbr_float_t *pfloat = NULL;
dbr_double_t *pdouble = NULL;
long status;
long i, j;
evid monix;
char pstring[NUM][MAX_STRING_SIZE];
unsigned size;
SEVCHK(ca_task_initialize(), "Unable to initialize");
conn_get_cb_count = 0;
conn_cb_count = 0;
printf("begin\n");
#ifdef VMS
lib$init_timer();
#endif /*VMS*/
ptr = (struct dbr_gr_float *)
malloc(dbr_size_n(DBR_GR_FLOAT, NUM));
{
TS_STAMP end_time;
TS_STAMP start_time;
dbr_double_t delay;
dbr_double_t request = 0.5;
dbr_double_t accuracy;
tsLocalTime(&start_time);
status = ca_pend_event(request);
if (status != ECA_TIMEOUT) {
SEVCHK(status, NULL);
}
tsLocalTime(&end_time);
TsDiffAsDouble(&delay,&end_time,&start_time);
accuracy = 100.0*(delay-request)/request;
printf("CA pend event delay accuracy = %f %%\n",
accuracy);
assert (abs(accuracy) < 10.0);
}
size = dbr_size_n(DBR_GR_FLOAT, NUM);
ptr = (struct dbr_gr_float *) malloc(size);
for (i = 0; i < 10; i++) {
@@ -213,41 +260,81 @@ int doacctst(char *pname)
ca_read_access(chix1),
ca_write_access(chix1));
#if 0
/*
* Verify that we can write and then read back
* the same value
* the same analog value
*/
if( (ca_field_type(chix1)==DBR_FLOAT ||
ca_field_type(chix1)==DBR_DOUBLE) &&
ca_read_access(chix1) &&
ca_write_access(chix1)){
double dval = 3.3;
float fval = -8893.3;
double dret = DBL_MAX;
float fret = FLT_MAX;
dbr_double_t incr;
dbr_double_t epsil;
dbr_double_t base;
unsigned long iter;
status = ca_put(DBR_DOUBLE, chix1, &dval);
SEVCHK(status, NULL);
status = ca_get(DBR_DOUBLE, chix1, &dret);
SEVCHK(status, NULL);
ca_pend_io(30.0);
assert( fabs(dval-dret) < DBL_EPSILON*4);
printf ("float test ...");
fflush(stdout);
epsil = FLT_EPSILON*4;
base = FLT_MIN;
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = FLT_MAX/fabs(incr);
iter = min (iter,10);
floatTest(chix1, base, incr, epsil, iter);
}
base = FLT_MAX;
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
incr = - ldexp (0.5,i);
iter = FLT_MAX/fabs(incr);
iter = min (iter,10);
floatTest(chix1, base, incr, epsil, iter);
}
base = - FLT_MAX;
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = FLT_MAX/fabs(incr);
iter = min (iter,10);
floatTest(chix1, base, incr, epsil, iter);
}
printf ("done\n");
status = ca_put(DBR_FLOAT, chix1, &fval);
SEVCHK(status, NULL);
status = ca_get(DBR_FLOAT, chix1, &fret);
SEVCHK(status, NULL);
ca_pend_io(30.0);
assert( fabs(fval-fret) < FLT_EPSILON*4);
printf ("double test ...");
fflush(stdout);
epsil = DBL_EPSILON*4;
base = DBL_MIN;
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = DBL_MAX/fabs(incr);
iter = min (iter,10);
doubleTest(chix1, base, incr, epsil, iter);
}
base = DBL_MAX;
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
incr = - ldexp (0.5,i);
iter = DBL_MAX/fabs(incr);
iter = min (iter,10);
doubleTest(chix1, base, incr, epsil, iter);
}
base = - DBL_MAX;
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
incr = ldexp (0.5,i);
iter = DBL_MAX/fabs(incr);
iter = min (iter,10);
doubleTest(chix1, base, incr, epsil, iter);
}
printf ("done\n");
}
#endif
/*
* verify we dont jam up on many uninterrupted
* solicitations
*/
if(ca_read_access(chix4)){
float temp;
dbr_float_t temp;
printf("Performing multiple get test...");
fflush(stdout);
@@ -268,7 +355,7 @@ int doacctst(char *pname)
printf("Performing multiple put test...");
fflush(stdout);
for(i=0; i<10000; i++){
double fval = 3.3;
dbr_double_t fval = 3.3;
status = ca_put(DBR_DOUBLE, chix4, &fval);
SEVCHK(status, NULL);
}
@@ -315,7 +402,7 @@ int doacctst(char *pname)
printf("Performing multiple put callback test...");
fflush(stdout);
for(i=0; i<10000; i++){
float fval = 3.3;
dbr_float_t fval = 3.3F;
status = ca_array_put_callback(
DBR_FLOAT,
1,
@@ -339,8 +426,8 @@ int doacctst(char *pname)
printf("Performing multiple monitor test...");
fflush(stdout);
{
evid mid[1000];
float temp;
evid mid[1000];
dbr_float_t temp;
for(i=0; i<NELEMENTS(mid); i++){
SEVCHK(ca_add_event(DBR_GR_FLOAT, chix4, null_event,
@@ -418,8 +505,8 @@ int doacctst(char *pname)
SEVCHK(status, NULL);
}
pfloat = (float *) calloc(sizeof(float),NUM);
pdouble = (double *) calloc(sizeof(double),NUM);
pfloat = (dbr_float_t *) calloc(sizeof(*pfloat),NUM);
pdouble = (dbr_double_t *) calloc(sizeof(*pdouble),NUM);
pgrfloat = (struct dbr_gr_float *) calloc(sizeof(*pgrfloat),NUM);
if (VALID_DB_REQ(chix1->type))
@@ -475,13 +562,13 @@ int doacctst(char *pname)
SEVCHK(ca_modify_user_name("Willma"), NULL);
SEVCHK(ca_modify_host_name("Bed Rock"), NULL);
if (conn_get_cb_count != 3){
if (conn_cb_count != 3){
printf ("!!!! Connect cb count = %d expected = 3 !!!!\n",
conn_get_cb_count);
conn_cb_count);
}
printf("-- Put/Gets done- waiting for Events --\n");
status = ca_pend_event(10.0);
status = ca_pend_event(1000.0);
if (status != ECA_TIMEOUT) {
SEVCHK(status, NULL);
}
@@ -505,11 +592,68 @@ int doacctst(char *pname)
return(0);
}
void floatTest(
chid chan,
dbr_float_t beginValue,
dbr_float_t increment,
dbr_float_t epsilon,
unsigned iterations)
{
unsigned i;
dbr_float_t fval;
dbr_float_t fretval;
int status;
fval = beginValue;
for (i=0; i<iterations; i++) {
fretval = FLT_MAX;
status = ca_put (DBR_FLOAT, chan, &fval);
SEVCHK (status, NULL);
status = ca_get (DBR_FLOAT, chan, &fretval);
SEVCHK (status, NULL);
status = ca_pend_io (100.0);
SEVCHK (status, NULL);
assert (fabs(fval-fretval) < epsilon);
fval += increment;
}
}
void doubleTest(
chid chan,
dbr_double_t beginValue,
dbr_double_t increment,
dbr_double_t epsilon,
unsigned iterations)
{
unsigned i;
dbr_double_t fval;
dbr_double_t fretval;
int status;
fval = beginValue;
for (i=0; i<iterations; i++) {
fretval = DBL_MAX;
status = ca_put (DBR_DOUBLE, chan, &fval);
SEVCHK (status, NULL);
status = ca_get (DBR_DOUBLE, chan, &fretval);
SEVCHK (status, NULL);
status = ca_pend_io (100.0);
SEVCHK (status, NULL);
assert (fabs(fval-fretval) < epsilon);
fval += increment;
}
}
void null_event(struct event_handler_args args)
{
static int i;
dbr_double_t fval = 3.8;
int status;
status = ca_put (DBR_DOUBLE, args.chid, &fval);
SEVCHK (status, NULL);
if (i++ > 1000) {
printf("1000 occurred\n");
@@ -521,9 +665,15 @@ void null_event(struct event_handler_args args)
void write_event(struct event_handler_args args)
{
int status;
float a = *(float *) args.dbr;
dbr_float_t *pFloat = (dbr_float_t *) args.dbr;
dbr_float_t a;
a += 10.1;
if (!args.dbr) {
return;
}
a = *pFloat;
a += 10.1F;
status = ca_array_put(
DBR_FLOAT,
@@ -544,15 +694,15 @@ void conn(struct connection_handler_args args)
else
printf("Ukn conn ev\n");
ca_get_callback(DBR_GR_FLOAT, args.chid, conn_cb, NULL);
ca_get_callback(DBR_GR_FLOAT, args.chid, get_cb, NULL);
}
void conn_cb(struct event_handler_args args)
void get_cb(struct event_handler_args args)
{
if(!(args.status & CA_M_SUCCESS)){
printf("Get cb failed because \"%s\"\n", ca_message(args.status));
}
conn_get_cb_count++;
conn_cb_count++;
}
@@ -612,10 +762,10 @@ void test_sync_groups(chid chix)
*/
void multiple_sg_requests(chid chix, CA_SYNC_GID gid)
{
int status;
unsigned i;
static float fvalput = 3.3;
static float fvalget;
int status;
unsigned i;
static dbr_float_t fvalput = 3.3F;
static dbr_float_t fvalget;
for(i=0; i<1000; i++){
if(ca_write_access(chix)){

View File

@@ -19,7 +19,7 @@ void caAddConfiguredAddr(
int port);
int local_addr(SOCKET socket, struct sockaddr_in *plcladdr);
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort);
unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort);
union caAddr{
struct sockaddr_in inetAddr;

View File

@@ -115,7 +115,13 @@ int cac_select_io(struct timeval *ptimeout, int flags)
&autoTimeOut);
# endif
cac_gettimeval (&ca_static->currentTime);
/*
* get a new time stamp if we have been waiting
* for any significant length of time
*/
if (ptimeout->tv_sec || ptimeout->tv_usec) {
cac_gettimeval (&ca_static->currentTime);
}
if (status<0) {
if (MYERRNO == EINTR) {

View File

@@ -59,6 +59,7 @@ LOCAL void test (
unsigned iterations
);
LOCAL tf test_pend;
LOCAL tf test_search;
LOCAL tf test_free;
LOCAL tf test_wait;
@@ -82,7 +83,7 @@ int main(int argc, char **argv)
catime(pname);
}
else{
printf("usage: %s <channel name>", argv[0]);
printf("usage: %s <channel name>\n", argv[0]);
return -1;
}
return 0;
@@ -119,6 +120,9 @@ int catime (char *channelName)
ca_field_type(itemList[0].chix),
ca_element_count(itemList[0].chix));
printf ("\tpend event test\n");
timeIt (test_pend, NULL, 100);
for (i=0; i<NELEMENTS(itemList); i++) {
itemList[i].val.fltval = 0.0;
itemList[i].type = DBR_FLOAT;
@@ -183,14 +187,56 @@ void timeIt(
unsigned inlineIter;
status = tsLocalTime(&start_time);
#if 0
assert (status == S_ts_OK);
#endif
(*pfunc) (pItems, iterations, &inlineIter);
status = tsLocalTime(&end_time);
#if 0
assert (status == S_ts_OK);
#endif
TsDiffAsDouble(&delay,&end_time,&start_time);
printf ("Elapsed Per Item = %f\n", delay/(iterations*inlineIter));
}
/*
* test_search ()
*/
LOCAL void test_pend(
ti *pItems,
unsigned iterations,
unsigned *pInlineIter
)
{
unsigned i;
int status;
for (i=0; i<iterations; i++) {
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
status = ca_pend_event(1e-9);
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
SEVCHK(status, NULL);
}
}
*pInlineIter = 5;
}
/*
* test_search ()

View File

@@ -1,5 +1,6 @@
/* $Id$ */
/************************************************************************/
/* */
/* */
/* L O S A L A M O S */
/* Los Alamos National Laboratory */
/* Los Alamos, New Mexico 87545 */
@@ -28,6 +29,7 @@
/* .12 110194 joh improved search scheduling */
/* (dont send all chans in a block) */
/* */
/* $Log$ */
/*_begin */
/************************************************************************/
/* */
@@ -349,7 +351,7 @@ LOCAL void logRetryInterval(char *pFN, unsigned lineno)
/*
* MARK_SERVER_AVAILABLE
*/
void mark_server_available(struct in_addr *pnet_addr)
void mark_server_available(const struct in_addr *pnet_addr)
{
chid chan;
ca_real currentPeriod;
@@ -502,7 +504,7 @@ void mark_server_available(struct in_addr *pnet_addr)
*
* LOCK must be applied
*/
bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr)
{
bhe *pBHE;
unsigned index;
@@ -535,7 +537,7 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
* start the average at zero
*/
pBHE->averagePeriod = 0.0;
cac_gettimeval(&pBHE->timeStamp);
pBHE->timeStamp = ca_static->currentTime;
/*
* install in the hash table
@@ -552,7 +554,7 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
*
* LOCK must be applied
*/
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
bhe *lookupBeaconInetAddr (const struct in_addr *pnet_addr)
{
bhe *pBHE;
unsigned index;
@@ -579,7 +581,7 @@ bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
*
* LOCK must be applied
*/
void removeBeaconInetAddr (struct in_addr *pnet_addr)
void removeBeaconInetAddr (const struct in_addr *pnet_addr)
{
bhe *pBHE;
bhe **ppBHE;

View File

@@ -1,4 +1,5 @@
/************************************************************************/
/* $Id$ */
/* */
/* L O S A L A M O S */
/* Los Alamos National Laboratory */
@@ -45,6 +46,7 @@
/* 021794 joh turn on SO_REUSEADDR only after the test for */
/* address in use so that test works on UNIX */
/* kernels that support multicast */
/* $Log$ */
/* */
/*_begin */
/************************************************************************/
@@ -94,8 +96,9 @@ LOCAL char *getToken(char **ppString);
*
*/
int alloc_ioc(
struct in_addr *pnet_addr,
struct ioc_in_use **ppiiu
const struct in_addr *pnet_addr,
unsigned short port,
struct ioc_in_use **ppiiu
)
{
int status;
@@ -127,6 +130,7 @@ struct ioc_in_use **ppiiu
status = create_net_chan(
ppiiu,
pnet_addr,
port,
IPPROTO_TCP);
if(status == ECA_NORMAL){
pBHE->piiu = *ppiiu;
@@ -145,7 +149,8 @@ struct ioc_in_use **ppiiu
*/
int create_net_chan(
struct ioc_in_use **ppiiu,
struct in_addr *pnet_addr, /* only used by TCP connections */
const struct in_addr *pnet_addr, /* only used by TCP connections */
unsigned short port,
int net_proto
)
{
@@ -190,8 +195,7 @@ int net_proto
memset((char *)&pNode->destAddr,0,sizeof(pNode->destAddr));
pNode->destAddr.inetAddr.sin_family = AF_INET;
pNode->destAddr.inetAddr.sin_addr = *pnet_addr;
pNode->destAddr.inetAddr.sin_port =
htons (ca_static->ca_server_port);
pNode->destAddr.inetAddr.sin_port = htons (port);
ellAdd(&piiu->destAddr, &pNode->node);
piiu->recvBytes = tcp_recv_msg;
piiu->sendBytes = cac_tcp_send_msg_piiu;
@@ -398,7 +402,7 @@ int net_proto
* let slib pick lcl addr
*/
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons(0);
saddr.sin_port = htons(0U);
status = bind( sock,
(struct sockaddr *) &saddr,
@@ -593,7 +597,7 @@ void notify_ca_repeater()
status = sendto(
piiuCast->sock_chan,
(char *)&msg, /* UCX requires a valid address here */
(char *)&msg,
len,
0,
(struct sockaddr *)&saddr,
@@ -601,11 +605,16 @@ void notify_ca_repeater()
if(status < 0){
if( MYERRNO != EINTR &&
MYERRNO != ENOBUFS &&
MYERRNO != EWOULDBLOCK){
MYERRNO != EWOULDBLOCK &&
/*
* This is returned from Linux when
* the repeater isnt running
*/
MYERRNO != ECONNREFUSED
){
ca_printf(
"send error => %s\n",
strerror(MYERRNO));
assert(0);
"CAC: error sending to repeater is \"%s\"\n",
strerror(MYERRNO));
}
}
else{
@@ -659,29 +668,24 @@ LOCAL void cac_udp_send_msg_piiu(struct ioc_in_use *piiu)
0,
&pNode->destAddr.sockAddr,
sizeof(pNode->destAddr.sockAddr));
if(status<0){
if(status>=0){
actualSendCnt = (unsigned long) status;
assert (actualSendCnt == sendCnt);
pNode = (caAddrNode *) pNode->node.next;
}
else {
int localErrno;
localErrno = MYERRNO;
if( localErrno == EWOULDBLOCK &&
localErrno == ENOBUFS &&
localErrno == EINTR){
UNLOCK;
return;
}
else {
if( localErrno != EWOULDBLOCK &&
localErrno != ENOBUFS &&
localErrno != EINTR){
ca_printf(
"CAC: error on socket send() %s\n",
"CAC: UDP send error = \"%s\"\n",
strerror(localErrno));
}
TAG_CONN_DOWN(piiu);
break;
}
actualSendCnt = (unsigned long) status;
assert (actualSendCnt == sendCnt);
pNode = (caAddrNode *) pNode->node.next;
}
/*
@@ -755,7 +759,7 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu)
CAC_RING_BUFFER_READ_ADVANCE(&piiu->send, status);
if (status != sendCnt) {
if (((unsigned long)status) != sendCnt) {
UNLOCK;
return;
}
@@ -926,7 +930,7 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
break;
}
assert (status<=writeSpace);
assert (((unsigned long)status)<=writeSpace);
CAC_RING_BUFFER_WRITE_ADVANCE(&piiu->recv, status);
@@ -936,7 +940,7 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
*/
piiu->timeAtLastRecv = ca_static->currentTime;
if (status != writeSpace) {
if (((unsigned long)status) != writeSpace) {
break;
}
}
@@ -1042,8 +1046,17 @@ LOCAL void udp_recv_msg(struct ioc_in_use *piiu)
UNLOCK;
return;
}
# ifdef linux
/*
* Avoid spurious ECONNREFUSED bug
* in linux
*/
if (MYERRNO==ECONNREFUSED) {
UNLOCK;
return;
}
# endif
ca_printf("Unexpected UDP failure %s\n", strerror(MYERRNO));
TAG_CONN_DOWN(piiu);
}
else if(status > 0){
unsigned long bytesActual;
@@ -1195,6 +1208,8 @@ void close_ioc (struct ioc_in_use *piiu)
piiuCast = NULL;
}
else {
chid pNext;
/*
* remove IOC from the hash table
*/
@@ -1208,73 +1223,20 @@ void close_ioc (struct ioc_in_use *piiu)
* handler tries to use a channel before
* I mark it disconnected.
*/
chix = (chid) &piiu->chidlist.node.next;
while (chix = (chid) chix->node.next) {
chix->type = TYPENOTCONN;
chix->count = 0U;
chix = (chid) ellFirst(&piiu->chidlist);
while (chix) {
chix->state = cs_prev_conn;
chix->id.sid = ~0U;
chix->ar.read_access = FALSE;
chix->ar.write_access = FALSE;
/*
* try to reconnect
*/
chix->retry = 0U;
chix = (chid) ellNext(&chix->node);
}
if (piiu->chidlist.count) {
ca_signal (ECA_DISCONN,piiu->host_name_str);
chix = (chid) ellFirst(&piiu->chidlist);
while (chix) {
pNext = (chid) ellNext(&chix->node);
cacDisconnectChannel(chix, TRUE);
chix = pNext;
}
/*
* clear outstanding get call backs
*/
caIOBlockListFree (&pend_read_list, chix, TRUE, ECA_DISCONN);
/*
* clear outstanding put call backs
*/
caIOBlockListFree (&pend_write_list, chix, TRUE, ECA_DISCONN);
/*
* call their connection handler as required
*/
chix = (chid) &piiu->chidlist.node.next;
while (chix = (chid) chix->node.next) {
LOCKEVENTS;
if (chix->pConnFunc) {
struct connection_handler_args args;
args.chid = chix;
args.op = CA_OP_CONN_DOWN;
(*chix->pConnFunc) (args);
}
if (chix->pAccessRightsFunc) {
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->pAccessRightsFunc) (args);
}
UNLOCKEVENTS;
chix->piiu = piiuCast;
}
/*
* move all channels to the broadcast IIU
*
* if we loose the broadcast IIU its a severe error
*/
assert (piiuCast);
ellConcat (&piiuCast->chidlist, &piiu->chidlist);
assert (piiu->chidlist.count==0);
}
/*
* Try to reconnect
*/
ca_static->ca_search_retry = 0;
if (fd_register_func) {
LOCKEVENTS;
(*fd_register_func) (fd_register_arg, piiu->sock_chan, FALSE);
@@ -1297,11 +1259,78 @@ void close_ioc (struct ioc_in_use *piiu)
ellFree (&piiu->destAddr);
ca_signal (ECA_DISCONN,piiu->host_name_str);
free (piiu);
UNLOCK;
}
/*
* cacDisconnectChannel()
*/
void cacDisconnectChannel(chid chix, int fullDisconnect)
{
struct ioc_in_use *piiu;
chix->type = TYPENOTCONN;
chix->count = 0U;
chix->id.sid = ~0U;
chix->ar.read_access = FALSE;
chix->ar.write_access = FALSE;
/*
* try to reconnect
*/
chix->retry = 0U;
/*
* call their connection handler as required
*/
if (fullDisconnect) {
chix->state = cs_prev_conn;
/*
* clear outstanding get call backs
*/
caIOBlockListFree (&pend_read_list, chix,
TRUE, ECA_DISCONN);
/*
* clear outstanding put call backs
*/
caIOBlockListFree (&pend_write_list, chix,
TRUE, ECA_DISCONN);
LOCKEVENTS;
if (chix->pConnFunc) {
struct connection_handler_args args;
args.chid = chix;
args.op = CA_OP_CONN_DOWN;
(*chix->pConnFunc) (args);
}
if (chix->pAccessRightsFunc) {
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->pAccessRightsFunc) (args);
}
UNLOCKEVENTS;
}
piiu = (struct ioc_in_use *)chix->piiu;
ellDelete(&piiu->chidlist, &chix->node);
assert (piiuCast);
chix->piiu = piiuCast;
ellAdd(&piiuCast->chidlist, &chix->node);
/*
* Try to reconnect this channel
*/
ca_static->ca_search_retry = 0;
}
/*
@@ -1704,7 +1733,7 @@ void caPrintAddrList(ELLLIST *pList)
/*
* caFetchPortConfig()
*/
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort)
unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort)
{
long longStatus;
long epicsParam;
@@ -1712,30 +1741,113 @@ int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort)
longStatus = envGetLongConfigParam(pEnv, &epicsParam);
if (longStatus!=0) {
epicsParam = defaultPort;
epicsParam = (long) defaultPort;
ca_printf ("EPICS \"%s\" integer fetch failed\n", pEnv->name);
ca_printf ("setting \"%s\" = %ld\n", pEnv->name, epicsParam);
}
/*
* This must be a server port that will fit in a signed
* This must be a server port that will fit in an unsigned
* short
*/
if (epicsParam<=IPPORT_USERRESERVED || epicsParam>SHRT_MAX) {
if (epicsParam<=IPPORT_USERRESERVED || epicsParam>USHRT_MAX) {
ca_printf ("EPICS \"%s\" out of range\n", pEnv->name);
/*
* Quit if the port is wrong due CA coding error
*/
assert (epicsParam != defaultPort);
epicsParam = defaultPort;
assert (epicsParam != (long) defaultPort);
epicsParam = (long) defaultPort;
ca_printf ("Setting \"%s\" = %ld\n", pEnv->name, epicsParam);
}
/*
* ok to clip to int here because we checked the range
*/
port = (int) epicsParam;
port = (unsigned short) epicsParam;
return port;
}
/*
* CAC_MUX_IO()
*/
void cac_mux_io(struct timeval *ptimeout)
{
int count;
struct timeval timeout;
cac_clean_iiu_list();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout = *ptimeout;
while (TRUE) {
count = cac_select_io(&timeout, CA_DO_RECVS|CA_DO_SENDS);
if (count<=0) {
/*
* if its a flush then loop until all
* of the send buffers are empty
*/
if (ca_static->ca_flush_pending) {
/*
* complete flush is postponed if we are
* inside an event routine
*/
if (EVENTLOCKTEST) {
break;
}
else {
if (caSendMsgPending()) {
LD_CA_TIME (SELECT_POLL, &timeout);
}
else {
ca_static->ca_flush_pending
= FALSE;
break;
}
}
}
else {
break;
}
}
else {
LD_CA_TIME (0.0, &timeout);
}
ca_process_input_queue();
}
}
/*
* caSendMsgPending()
*/
int caSendMsgPending()
{
int pending = FALSE;
unsigned long bytesPending;
struct ioc_in_use *piiu;
LOCK;
for( piiu = (IIU *) ellFirst(&iiuList);
piiu;
piiu = (IIU *) ellNext(&piiu->node)){
if(piiu == piiuCast || piiu->conn_up == FALSE){
continue;
}
bytesPending = cacRingBufferReadSize(&piiu->send, FALSE);
if(bytesPending > 0U){
pending = TRUE;
}
}
UNLOCK;
return pending;
}

View File

@@ -1,3 +1,4 @@
/* $Id */
/************************************************************************/
/* */
/* L O S A L A M O S */
@@ -28,7 +29,20 @@
/* .17 121892 joh added TCP send buf size var */
/* .18 122192 joh added outstanding ack var */
/* .19 012094 joh added minor version (for each server) */
/* */
/************************************************************************/
/* $Log$
* Revision 1.49 1995/10/12 01:33:12 jhill
* Initial delay between search frames went from .1 to .01 sec,
* Added flush pending flag, Make all usage of port be unsigned short.
*
* Revision 1.48 1995/09/29 21:55:38 jhill
* added func proto for cacDisconnectChannel()
*
* Revision 1.47 1995/08/22 00:20:27 jhill
* added KLUDGE def of S_db_Pending
*/
/*_begin */
/************************************************************************/
/* */
@@ -86,6 +100,7 @@ HDRVERSIONID(iocinfh, "$Id$")
#include <limits.h>
#include <stdarg.h>
#include <shareLib.h>
/*
* OS dependent includes
@@ -158,8 +173,8 @@ struct putCvrtBuf{
/*
* for use with cac_select_io()
*/
#define CA_DO_SENDS 1
#define CA_DO_RECVS 2
#define CA_DO_SENDS (1<<0)
#define CA_DO_RECVS (1<<1)
struct pending_io_event{
ELLNODE node;
@@ -190,8 +205,12 @@ extern const ca_time CA_CURRENT_TIME;
*/
#define MAXCONNTRIES 30 /* N conn retries on unchanged net */
#define SELECT_POLL (0.05) /* units sec - polls into recast */
#define CA_RECAST_DELAY (0.1) /* initial delay to next recast (sec) */
/*
* NOTE: These must be larger than one vxWorks tick or we will end up
* using the CPU. A vxWorks tick is usually 1/60th of a sec.
*/
#define SELECT_POLL (0.025) /* units sec - polls into recast */
#define CA_RECAST_DELAY (0.025) /* initial delay to next recast (sec) */
#define CA_RECAST_PORT_MASK 0xff /* random retry interval off port */
#define CA_RECAST_PERIOD (5.0) /* ul on retry period long term (sec) */
@@ -409,9 +428,11 @@ struct ca_static{
void (*ca_exception_func)
(struct exception_handler_args);
void *ca_exception_arg;
#if 0
void (*ca_connection_func)
(struct connection_handler_args);
void *ca_connection_arg;
#endif
int (*ca_printf_func)(const char *pformat, va_list args);
void (*ca_fd_register_func)
(void *, SOCKET, int);
@@ -430,6 +451,7 @@ struct ca_static{
unsigned ca_post_msg_active:1;
unsigned ca_manage_conn_active:1;
unsigned ca_repeater_contacted:1;
unsigned ca_flush_pending:1;
#if defined(vxWorks)
SEM_ID ca_io_done_sem;
SEM_ID ca_blockSem;
@@ -511,7 +533,7 @@ void issue_client_host_name(struct ioc_in_use *piiu);
int ca_defunct(void);
int ca_printf(char *pformat, ...);
void manage_conn(int silent);
void mark_server_available(struct in_addr *pnet_addr);
void mark_server_available(const struct in_addr *pnet_addr);
void flow_control(struct ioc_in_use *piiu);
int broadcast_addr(struct in_addr *pcastaddr);
void ca_repeater(void);
@@ -521,18 +543,19 @@ void ca_sg_init(void);
void ca_sg_shutdown(struct ca_static *ca_temp);
int cac_select_io(struct timeval *ptimeout, int flags);
void caHostFromInetAddr(
struct in_addr *pnet_addr,
char *pBuf,
unsigned size
const struct in_addr *pnet_addr,
char *pBuf,
unsigned size
);
int post_msg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr,
const struct in_addr *pnet_addr,
char *pInBuf,
unsigned long blockSize
);
int alloc_ioc(
struct in_addr *pnet_addr,
const struct in_addr *pnet_addr,
unsigned short port,
struct ioc_in_use **ppiiu
);
unsigned long cacRingBufferWrite(
@@ -565,7 +588,8 @@ char *localHostName(void);
int create_net_chan(
struct ioc_in_use **ppiiu,
struct in_addr *pnet_addr, /* only used by TCP connections */
const struct in_addr *pnet_addr, /* only used by TCP connections */
unsigned short port,
int net_proto
);
@@ -576,9 +600,9 @@ void caSetupBCastAddrList (ELLLIST *pList, SOCKET sock, unsigned port);
int ca_os_independent_init (void);
void freeBeaconHash(struct ca_static *ca_temp);
void removeBeaconInetAddr(struct in_addr *pnet_addr);
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr);
bhe *createBeaconHashEntry(struct in_addr *pnet_addr);
void removeBeaconInetAddr(const struct in_addr *pnet_addr);
bhe *lookupBeaconInetAddr(const struct in_addr *pnet_addr);
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr);
void close_ioc(IIU *piiu);
void notify_ca_repeater(void);
void cac_clean_iiu_list(void);
@@ -602,7 +626,9 @@ ca_real cac_time_diff(ca_time *pTVA, ca_time *pTVB);
ca_time cac_time_sum(ca_time *pTVA, ca_time *pTVB);
void caIOBlockFree(evid pIOBlock);
void clearChannelResources(unsigned id);
void caSetDefaultPrintfHandler ();
void caSetDefaultPrintfHandler (void);
void cacDisconnectChannel(chid chix, int fullDisconnect);
int caSendMsgPending(void);
/*
* !!KLUDGE!!
@@ -613,5 +639,6 @@ void caSetDefaultPrintfHandler ();
*/
#define M_dbAccess (501 <<16) /*Database Access Routines */
#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/
#define S_db_Pending (M_dbAccess|37) /*Request is pending*/
#endif /* this must be the last line in this file */

View File

@@ -1,4 +1,5 @@
#ifndef __IOCMSG__
/* $Id$ */
/*
* History
* .01 01xx90 joh removed status field in favor of a independent m_cmmd-
@@ -23,6 +24,10 @@
* .09 050594 joh New command added for CA V4.3 - repeater fanout register
*
* .10 050594 joh New command added for CA V4.3 - wakeup the server
* $Log$
* Revision 1.23 1995/08/23 00:35:17 jhill
* added log entries
*
*/
#define __IOCMSG__
@@ -31,23 +36,29 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
/* TCP/UDP port number (bumped each protocol change) */
#define CA_PROTOCOL_VERSION 4
#define CA_MINOR_VERSION 4
#define CA_MINOR_VERSION 6
#define CA_UKN_MINOR_VERSION 0 /* unknown minor version */
#if CA_PROTOCOL_VERSION == 4
#define CA_V41(MAJOR,MINOR) ((MINOR)>=1)
#define CA_V42(MAJOR,MINOR) ((MINOR)>=2)
#define CA_V43(MAJOR,MINOR) ((MINOR)>=3)
#define CA_V44(MAJOR,MINOR) ((MINOR)>=4)
#define CA_V45(MAJOR,MINOR) ((MINOR)>=5)
#define CA_V46(MAJOR,MINOR) ((MINOR)>=6)
#elif CA_PROTOCOL_VERSION > 4
#define CA_V41(MAJOR,MINOR) ( 1 )
#define CA_V42(MAJOR,MINOR) ( 1 )
#define CA_V43(MAJOR,MINOR) ( 1 )
#define CA_V44(MAJOR,MINOR) ( 1 )
#define CA_V45(MAJOR,MINOR) ( 1 )
#define CA_V46(MAJOR,MINOR) ( 1 )
#else
#define CA_V41(MAJOR,MINOR) ( 0 )
#define CA_V42(MAJOR,MINOR) ( 0 )
#define CA_V43(MAJOR,MINOR) ( 0 )
#define CA_V44(MAJOR,MINOR) ( 0 )
#define CA_V45(MAJOR,MINOR) ( 0 )
#define CA_V46(MAJOR,MINOR) ( 0 )
#endif
/*
@@ -56,7 +67,7 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
* environment variables "EPICS_CA_REPEATER_PORT" and
* "EPICS_CA_SERVER_PORT"
*/
#define CA_PORT_BASE IPPORT_USERRESERVED + 56
#define CA_PORT_BASE IPPORT_USERRESERVED + 56U
#define CA_SERVER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2)
#define CA_REPEATER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1)
@@ -72,7 +83,7 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
typedef unsigned short ca_uint16_t;
typedef unsigned int ca_uint32_t;
typedef float ca_float32_t;
typedef ca_uint32_t caResId;
/* values for m_cmmd */
#define IOC_NOOP 0 /* do nothing, but verify TCP */
@@ -101,6 +112,7 @@ typedef float ca_float32_t;
#define IOC_ECHO 23 /* CA V4.3 connection verify */
#define REPEATER_REGISTER 24 /* registr for repeater fan out */
#define IOC_SIGNAL 25 /* knock the server out of select */
#define IOC_CLAIM_CIU_FAILED 26 /* unable to create chan resource in server */
/*
* for use with search and not_found (if search fails and
@@ -110,15 +122,15 @@ typedef float ca_float32_t;
#define DONTREPLY 5
/* size of object in bytes rounded up to nearest oct word */
#define OCT_ROUND(A) ((((unsigned long)A)+7)>>3)
#define OCT_ROUND(A) ((((unsigned long)(A))+7)>>3)
#define OCT_SIZEOF(A) (OCT_ROUND(sizeof(A)))
/* size of object in bytes rounded up to nearest long word */
#define QUAD_ROUND(A) (((unsigned long)A)+3)>>2)
#define QUAD_ROUND(A) (((unsigned long)(A))+3)>>2)
#define QUAD_SIZEOF(A) (QUAD_ROUND(sizeof(A)))
/* size of object in bytes rounded up to nearest short word */
#define BI_ROUND(A) ((((unsigned long)A)+1)>>1)
#define BI_ROUND(A) ((((unsigned long)(A))+1)>>1)
#define BI_SIZEOF(A) (BI_ROUND(sizeof(A)))
/*
@@ -169,4 +181,5 @@ struct monops { /* monitor req opi to ioc */
struct mon_info m_info;
};
#endif
#endif /* __IOCMSG__ */

View File

@@ -38,7 +38,7 @@ static char *sccsId = "@(#) $Id$";
#include <stdio.h>
#include <string.h>
#ifdef _WINDOWS
#ifdef WIN32
# include <winsock.h>
#else
# include <sys/types.h>
@@ -54,7 +54,10 @@ static char *sccsId = "@(#) $Id$";
/*
* caHostFromInetAddr()
*/
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
void caHostFromInetAddr(
const struct in_addr *pnet_addr,
char *pBuf,
unsigned size)
{
char *pString;
struct hostent *ent;

View File

@@ -25,7 +25,9 @@
* .11 GeG 120992 support VMS/UCX
* .12 CJM 130794 define MYERRNO properly for UCX
* .13 CJM 311094 mods to support DEC C compiler
*
* .14 joh 100695 removed UNIX include of filio.h and sockio.h
* because they are include by ioctl.h under
* BSD and SVR4 (and they dont exist under linux)
*/
#ifndef INCos_depenh
@@ -51,6 +53,14 @@ static char *os_depenhSccsId = "$Id$";
# include <netinet/tcp.h>
# include <net/if.h>
# include <arpa/inet.h>
# include <netdb.h>
/*
* normally these are included by ioctl.h
*/
# ifdef SOLARIS
# include <sys/filio.h>
# include <sys/sockio.h>
# endif
# define CA_OS_CONFIGURED
#endif
@@ -123,16 +133,16 @@ static char *os_depenhSccsId = "$Id$";
# define CA_OS_CONFIGURED
#endif /*VMS*/
#ifdef _WINDOWS
#ifdef WIN32
# include <errno.h>
# include <time.h>
# include <windows.h>
# include <winsock.h>
# define CA_OS_CONFIGURED
#endif /*_WINDOWS*/
#endif /*WIN32*/
#ifndef CA_OS_CONFIGURED
#error Please define one of vxWorks, UNIX VMS, or _WINDOWS
#error Please define one of vxWorks, UNIX, VMS, or WIN32
#endif
/*
@@ -213,6 +223,13 @@ static char *os_depenhSccsId = "$Id$";
#define DELAYTICKS 50L /* (adjust units below) */
#define TICKSPERSEC 1000L /* mili sec per sec */
/*
* BSD prototypes missing from SUNOS4, MULTINET and
* perhaps other environments
*/
#include <epicsTypes.h>
#include <bsdProto.h>
/*
* order of ops is important here
*
@@ -290,25 +307,26 @@ static char *os_depenhSccsId = "$Id$";
# define INVALID_SOCKET (-1)
#endif
#ifdef _WINDOWS
#ifdef WIN32
# define LOCK
# define UNLOCK
# define LOCKEVENTS
# define UNLOCKEVENTS
# define EVENTLOCKTEST (post_msg_active)
# define MAXHOSTNAMELEN 75
# define IPPORT_USERRESERVED 5000
# define IPPORT_USERRESERVED 5000U
# define EWOULDBLOCK WSAEWOULDBLOCK
# define ENOBUFS WSAENOBUFS
# define ECONNRESET WSAECONNRESET
# define ETIMEDOUT WSAETIMEDOUT
# define EADDRINUSE WSAEADDRINUSE
# define ECONNREFUSED WSAECONNREFUSED
# define socket_close(S) closesocket(S)
# define socket_ioctl(A,B,C) ioctlsocket(A,B,C)
# define MYERRNO WSAGetLastError()
# define POST_IO_EV
# define SYSFREQ 1000000L /* 1 MHz */
#endif /*_WINDOWS*/
#endif /*WIN32*/
#endif

View File

@@ -28,6 +28,10 @@
*
* Modification Log:
* -----------------
* $Log$
* Revision 1.15 1995/08/22 00:22:07 jhill
* Dont recompute connection timers if the time stamp hasnt changed
*
*
*/
@@ -53,49 +57,21 @@ void cac_gettimeval(struct timeval *pt)
assert(status == 0);
}
/*
* CAC_MUX_IO()
*
* Asynch notification of incomming messages under UNIX
* 1) Wait no longer than timeout
* 2) Return early if nothing outstanding
*
*
*/
void cac_mux_io(struct timeval *ptimeout)
{
int count;
struct timeval timeout;
cac_clean_iiu_list();
timeout = *ptimeout;
do{
count = cac_select_io(
&timeout,
CA_DO_RECVS | CA_DO_SENDS);
ca_process_input_queue();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
while(count>0);
}
/*
* cac_block_for_io_completion()
*/
void cac_block_for_io_completion(struct timeval *pTV)
{
cac_mux_io(pTV);
cac_mux_io (pTV);
}
/*
* cac_block_for_sg_completion()
*/
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
{
cac_mux_io (pTV);
}
@@ -117,12 +93,6 @@ void os_specific_sg_delete(CASG *pcasg)
{
}
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
{
cac_mux_io(pTV);
}
/*
* CAC_ADD_TASK_VARIABLE()
@@ -140,17 +110,36 @@ int cac_add_task_variable(struct ca_static *ca_temp)
int cac_os_depen_init(struct ca_static *pcas)
{
int status;
struct sigaction sa;
ca_static = pcas;
/*
* dont allow disconnect to terminate process
* when running in UNIX enviroment
* when running in UNIX environment
*
* allow error to be returned to sendto()
* instead of handling disconnect at interrupt
*/
signal(SIGPIPE,SIG_IGN);
status = sigaction(SIGPIPE, NULL, &sa);
if (status==0) {
if (sa.sa_handler == SIG_DFL) {
sa.sa_handler = SIG_IGN;
status = sigaction(SIGPIPE, &sa, NULL);
if (status) {
ca_printf(
"%s: Error from signal replace was \"%s\"\n",
__FILE__,
strerror(MYERRNO));
}
}
}
else {
ca_printf(
"%s: Error from signal query was \"%s\"\n",
__FILE__,
strerror(MYERRNO));
}
status = ca_os_independent_init ();

View File

@@ -1,4 +1,6 @@
/*
* $Id$
*
* REPEATER.C
*
* CA broadcast repeater
@@ -29,7 +31,7 @@
* PURPOSE:
* Broadcasts fan out over the LAN, but UDP does not allow
* two processes on the same machine to get the same broadcast.
* This code takes extends the broadcast model from the net to within
* This code extends the broadcast model from the net to within
* the OS.
*
* NOTES:
@@ -57,29 +59,39 @@
* .06 120492 joh removed unnecessary includes
* .07 120992 joh now uses dll list routines
* .08 102993 joh toggle set sock opt to set
* .09 070195 joh discover client has vanished by connecting its
* datagram socket (and watching for ECONNREFUSED)
*
* $Log$
*/
static char *sccsId = "@(#)$Id$";
#include "iocinf.h"
/*
* one socket per client so we will get the ECONNREFUSED
* error code (and then delete the client)
*/
struct one_client{
ELLNODE node;
struct sockaddr_in from;
SOCKET sock;
};
/*
* these can be external since there is only one instance
* per machine so we dont care about reentrancy
*/
struct one_client{
ELLNODE node;
struct sockaddr_in from;
};
static ELLLIST client_list;
static char buf[MAX_UDP];
LOCAL int clean_client(struct one_client *pclient);
LOCAL void register_new_client(SOCKET sock, struct sockaddr_in *pLocal,
LOCAL void register_new_client(struct sockaddr_in *pLocal,
struct sockaddr_in *pFrom);
#define PORT_ANY 0U
LOCAL SOCKET makeSocket(unsigned short port);
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize);
/*
@@ -93,14 +105,10 @@ void ca_repeater()
int status;
int size;
SOCKET sock;
int true = 1;
struct sockaddr_in from;
struct sockaddr_in bd;
struct sockaddr_in local;
int from_size = sizeof from;
struct one_client *pclient;
struct one_client *pnxtclient;
short port;
unsigned short port;
port = caFetchPortConfig(
&EPICS_CA_REPEATER_PORT,
@@ -108,37 +116,20 @@ void ca_repeater()
ellInit(&client_list);
/* allocate a socket */
sock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
assert(sock != INVALID_SOCKET);
memset((char *)&bd, 0, sizeof(bd));
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = htons(port);
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
if(status<0){
if(MYERRNO != EADDRINUSE){
ca_printf("CA Repeater: unexpected bind fail %s\n",
strerror(MYERRNO));
sock = makeSocket(port);
if (sock==INVALID_SOCKET) {
/*
* test for server was already started
*/
if (MYERRNO==EADDRINUSE) {
exit(0);
}
socket_close(sock);
ca_printf("%s: Unable to create repeater socket because \"%s\"\n",
__FILE__,
strerror(MYERRNO));
exit(0);
}
status = setsockopt( sock,
SOL_SOCKET,
SO_REUSEADDR,
(char *)&true,
sizeof(true));
if(status<0){
ca_printf( "%s: set socket option failed\n",
__FILE__);
}
status = local_addr(sock, &local);
if(status != OK){
ca_printf(
@@ -162,80 +153,142 @@ void ca_repeater()
&from_size);
if(size < 0){
# ifdef linux
/*
* Avoid spurious ECONNREFUSED bug
* in linux
*/
if (MYERRNO==ECONNREFUSED) {
continue;
}
# endif
ca_printf("CA Repeater: recv err %s\n",
strerror(MYERRNO));
continue;
}
pMsg = (struct extmsg *) buf;
/*
* both zero leng message and a registartion message
* both zero length message and a registration message
* will register a new client
*/
if(size >= sizeof(*pMsg)){
if(ntohs(pMsg->m_cmmd) == REPEATER_REGISTER){
register_new_client(sock, &local, &from);
register_new_client(&local, &from);
/*
* strip register client message
*/
pMsg++;
size -= sizeof(*pMsg);
if (size==0) {
continue;
}
}
}
else if(size == 0){
register_new_client(sock, &local, &from);
register_new_client(&local, &from);
continue;
}
fanOut(&from, (char *) pMsg, size);
}
}
/*
* fanOut()
*/
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize)
{
ELLLIST theClients;
struct one_client *pclient;
int status;
ellInit(&theClients);
while (pclient=(struct one_client *)ellGet(&client_list)) {
ellAdd(&theClients, &pclient->node);
/*
* size may have been adjusted above
* Dont reflect back to sender
*/
if(size){
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
pclient = (struct one_client *)
pclient->node.next){
if(pFrom->sin_port == pclient->from.sin_port &&
pFrom->sin_addr.s_addr == pclient->from.sin_addr.s_addr){
continue;
}
/*
* Dont reflect back to sender
*/
if(from.sin_port == pclient->from.sin_port &&
from.sin_addr.s_addr ==
pclient->from.sin_addr.s_addr){
continue;
}
status = sendto(
sock,
(char *)pMsg,
size,
0,
(struct sockaddr *)&pclient->from,
sizeof pclient->from);
if(status < 0){
ca_printf("CA Repeater: fanout err %s\n",
strerror(MYERRNO));
}
status = send(
pclient->sock,
(char *)pMsg,
msgSize,
0);
if (status>=0) {
#ifdef DEBUG
ca_printf("Sent\n");
ca_printf("Sent to %d\n",
pclient->from.sin_port);
#endif
}
if(status < 0){
if (MYERRNO == ECONNREFUSED) {
#ifdef DEBUG
ca_printf("Deleted client %d\n",
pclient->from.sin_port);
#endif
ellDelete(&theClients,
&pclient->node);
socket_close(pclient->sock);
free(pclient);
}
else {
ca_printf(
"CA Repeater: fan out err was \"%s\"\n",
strerror(MYERRNO));
}
}
/*
* remove any dead wood prior to pending
*/
for( pclient = (struct one_client *)
client_list.node.next;
pclient;
pclient = pnxtclient){
/* do it now in case item deleted */
pnxtclient = (struct one_client *)
pclient->node.next;
clean_client(pclient);
}
}
ellConcat(&client_list, &theClients);
}
/*
* makeSocket()
*/
LOCAL SOCKET makeSocket(unsigned short port)
{
int status;
struct sockaddr_in bd;
SOCKET sock;
int true = 1;
sock = socket( AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
if (sock == INVALID_SOCKET) {
return sock;
}
status = setsockopt( sock,
SOL_SOCKET,
SO_REUSEADDR,
(char *)&true,
sizeof(true));
if(status<0){
ca_printf( "%s: set socket option failed\n",
__FILE__);
}
memset((char *)&bd, 0, sizeof(bd));
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = htons(port);
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
if(status<0){
socket_close(sock);
return INVALID_SOCKET;
}
return sock;
}
@@ -243,17 +296,17 @@ void ca_repeater()
* register_new_client()
*/
LOCAL void register_new_client(
SOCKET sock,
struct sockaddr_in *pLocal,
struct sockaddr_in *pFrom)
{
int status;
struct one_client *pclient;
struct extmsg confirm;
struct extmsg noop;
for( pclient = (struct one_client *) client_list.node.next;
for( pclient = (struct one_client *) ellFirst(&client_list);
pclient;
pclient = (struct one_client *) pclient->node.next){
pclient = (struct one_client *) ellNext(&pclient->node)){
if( pFrom->sin_port == pclient->from.sin_port &&
pFrom->sin_addr.s_addr == pclient->from.sin_addr.s_addr)
@@ -262,101 +315,73 @@ struct sockaddr_in *pFrom)
if(!pclient){
pclient = (struct one_client *)calloc (1, sizeof(*pclient));
if(pclient){
pclient->from = *pFrom;
ellAdd (&client_list, &pclient->node);
#ifdef DEBUG
ca_printf (
"Added %d\n",
pFrom->sin_port);
#endif
if(!pclient){
ca_printf("%s: no memory for new client\n",
__FILE__);
return;
}
pclient->sock = makeSocket(PORT_ANY);
if (!pclient->sock) {
free(pclient);
ca_printf("%s: no client sock because \"%s\"\n",
__FILE__,
strerror(MYERRNO));
return;
}
status = connect(pclient->sock,
(struct sockaddr *)pFrom,
sizeof(*pFrom));
if (status<0) {
socket_close(pclient->sock);
free(pclient);
ca_printf("%s: unable to connect client sock\n",
__FILE__);
return;
}
pclient->from = *pFrom;
ellAdd (&client_list, &pclient->node);
#ifdef DEBUG
ca_printf (
"Added %d\n",
pFrom->sin_port);
#endif
}
memset((char *)&confirm, 0, sizeof confirm);
memset((char *)&confirm, '\0', sizeof(confirm));
confirm.m_cmmd = htons(REPEATER_CONFIRM);
confirm.m_available = pLocal->sin_addr.s_addr;
status = sendto(
sock,
status = send(
pclient->sock,
(char *)&confirm,
sizeof(confirm),
0,
(struct sockaddr *)pFrom, /* back to sender */
sizeof(*pFrom));
if(status != sizeof(confirm)){
ca_printf("CA Repeater: confirm err %s\n",
strerror(MYERRNO));
0);
if(status >= 0){
assert(status == sizeof(confirm));
}
}
/*
*
* check to see if this client is still around
*
* NOTE:
* This closes the socket only whenever we are
* able to bind so that we free the port.
*/
LOCAL int clean_client(struct one_client *pclient)
{
static int sockExists;
static SOCKET sock;
int port = pclient->from.sin_port;
struct sockaddr_in bd;
int status;
int present = FALSE;
/*
* allocate a socket
* (no lock required because this is implemented with
* a single thread)
*/
if(!sockExists){
sock = socket(
AF_INET, /* domain */
SOCK_DGRAM, /* type */
0); /* deflt proto */
if(sock != INVALID_SOCKET){
sockExists = TRUE;
}
else{
ca_printf("CA Repeater: no bind test sock err %s\n",
strerror(MYERRNO));
return OK;
}
}
memset((char *)&bd, 0, sizeof(bd));
bd.sin_family = AF_INET;
bd.sin_addr.s_addr = INADDR_ANY;
bd.sin_port = port;
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
if(status>=0){
socket_close (sock);
sockExists = FALSE;
}
else{
if(MYERRNO == EADDRINUSE){
present = TRUE;
}
else{
ca_printf("CA Repeater: client cleanup err %s\n",
strerror(MYERRNO));
ca_printf("CA Repeater: sock=%d family=%d addr=%x port=%d\n",
sock, bd.sin_family, bd.sin_addr.s_addr,
bd.sin_port);
}
}
if(!present){
else if (MYERRNO == ECONNREFUSED){
#ifdef DEBUG
ca_printf("Deleted %d\n", pclient->from.sin_port);
ca_printf("Deleted repeater client=%d sending ack\n",
pFrom->sin_port);
#endif
ellDelete(&client_list, &pclient->node);
socket_close(pclient->sock);
free(pclient);
}
else {
ca_printf("CA Repeater: confirm err was \"%s\"\n",
strerror(MYERRNO));
}
return OK;
/*
* send a noop message to all other clients so that we dont
* accumulate sockets when there are no beacons
*/
memset((char *)&noop, '\0', sizeof(noop));
confirm.m_cmmd = htons(IOC_NOOP);
fanOut(pFrom, (char *)&noop, sizeof(noop));
}

View File

@@ -81,12 +81,12 @@ chid chan
LOCAL int cacMsg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
);
LOCAL void perform_claim_channel(
IIU *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
);
#ifdef CONVERSION_REQUIRED
@@ -103,7 +103,7 @@ extern CACVRTFUNC *cac_dbr_cvrt[];
*/
int post_msg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr,
const struct in_addr *pnet_addr,
char *pInBuf,
unsigned long blockSize
)
@@ -236,7 +236,7 @@ unsigned long blockSize
*/
LOCAL int cacMsg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
)
{
evid monix;
@@ -263,8 +263,6 @@ struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client write io id from server");
break;
}
@@ -293,9 +291,8 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_write_list, &monix->node);
UNLOCK;
caIOBlockFree(monix);
UNLOCK;
break;
@@ -314,8 +311,6 @@ struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client read notify io id from server");
break;
}
@@ -366,8 +361,8 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_read_list, &monix->node);
UNLOCK;
caIOBlockFree(monix);
UNLOCK;
break;
}
@@ -385,8 +380,6 @@ struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client event id from server");
break;
}
@@ -398,8 +391,8 @@ struct in_addr *pnet_addr
if (!piiu->curMsg.m_postsize) {
LOCK;
ellDelete(&monix->chan->eventq, &monix->node);
UNLOCK;
caIOBlockFree(monix);
UNLOCK;
break;
}
@@ -466,8 +459,6 @@ struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!pIOBlock){
ca_signal(ECA_INTERNAL,
"bad client read io id from server");
break;
}
@@ -509,8 +500,8 @@ struct in_addr *pnet_addr
}
LOCK;
ellDelete(&pend_read_list, &pIOBlock->node);
UNLOCK;
caIOBlockFree(pIOBlock);
UNLOCK;
break;
}
case IOC_SEARCH:
@@ -548,6 +539,7 @@ struct in_addr *pnet_addr
case IOC_ERROR:
{
ELLLIST *pList = NULL;
evid monix;
char nameBuf[64];
char context[255];
@@ -584,32 +576,30 @@ struct in_addr *pnet_addr
*/
monix = NULL;
args.addr = NULL;
LOCK;
switch (ntohs(req->m_cmmd)) {
case IOC_READ_NOTIFY:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
pList = &pend_read_list;
op = CA_OP_GET;
break;
case IOC_READ:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
if(monix){
args.addr = monix->usr_arg;
}
pList = &pend_read_list;
op = CA_OP_GET;
break;
case IOC_WRITE_NOTIFY:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
pList = &pend_write_list;
op = CA_OP_PUT;
break;
case IOC_WRITE:
@@ -619,19 +609,18 @@ struct in_addr *pnet_addr
op = CA_OP_SEARCH;
break;
case IOC_EVENT_ADD:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
op = CA_OP_ADD_EVENT;
if (monix) {
pList = &monix->chan->eventq;
}
break;
case IOC_EVENT_CANCEL:
LOCK;
monix = (evid) bucketLookupItemUnsignedId(
pFastBucket,
&req->m_available);
UNLOCK;
op = CA_OP_CLEAR_EVENT;
break;
default:
@@ -640,10 +629,12 @@ struct in_addr *pnet_addr
}
if (monix) {
if (pList) {
ellDelete(pList, &monix->node);
}
caIOBlockFree(monix);
}
LOCK;
args.chid = bucketLookupItemUnsignedId
(pSlowBucket, &piiu->curMsg.m_cid);
UNLOCK;
@@ -710,6 +701,31 @@ struct in_addr *pnet_addr
reconnect_channel(piiu, chan);
break;
}
case IOC_CLAIM_CIU_FAILED:
{
chid chan;
LOCK;
chan = bucketLookupItemUnsignedId(
pSlowBucket, &piiu->curMsg.m_cid);
UNLOCK;
if(!chan){
/*
* end up here if they delete the channel
* prior to this response
*/
break;
}
/*
* need to move the channel back to the cast IIU
* (so we will be able to reconnect)
*/
LOCK;
cacDisconnectChannel(chan, FALSE);
UNLOCK;
break;
}
default:
ca_printf("CAC: post_msg(): Corrupt cmd in msg %x\n",
piiu->curMsg.m_cmmd);
@@ -728,16 +744,18 @@ struct in_addr *pnet_addr
*/
LOCAL void perform_claim_channel(
IIU *piiu,
struct in_addr *pnet_addr
const struct in_addr *pnet_addr
)
{
int v42;
unsigned short port;
char rej[64];
chid chan;
int status;
IIU *allocpiiu;
IIU *chpiiu;
unsigned short *pMinorVersion;
unsigned minorVersion;
/*
* ignore broadcast replies for deleted channels
@@ -792,8 +810,31 @@ struct in_addr *pnet_addr
return;
}
status = alloc_ioc(pnet_addr, &allocpiiu);
switch(status){
/*
* Starting with CA V4.1 the minor version number
* is appended to the end of each search reply.
* This value is ignored by earlier clients.
*/
if(piiu->curMsg.m_postsize >= sizeof(*pMinorVersion)){
pMinorVersion = (unsigned short *)(piiu->pCurData);
minorVersion = ntohs(*pMinorVersion);
}
else{
minorVersion = CA_UKN_MINOR_VERSION;
}
/*
* the type field is abused to carry the port number
* so that we can have multiple servers on one host
*/
if (CA_V45 (CA_PROTOCOL_VERSION,minorVersion)) {
port = piiu->curMsg.m_type;
}
else {
port = ca_static->ca_server_port;
}
status = alloc_ioc (pnet_addr, port, &allocpiiu);
switch (status) {
case ECA_NORMAL:
break;
@@ -801,7 +842,7 @@ struct in_addr *pnet_addr
case ECA_DISCONN:
/*
* This indicates that the connection is tagged
* is tagged for shutdown and we are waiting for
* for shutdown and we are waiting for
* it to go away. Search replies are ignored
* in the interim.
*/
@@ -818,22 +859,11 @@ struct in_addr *pnet_addr
}
/*
* Starting with CA V4.1 the minor version number
* is appended to the end of each search reply.
* This value is ignored by earlier clients.
*/
if(piiu->curMsg.m_postsize >= sizeof(*pMinorVersion)){
pMinorVersion = (unsigned short *)(piiu->pCurData);
allocpiiu->minor_version_number = ntohs(*pMinorVersion);
}
else{
allocpiiu->minor_version_number = CA_UKN_MINOR_VERSION;
}
allocpiiu->minor_version_number = minorVersion;
ellDelete(&chpiiu->chidlist, &chan->node);
ellDelete (&chpiiu->chidlist, &chan->node);
chan->piiu = allocpiiu;
ellAdd(&allocpiiu->chidlist, &chan->node);
ellAdd (&allocpiiu->chidlist, &chan->node);
ca_static->ca_search_responses++;
/*
@@ -842,7 +872,7 @@ struct in_addr *pnet_addr
* the client's name to the server.
* (CA V4.1 or higher)
*/
if(ellCount(&allocpiiu->chidlist)==1){
if (ellCount(&allocpiiu->chidlist)==1) {
issue_identify_client(allocpiiu);
issue_client_host_name(allocpiiu);
}
@@ -963,9 +993,6 @@ chid chan
/* decrement the outstanding IO count */
CLRPENDRECV(TRUE);
}
UNLOCK;
}

View File

@@ -28,6 +28,13 @@
*
* Modification Log:
* -----------------
* $Log$
* Revision 1.17 1995/09/29 22:13:59 jhill
* check for nill dbr pointer
*
* Revision 1.16 1995/08/22 00:27:55 jhill
* added cvs style mod log
*
*
* NOTES:
* 1) Need to fix if the OP is on a FD that
@@ -97,7 +104,7 @@ void ca_sg_shutdown(struct ca_static *ca_temp)
/*
* ca_sg_create()
*/
int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
int epicsShareAPI ca_sg_create(CA_SYNC_GID *pgid)
{
int status;
CASG *pcasg;
@@ -130,29 +137,38 @@ int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
*/
memset((char *)pcasg,0,sizeof(*pcasg));
pcasg->magic = CASG_MAGIC;
pcasg->id = CLIENT_SLOW_ID_ALLOC;
pcasg->opPendCount = 0;
pcasg->seqNo = 0;
os_specific_sg_create(pcasg);
status = bucketAddItemUnsignedId(pSlowBucket, &pcasg->id, pcasg);
if(status == BUCKET_SUCCESS){
do {
pcasg->id = CLIENT_SLOW_ID_ALLOC;
status = bucketAddItemUnsignedId (pSlowBucket,
&pcasg->id, pcasg);
} while (status == S_bucket_idInUse);
if (status == S_bucket_success) {
/*
* place it on the active sync group list
*/
ellAdd(&ca_static->activeCASG, &pcasg->node);
* place it on the active sync group list
*/
ellAdd (&ca_static->activeCASG, &pcasg->node);
}
else{
else {
/*
* place it back on the free sync group list
*/
ellAdd(&ca_static->freeCASG, &pcasg->node);
ellAdd (&ca_static->freeCASG, &pcasg->node);
UNLOCK;
if (status == S_bucket_noMemory) {
return ECA_ALLOCMEM;
}
else {
return ECA_INTERNAL;
}
}
UNLOCK;
if(status != BUCKET_SUCCESS){
return ECA_ALLOCMEM;
}
*(WRITEABLE_CA_SYNC_GID *)pgid = pcasg->id;
return ECA_NORMAL;
@@ -162,7 +178,7 @@ int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
/*
* ca_sg_delete()
*/
int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
int epicsShareAPI ca_sg_delete(CA_SYNC_GID gid)
{
int status;
CASG *pcasg;
@@ -183,7 +199,7 @@ int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
}
status = bucketRemoveItemUnsignedId(pSlowBucket, &gid);
assert(status == BUCKET_SUCCESS);
assert (status == S_bucket_success);
os_specific_sg_delete(pcasg);
@@ -200,7 +216,7 @@ int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
/*
* ca_sg_block()
*/
int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
int epicsShareAPI ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
{
struct timeval beg_time;
ca_real delay;
@@ -237,16 +253,11 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
UNLOCK;
/*
* always flush and take care
* of connection management
* at least once.
* always flush at least once.
*/
ca_flush_io();
ca_static->ca_flush_pending = TRUE;
/*
* the current time set within ca_flush_io()
* above.
*/
cac_gettimeval (&ca_static->currentTime);
beg_time = ca_static->currentTime;
delay = 0.0;
@@ -257,9 +268,23 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
/*
* Exit if the timeout has expired
* (dont wait forever for an itsy bitsy
* delay which will no be updated if
* select is called with no delay)
*
* current time is only updated by
* cac_select_io() if we specify
* at least 1 usec to wait
*/
remaining = timeout-delay;
if (remaining<=0.0) {
if (remaining<=(1.0/USEC_PER_SEC)) {
/*
* Make sure that we take care of
* recv backlog at least once
*/
tmo.tv_sec = 0L;
tmo.tv_usec = 0L;
cac_mux_io (&tmo);
status = ECA_TIMEOUT;
break;
}
@@ -276,10 +301,6 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
cac_block_for_sg_completion (pcasg, &tmo);
/*
* the current time set within cac_block_for_sg_completion()
* above.
*/
delay = cac_time_diff (&ca_static->currentTime, &beg_time);
}
pcasg->opPendCount = 0;
@@ -291,7 +312,7 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
/*
* ca_sg_reset
*/
int APIENTRY ca_sg_reset(CA_SYNC_GID gid)
int epicsShareAPI ca_sg_reset(CA_SYNC_GID gid)
{
CASG *pcasg;
@@ -313,7 +334,7 @@ int APIENTRY ca_sg_reset(CA_SYNC_GID gid)
/*
* ca_sg_test
*/
int APIENTRY ca_sg_test(CA_SYNC_GID gid)
int epicsShareAPI ca_sg_test(CA_SYNC_GID gid)
{
CASG *pcasg;
@@ -339,7 +360,7 @@ int APIENTRY ca_sg_test(CA_SYNC_GID gid)
/*
* ca_sg_array_put()
*/
int APIENTRY ca_sg_array_put(
int epicsShareAPI ca_sg_array_put(
CA_SYNC_GID gid,
chtype type,
unsigned long count,
@@ -404,7 +425,7 @@ void *pvalue)
/*
* ca_sg_array_get()
*/
int APIENTRY ca_sg_array_get(
int epicsShareAPI ca_sg_array_get(
CA_SYNC_GID gid,
chtype type,
unsigned long count,
@@ -505,7 +526,7 @@ LOCAL void io_complete(struct event_handler_args args)
* Update the user's variable
* (if its a get)
*/
if(pcasgop->pValue){
if(pcasgop->pValue && args.dbr){
size = dbr_size_n(args.type, args.count);
memcpy(pcasgop->pValue, args.dbr, size);
}

View File

@@ -19,7 +19,7 @@ static char *sccsId = "$Id$";
#include "iocinf.h"
void APIENTRY ca_test_event(struct event_handler_args args)
void epicsShareAPI ca_test_event(struct event_handler_args args)
{
ca_printf("CAC: ~~~### in test event for [%s] ###~~~\n",args.chid+1);
ca_printf("CAC: User argument\t%x\n", args.usr);

View File

@@ -28,6 +28,10 @@
*
* Modification Log:
* -----------------
* $Log$
* Revision 1.17 1995/08/22 00:27:56 jhill
* added cvs style mod log
*
*
*/
@@ -55,44 +59,6 @@ void cac_gettimeval(struct timeval *pt)
assert(status==0);
}
/*
* CAC_MUX_IO()
*
* Wait for send ready under VMS
* 1) Wait no longer than timeout
*
* Under VMS all recv's and input processing
* handled by ASTs
*/
void cac_mux_io(struct timeval *ptimeout)
{
int count;
struct timeval timeout;
cac_clean_iiu_list();
timeout = *ptimeout;
do{
count = cac_select_io(
&timeout,
CA_DO_RECVS | CA_DO_SENDS);
ca_process_input_queue();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
while(count>0);
}
/*
* cac_block_for_io_completion()
@@ -286,7 +252,8 @@ void ca_spawn_repeater()
* gethostbyaddr(). This makes gethostbyaddr()
* hang when it is called from AST level.
*/
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
void caHostFromInetAddr(const struct in_addr *pnet_addr,
char *pBuf, unsigned size)
{
char *pString;

View File

@@ -28,6 +28,13 @@
*
* Modification Log:
* -----------------
* $Log$
* Revision 1.20 1995/10/12 01:35:31 jhill
* Moved cac_mux_io() to iocinf.c
*
* Revision 1.19 1995/08/22 00:27:58 jhill
* added cvs style mod log
*
*
*/
@@ -42,6 +49,7 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid);
LOCAL int cac_add_task_variable (struct ca_static *ca_temp);
LOCAL void deleteCallBack(CALLBACK *pcb);
/*
* cac_gettimeval()
@@ -85,40 +93,6 @@ void cac_gettimeval(struct timeval *pt)
pt->tv_usec = ((current-sec*rate)*USEC_PER_SEC)/rate;
}
/*
* CAC_MUX_IO()
*
* Asynch notification of send unblocked for vxWorks
* 1) Wait no longer than timeout
* 2) Return early if nothing outstanding
*
*
*/
void cac_mux_io(struct timeval *ptimeout)
{
int count;
struct timeval timeout;
#if NOASYNCRECV
cac_clean_iiu_list();
#endif
timeout = *ptimeout;
do{
count = cac_select_io(
&timeout,
CA_DO_SENDS | CA_DO_RECVS);
timeout.tv_usec = 0;
timeout.tv_sec = 0;
}
while(count>0);
#if NOASYNCRECV
ca_process_input_queue();
manage_conn(TRUE);
#endif
}
/*
* cac_block_for_io_completion()
@@ -129,7 +103,7 @@ void cac_block_for_io_completion(struct timeval *pTV)
unsigned long ticks;
unsigned long rate = sysClkRateGet();
#if NOASYNCRECV
#ifdef NOASYNCRECV
cac_mux_io(pTV);
#else
/*
@@ -144,6 +118,12 @@ void cac_block_for_io_completion(struct timeval *pTV)
ticks = min(LOCALTICKS, ticks);
semTake(io_done_sem, ticks);
/*
* force a time update because we are not
* going to get one with a nill timeout in
* ca_mux_io()
*/
cac_gettimeval (&ca_static->currentTime);
#endif
}
@@ -191,7 +171,7 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
unsigned long ticks;
unsigned long rate = sysClkRateGet();
#if NOASYNCRECV
#ifdef NOASYNCRECV
cac_mux_io(pTV);
#else
/*
@@ -206,6 +186,12 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
ticks = min(LOCALTICKS, ticks);
semTake (pcasg->sem, ticks);
/*
* force a time update because we are not
* going to get one with a nill timeout in
* ca_mux_io()
*/
cac_gettimeval (&ca_static->currentTime);
#endif
}
@@ -601,7 +587,10 @@ char *localUserName()
/*
* caHostFromInetAddr()
*/
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
void caHostFromInetAddr(
const struct in_addr *pnet_addr,
char *pBuf,
unsigned size)
{
char str[INET_ADDR_LEN];
@@ -857,17 +846,18 @@ void cac_recv_task(int tid)
* ca_task_exit() is called.
*/
while(TRUE){
#if NOASYNCRECV
#ifdef NOASYNCRECV
taskDelay(60);
#else
cac_clean_iiu_list();
timeout.tv_usec = 50000;
/*
* NOTE: this must be longer than one vxWorks
* tick or we will infinite loop
*/
timeout.tv_usec = (4*USEC_PER_SEC)/sysClkRateGet();
timeout.tv_sec = 0;
count = cac_select_io(
&timeout,
CA_DO_SENDS | CA_DO_RECVS);
count = cac_select_io(&timeout, CA_DO_RECVS);
ca_process_input_queue();
manage_conn(TRUE);
#endif

View File

@@ -27,22 +27,29 @@
* Advanced Photon Source
* Argonne National Laboratory
*
* Lawrence Berkley National Laboratory
*
* Modification Log:
* -----------------
*
*/
/*
* Windows includes
*/
#include <windows.h>
#include <process.h>
#include <mmsystem.h>
#include "iocinf.h"
#ifndef _WINDOWS
#error This source is specific to DOS/WINDOS
#ifndef WIN32
#error This source is specific to WIN32
#endif
long offset_time; /* time diff (sec) between 1970 and when windows started */
DWORD prev_time;
static void init_timers();
static int get_subnet_mask ( char SubNetMaskStr[256]);
static int RegTcpParams (char IpAddr[256], char SubNetMask[256]);
static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
@@ -54,48 +61,25 @@ static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
*/
void cac_gettimeval(struct timeval *pt)
{
SYSTEMTIME st;
/**
The multi-media timers used here should be good to a millisecond
resolution. However, since the timer rolls back to 0 every 49.7
days (2^32 ms, 4,294,967.296 sec), it's not very good for
time stamping over long periods (if Windows is restarted more
often than 49 days, it wont be a problem). An attempt is made
to keep the time returned increasing, but there is no guarantee
the UTC time is right after 49 days.
**/
GetSystemTime(&st);
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 +
(long)st.wHour*360;
pt->tv_usec = st.wMilliseconds*1000;
}
DWORD win_sys_time; /* time (ms) since windows started */
/*
* CAC_MUX_IO()
*
* Asynch notification of incomming messages under UNIX
* 1) Wait no longer than timeout
* 2) Return early if nothing outstanding
*
*
*/
void cac_mux_io(struct timeval *ptimeout)
{
int count;
struct timeval timeout;
cac_clean_iiu_list();
timeout = *ptimeout;
do{
count = cac_select_io(
&timeout,
CA_DO_RECVS | CA_DO_SENDS);
ca_process_input_queue();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
while(count>0);
win_sys_time = timeGetTime();
if (prev_time > win_sys_time) { /* must have been a timer roll-over */
offset_time += 4294967; /* add number of seconds in 49.7 days */
}
pt->tv_sec = (long)win_sys_time/1000 + offset_time; /* time (sec) since 1970 */
pt->tv_usec = (long)((win_sys_time % 1000) * 1000);
prev_time = win_sys_time;
}
@@ -138,8 +122,7 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
*/
int cac_os_depen_init(struct ca_static *pcas)
{
int status;
WSADATA WsaData;
int status;
ca_static = pcas;
@@ -153,10 +136,7 @@ int cac_os_depen_init(struct ca_static *pcas)
/* signal(SIGPIPE,SIG_IGN); */
# ifdef _WINSOCKAPI_
status = WSAStartup(MAKEWORD(1,1), &WsaData);
assert (status==0);
# endif
/* DllMain does most OS dependent init & cleanup */
status = ca_os_independent_init ();
@@ -290,11 +270,8 @@ int local_addr (SOCKET s, struct sockaddr_in *plcladdr)
*/
void caDiscoverInterfaces(ELLLIST *pList, SOCKET socket, int port)
{
struct sockaddr_in localAddr;
struct sockaddr_in InetAddr;
struct in_addr bcast_addr;
caAddrNode *pNode;
int status;
pNode = (caAddrNode *) calloc(1,sizeof(*pNode));
if(!pNode){
@@ -352,6 +329,13 @@ static int get_subnet_mask ( char SubNetMaskStr[256])
return RegTcpParams (localadr, SubNetMaskStr);
}
/* For NT 3.51, enumerates network interfaces returns the ip address */
/* and subnet mask for the LAST interface found. This needs to be changed */
/* to work in conjuction with caDiscoverInterfaces to add all the */
/* add all the interfaces to the elist. Also could be more efficient in
calling */
/* RegKeyOpen */
static int RegTcpParams (char IpAddrStr[256], char SubNetMaskStr[256])
{
#define MAX_VALUE_NAME 128
@@ -360,37 +344,65 @@ static int RegTcpParams (char IpAddrStr[256], char SubNetMaskStr[256])
DWORD cbDataLen;
CHAR cbData[256];
DWORD dwType;
int status;
int status, i, card_cnt;
char *pNetCard[16], *pData;
static char IpAddr[256], SubNetMask[256];
cbDataLen = sizeof(cbData);
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\1");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
/****
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\NetworkCards\\1");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType,
cbData, &cbDataLen);
if (status) {
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\01");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\NetworkCards\\01");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType,
cbData, &cbDataLen);
if (status)
return status;
}
****/
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\");
strcat(RegPath,cbData);
strcat(RegPath,"\\Parameters\\Tcpip");
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "Route", &dwType, cbData,
&cbDataLen);
if (status) {
return status;
}
i=0; card_cnt = 0; pData = cbData; /* enumerate network interfaces */
while( i < 16 && (pNetCard[i]=strtok(pData,"\"")) ) {
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\");
strcat(RegPath,pNetCard[i]);
strcat(RegPath,"\\Parameters\\Tcpip");
cbDataLen = sizeof(IpAddr);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "IPAddress", &dwType,
IpAddr, &cbDataLen);
if (status == 0) {
cbDataLen = sizeof(SubNetMask);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "SubnetMask",
&dwType, SubNetMask, &cbDataLen);
if (status)
return status;
card_cnt++;
}
pData += strlen(pNetCard[i])+3;
i++;
}
if (card_cnt == 0)
return 1;
cbDataLen = sizeof(IpAddr);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "IPAddress", &dwType, IpAddr, &cbDataLen);
if (status)
return status;
strcpy(IpAddrStr,IpAddr);
cbDataLen = sizeof(SubNetMask);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "SubnetMask", &dwType, SubNetMask, &cbDataLen);
if (status)
return status;
strcpy(SubNetMaskStr,SubNetMask);
return 0;
return 0;
}
@@ -417,7 +429,7 @@ static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
}
retCode = RegQueryValueEx (hKey, // Key handle returned from RegOpenKeyEx.
retCode = RegQueryValueEx (hKey, // Key handle returned from
lpzValueName, // Name of value.
NULL, // Reserved, dword = NULL.
lpdwType, // Type of data.
@@ -434,36 +446,61 @@ static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
BOOL epicsShareAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
int status;
WSADATA WsaData;
TIMECAPS tc;
UINT wTimerRes;
switch (dwReason) {
case DLL_PROCESS_ATTACH:
if ((status = WSAStartup(MAKEWORD(1,1), &WsaData)) != 0)
return FALSE;
#if _DEBUG /* for gui applications, setup console for error messages */
if (AllocConsole()) {
SetConsoleTitle("Channel Access Status");
freopen( "CONOUT$", "a", stderr );
fprintf(stderr, "Process attached to ca.dll R12\n");
}
fprintf(stderr, "Process attached to ca.dll R3.12.1\n");
#endif /* init. winsock */
if ((status = WSAStartup(MAKEWORD(1,1), &WsaData)) != 0) {
fprintf(stderr,"Cant init winsock \n");
return FALSE;
}
/* setup multi-media timer */
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
fprintf(stderr,"cant get timer info \n");
return FALSE;
}
/* set for 1 ms resoulution */
wTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax);
status = timeBeginPeriod(wTimerRes);
if (status != TIMERR_NOERROR)
fprintf(stderr,"timer setup failed\n");
offset_time = (long)time(NULL) - (long)timeGetTime()/1000;
prev_time = timeGetTime();
break;
case DLL_PROCESS_DETACH:
timeEndPeriod(wTimerRes);
if ((status = WSACleanup()) !=0)
return FALSE;
break;
case DLL_THREAD_ATTACH:
fprintf(stderr, "Thread attached to ca.dll R12\n");
#if _DEBUG
fprintf(stderr, "Thread attached to ca.dll R3.12.1\n");
#endif
break;
case DLL_THREAD_DETACH:
fprintf(stderr, "Thread detached from ca.dll R12\n");
#if _DEBUG
fprintf(stderr, "Thread detached from ca.dll R3.12.1\n");
#endif
break;
default:
@@ -472,4 +509,8 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
return TRUE;
}

View File

@@ -2,27 +2,25 @@ EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
USR_CFLAGS = -ansi
VX_WARN_YES = -Wall -pedantic
SRCS.c = \
../dbAccess.c ../dbBkpt.c ../dbFastLinkConv.c ../dbLink.c \
../dbNotify.c ../dbStaticLib.c ../iocInit.c ../drvTS.c ../dbScan.c \
../dbEvent.c ../dbTest.c ../dbls.c ../db_access.c \
../db_test.c ../recGbl.c ../callback.c ../taskwd.c \
../dbCaLink.c ../dbCaDblink.c ../devLib.c ../initHooks.c
../dbCaLink.c ../dbCaDblink.c ../devLib.c ../initHooks.c ../cvtBpt.c
OBJSdbLib = \
LIBOBJS = \
dbAccess.o dbBkpt.o dbFastLinkConv.o dbLink.o dbNotify.o \
dbStaticLib.o iocInit.o drvTS.o dbScan.o dbEvent.o dbTest.o dbls.o \
db_access.o db_test.o recGbl.o callback.o taskwd.o dbCaLink.o \
dbCaDblink.o devLib.o
dbCaDblink.o devLib.o cvtBpt.o
PROD = initHooks.o
PROD = initHooks.o dbLib
LIBNAME = dbLib
include $(EPICS)/config/RULES.Vx
dbLib: $(OBJSdbLib)
$(RM) $@
$(LINK.c) $@ $(OBJSdbLib) $(LDLIBS)

View File

@@ -112,7 +112,7 @@ words:
else if((p=strstr($2,".PP.NMS"))) {p[0]=' ';p[3]=' ';}
else if((p=strstr($2,".NPP.MS"))) {p[0]=' ';p[4]=' ';}
else if((p=strstr($2,".NPP.NMS"))) {p[0]=' ';p[4]=' ';}
else if(strlen(curr_value)>0) { strcat(curr_value," "); }
else if(strlen(curr_value)>(size_t)0) { strcat(curr_value," "); }
strcat(curr_value,$2);
}
;

View File

@@ -1,6 +1,6 @@
/* $Id$ */
/* cvtBpt.c - Convert using breakpoint table
/* cvtBpt.c - Convert using breakpoint table */
/*
* Author: Janet Anderson
* Date: 9-19-91

View File

@@ -90,10 +90,12 @@
#include <dbFldTypes.h>
#include <dbRecDes.h>
#include <dbRecType.h>
#include <dbEvent.h>
#include <db_field_log.h>
#include <errMdef.h>
#include <recSup.h>
#include <special.h>
#include <asLib.h>
extern struct dbBase *pdbBase;
extern long lset_stack_not_empty;
@@ -297,8 +299,6 @@ long dbProcess(struct dbCommon *precord)
static char trace=0;
static int trace_lset=0;
int set_trace=FALSE;
long options=0;
long nRequest=1;
/*
* Note that it is likely that if any changes are made
@@ -377,7 +377,7 @@ long dbProcess(struct dbCommon *precord)
/*take care of caching and notifyCompletion*/
precord->rpro = FALSE;
if (precord->ppn)
dbNotifyCompletion(precord->ppn);
dbNotifyCompletion(precord);
/* raise disable alarm */
if (precord->stat==DISABLE_ALARM)
@@ -681,7 +681,7 @@ long dbFastLinkPut(
}
}
else if (special == SPC_AS) {
asChangeGroup(&pdest->asp, pdest->asg);
asChangeGroup((ASMEMBERPVT *)&pdest->asp, pdest->asg);
}
}
else {

View File

@@ -622,14 +622,16 @@ int db_post_single_event(struct event_block *pevent)
*
*/
int db_post_events(
struct dbCommon *precord,
union native_value *pvalue,
unsigned int select
void *prec,
void *pval,
unsigned int select
)
{
struct event_block *event;
struct event_que *ev_que;
unsigned int putix;
struct dbCommon *precord = (struct dbCommon *)prec;
union native_value *pvalue = (union native_value *)pval;
struct event_block *event;
struct event_que *ev_que;
unsigned int putix;
if (precord->mlis.count == 0) return OK; /* no monitors set */

View File

@@ -83,10 +83,12 @@
#include <dbFldTypes.h>
#include <dbRecDes.h>
#include <dbRecType.h>
#include <dbEvent.h>
#include <db_field_log.h>
#include <errMdef.h>
#include <recSup.h>
#include <special.h>
#include <asLib.h>
extern struct dbBase *pdbBase;
@@ -186,6 +188,7 @@ long dbPutField(
if((paddr->pfield==(void *)&precord->proc)
||(pfldDes->process_passive && precord->scan==0 && dbrType<DBR_PUT_ACKT)) {
if(precord->pact) {
if(precord->tpro) printf("active: %s\n",precord->name);
precord->rpro = TRUE;
} else {
/*indicate that dbPutField called dbProcess*/
@@ -2782,7 +2785,6 @@ void *pflin
long (*pconvert_routine)();
struct dbCommon *pcommon;
long status;
long *perr_status=NULL;
prset=GET_PRSET(pdbBase->precSup,paddr->record_type);
@@ -2801,16 +2803,18 @@ void *pflin
}
*((unsigned short *)pbuffer)++ = pcommon->acks;
*((unsigned short *)pbuffer)++ = pcommon->ackt;
*perr_status = 0;
}
if( (*options) & DBR_UNITS ) {
if( prset && prset->get_units ){
(*prset->get_units)(paddr,pbuffer);
char * pchr = (char *)pbuffer;
(*prset->get_units)(paddr,pchr);
pchr[DB_UNITS_SIZE-1] = '\0';
} else {
memset(pbuffer,'\0',dbr_units_size);
*options = (*options) ^ DBR_UNITS; /*Turn off DBR_UNITS*/
}
pbuffer += dbr_units_size;
pbuffer = (char *)pbuffer + dbr_units_size;
}
if( (*options) & DBR_PRECISION ) {
struct dbr_precision *pdbr_precision=( struct dbr_precision *)pbuffer;
@@ -2823,7 +2827,7 @@ void *pflin
memset(pbuffer,'\0',dbr_precision_size);
*options = (*options) ^ DBR_PRECISION; /*Turn off DBR_PRECISION*/
}
pbuffer += dbr_precision_size;
pbuffer = (char *)pbuffer + dbr_precision_size;
}
if( (*options) & DBR_TIME ) {
if(pfl!=NULL) {
@@ -2852,7 +2856,6 @@ GET_DATA:
sprintf(message,"dbGet - database request type is %d",dbrType);
recGblDbaddrError(S_db_badDbrtype,paddr,message);
if(perr_status) *perr_status = S_db_badDbrtype;
return(S_db_badDbrtype);
}
@@ -2867,7 +2870,6 @@ GET_DATA:
sprintf(message,"dbGet - database request type is %d",dbrType);
recGblDbaddrError(S_db_badDbrtype,paddr,message);
if(perr_status) *perr_status = S_db_badDbrtype;
return(S_db_badDbrtype);
}
/* convert database field to buffer type and place it in the buffer */
@@ -2883,7 +2885,6 @@ GET_DATA:
status=(*pconvert_routine)(paddr,pbuffer,*nRequest,
no_elements,offset);
}
if(perr_status) *perr_status = status;
return(status);
}
@@ -2961,7 +2962,7 @@ choice_common:
*options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
break;
}
*ppbuffer += dbr_enumStrs_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_enumStrs_size;
return;
}
@@ -2986,7 +2987,7 @@ static void get_graphics(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_grLong_size);
*options = (*options) ^ DBR_GR_LONG; /*Turn off option*/
}
*ppbuffer += dbr_grLong_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_grLong_size;
}
if( (*options) & (DBR_GR_DOUBLE) ) {
char *pbuffer=*ppbuffer;
@@ -2999,7 +3000,7 @@ static void get_graphics(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_grDouble_size);
*options = (*options) ^ DBR_GR_DOUBLE; /*Turn off option*/
}
*ppbuffer += dbr_grDouble_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_grDouble_size;
}
return;
}
@@ -3025,7 +3026,7 @@ static void get_control(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_ctrlLong_size);
*options = (*options) ^ DBR_CTRL_LONG; /*Turn off option*/
}
*ppbuffer += dbr_ctrlLong_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_ctrlLong_size;
}
if( (*options) & (DBR_CTRL_DOUBLE) ) {
char *pbuffer=*ppbuffer;
@@ -3038,7 +3039,7 @@ static void get_control(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_ctrlDouble_size);
*options = (*options) ^ DBR_CTRL_DOUBLE; /*Turn off option*/
}
*ppbuffer += dbr_ctrlDouble_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_ctrlDouble_size;
}
return;
}
@@ -3066,7 +3067,7 @@ static void get_alarm(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_alLong_size);
*options = (*options) ^ DBR_AL_LONG; /*Turn off option*/
}
*ppbuffer += dbr_alLong_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_alLong_size;
}
if( (*options) & (DBR_AL_DOUBLE) ) {
char *pbuffer=*ppbuffer;
@@ -3081,7 +3082,7 @@ static void get_alarm(struct dbAddr *paddr,void **ppbuffer,
memset(pbuffer,'\0',dbr_alDouble_size);
*options = (*options) ^ DBR_AL_DOUBLE; /*Turn off option*/
}
*ppbuffer += dbr_alDouble_size;
*ppbuffer = ((char *)*ppbuffer) + dbr_alDouble_size;
}
return;
}
@@ -3227,19 +3228,21 @@ long no_elements;
long offset;
{
unsigned short *pdest=(unsigned short *)paddr->pfield;
unsigned short value;
float value;
/*Convert to float first so that numbers like 1.0e3 convert properly*/
/*Problem was old database access said to get unsigned short as float*/
if(nRequest==1 && offset==0) {
if(sscanf(pbuffer,"%hu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%f",&value) == 1) {
*pdest = (unsigned short)value;
return(0);
}
else return(-1);
}
pdest += offset;
while (nRequest) {
if(sscanf(pbuffer,"%hu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%f",&value) == 1) {
*pdest = (unsigned short)value;
} else {
return(-1);
}
@@ -3295,19 +3298,21 @@ long no_elements;
long offset;
{
unsigned long *pdest=(unsigned long *)paddr->pfield;
unsigned long value;
double value;
/*Convert to double first so that numbers like 1.0e3 convert properly*/
/*Problem was old database access said to get unsigned long as double*/
if(nRequest==1 && offset==0) {
if(sscanf(pbuffer,"%lu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%lf",&value) == 1) {
*pdest = (unsigned long)value;
return(0);
}
else return(-1);
}
pdest += offset;
while (nRequest) {
if(sscanf(pbuffer,"%lu",&value) == 1) {
*pdest = value;
if(sscanf(pbuffer,"%lf",&value) == 1) {
*pdest = (unsigned long)value;
} else {
return(-1);
}
@@ -5675,7 +5680,6 @@ long no_elements;
long offset;
{
struct dbCommon *precord=(struct dbCommon *)(paddr->precord);
unsigned short acks=precord->acks;
if(*pbuffer >= precord->acks) {
precord->acks = 0;
@@ -5831,7 +5835,7 @@ long dbPut(
if(special==SPC_SCAN) {
scanAdd(precord);
} else if(special==SPC_AS) {
asChangeGroup(&precord->asp,precord->asg);
asChangeGroup((ASMEMBERPVT *)&precord->asp,precord->asg);
}
}
else {

View File

@@ -35,7 +35,10 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <semLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <fast_lock.h>
@@ -45,185 +48,325 @@
#include <dbScan.h>
#include <dbCommon.h>
#include <errMdef.h>
#include <ellLib.h>
/*NODE structure attached to ppnn field of each record in list*/
typedef struct {
ELLNODE node;
struct dbCommon *precord;
} PNWAITNODE;
/*Local routines*/
static void restartAdd(PUTNOTIFY *ppnto, PUTNOTIFY *ppnfrom);
static void waitAdd(struct dbCommon *precord,PUTNOTIFY *ppn);
static long putNotify(PUTNOTIFY *ppn);
static void notifyCallback(CALLBACK *pcallback);
static void notifyCancel(PUTNOTIFY *ppn);
static void issueCallback(PUTNOTIFY *ppn);
/*callbackState values */
typedef enum {
callbackNotActive,callbackActive,callbackCanceled}callbackState;
static void notifyCallback(CALLBACK *pcallback)
{
PUTNOTIFY *ppn=NULL;
long status;
/* This module provides code to handle put notify. If a put causes a record to
* be processed, then a user supplied callback is called when that record
* and all records processed because of that record complete processing.
* For asynchronous records completion means completion of the asyn phase.
*
* User code calls dbPutNotify and dbNotifyCancel.
*
* The other global routines (dbNotifyAdd and dbNotifyCompletion) are called by:
*
* dbAccess.c
* dbScanPassive and dbScanLink
* call dbNotifyAdd just before calling dbProcess
* dbProcess
* Calls dbNotifyCompletion if record is disabled.
* recGbl
* recGblFwdLink calls dbNotifyCompletion
*/
callbackGetUser(ppn,pcallback);
if(ppn->cmd==notifyCmdRepeat) {
status = dbPutNotify(ppn);
} else if(ppn->cmd==notifyCmdCallUser) {
ppn->cmd = notifyUserCalled;
(ppn->userCallback)(ppn);
} else {/*illegal request*/
recGblRecordError(-1,ppn->paddr->precord,
"dbNotifyCompletion: illegal callback request");
}
}
static void notifyCancel(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->list;
while(precord) {
void *pnext;
if(precord->rpro) {
precord->rpro = FALSE;
scanOnce(precord);
}
precord->ppn = NULL;
pnext = precord->ppnn;
precord->ppnn = NULL;
precord = pnext;
}
ppn->list = NULL;
}
void dbNotifyCancel(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->list;
if(!precord) return;
dbScanLock(precord);
notifyCancel(ppn);
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
/*Bad lets try one time to wait*/
dbScanUnlock(precord);
taskDelay(10);
dbScanLock(precord);
}
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
epicsPrintf("dbNotifyCancel called while callback requested"
" but not called\n");
}
dbScanUnlock(precord);
}
static void issueCallback(PUTNOTIFY *ppn, notifyCmd cmd)
{
if(ppn->cmd!=notifyCmdNull) return;
ppn->cmd = cmd;
notifyCancel(ppn);
callbackRequest(&ppn->callback);
}
/* Two fields in dbCommon are used for put notify.
* ppn
* If a record is part of a put notify group,
* This field is tha address of the associated PUTNOTIFY.
* As soon as a record completes processing the field is set NULL
* ppnn
* Address of an PNWAITNODE for keeping list of records in a
* put notify group. Once an PNWAITNODE is allocated for a record,
* it is never freed under the assumption that once a record
* becomes part of a put notify group it is likely to become
* one again in the future.
*/
static void restartAdd(PUTNOTIFY *ppnto, PUTNOTIFY *ppnfrom)
{
ppnfrom->restartNode.ppn = ppnfrom;
ppnfrom->restartNode.ppnrestartList = ppnto;
ppnfrom->restart = TRUE;
ellAdd(&ppnto->restartList,&ppnfrom->restartNode.node);
}
static void waitAdd(struct dbCommon *precord,PUTNOTIFY *ppn)
{
PNWAITNODE *ppnnode;
if(!precord->ppnn) precord->ppnn = dbCalloc(1,sizeof(PNWAITNODE));
ppnnode = (PNWAITNODE *)precord->ppnn;
ppnnode->precord = precord;
precord->ppn = ppn;
ellAdd(&ppn->waitList,&ppnnode->node);
}
long dbPutNotify(PUTNOTIFY *ppn)
{
long status;
struct dbCommon *precord = ppn->paddr->precord;
dbScanLock(precord);
ellInit(&ppn->restartList);
memset(&ppn->restartNode,'\0',sizeof(PNRESTARTNODE));
status = putNotify(ppn);
dbScanUnlock(precord);
return(status);
}
static long putNotify(PUTNOTIFY *ppn)
{
struct dbAddr *paddr = ppn->paddr;
short dbrType = ppn->dbrType;
void *pbuffer = ppn->pbuffer;
long nRequest = ppn->nRequest;
long status=0;
short dbrType = ppn->dbrType;
void *pbuffer = ppn->pbuffer;
long nRequest = ppn->nRequest;
long status=0;
struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes);
struct dbCommon *precord = (struct dbCommon *)(paddr->precord);
if(precord->ppn == ppn) {
return(S_db_Blocked);
}
/*Initialize everything in PUTNOTIFY except restart list and node*/
callbackSetCallback(notifyCallback,&ppn->callback);
callbackSetUser(ppn,&ppn->callback);
callbackSetPriority(priorityLow,&ppn->callback);
ppn->status = 0;
ppn->restart = FALSE;
ppn->callbackState = callbackNotActive;
ellInit(&ppn->waitList);
/*check for putField disabled*/
if(precord->disp) {
if((void *)(&precord->disp) != paddr->pfield) {
ppn->status = S_db_putDisabled;
issueCallback(ppn,notifyCmdCallUser);
return(S_db_putDisabled);
issueCallback(ppn);
goto ret_pending;
}
}
ppn->status = 0;
ppn->cmd = notifyCmdNull;
ppn->nwaiting = 1;
ppn->rescan = FALSE;
dbScanLock(precord);
if(precord->ppn) {/*Another put notify is in progress*/
restartAdd(precord->ppn,ppn);
goto ret_pending;
}
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
precord->ppn = ppn;
waitAdd(precord,ppn);
restartAdd(precord->ppn,ppn);
goto ret_pending;
}
status=dbPut(paddr,dbrType,pbuffer,nRequest);
ppn->status = status;
if(status==0){
if((paddr->pfield==(void *)&precord->proc)
||(pfldDes->process_passive && precord->scan==0)) {
if(precord->ppn) {
/*record already has attached ppn. Blocked*/
ppn->status = status = S_db_Blocked;
dbScanUnlock(precord);
return(status);
}
precord->ppn = ppn;
precord->ppnn = NULL;
ppn->list = precord;
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
ppn->rescan = TRUE;
dbScanUnlock(precord);
return(S_db_Pending);
}
status=dbProcess(precord);
if(status!=0) {
ppn->status = status;
issueCallback(ppn,notifyCmdCallUser);
}
} else { /*Make callback immediately*/
issueCallback(ppn,notifyCmdCallUser);
}
if(status) {
ppn->status = status;
issueCallback(ppn);
goto ret_pending;
}
/*check for no processing required*/
if(!(paddr->pfield==(void *)&precord->proc)
&& (!pfldDes->process_passive || precord->scan!=0)) {
issueCallback(ppn);
goto ret_pending;
}
dbScanUnlock(precord);
/*Add record to waitlist*/
waitAdd(precord,ppn);
status=dbProcess(precord);
if(status!=0) {
ppn->status = status;
issueCallback(ppn);
}
ret_pending:
return(S_db_Pending);
}
void dbNotifyCompletion(PUTNOTIFY *ppn)
static void notifyCallback(CALLBACK *pcallback)
{
PUTNOTIFY *ppn=NULL;
struct dbCommon *precord;
if(ppn->status!=0) {
issueCallback(ppn,notifyCmdCallUser);
callbackGetUser(ppn,pcallback);
precord = ppn->paddr->precord;
dbScanLock(precord);
if(ppn->callbackState==callbackCanceled) {
dbScanUnlock(precord);
ppn->restart = FALSE;
ppn->callbackState = callbackNotActive;
semGive((SEM_ID)ppn->waitForCallback);
return;
}
/*decrement number of records being waited on*/
if(ppn->nwaiting<=0) {
recGblRecordError(-1,ppn->paddr->precord,"dbNotifyCompletion: nwaiting<-0 LOGIC");
return;
}
if(--ppn->nwaiting == 0) {/*original request completed*/
if(ppn->rescan) {
issueCallback(ppn,notifyCmdRepeat);
if(ppn->callbackState==callbackActive) {
if(ppn->restart) {
putNotify(ppn);
dbScanUnlock(precord);
} else {
issueCallback(ppn,notifyCmdCallUser);
dbScanUnlock(precord);
(ppn->userCallback)(ppn);
}
}
}
/*Remove all nonactive records from put notify list*/
void cleanPpList(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->list;
struct dbCommon *pnext;
struct dbCommon *pprev=NULL;
while(precord) {
pnext = precord->ppnn;
if(!precord->pact) {
if(!pprev) ppn->list = pnext; else pprev->ppnn = pnext;
precord->ppn = NULL;
precord->ppnn = NULL;
} else {
pprev = precord;
static void issueCallback(PUTNOTIFY *ppn)
{
notifyCancel(ppn);
ppn->callbackState = callbackActive;
callbackRequest(&ppn->callback);
}
void dbNotifyCancel(PUTNOTIFY *ppn)
{
struct dbCommon *precord = ppn->paddr->precord;;
dbScanLock(precord);
notifyCancel(ppn);
if(ppn->callbackState == callbackActive) {
ppn->waitForCallback = (void *)semBCreate(SEM_Q_FIFO,SEM_FULL);
ppn->callbackState = callbackCanceled;
dbScanUnlock(precord);
if(semTake((SEM_ID)ppn->waitForCallback,sysClkRateGet()*10)!=OK) {
errMessage(0,"dbNotifyCancel had semTake timeout");
ppn->callbackState = callbackNotActive;
}
precord = pnext;
semDelete((SEM_ID)ppn->waitForCallback);
} else {
dbScanUnlock(precord);
}
}
static void notifyCancel(PUTNOTIFY *ppn)
{
PNWAITNODE *ppnnode;
struct dbCommon *precord;
PNRESTARTNODE *pfirst;
/*Remove everything on waitList*/
while(ppnnode = (PNWAITNODE *)ellLast(&ppn->waitList)) {
precord = ppnnode->precord;
precord->ppn = NULL;
ellDelete(&ppn->waitList,&ppnnode->node);
}
/*If on restartList remove it*/
if(ppn->restartNode.ppnrestartList)
ellDelete(&ppn->restartNode.ppnrestartList->restartList,
&ppn->restartNode.node);
/*If this ppn has a restartList move it */
if(pfirst = (PNRESTARTNODE *)ellFirst(&ppn->restartList)) {
PNRESTARTNODE *pnext;
PUTNOTIFY *pfirstppn;
pfirstppn = pfirst->ppn;
ellConcat(&pfirstppn->restartList,&ppn->restartList);
pnext = (PNRESTARTNODE *)ellFirst(&pfirstppn->restartList);
while(pnext) {
pnext->ppnrestartList = pfirstppn;
pnext = (PNRESTARTNODE *)ellNext(&pnext->node);
}
pfirstppn->restart = TRUE;
pfirstppn->callbackState = callbackActive;
callbackRequest(&pfirstppn->callback);
}
memset(&ppn->restartNode,'\0',sizeof(PNRESTARTNODE));
}
void dbNotifyCompletion(struct dbCommon *precord)
{
PUTNOTIFY *ppn = (PUTNOTIFY *)precord->ppn;
PNWAITNODE *ppnnode = (PNWAITNODE *)precord->ppnn;;
ellDelete(&ppn->waitList,&ppnnode->node);
precord->ppn = NULL;
if((ppn->status!=0) || (ellCount(&ppn->waitList)==0))
issueCallback(ppn);
}
void dbNotifyAdd(struct dbCommon *pfrom, struct dbCommon *pto)
{
PUTNOTIFY *ppn = pfrom->ppn;
PUTNOTIFY *pfromppn = (PUTNOTIFY *)pfrom->ppn;
PUTNOTIFY *ppn=NULL;
if(pto->ppn) cleanPpList(pto->ppn); /* clean list before giving up*/
if(pto->ppn == pfrom->ppn) return; /*Aready in same set*/
if (pto->ppn) { /*already being used. Abandon request*/
ppn->status = S_db_Blocked;
dbNotifyCompletion(ppn);
notifyCancel(pfrom->ppn);
restartAdd(pto->ppn,pfromppn);
return;
} else {
ppn->nwaiting++;
pto->ppn = pfrom->ppn;
pto->ppnn = ppn->list;
ppn->list = pto;
/*If already active must redo*/
if(pto->pact) ppn->rescan = TRUE;
/*If already active must redo*/
if(pto->pact) {
ppn = pfrom->ppn;
notifyCancel(pfrom->ppn);
waitAdd(pto,ppn);
restartAdd(pto->ppn,ppn);
} else {
waitAdd(pto,pfrom->ppn);
}
}
}
static void dbtpnCallback(PUTNOTIFY *ppn)
{
DBADDR *pdbaddr = ppn->paddr;
long status = ppn->status;
if(status==S_db_Blocked)
printf("dbtpnCallback: blocked record=%s\n",ppn->paddr->precord->name);
else if(status==0)
printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord->name);
else
recGblRecordError(status,pdbaddr->precord,"dbtpnCallback");
free((void *)pdbaddr);
free(ppn);
}
long dbtpn(char *pname,char *pvalue)
{
long status;
DBADDR *pdbaddr=NULL;
PUTNOTIFY *ppn=NULL;
char *psavevalue;
int len;
len = strlen(pvalue);
/*allocate space for value immediately following DBADDR*/
pdbaddr = dbCalloc(1,sizeof(DBADDR) + len+1);
psavevalue = (char *)(pdbaddr + 1);
strcpy(psavevalue,pvalue);
status = dbNameToAddr(pname,pdbaddr);
if(status) {
errMessage(status, "dbtpn: dbNameToAddr");
free((void *)pdbaddr);
return(-1);
}
ppn = dbCalloc(1,sizeof(PUTNOTIFY));
ppn->paddr = pdbaddr;
ppn->pbuffer = psavevalue;
ppn->nRequest = 1;
ppn->dbrType = DBR_STRING;
ppn->userCallback = dbtpnCallback;
status = dbPutNotify(ppn);
if(status==S_db_Pending) {
printf("dbtpn: Pending nwaiting=%d\n",ellCount(&ppn->waitList));
return(0);
}
if(status==S_db_Blocked) {
printf("dbtpn: blocked record=%s\n",pname);
} else if(status) {
errMessage(status, "dbtpn");
}
return(0);
}

View File

@@ -51,6 +51,7 @@
#include <ellLib.h>
#include <vxLib.h>
#include <tickLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <dbAccess.h>
@@ -66,7 +67,6 @@
#include <dbStaticLib.h>
extern struct dbBase *pdbBase;
extern volatile int interruptAccept;
/* SCAN ONCE */
#define ONCE_QUEUE_SIZE 256
@@ -146,7 +146,7 @@ long scanInit()
void post_event(int event)
{
unsigned char evnt;
int status;
static int newOverflow=TRUE;
if (!interruptAccept) return; /* not awake yet */
if(event<0 || event>=MAX_EVENTS) {
@@ -156,14 +156,13 @@ void post_event(int event)
evnt = (unsigned)event;
/*multiple writers can exist. Thus if evnt is ever changed to use*/
/*something bigger than a character interrupts will have to be blocked*/
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))!=sizeof(unsigned char))
errMessage(0,"rngBufPut overflow in post_event");
if((status=semGive(eventSem))!=OK){
/*semGive randomly returns garbage value*/
/*
errMessage(0,"semGive returned error in post_event");
*/
}
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))!=sizeof(unsigned char)) {
if(newOverflow) errMessage(0,"rngBufPut overflow in post_event");
newOverflow = FALSE;
} else {
newOverflow = TRUE;
}
semGive(eventSem);
}
@@ -382,8 +381,14 @@ void scanIoRequest(IOSCANPVT pioscanpvt)
void scanOnce(void *precord)
{
if(rngBufPut(onceQ,(void *)&precord,sizeof(precord))!=sizeof(precord))
errMessage(0,"rngBufPut overflow in scanOnce");
static int newOverflow=TRUE;
if(rngBufPut(onceQ,(void *)&precord,sizeof(precord))!=sizeof(precord)) {
if(newOverflow)errMessage(0,"rngBufPut overflow in scanOnce");
newOverflow = FALSE;
}else {
newOverflow = TRUE;
}
semGive(onceSem);
}
@@ -598,7 +603,7 @@ static void printList(struct scan_list *psl,char *message)
struct scan_element *pse;
FASTLOCK(&psl->lock);
(void *)pse = ellFirst(&psl->list);
pse = (struct scan_element *)ellFirst(&psl->list);
FASTUNLOCK(&psl->lock);
if(pse==NULL) return;
printf("%s\n",message);
@@ -610,7 +615,7 @@ static void printList(struct scan_list *psl,char *message)
printf("Returning because list changed while processing.");
return;
}
(void *)pse = ellNext((void *)pse);
pse = (struct scan_element *)ellNext((void *)pse);
FASTUNLOCK(&psl->lock);
}
}
@@ -624,9 +629,9 @@ static void scanList(struct scan_list *psl)
FASTLOCK(&psl->lock);
psl->modified = FALSE;
(void *)pse = ellFirst(&psl->list);
pse = (struct scan_element *)ellFirst(&psl->list);
prev = NULL;
(void *)next = ellNext((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
FASTUNLOCK(&psl->lock);
while(pse!=NULL) {
struct dbCommon *precord = pse->precord;
@@ -637,27 +642,27 @@ static void scanList(struct scan_list *psl)
FASTLOCK(&psl->lock);
if(!psl->modified) {
prev = pse;
(void *)pse = ellNext((void *)pse);
if(pse!=NULL) (void *)next = ellNext((void *)pse);
pse = (struct scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
} else if (pse->pscan_list==psl) {
/*This scan element is still in same scan list*/
prev = pse;
(void *)pse = ellNext((void *)pse);
if(pse!=NULL) (void *)next = ellNext((void *)pse);
pse = (struct scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
psl->modified = FALSE;
} else if (prev!=NULL && prev->pscan_list==psl) {
/*Previous scan element is still in same scan list*/
(void *)pse = ellNext((void *)prev);
pse = (struct scan_element *)ellNext((void *)prev);
if(pse!=NULL) {
(void *)prev = ellPrevious((void *)pse);
(void *)next = ellNext((void *)pse);
prev = (struct scan_element *)ellPrevious((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
}
psl->modified = FALSE;
} else if (next!=NULL && next->pscan_list==psl) {
/*Next scan element is still in same scan list*/
pse = next;
(void *)prev = ellPrevious((void *)pse);
(void *)next = ellNext((void *)pse);
prev = (struct scan_element *)ellPrevious((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
psl->modified = FALSE;
} else {
/*Too many changes. Just wait till next period*/
@@ -703,17 +708,17 @@ static void addToList(struct dbCommon *precord,struct scan_list *psl)
if(pse==NULL) {
pse = dbCalloc(1,sizeof(struct scan_element));
precord->spvt = (void *)pse;
(void *)pse->precord = precord;
pse->precord = precord;
}
pse ->pscan_list = psl;
(void *)ptemp = ellFirst(&psl->list);
ptemp = (struct scan_element *)ellFirst(&psl->list);
while(ptemp!=NULL) {
if(ptemp->precord->phas>precord->phas) {
ellInsert(&psl->list,
ellPrevious((void *)ptemp),(void *)pse);
break;
}
(void *)ptemp = ellNext((void *)ptemp);
ptemp = (struct scan_element *)ellNext((void *)ptemp);
}
if(ptemp==NULL) ellAdd(&psl->list,(void *)pse);
psl->modified = TRUE;

View File

@@ -57,6 +57,15 @@
#define messagesize 100
#define RPCL_LEN 184
#if defined(EPICS_LITTLE_ENDIAN)
#define BYTE_SWAP_4(A) \
( (((A) & 0xFF) << 24 ) | \
(((A) & 0xFF00) << 8) | \
(((A) & 0xFF0000) >> 8) | \
(((A) & 0xFF000000) >> 24) )
#endif
long postfix(char *pinfix, char *ppostfix,short *perror);
static char *ppstring[2]={"NPP","PP"};
@@ -430,7 +439,6 @@ DBBASE *pdbbase;
ELLLIST *preclist;
int recType;
if (!pdbbase || !ppvd || !precType) return;
dbPvdFreeMem(pdbbase);
/* loop thru the recLocs - removing lists then recLoc only */
for (recType = 0; recType < precType->number; recType++) {
if (!(precLoc = GET_PRECLOC(precHeader, recType))) continue;
@@ -452,6 +460,7 @@ DBBASE *pdbbase;
free((void *) precLoc);
}
/* free the rest of the memory allocations */
dbPvdFreeMem(pdbbase);
if (pdbbase->pchoiceCvt)
free((void *) pdbbase->pchoiceCvt);
if (pdbbase->pchoiceDev)
@@ -740,7 +749,7 @@ char *precordName;
struct recLoc *precLoc = NULL;
short rec_size;
if(strlen(precordName)>PVNAME_SZ) return(S_dbLib_nameLength);
if(strlen(precordName)>(size_t)PVNAME_SZ) return(S_dbLib_nameLength);
/* clear callers entry */
zeroDbentry(pdbentry);
if(!dbFindRecord(pdbentry,precordName)) return (S_dbLib_recExists);
@@ -938,7 +947,7 @@ char *newName;
long status;
DBENTRY dbentry;
if(strlen(newName)>PVNAME_SZ) return(S_dbLib_nameLength);
if(strlen(newName)>(size_t)PVNAME_SZ) return(S_dbLib_nameLength);
if(!precnode) return(S_dbLib_recNotFound);
dbInitEntry(pdbentry->pdbbase,&dbentry);
status = dbFindRecord(&dbentry,newName);
@@ -1008,15 +1017,23 @@ char *pfieldName;
bottom = 0;
test = (top + bottom) / 2;
while (1) {
unsigned int t1, t2;
/* check the field name */
if (sortFldName[test] == *(unsigned long *) pconvName) {
t1 = (unsigned int) sortFldName[ test];
t2 = (unsigned int) *(unsigned int*)pconvName;
#if defined(EPICS_LITTLE_ENDIAN)
t1 = BYTE_SWAP_4( t1);
t2 = BYTE_SWAP_4( t2);
#endif
if(t1 == t2) {
if(!(pflddes=GET_PFLDDES(precTypDes,sortFldInd[test])))
return(S_dbLib_recdesNotFound);
pdbentry->pflddes = pflddes;
pdbentry->pfield = precord + pflddes->offset;
pdbentry->indfield = sortFldInd[test];
return (0);
} else if (sortFldName[test] > *(unsigned long *) pconvName) {
} else if (t1 > t2) {
top = test - 1;
if (top < bottom) return (S_dbLib_fieldNotFound);
test = (top + bottom) / 2;
@@ -1591,7 +1608,7 @@ char *pstring;
if (!(pchoice = pdevChoiceSet->papDevChoice[i]->pchoice))
continue;
if (strcmp(pchoice, pstring) == 0) {
long link_type,status;
long link_type;
link_type = pdevChoiceSet->papDevChoice[i]->link_type;
/*If no INP or OUT OK */
@@ -1623,7 +1640,7 @@ char *pstring;
if(pstr[ind]!=' ' && pstr[ind]!='\t') break;
pstr[ind] = '\0';
}
if(!pstr || strlen(pstr)<=0 ) {
if(!pstr || strlen(pstr)==0 ) {
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
if(plink->type!=CONSTANT) return(S_dbLib_badField);
return(0);
@@ -1689,12 +1706,18 @@ char *pstring;
if(!(end = strchr(pstr,'N'))) return (S_dbLib_badField);
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.n);
if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField);
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.a);
if(!(end = strchr(pstr,'F'))) return (S_dbLib_badField);
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.f);
if(!(end = strchr(pstr,'A'))) {
plink->value.camacio.a = 0;
} else {
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.a);
}
if(!(end = strchr(pstr,'F'))) {
plink->value.camacio.f = 0;
} else {
pstr = end + 1;
sscanf(pstr,"%hd",&plink->value.camacio.f);
}
plink->value.camacio.parm[0] = 0;
if(end = strchr(pstr,'@')) {
pstr = end + 1;
@@ -4127,16 +4150,29 @@ FILE *fp;
}
/* Beginning of Process Variable Directory Routines*/
#define HASH_NO 512 /* number of hash table entries */
int dbPvdHashTableSize = 512;
static int dbPvdHashTableShift;
#define NTABLESIZES 9
static struct {
unsigned int tablesize;
int shift;
}hashTableParms[9] = {
{256,0},
{512,1},
{1024,2},
{2048,3},
{4096,4},
{8192,5},
{16384,6},
{32768,7},
{65536,8}
};
/*The hash algorithm is a modification of the algorithm described in */
/* Fast Hashing of Variable Length Text Strings, Peter K. Pearson, */
/* Communications of the ACM, June 1990 */
/* The modifications were desdigned by Marty Kraimer and Ben Chin Cha */
/* The mods were implemented and tested by Ben Chin Cha */
/* The modifications were designed by Marty Kraimer */
static unsigned char T0[256] = {
static unsigned char T[256] = {
39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69,
157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160,
176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77,
@@ -4155,45 +4191,24 @@ static unsigned char T0[256] = {
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47
};
static unsigned char T1[256] = {
9,139,209, 40, 31,202, 58,179,116, 33,207,146, 76, 60,242,124,
254,197, 80,167,153,145,129,233,132, 48,246, 86,156,177, 36,187,
45, 1, 96, 18, 19, 62,185,234, 99, 16,218, 95,128,224,123,253,
42,109, 4,247, 72, 5,151,136, 0,152,148,127,204,133, 17, 14,
182,217, 54,199,119,174, 82, 57,215, 41,114,208,206,110,239, 23,
189, 15, 3, 22,188, 79,113,172, 28, 2,222, 21,251,225,237,105,
102, 32, 56,181,126, 83,230, 53,158, 52, 59,213,118,100, 67,142,
220,170,144,115,205, 26,125,168,249, 66,175, 97,255, 92,229, 91,
214,236,178,243, 46, 44,201,250,135,186,150,221,163,216,162, 43,
11,101, 34, 37,194, 25, 50, 12, 87,198,173,240,193,171,143,231,
111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238,
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47,
39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69,
157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160,
176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77,
75,107,169,138,195,184, 70, 90, 61,166, 7,244,165,108,219, 51,
};
#ifdef __STDC__
static unsigned short hash( char *pname, int length)
#else
static unsigned short hash( pname, length)
char *pname;
int length;
#endif /*__STDC__*/
{
unsigned short h=0;
unsigned short hret;
unsigned char *h0=(unsigned char *)&h;
unsigned char *h1= h0 + 1;
unsigned char h0=0;
unsigned char h1=0;
unsigned short ind0,ind1;
int even = TRUE;
unsigned char c;
int i;
for(i=0; i<length; i+=2, pname+=2) {
*h0 = T0[*h0 ^ *pname];
*h1 = T1[*h1 ^ *(pname+1)];
for(i=0; i<length; i++, pname++) {
c = *pname;
if(even) {h0 = T[h0^c]; even = FALSE;}
else {h1 = T[h1^c]; even = TRUE;}
}
hret = *h0;
return(hret + *h1);
ind0 = (unsigned short)h0;
ind1 = (unsigned short)h1;
return((ind1<<dbPvdHashTableShift) ^ ind0);
}
#ifdef __STDC__
@@ -4203,9 +4218,19 @@ void dbPvdInitPvt(pdbbase)
DBBASE *pdbbase;
#endif /*__STDC__*/
{
ELLLIST **ppvd;
ELLLIST **ppvd;
int i;
ppvd = dbCalloc(HASH_NO, sizeof(ELLLIST *));
for(i=0; i< NTABLESIZES; i++) {
if((i==NTABLESIZES-1)
||((dbPvdHashTableSize>=hashTableParms[i].tablesize)
&& (dbPvdHashTableSize<hashTableParms[i+1].tablesize))) {
dbPvdHashTableSize = hashTableParms[i].tablesize;
dbPvdHashTableShift = hashTableParms[i].shift;
break;
}
}
ppvd = dbCalloc(dbPvdHashTableSize, sizeof(ELLLIST *));
pdbbase->ppvd = (void *) ppvd;
return;
}
@@ -4291,7 +4316,8 @@ RECNODE *precnode;
ppvdlist=ppvd[hashInd];
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
while(ppvdNode) {
if(strcmp(name,(char *)ppvdNode->precnode->precord) == 0) {
if(ppvdNode->precnode && ppvdNode->precnode->precord
&& strcmp(name,(char *)ppvdNode->precnode->precord) == 0) {
ellDelete(ppvdlist, (ELLNODE*)ppvdNode);
free((void *)ppvdNode);
return;
@@ -4315,7 +4341,7 @@ DBBASE *pdbbase;
PVDENTRY *next;
if (ppvd == NULL) return;
for (hashInd=0; hashInd<HASH_NO; hashInd++) {
for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) {
if(ppvd[hashInd] == NULL) continue;
ppvdlist=ppvd[hashInd];
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
@@ -4331,10 +4357,11 @@ DBBASE *pdbbase;
}
#ifdef __STDC__
void dbPvdDump(DBBASE *pdbbase)
void dbPvdDump(DBBASE *pdbbase,int verbose)
#else
void dbPvdDump(pdbbase)
void dbPvdDump(pdbbase,verbose)
DBBASE *pdbbase;
int verbose;
#endif /*__STDC__*/
{
unsigned short hashInd;
@@ -4344,14 +4371,16 @@ DBBASE *pdbbase;
int number;
if (ppvd == NULL) return;
printf("Process Variable Directory\n");
for (hashInd=0; hashInd<HASH_NO; hashInd++) {
printf("Process Variable Directory ");
printf("dbPvdHashTableSize %d dbPvdHashTableShift %d\n",
dbPvdHashTableSize,dbPvdHashTableShift);
for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) {
if(ppvd[hashInd] == NULL) continue;
ppvdlist=ppvd[hashInd];
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
printf(" %3.3hd=%3.3d\n",hashInd,ellCount(ppvdlist));
printf("\n%3.3hd=%3.3d ",hashInd,ellCount(ppvdlist));
number=0;
while(ppvdNode) {
while(ppvdNode && verbose) {
printf(" %s",(char *)ppvdNode->precnode->precord);
if(number++ ==2) {number=0;printf("\n ");}
ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode);

View File

@@ -40,6 +40,7 @@
* .09 09-24-93 jbk adjusted dbpr to print vxi links correctly
* .10 02-02-94 mrk added dbtpn (test dbPutNotify)
* .11 03-18-94 mcn added dbgrep and timing routines.
* .12 08-14-95 mrk Moved dbtpn to dbNotify
*/
/* Global Database Test Routines - All can be invoked via vxWorks shell
@@ -76,10 +77,6 @@
* char *pname;
* char *pvalue
*
* dbtpn(pname,pvalue) test put notify
* char *pname;
* char *pvalue
*
* dbior(pname,type) io_report
* char *pname Driver name. If null all drivers
* int type <0,1> => <short, full> report
@@ -99,6 +96,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <timexLib.h>
#include <ellLib.h>
#include <fast_lock.h>
@@ -115,6 +113,7 @@
#include <special.h>
#include <dbRecDes.h>
#include <dbStaticLib.h>
#include <dbEvent.h>
#include <ellLib.h>
#include <callback.h>
@@ -173,18 +172,6 @@ long dba(char*pname)
if(status) return(1); else return(0);
}
/*Following definition is from dbEvent.c*/
struct event_block{
ELLNODE node;
struct dbAddr *paddr;
void (*user_sub)();
void *user_arg;
struct event_que *ev_que;
unsigned char select;
char valque;
unsigned short npend; /* n times this event is on the que */
};
long dbel(char*pname)
{
struct dbAddr addr;
@@ -203,7 +190,7 @@ long dbel(char*pname)
return(0);
}
while(peb) {
pfldDes = peb->paddr->pfldDes;
pfldDes = ((struct dbAddr *)peb->paddr)->pfldDes;
printf("%4.4s",&pfldDes->fldname[0]);
if(peb->select&&DBE_VALUE) printf(" VALUE");
if(peb->select&&DBE_LOG) printf(" LOG");
@@ -292,8 +279,6 @@ long dbgrep(char *pmask)
int rectype, beg, end;
struct recLoc *precLoc;
struct dbCommon *precord;
char *pstr;
char name[PVNAME_SZ+1];
struct recType *precType;
struct recHeader *precHeader;
RECNODE *precNode;
@@ -699,59 +684,6 @@ long dbtpf(char *pname,char *pvalue)
return(0);
}
static void dbtpnCallback(PUTNOTIFY *ppn)
{
DBADDR *pdbaddr = ppn->paddr;
long status = ppn->status;
if(status==S_db_Blocked)
printf("dbtpnCallback: blocked record=%s\n",ppn->paddr->precord);
else if(status==0)
printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord);
else
recGblRecordError(status,pdbaddr->precord,"dbtpnCallback");
free((void *)pdbaddr);
free(ppn);
}
long dbtpn(char *pname,char *pvalue)
{
long status;
DBADDR *pdbaddr=NULL;
PUTNOTIFY *ppn=NULL;
char *psavevalue;
int len;
len = strlen(pvalue);
/*allocate space for value immediately following DBADDR*/
pdbaddr = dbCalloc(1,sizeof(DBADDR) + len+1);
psavevalue = (char *)(pdbaddr + 1);
strcpy(psavevalue,pvalue);
status = dbNameToAddr(pname,pdbaddr);
if(status) {
errMessage(status, "dbtpn: dbNameToAddr");
free((void *)pdbaddr);
return(-1);
}
ppn = dbCalloc(1,sizeof(PUTNOTIFY));
ppn->paddr = pdbaddr;
ppn->pbuffer = psavevalue;
ppn->nRequest = 1;
ppn->dbrType = DBR_STRING;
ppn->userCallback = dbtpnCallback;
status = dbPutNotify(ppn);
if(status==S_db_Pending) {
printf("dbtpn: Pending nwaiting=%d\n",ppn->nwaiting);
return(0);
}
if(status==S_db_Blocked) {
printf("dbtpn: blocked record=%s\n",pname);
} else if(status) {
errMessage(status, "dbtpn");
}
return(0);
}
long dbior(char *pdrvName,int type)
{
int i,j;
@@ -914,7 +846,7 @@ static void printBuffer(
pdbr_status->status, pdbr_status->severity);
} else
printf("status and severity not returned\n");
pbuffer += dbr_status_size;
pbuffer = (char *)pbuffer + dbr_status_size;
}
if (reqOptions & DBR_UNITS) {
if (retOptions & DBR_UNITS) {
@@ -924,7 +856,7 @@ static void printBuffer(
}else{
printf("units not returned\n");
}
pbuffer += dbr_units_size;
pbuffer = (char *)pbuffer + dbr_units_size;
}
if (reqOptions & DBR_PRECISION) {
precision = *((long *) pbuffer);
@@ -935,7 +867,7 @@ static void printBuffer(
}else{
printf("precision not returned\n");
}
pbuffer += dbr_precision_size;
pbuffer = (char *)pbuffer + dbr_precision_size;
}
if (reqOptions & DBR_TIME) {
if (retOptions & DBR_TIME) {
@@ -946,7 +878,7 @@ static void printBuffer(
}else{
printf("time not returned\n");
}
pbuffer += dbr_time_size;
pbuffer = (char *)pbuffer + dbr_time_size;
}
if (reqOptions & DBR_ENUM_STRS) {
if (retOptions & DBR_ENUM_STRS) {
@@ -957,7 +889,7 @@ static void printBuffer(
printf("%s\n",&pdbr_enumStrs->strs[i][0]);
} else
printf("enum strings not returned\n");
pbuffer += dbr_enumStrs_size;
pbuffer = (char *)pbuffer + dbr_enumStrs_size;
}
if (reqOptions & DBR_GR_LONG) {
if (retOptions & DBR_GR_LONG) {
@@ -968,7 +900,7 @@ static void printBuffer(
}else{
printf("DBRgrLong not returned\n");
}
pbuffer += dbr_grLong_size;
pbuffer = (char *)pbuffer + dbr_grLong_size;
}
if (reqOptions & DBR_GR_DOUBLE) {
if (retOptions & DBR_GR_DOUBLE) {
@@ -979,7 +911,7 @@ static void printBuffer(
}else{
printf("DBRgrDouble not returned\n");
}
pbuffer += dbr_grDouble_size;
pbuffer = (char *)pbuffer + dbr_grDouble_size;
}
if (reqOptions & DBR_CTRL_LONG) {
if (retOptions & DBR_CTRL_LONG){
@@ -990,7 +922,7 @@ static void printBuffer(
}else{
printf("DBRctrlLong not returned\n");
}
pbuffer += dbr_ctrlLong_size;
pbuffer = (char *)pbuffer + dbr_ctrlLong_size;
}
if (reqOptions & DBR_CTRL_DOUBLE) {
if (retOptions & DBR_CTRL_DOUBLE) {
@@ -1001,7 +933,7 @@ static void printBuffer(
}else{
printf("DBRctrlDouble not returned\n");
}
pbuffer += dbr_ctrlDouble_size;
pbuffer = (char *)pbuffer + dbr_ctrlDouble_size;
}
if (reqOptions & DBR_AL_LONG) {
if (retOptions & DBR_AL_LONG) {
@@ -1013,7 +945,7 @@ static void printBuffer(
}else{
printf("DBRalLong not returned\n");
}
pbuffer += dbr_alLong_size;
pbuffer = (char *)pbuffer + dbr_alLong_size;
}
if (reqOptions & DBR_AL_DOUBLE) {
if (retOptions & DBR_AL_DOUBLE) {
@@ -1025,7 +957,7 @@ static void printBuffer(
}else{
printf("DBRalDouble not returned\n");
}
pbuffer += dbr_alDouble_size;
pbuffer = (char *)pbuffer + dbr_alDouble_size;
}
/* Now print values */
if (no_elements == 0) return;
@@ -1044,7 +976,7 @@ static void printBuffer(
sprintf(pmsg, " %s", (char *)pbuffer);
dbpr_msgOut(pMsgBuff, tab_size);
}
pbuffer += MAX_STRING_SIZE;
pbuffer = (char *)pbuffer + MAX_STRING_SIZE;
}
break;
case (DBR_CHAR):
@@ -1059,7 +991,7 @@ static void printBuffer(
svalue = *(char *) pbuffer;
sprintf(pmsg, "%-9d 0x%-9x", svalue,svalue);
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 1;
pbuffer = (char *)pbuffer + 1;
}
break;
case (DBR_UCHAR):
@@ -1074,7 +1006,7 @@ static void printBuffer(
usvalue = *(unsigned char *) pbuffer;
sprintf(pmsg, "%-9d 0x%-9x", usvalue,usvalue);
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 1;
pbuffer = (char *)pbuffer + 1;
}
break;
case (DBR_SHORT):
@@ -1088,7 +1020,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9d 0x%-9x", *((short *) pbuffer), *((short *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 2;
pbuffer = (char *)pbuffer + sizeof(short);
}
break;
case (DBR_USHORT):
@@ -1102,7 +1034,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9u 0x%-9x",*((unsigned short *) pbuffer),*((unsigned short *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 2;
pbuffer = (char *)pbuffer + sizeof(unsigned short);
}
break;
case (DBR_LONG):
@@ -1116,7 +1048,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9ld 0x%-9lx", *((long *) pbuffer), *((long *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 4;
pbuffer = (char *)pbuffer + sizeof(long);
}
break;
case (DBR_ULONG):
@@ -1130,7 +1062,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9ld 0x%-9lx",*((unsigned long *) pbuffer),*((unsigned long *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 4;
pbuffer = (char *)pbuffer + sizeof(unsigned long);
}
break;
case (DBR_FLOAT):
@@ -1144,7 +1076,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-13.6g", *((float *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 4;
pbuffer = (char *)pbuffer + sizeof(float);
}
break;
case (DBR_DOUBLE):
@@ -1158,7 +1090,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-13.6g", *((double *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 8;
pbuffer = (char *)pbuffer + sizeof(double);
}
break;
case (DBR_ENUM):
@@ -1172,7 +1104,7 @@ static void printBuffer(
for (i = 0; i < no_elements; i++) {
sprintf(pmsg, "%-9u", *((unsigned short *) pbuffer));
dbpr_msgOut(pMsgBuff, tab_size);
pbuffer += 2;
pbuffer = (char *)pbuffer + sizeof(unsigned short);
}
break;
default:
@@ -1814,9 +1746,62 @@ char *record_name;
* Time the record
*/
dbScanLock(precord);
timexN(timing_routine, precord);
timexN((FUNCPTR)timing_routine, (int)precord,
0,0,0,0,0,0,0);
dbScanUnlock(precord);
return(0);
}
int dbllsdblinks(int lset)
{
int i,link;
struct recLoc *precLoc;
struct recDes *precDes;
struct recTypDes *precTypDes;
struct recHeader *precHeader;
RECNODE *precNode;
struct fldDes *pfldDes;
struct dbCommon *precord;
struct link *plink;
if(!(precHeader = pdbBase->precHeader)) return(-1);
if(!(precDes = pdbBase->precDes)) return(-1);
for(i=0; i< (precHeader->number); i++) {
if(!(precLoc = precHeader->papRecLoc[i]))continue;
if(!precLoc->preclist) continue;
precTypDes = precDes->papRecTypDes[i];
for(precNode=(RECNODE *)ellFirst(precLoc->preclist);
precNode; precNode = (RECNODE *)ellNext(&precNode->node)) {
precord = precNode->precord;
/* If NAME is null then skip this record*/
if(!(precord->name[0])) continue;
if(precord->lset != lset) continue;
printf("%s\n",precord->name);
for(link=0; (link<precTypDes->no_links) ; link++) {
struct dbAddr *pdbAddr;
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
/*
* Find link structure, which is at an offset in the record
*/
plink = (struct link *)((char *)precord + pfldDes->offset);
/* Ignore link if type is constant, channel access, or hardware specific */
if(plink->type != DB_LINK) continue;
pdbAddr = (struct dbAddr *)(plink->value.db_link.pdbAddr);
if(pfldDes->field_type==DBF_INLINK) {
printf("\t INLINK");
} else if(pfldDes->field_type==DBF_OUTLINK) {
printf("\tOUTLINK");
} else if(pfldDes->field_type==DBF_FWDLINK) {
printf("\tFWDLINK");
}
printf(" %s %s",
((plink->value.db_link.process_passive)?" PP":"NPP"),
((plink->value.db_link.maximize_sevr)?" MS":"NMS"));
printf(" %s\n",pdbAddr->precord->name);
}
}
}
return(0);
}

View File

@@ -129,6 +129,9 @@
#define MAX_STRING_SIZE 40
#endif
#ifndef MAX_UNITS_SIZE
#define MAX_UNITS_SIZE 8
#endif
/* VALUES WITH STATUS STRUCTURES */
@@ -269,7 +272,7 @@ struct dbr_time_double{
struct dbr_gr_int{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -281,7 +284,7 @@ struct dbr_gr_int{
struct dbr_gr_short{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -297,7 +300,7 @@ struct dbr_gr_float{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad0; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
float upper_disp_limit; /* upper limit of graph */
float lower_disp_limit; /* lower limit of graph */
float upper_alarm_limit;
@@ -320,7 +323,7 @@ struct dbr_gr_enum{
struct dbr_gr_char{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
unsigned char upper_disp_limit; /* upper limit of graph */
unsigned char lower_disp_limit; /* lower limit of graph */
unsigned char upper_alarm_limit;
@@ -335,7 +338,7 @@ struct dbr_gr_char{
struct dbr_gr_long{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
long upper_disp_limit; /* upper limit of graph */
long lower_disp_limit; /* lower limit of graph */
long upper_alarm_limit;
@@ -351,7 +354,7 @@ struct dbr_gr_double{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad0; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
double upper_disp_limit; /* upper limit of graph */
double lower_disp_limit; /* lower limit of graph */
double upper_alarm_limit;
@@ -370,7 +373,7 @@ struct dbr_gr_double{
struct dbr_ctrl_int{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -384,7 +387,7 @@ struct dbr_ctrl_int{
struct dbr_ctrl_short{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -402,7 +405,7 @@ struct dbr_ctrl_float{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
float upper_disp_limit; /* upper limit of graph */
float lower_disp_limit; /* lower limit of graph */
float upper_alarm_limit;
@@ -427,7 +430,7 @@ struct dbr_ctrl_enum{
struct dbr_ctrl_char{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
unsigned char upper_disp_limit; /* upper limit of graph */
unsigned char lower_disp_limit; /* lower limit of graph */
unsigned char upper_alarm_limit;
@@ -444,7 +447,7 @@ struct dbr_ctrl_char{
struct dbr_ctrl_long{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
long upper_disp_limit; /* upper limit of graph */
long lower_disp_limit; /* lower limit of graph */
long upper_alarm_limit;
@@ -462,7 +465,7 @@ struct dbr_ctrl_double{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad0; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
double upper_disp_limit; /* upper limit of graph */
double lower_disp_limit; /* lower limit of graph */
double upper_alarm_limit;
@@ -1017,7 +1020,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1051,7 +1055,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1083,7 +1088,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1114,7 +1120,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1148,7 +1155,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1182,7 +1190,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1219,7 +1228,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1286,7 +1296,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1320,7 +1331,8 @@ void *pfl;
status = dbGetField(paddr,DBR_LONG,&new,&options,&nRequest,pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1357,7 +1369,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;

View File

@@ -68,9 +68,9 @@ short index;
}
printf(" Record Name: %s\n",pname);
printf(" Record Type: %d\n",addr.record_type);
printf("Record Address: 0x%x\n",addr.precord);
printf("Record Address: 0x%p\n",addr.precord);
printf(" Field Type: %d\n",addr.field_type);
printf(" Field Address: 0x%x\n",addr.pfield);
printf(" Field Address: 0x%p\n",addr.pfield);
printf(" Field Size: %d\n",addr.field_size);
printf(" No Elements: %d\n",addr.no_elements);
number_elements =
@@ -128,9 +128,9 @@ short index;
}
printf(" Record Name: %s\n",pname);
printf(" Record Type: %d\n",addr.record_type);
printf("Record Address: 0x%x\n",addr.precord);
printf("Record Address: 0x%p\n",addr.precord);
printf(" Field Type: %d\n",addr.field_type);
printf(" Field Address: 0x%x\n",addr.pfield);
printf(" Field Address: 0x%p\n",addr.pfield);
printf(" Field Size: %d\n",addr.field_size);
printf(" No Elements: %d\n",addr.no_elements);
if (db_put_field(paddr,DBR_STRING,pvalue,1) < 0) printf("\n\t failed ");
@@ -312,7 +312,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_sts_long *pvalue
= (struct dbr_sts_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d",pvalue->status,pvalue->severity);
if(count==1) printf("\tValue: ");
for (i = 0; i < count; i++,plong++){
@@ -395,7 +395,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_time_long *pvalue
= (struct dbr_time_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d",pvalue->status,pvalue->severity);
printf("\tTimeStamp: %lx %lx",
pvalue->stamp.secPastEpoch, pvalue->stamp.nsec);
@@ -495,7 +495,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_gr_long *pvalue
= (struct dbr_gr_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d %.8s",pvalue->status,pvalue->severity,
pvalue->units);
printf("\n\t%8d %8d %8d %8d %8d %8d",
@@ -596,7 +596,7 @@ static void print_returned(type,pbuffer,count)
{
struct dbr_ctrl_long *pvalue
= (struct dbr_ctrl_long *)pbuffer;
long *plong = &pvalue->value;
dbr_long_t *plong = &pvalue->value;
printf("%2d %2d %.8s",pvalue->status,pvalue->severity,
pvalue->units);
printf("\n\t%8d %8d %8d %8d %8d %8d",

View File

@@ -120,7 +120,7 @@ if (strcmp(dbl_option,"-1") == 0)
ntype = dbl_dbGetRecTypes(pdbbase);
else {
if (strlen(dbl_option) > 1) DBL_OPTION = 2;
if (strlen(dbl_option) > (size_t)1) DBL_OPTION = 2;
else if (strcmp(dbl_option,"1") == 0) DBL_OPTION = 1;
else if (strcmp(dbl_option,"2") == 0) DBL_OPTION = 3;
else DBL_OPTION = 0;

View File

@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <string.h>
#include <dbDefs.h>
#include <dbStaticLib.h>
#include <errno.h>
#else
#include <vxWorks.h>
@@ -74,8 +75,7 @@
#include <sdrHeader.h>
#ifndef vxWorks
struct dbBase *pdbBase=NULL;
extern long dbLoad();
DBBASE *pdbBase=NULL;
#ifndef MYERRNO
#define MYERRNO (int errno)
#endif
@@ -163,14 +163,25 @@ static struct PRTAB {
#ifndef vxWorks
main()
{
/* load the default.dctsdr file */
long status;
FILE *fp;
status=dbRead(&pdbBase, "default.dctsdr");
/* Create the database */
pdbBase=dbAllocBase();
/* open the default.dctsdr file */
if ((fp = fopen("default.dctsdr", "rb")) == NULL) {
printf("dbls can't open default.dctsdr\n");
return(-1);
}
/* read in the database */
status=dbRead(pdbBase, fp);
if(status!=0) {
printf("dbls aborting because dbRead failed\n");
return(-1);
}
fclose(fp);
dbls();
return(0);
}
@@ -318,17 +329,17 @@ DbRecType(fp, fflag)
if(!(precType=pdbBase->precType)) return;
sprintf(buffer, "\n\ndbls: listing the precType structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precType-> recType", &precType, precType);
sprintf(buffer, "%p[%p] precType-> recType", &precType, precType);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t number\t [ %d ]\t/* number of types */",
sprintf(buffer, "%p\t number\t [ %d ]\t/* number of types */",
&precType->number, precType->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papName\t\t /* pap to record type */",
sprintf(buffer, "%p[%p] **papName\t\t /* pap to record type */",
&precType->papName, precType->papName);
bufOut(fp, fflag);
for (i = 0; i < precType->number; i++) {
if (precType->papName[i]) {
sprintf(buffer, "%8x[%8x] papName->[%d]->\t\"%s\"",
sprintf(buffer, "%p[%p] papName->[%d]->\t\"%s\"",
&precType->papName[i],
precType->papName[i],
i, precType->papName[i]);
@@ -349,33 +360,33 @@ ChoiceGbl(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the choiceGbl structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pchoiceGbl -> arrChoiceSet", &pchoiceGbl, pchoiceGbl);
sprintf(buffer, "%p[%p] pchoiceGbl -> arrChoiceSet", &pchoiceGbl, pchoiceGbl);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of choice sets */",
&pchoiceGbl->number,
pchoiceGbl->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papChoiceSet -> choiceSet",
sprintf(buffer, "%p[%p]\t**papChoiceSet -> choiceSet",
&pchoiceGbl->papChoiceSet,
pchoiceGbl->papChoiceSet);
bufOut(fp, fflag);
for (i = 0; i < pchoiceGbl->number; i++) {
if (pchoiceGbl->papChoiceSet[i]) {
sprintf(buffer, "%8x[%8x]\t papChoiceSet->[%d]\tINDEX[%d]",
sprintf(buffer, "%p[%p]\t papChoiceSet->[%d]\tINDEX[%d]",
&pchoiceGbl->papChoiceSet[i],
pchoiceGbl->papChoiceSet[i], i, i);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number [%d]\t\t/* number of choices */",
sprintf(buffer, "%p\t\t number [%d]\t\t/* number of choices */",
&pchoiceGbl->papChoiceSet[i]->number,
pchoiceGbl->papChoiceSet[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papChoice -> \t\"choice string\"",
sprintf(buffer, "%p[%p]\t **papChoice -> \t\"choice string\"",
&pchoiceGbl->papChoiceSet[i]->papChoice,
pchoiceGbl->papChoiceSet[i]->papChoice);
bufOut(fp, fflag);
for (j = 0; j < pchoiceGbl->papChoiceSet[i]->number; j++) {
if (pchoiceGbl->papChoiceSet[i]->papChoice[j]) {
sprintf(buffer, "%8x[%8x]\t\t papChoice->[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t\t papChoice->[%d]\t\"%s\"",
&pchoiceGbl->papChoiceSet[i]->papChoice[j],
pchoiceGbl->papChoiceSet[i]->papChoice[j],
j,
@@ -402,41 +413,41 @@ ChoiceDev(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the choiceDev structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]pchoiceDev-> devChoiceRec ", &pchoiceDev, pchoiceDev);
sprintf(buffer, "%p[%p]pchoiceDev-> devChoiceRec ", &pchoiceDev, pchoiceDev);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t number\t[%d]\t\t\t/* number of devChoiceSet */",
sprintf(buffer, "%p\t number\t[%d]\t\t\t/* number of devChoiceSet */",
&pchoiceDev->number, pchoiceDev->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDevChoiceSet -> devChoiceSet ",
sprintf(buffer, "%p[%p] **papDevChoiceSet -> devChoiceSet ",
&pchoiceDev->papDevChoiceSet,
pchoiceDev->papDevChoiceSet);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (pchoiceDev->papDevChoiceSet[i]) {
sprintf(buffer, "\n%8x[%8x]\tpapDevChoiceSet->[%d]\t\tRECTYPE \"%s\"",
sprintf(buffer, "\n%p[%p]\tpapDevChoiceSet->[%d]\t\tRECTYPE \"%s\"",
&pchoiceDev->papDevChoiceSet[i],
pchoiceDev->papDevChoiceSet[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t\t/*number of choices */ ",
sprintf(buffer, "%p\t\t number\t[%d]\t\t/*number of choices */ ",
&pchoiceDev->papDevChoiceSet[i]->number,
pchoiceDev->papDevChoiceSet[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papDevChoice -> devChoice",
sprintf(buffer, "%p[%p]\t **papDevChoice -> devChoice",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice,
pchoiceDev->papDevChoiceSet[i]->papDevChoice);
bufOut(fp, fflag);
for (j = 0; j < pchoiceDev->papDevChoiceSet[i]->number; j++) {
if (pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]) {
sprintf(buffer, "%8x[%8x]\t papDevChoice[%d]",
sprintf(buffer, "%p[%p]\t papDevChoice[%d]",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j],
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j], j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t link_type [%d]",
sprintf(buffer, "%p\t\t link_type [%d]",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type,
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t\t*pchoice\t\t\"%s\"",
sprintf(buffer, "%p[%p]\t\t*pchoice\t\t\"%s\"",
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice,
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice,
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice);
@@ -459,18 +470,18 @@ ChoiceCvt(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the choiceCvt structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] choiceCvt -> choiceCvt", &pchoiceCvt, pchoiceCvt);
sprintf(buffer, "%p[%p] choiceCvt -> choiceCvt", &pchoiceCvt, pchoiceCvt);
bufOut(fp, fflag);
sprintf(buffer, "%8x number\t [ %d ]\t/* number of choices */",
sprintf(buffer, "%p number\t [ %d ]\t/* number of choices */",
&pchoiceCvt->number, pchoiceCvt->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papChoice -> \"choice string\"",
sprintf(buffer, "%p[%p] **papChoice -> \"choice string\"",
&pchoiceCvt->papChoice, pchoiceCvt->papChoice);
bufOut(fp, fflag);
for (i = 0; i < pchoiceCvt->number; i++)
if (pchoiceCvt->papChoice[i]) {
sprintf(buffer, "%8x[%8x] papChoice[%d]\t\"%s\" ",
sprintf(buffer, "%p[%p] papChoice[%d]\t\"%s\" ",
&pchoiceCvt->papChoice[i], pchoiceCvt->papChoice[i], i,
pchoiceCvt->papChoice[i]);
bufOut(fp, fflag);
@@ -523,55 +534,55 @@ CvtTable(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the pcvtTable structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pcvtTable -> arrBrkTable", &pcvtTable, pcvtTable);
sprintf(buffer, "%p[%p] pcvtTable -> arrBrkTable", &pcvtTable, pcvtTable);
bufOut(fp, fflag);
sprintf(buffer, "%8x number\t [ %d ]\t/* number of break tables */",
sprintf(buffer, "%p number\t [ %d ]\t/* number of break tables */",
&pcvtTable->number, pcvtTable->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papBrkTable -> brkTable",
sprintf(buffer, "%p[%p] **papBrkTable -> brkTable",
&pcvtTable->papBrkTable, pcvtTable->papBrkTable);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (pcvtTable->papBrkTable[i]) {
sprintf(buffer, "%8x[%8x] papBrkTable[%d] ",
sprintf(buffer, "%p[%p] papBrkTable[%d] ",
&pcvtTable->papBrkTable[i], pcvtTable->papBrkTable[i], i);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *name\t\t\t\"%s\"",
sprintf(buffer, "%p[%p]\t *name\t\t\t\"%s\"",
&pcvtTable->papBrkTable[i]->name,
pcvtTable->papBrkTable[i]->name,
pcvtTable->papBrkTable[i]->name);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number [ %d ]\t/* number of brkInt in this table */ ",
sprintf(buffer, "%p\t\t number [ %d ]\t/* number of brkInt in this table */ ",
&pcvtTable->papBrkTable[i]->number,
pcvtTable->papBrkTable[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rawLow\t\t\t%-d",
sprintf(buffer, "%p\t\t rawLow\t\t\t%-d",
&pcvtTable->papBrkTable[i]->rawLow,
pcvtTable->papBrkTable[i]->rawLow);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rawHigh\t\t\t%-d",
sprintf(buffer, "%p\t\t rawHigh\t\t\t%-d",
&pcvtTable->papBrkTable[i]->rawHigh,
pcvtTable->papBrkTable[i]->rawHigh);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papBrkInt",
sprintf(buffer, "%p[%p]\t**papBrkInt",
&pcvtTable->papBrkTable[i]->papBrkInt,
pcvtTable->papBrkTable[i]->papBrkInt);
bufOut(fp, fflag);
for (j = 0; j < pcvtTable->papBrkTable[i]->number; j++) {
if (pcvtTable->papBrkTable[i]->papBrkInt[j]) {
sprintf(buffer, "%8x[%8x]\t papBrkInt[%d] -> brkInt",
sprintf(buffer, "%p[%p]\t papBrkInt[%d] -> brkInt",
&pcvtTable->papBrkTable[i]->papBrkInt[j],
pcvtTable->papBrkTable[i]->papBrkInt[j], j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t raw\t\t\t%-d",
sprintf(buffer, "%p\t\t raw\t\t\t%-d",
&pcvtTable->papBrkTable[i]->papBrkInt[j]->raw,
pcvtTable->papBrkTable[i]->papBrkInt[j]->raw);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t slope\t\t\t%-.5f",
sprintf(buffer, "%p\t\t slope\t\t\t%-.5f",
&pcvtTable->papBrkTable[i]->papBrkInt[j]->slope,
pcvtTable->papBrkTable[i]->papBrkInt[j]->slope);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t eng\t\t\t%-.5f",
sprintf(buffer, "%p\t\t eng\t\t\t%-.5f",
&pcvtTable->papBrkTable[i]->papBrkInt[j]->eng,
pcvtTable->papBrkTable[i]->papBrkInt[j]->eng);
bufOut(fp, fflag);
@@ -596,42 +607,42 @@ DevSup(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the devSup structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precDevSup -> recDevSup ", &precDevSup, precDevSup);
sprintf(buffer, "%p[%p] precDevSup -> recDevSup ", &precDevSup, precDevSup);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t/* number of record types */",
sprintf(buffer, "%p\t\tnumber\t [ %d ]\t/* number of record types */",
&precDevSup->number, precDevSup->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDevSup -> precDevSup ",
sprintf(buffer, "%p[%p] **papDevSup -> precDevSup ",
&precDevSup->papDevSup, precDevSup->papDevSup);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precDevSup->papDevSup[i]) {
sprintf(buffer, "%8x[%8x] papDevSup->[%d]\t\"%s\"",
sprintf(buffer, "%p[%p] papDevSup->[%d]\t\"%s\"",
&precDevSup->papDevSup[i],
precDevSup->papDevSup[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */",
sprintf(buffer, "%p\t\t number\t[%d]\t/* number of dset */",
&precDevSup->papDevSup[i]->number,
precDevSup->papDevSup[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDsetName",
sprintf(buffer, "%p[%p] **papDsetName",
&precDevSup->papDevSup[i]->papDsetName,
precDevSup->papDevSup[i]->papDsetName);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDset",
sprintf(buffer, "%p[%p] **papDset",
&precDevSup->papDevSup[i]->papDset,
precDevSup->papDevSup[i]->papDset);
bufOut(fp, fflag);
for (j = 0; j < precDevSup->papDevSup[i]->number; j++) {
if (precDevSup->papDevSup[i]->papDsetName[j]) {
sprintf(buffer, "%8x[%8x]\t\tpapDsetName[%d]\t%s",
sprintf(buffer, "%p[%p]\t\tpapDsetName[%d]\t%s",
&precDevSup->papDevSup[i]->papDsetName[j],
precDevSup->papDevSup[i]->papDsetName[j],
j,
precDevSup->papDevSup[i]->papDsetName[j]);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t\tpapDset[%d]",
sprintf(buffer, "%p[%p]\t\tpapDset[%d]",
&precDevSup->papDevSup[i]->papDset[j],
precDevSup->papDevSup[i]->papDset[j], j);
bufOut(fp, fflag);
@@ -652,24 +663,24 @@ DrvSup(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the drvSup structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pdrvSup -> pdrvSup ", &pdrvSup, pdrvSup);
sprintf(buffer, "%p[%p] pdrvSup -> pdrvSup ", &pdrvSup, pdrvSup);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */", &pdrvSup->number, pdrvSup->number);
sprintf(buffer, "%p\t\t number\t[%d]\t/* number of dset */", &pdrvSup->number, pdrvSup->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDrvName -> \t/* pArr of ptr to papDrvName */ ",
sprintf(buffer, "%p[%p] **papDrvName -> \t/* pArr of ptr to papDrvName */ ",
&pdrvSup->papDrvName, pdrvSup->papDrvName);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papDrvet-> drvet \t/* pArr ptr to drvet */",
sprintf(buffer, "%p[%p] **papDrvet-> drvet \t/* pArr ptr to drvet */",
&pdrvSup->papDrvet, pdrvSup->papDrvet);
bufOut(fp, fflag);
for (i = 0; i < pdrvSup->number; i++) {
if (pdrvSup->papDrvName[i])
sprintf(buffer, "%8x[%8x]\t papDrvName->[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t papDrvName->[%d]\t\"%s\"",
&pdrvSup->papDrvName[i],
pdrvSup->papDrvName[i],
i, pdrvSup->papDrvName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t papDrvet->[%d] /* reserved ptr to drvet */",
sprintf(buffer, "%p[%p]\t papDrvet->[%d] /* reserved ptr to drvet */",
&pdrvSup->papDrvet[i],
pdrvSup->papDrvet[i], i);
bufOut(fp, fflag);
@@ -703,7 +714,7 @@ DbRecDes(fp, fflag)
for (j = 0; j < endNumJ; j++) {
printf("%3d %4.4s",
precDes->papRecTypDes[begNumI]->sortFldInd[j],
&precDes->papRecTypDes[begNumI]->sortFldName[j]);
(char *)&precDes->papRecTypDes[begNumI]->sortFldName[j]);
if (!((j + 1) % 8))
printf("\n");
}
@@ -723,48 +734,48 @@ DbRecDes(fp, fflag)
sprintf(buffer, "\n\ndbls: listing the precDes structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precDes-> recDes", &precDes, precDes);
sprintf(buffer, "%p[%p] precDes-> recDes", &precDes, precDes);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber [%d] \t/* number of recTypDes */",
sprintf(buffer, "%p\t\tnumber [%d] \t/* number of recTypDes */",
&precDes->number, precDes->number);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precDes->papRecTypDes[i]) {
sprintf(buffer, "\n%8x[%8x] **papRecTypDes-> recTypDes\t\"%s\"",
sprintf(buffer, "\n%p[%p] **papRecTypDes-> recTypDes\t\"%s\"",
&precDes->papRecTypDes,
precDes->papRecTypDes,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rec_size [%d]",
sprintf(buffer, "%p\t\t rec_size [%d]",
&precDes->papRecTypDes[i]->rec_size,
precDes->papRecTypDes[i]->rec_size);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t no_fields [%d]",
sprintf(buffer, "%p\t\t no_fields [%d]",
&precDes->papRecTypDes[i]->no_fields,
precDes->papRecTypDes[i]->no_fields);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t no_prompt [%d]",
sprintf(buffer, "%p\t\t no_prompt [%d]",
&precDes->papRecTypDes[i]->no_prompt,
precDes->papRecTypDes[i]->no_prompt);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t no_links [%d]",
sprintf(buffer, "%p\t\t no_links [%d]",
&precDes->papRecTypDes[i]->no_links,
precDes->papRecTypDes[i]->no_links);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *link_ind",
sprintf(buffer, "%p[%p]\t *link_ind",
&precDes->papRecTypDes[i]->link_ind,
precDes->papRecTypDes[i]->link_ind);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *sortFldName",
sprintf(buffer, "%p[%p]\t *sortFldName",
&precDes->papRecTypDes[i]->sortFldName,
precDes->papRecTypDes[i]->sortFldName);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t *sortFldInd",
sprintf(buffer, "%p[%p]\t *sortFldInd",
&precDes->papRecTypDes[i]->sortFldInd,
precDes->papRecTypDes[i]->sortFldInd);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papFldDes-> fldDes",
sprintf(buffer, "%p[%p]\t **papFldDes-> fldDes",
&precDes->papRecTypDes[i]->papFldDes,
precDes->papRecTypDes[i]->papFldDes);
bufOut(fp, fflag);
@@ -773,7 +784,7 @@ DbRecDes(fp, fflag)
endNumJ = precDes->papRecTypDes[i]->no_fields;
/* expand *link_ind */
for (j = 0; j < precDes->papRecTypDes[i]->no_links; j++) {
sprintf(buffer,"%8x\tlink_ind[%d] offset=[%d]",
sprintf(buffer,"%p\tlink_ind[%d] offset=[%d]",
&precDes->papRecTypDes[i]->link_ind[j],
j,
precDes->papRecTypDes[i]->link_ind[j]);
@@ -782,7 +793,7 @@ DbRecDes(fp, fflag)
/* expand *sortFldName and *sortFldInd */
ptemp = (char *) precDes->papRecTypDes[i]->sortFldName;
for (j = 0; j < precDes->papRecTypDes[i]->no_fields; j++) {
sprintf(buffer,"[%8x] sortFldName[%2d]=%4.4s [%8x] sortFldInd=%2d",
sprintf(buffer,"[%p] sortFldName[%2d]=%4.4s [%p] sortFldInd=%2d",
ptemp,
j,
ptemp,
@@ -796,89 +807,89 @@ DbRecDes(fp, fflag)
for (j = begNumJ; j < endNumJ; j++) {
sprintf(buffer, "\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papFldDes->fldDes[%d]",
sprintf(buffer, "%p[%p]\t **papFldDes->fldDes[%d]",
&precDes->papRecTypDes[i]->papFldDes[j],
precDes->papRecTypDes[i]->papFldDes[j], j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tprompt\t\t\"%s\"",
sprintf(buffer, "%p\t\t\tprompt\t\t\"%s\"",
precDes->papRecTypDes[i]->papFldDes[j]->prompt,
precDes->papRecTypDes[i]->papFldDes[j]->prompt);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tfldname\t\t\"%4.4s\"",
sprintf(buffer, "%p\t\t\tfldname\t\t\"%4.4s\"",
precDes->papRecTypDes[i]->papFldDes[j]->fldname,
precDes->papRecTypDes[i]->papFldDes[j]->fldname);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\toffset [%d]",
sprintf(buffer, "%p\t\t\toffset [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->offset,
precDes->papRecTypDes[i]->papFldDes[j]->offset);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tsize [%d]",
sprintf(buffer, "%p\t\t\tsize [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->size,
precDes->papRecTypDes[i]->papFldDes[j]->size);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tspecial [%d]",
sprintf(buffer, "%p\t\t\tspecial [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->special,
precDes->papRecTypDes[i]->papFldDes[j]->special);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tfield_type [%d]",
sprintf(buffer, "%p\t\t\tfield_type [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->field_type,
precDes->papRecTypDes[i]->papFldDes[j]->field_type);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tprocess_passive [%d]",
sprintf(buffer, "%p\t\t\tprocess_passive [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->process_passive,
precDes->papRecTypDes[i]->papFldDes[j]->process_passive);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tchoice_set [%d]",
sprintf(buffer, "%p\t\t\tchoice_set [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->choice_set,
precDes->papRecTypDes[i]->papFldDes[j]->choice_set);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tcvt_type [%d]",
sprintf(buffer, "%p\t\t\tcvt_type [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->cvt_type,
precDes->papRecTypDes[i]->papFldDes[j]->cvt_type);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tpromptflag [%d]",
sprintf(buffer, "%p\t\t\tpromptflag [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->promptflag,
precDes->papRecTypDes[i]->papFldDes[j]->promptflag);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tlowfl [%d]",
sprintf(buffer, "%p\t\t\tlowfl [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->lowfl,
precDes->papRecTypDes[i]->papFldDes[j]->lowfl);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\thighfl [%d]",
sprintf(buffer, "%p\t\t\thighfl [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->highfl,
precDes->papRecTypDes[i]->papFldDes[j]->highfl);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tinterest [%d]",
sprintf(buffer, "%p\t\t\tinterest [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->interest,
precDes->papRecTypDes[i]->papFldDes[j]->interest);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tas_level [%d]",
sprintf(buffer, "%p\t\t\tas_level [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->as_level,
precDes->papRecTypDes[i]->papFldDes[j]->as_level);
bufOut(fp, fflag);
memcpy((void *) buff,
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->initial, 8);
sprintf(buffer, "%8x[%8x][%8x]\tinitial",
sprintf(buffer, "%p[%8x][%8x]\tinitial",
&precDes->papRecTypDes[i]->papFldDes[j]->initial,
buff[0], buff[1]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\trange1.fldnum [%d]",
sprintf(buffer, "%p\t\t\trange1.fldnum [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum,
precDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum);
bufOut(fp, fflag);
memcpy((void *) buff,
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->range1.value, 8);
sprintf(buffer, "%8x[%8x][%8x]\trange1.value",
sprintf(buffer, "%p[%8x][%8x]\trange1.value",
&precDes->papRecTypDes[i]->papFldDes[j]->range1.value,
buff[0], buff[1]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\trange2.fldnum [%d]",
sprintf(buffer, "%p\t\t\trange2.fldnum [%d]",
&precDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum,
precDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum);
bufOut(fp, fflag);
memcpy((void *) buff,
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->range2.value, 8);
sprintf(buffer, "%8x[%8x][%8x]\trange2.value",
sprintf(buffer, "%p[%8x][%8x]\trange2.value",
&precDes->papRecTypDes[i]->papFldDes[j]->range2.value,
buff[0], buff[1]);
bufOut(fp, fflag);
@@ -935,48 +946,48 @@ ChoiceRec(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the choiceRec structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] pchoiceRec -> pchoiceRec", &pchoiceRec, pchoiceRec);
sprintf(buffer, "%p[%p] pchoiceRec -> pchoiceRec", &pchoiceRec, pchoiceRec);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber\t\t[%d]", &pchoiceRec->number, pchoiceRec->number);
sprintf(buffer, "%p\t\tnumber\t\t[%d]", &pchoiceRec->number, pchoiceRec->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papArrChoiceSet -> arrChoiceSet",
sprintf(buffer, "%p[%p]\t**papArrChoiceSet -> arrChoiceSet",
&pchoiceRec->papArrChoiceSet,
pchoiceRec->papArrChoiceSet);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (pchoiceRec->papArrChoiceSet[i]) {
sprintf(buffer, "%8x[%8x]\tpapArrChoiceSet[%d] -> arrChoiceSet\t\tRECTYPE \"%s\"",
sprintf(buffer, "%p[%p]\tpapArrChoiceSet[%d] -> arrChoiceSet\t\tRECTYPE \"%s\"",
&pchoiceRec->papArrChoiceSet[i],
pchoiceRec->papArrChoiceSet[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of choice sets */",
&pchoiceRec->papArrChoiceSet[i]->number,
pchoiceRec->papArrChoiceSet[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t **papChoiceSet",
sprintf(buffer, "%p[%p]\t **papChoiceSet",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet);
bufOut(fp, fflag);
for (j = 0; j < pchoiceRec->papArrChoiceSet[i]->number; j++) {
if (pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]) {
sprintf(buffer, "%8x[%8x]\t papChoiceSet[%d] -> choiceSet \t\tINDEX[%d]",
sprintf(buffer, "%p[%p]\t papChoiceSet[%d] -> choiceSet \t\tINDEX[%d]",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j],
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j], j, j);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t\tnumber\t\t[%d]\t/* number of choices */ ",
sprintf(buffer, "%p\t\t\tnumber\t\t[%d]\t/* number of choices */ ",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t\t**papChoice -> \"string\"",
sprintf(buffer, "%p[%p]\t\t**papChoice -> \"string\"",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice);
bufOut(fp, fflag);
for (k = 0; k < pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number; k++) {
if (pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]) {
sprintf(buffer, "%8x[%8x]\t\tpapChoice[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t\tpapChoice[%d]\t\"%s\"",
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k],
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k], k,
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]);
@@ -1003,28 +1014,28 @@ DbErrDes(fp, fflag)
}
sprintf(buffer, "\n\ndbls: listing the dbErrDes structure");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] dbErrDes -> errDes ", &dbErrDes, dbErrDes);
sprintf(buffer, "%p[%p] dbErrDes -> errDes ", &dbErrDes, dbErrDes);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t /* dim of err modules */",
sprintf(buffer, "%p\t\tnumber\t [ %d ]\t /* dim of err modules */",
&dbErrDes->number, dbErrDes->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papErrSet -> errSet ",
sprintf(buffer, "%p[%p] **papErrSet -> errSet ",
&dbErrDes->papErrSet, dbErrDes->papErrSet);
bufOut(fp, fflag);
for (i = 0; i < dbErrDes->number; i++) {
if (dbErrDes->papErrSet[i]) {
sprintf(buffer, "%8x[%8x] papErrSet->[%d]\tmodule[%d]",
sprintf(buffer, "%p[%p] papErrSet->[%d]\tmodule[%d]",
&dbErrDes->papErrSet[i],
dbErrDes->papErrSet[i], i,
i + 501);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t[%d]\t/* dim of errSet */",
sprintf(buffer, "%p\t\t number\t[%d]\t/* dim of errSet */",
&dbErrDes->papErrSet[i]->number,
dbErrDes->papErrSet[i]->number);
bufOut(fp, fflag);
for (j = 0; j < dbErrDes->papErrSet[i]->number; j++) {
if (dbErrDes->papErrSet[i]->papName[j]) {
sprintf(buffer, "%8x[%8x]\t\tpapName[%d]\t\"%s\"",
sprintf(buffer, "%p[%p]\t\tpapName[%d]\t\"%s\"",
&dbErrDes->papErrSet[i]->papName[j],
dbErrDes->papErrSet[i]->papName[j],
j,
@@ -1055,30 +1066,30 @@ DbRecords(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the precHeader structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precHeader -> recHeader", &precHeader, precHeader);
sprintf(buffer, "%p[%p] precHeader -> recHeader", &precHeader, precHeader);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of record types */",
&precHeader->number,
precHeader->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t**papRecLoc -> recLoc",
sprintf(buffer, "%p[%p]\t**papRecLoc -> recLoc",
&precHeader->papRecLoc,
precHeader->papRecLoc);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precHeader->papRecLoc[i]) {
sprintf(buffer, "%8x[%8x]\t papRecLoc->[%d]\tRECTYPE[\"%s\"]",
sprintf(buffer, "%p[%p]\t papRecLoc->[%d]\tRECTYPE[\"%s\"]",
&precHeader->papRecLoc[i],
precHeader->papRecLoc[i],
i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t rec_size [%d]\t\t/* rec_size in bytes */",
sprintf(buffer, "%p\t\t rec_size [%d]\t\t/* rec_size in bytes */",
&precHeader->papRecLoc[i]->rec_size,
precHeader->papRecLoc[i]->rec_size);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t record_type [%d]\t\t/* record_type in bytes */",
sprintf(buffer, "%p\t\t record_type [%d]\t\t/* record_type in bytes */",
&precHeader->papRecLoc[i]->record_type,
precHeader->papRecLoc[i]->record_type);
bufOut(fp, fflag);
@@ -1102,84 +1113,84 @@ RecSup(fp, fflag)
getRecTypeSel();
sprintf(buffer, "\n\ndbls: listing the recSup structure\n");
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] precSup -> precSup", &precSup, precSup);
sprintf(buffer, "%p[%p] precSup -> precSup", &precSup, precSup);
bufOut(fp, fflag);
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */",
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of record types */",
&precSup->number,
precSup->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x] **papRset -> rset",
sprintf(buffer, "%p[%p] **papRset -> rset",
&precSup->papRset,
precSup->papRset);
bufOut(fp, fflag);
for (i = begNumI; i < endNumI; i++) {
if (precSup->papRset[i]) {
sprintf(buffer, "%8x[%8x]\t papRset->[%d]\t\tRECTYPE[\"%s\"]",
sprintf(buffer, "%p[%p]\t papRset->[%d]\t\tRECTYPE[\"%s\"]",
&precSup->papRset[i],
precSup->papRset[i], i,
precType->papName[i]);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t number\t\t/*number of support routines */",
sprintf(buffer, "%p[%d]\t number\t\t/*number of support routines */",
&precSup->papRset[i]->number,
precSup->papRset[i]->number);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t report\t\t/*print report */",
sprintf(buffer, "%p[%p]\t report\t\t/*print report */",
&precSup->papRset[i]->report,
precSup->papRset[i]->report);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t init\t\t/*init support */",
sprintf(buffer, "%p[%p]\t init\t\t/*init support */",
&precSup->papRset[i]->init,
precSup->papRset[i]->init);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t init_record\t/*init record */",
sprintf(buffer, "%p[%p]\t init_record\t/*init record */",
&precSup->papRset[i]->init_record,
precSup->papRset[i]->init_record);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t process\t\t/*process record */",
sprintf(buffer, "%p[%p]\t process\t\t/*process record */",
&precSup->papRset[i]->process,
precSup->papRset[i]->process);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t special\t\t/*special processing */",
sprintf(buffer, "%p[%p]\t special\t\t/*special processing */",
&precSup->papRset[i]->special,
precSup->papRset[i]->special);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_precision\t/* get_precision of this type */",
sprintf(buffer, "%p[%p]\t get_precision\t/* get_precision of this type */",
&precSup->papRset[i]->get_precision,
precSup->papRset[i]->get_precision);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_value\t\t/*get value field */",
sprintf(buffer, "%p[%p]\t get_value\t\t/*get value field */",
&precSup->papRset[i]->get_value,
precSup->papRset[i]->get_value);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t cvt_dbaddr\t\t/*cvt dbAddr */",
sprintf(buffer, "%p[%p]\t cvt_dbaddr\t\t/*cvt dbAddr */",
&precSup->papRset[i]->cvt_dbaddr,
precSup->papRset[i]->cvt_dbaddr);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_array_info\t/* get_array_info of this type */",
sprintf(buffer, "%p[%p]\t get_array_info\t/* get_array_info of this type */",
&precSup->papRset[i]->get_array_info,
precSup->papRset[i]->get_array_info);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t put_array_info\t/* put_array_info of this type */",
sprintf(buffer, "%p[%p]\t put_array_info\t/* put_array_info of this type */",
&precSup->papRset[i]->put_array_info,
precSup->papRset[i]->put_array_info);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_enum_str\t/*get string from enum item*/",
sprintf(buffer, "%p[%p]\t get_enum_str\t/*get string from enum item*/",
&precSup->papRset[i]->get_enum_str,
precSup->papRset[i]->get_enum_str);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_units \t\t/* get_units of this type */",
sprintf(buffer, "%p[%p]\t get_units \t\t/* get_units of this type */",
&precSup->papRset[i]->get_units,
precSup->papRset[i]->get_units);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_graphic_double /* get_graphic_double of this type */",
sprintf(buffer, "%p[%p]\t get_graphic_double /* get_graphic_double of this type */",
&precSup->papRset[i]->get_graphic_double,
precSup->papRset[i]->get_graphic_double);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_control_double /* get_control_double of this type */",
sprintf(buffer, "%p[%p]\t get_control_double /* get_control_double of this type */",
&precSup->papRset[i]->get_control_double,
precSup->papRset[i]->get_control_double);
bufOut(fp, fflag);
sprintf(buffer, "%8x[%8x]\t get_enum_strs\t/*get all enum strings */",
sprintf(buffer, "%p[%p]\t get_enum_strs\t/*get all enum strings */",
&precSup->papRset[i]->get_enum_strs,
precSup->papRset[i]->get_enum_strs);
bufOut(fp, fflag);

File diff suppressed because it is too large Load Diff

View File

@@ -55,8 +55,6 @@ int callNumber;
switch (callNumber) {
case INITHOOKatBeginning :
break;
case INITHOOKafterSetEnvParams :
break;
case INITHOOKafterGetResources :
break;
case INITHOOKafterLogInit :

View File

@@ -98,6 +98,8 @@
#include <envDefs.h>
#include <dbStaticLib.h>
#include <initHooks.h>
#include <drvTS.h>
#include <asLib.h>
/*This module will declare and initilize module_type variables*/
#define MODULE_TYPES_INIT 1
@@ -106,10 +108,11 @@
LOCAL int initialized=FALSE;
/* The following is for use by interrupt routines */
int interruptAccept=FALSE;
volatile int interruptAccept=FALSE;
struct dbBase *pdbBase=NULL;
/* added for Channel Access Links */
long dbCommonInit();
@@ -120,7 +123,8 @@ LOCAL long initDevSup(void);
LOCAL long finishDevSup(void);
LOCAL long initDatabase(void);
LOCAL void createLockSets(void);
LOCAL short makeSameSet(struct dbAddr *paddr,short set);
LOCAL void createLockSetsExtraPass(int *anyChange);
LOCAL short makeSameSet(struct dbAddr *paddr,short set,int *anyChange);
LOCAL long initialProcess(void);
LOCAL long getResources(char *fname);
LOCAL int getResourceToken(FILE *fp, char *pToken, unsigned maxToken);
@@ -165,15 +169,6 @@ int iocInit(char * pResourceFilename)
* Print out version of iocCore
*/
coreRelease();
/*
* Read EPICS environment
*/
epicsSetEnvParams();
/* Hook after environment has been set */
if (pinitHooks) (*pinitHooks)(INITHOOKafterSetEnvParams);
/*
* Read EPICS resources.
*/
@@ -829,17 +824,6 @@ LOCAL long initDatabase(void)
return(status);
}
/*
* Create lock sets for records
* A lock set is a set of records that must be locked
* with a semaphore so as to prevent mutual exclusion
* hazards. Lock sets are determined by examining the
* links interconnecting the records. If a link connecting
* two records is not an NPP/NMS single-valued input link,
* then the two records are considered part of the same
* lock set. Records connected by forward links are
* definately considered part of the same lockset.
*/
LOCAL void createLockSets(void)
{
int i,link;
@@ -853,6 +837,7 @@ LOCAL void createLockSets(void)
struct link *plink;
short nset,maxnset,newset;
int again;
int anyChange;
nset = 0;
if(!(precHeader = pdbBase->precHeader)) return;
@@ -873,7 +858,6 @@ LOCAL void createLockSets(void)
* We shall see later if this assumption is incorrect.
*/
precord->lset = maxnset = ++nset;
/*
* Use the process active flag to eliminate traversing
* cycles in the database "graph"
@@ -881,7 +865,7 @@ LOCAL void createLockSets(void)
precord->pact = TRUE; again = TRUE;
while(again) {
again = FALSE;
for(link=0; link<precTypDes->no_links; link++) {
for(link=0; (link<precTypDes->no_links&&!again) ; link++) {
struct dbAddr *pdbAddr;
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
@@ -910,7 +894,7 @@ LOCAL void createLockSets(void)
* Combine the lock sets of the current record with the
* remote record pointed to by the link. (recursively)
*/
newset = makeSameSet(pdbAddr,precord->lset);
newset = makeSameSet(pdbAddr,precord->lset,&anyChange);
/*
* Perform an iteration of the while-loop again
@@ -930,10 +914,70 @@ LOCAL void createLockSets(void)
precord->pact = FALSE;
}
}
anyChange = TRUE;
while(anyChange) {
anyChange = FALSE;
createLockSetsExtraPass(&anyChange);
}
dbScanLockInit(nset);
}
LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
LOCAL void createLockSetsExtraPass(int *anyChange)
{
int i,link;
struct recLoc *precLoc;
struct recDes *precDes;
struct recTypDes *precTypDes;
struct recHeader *precHeader;
RECNODE *precNode;
struct fldDes *pfldDes;
struct dbCommon *precord;
struct link *plink;
int again;
if(!(precHeader = pdbBase->precHeader)) return;
if(!(precDes = pdbBase->precDes)) return;
for(i=0; i< (precHeader->number); i++) {
if(!(precLoc = precHeader->papRecLoc[i]))continue;
if(!precLoc->preclist) continue;
precTypDes = precDes->papRecTypDes[i];
for(precNode=(RECNODE *)ellFirst(precLoc->preclist);
precNode; precNode = (RECNODE *)ellNext(&precNode->node)) {
precord = precNode->precord;
if(!(precord->name[0])) continue;
/*Prevent cycles in database graph*/
precord->pact = TRUE; again = TRUE;
while(again) {
short newset;
again = FALSE;
for(link=0; (link<precTypDes->no_links&&!again) ; link++) {
struct dbAddr *pdbAddr;
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
plink = (struct link *)((char *)precord + pfldDes->offset);
if(plink->type != DB_LINK) continue;
pdbAddr = (struct dbAddr *)(plink->value.db_link.pdbAddr);
if (pfldDes->field_type==DBF_INLINK
&& ( !(plink->value.db_link.process_passive)
&& !(plink->value.db_link.maximize_sevr))
&& pdbAddr->no_elements<=1) continue;
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
if (newset!=precord->lset) {
precord->lset = newset;
*anyChange = TRUE;
again = TRUE;
break;
}
}
}
precord->pact = FALSE;
}
}
}
LOCAL short makeSameSet(struct dbAddr *paddr, short lset,int *anyChange)
{
struct dbCommon *precord = paddr->precord;
short link;
@@ -943,12 +987,7 @@ LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
struct recDes *precDes;
int again;
/*
* Use the process active flag to eliminate traversing
* cycles in the database "graph." Effectively converts
* the arbitrary database "graph" (where edges are
* defined as links) into a tree structure.
*/
/*Prevent cycles in database graph*/
if(precord->pact) return(((precord->lset<lset) ? precord->lset : lset));
/*
@@ -988,10 +1027,11 @@ LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
&& ( !(plink->value.db_link.process_passive)
&& !(plink->value.db_link.maximize_sevr) )
&& pdbAddr->no_elements<=1) continue;
newset = makeSameSet(pdbAddr,precord->lset);
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
if(newset != precord->lset) {
precord->lset = newset;
again = TRUE;
*anyChange = TRUE;
break;
}
}

View File

@@ -52,6 +52,7 @@
#include <dbBase.h>
#include <dbRecType.h>
#include <dbRecDes.h>
#include <dbEvent.h>
#include <dbAccess.h>
#include <dbScan.h>
#include <devSup.h>
@@ -201,9 +202,9 @@ void recGblGetGraphicDouble(struct dbAddr *paddr,struct dbr_grDouble *pgd)
void recGblGetAlarmDouble(struct dbAddr *paddr,struct dbr_alDouble *pad)
{
pad->upper_alarm_limit = 0;
pad->upper_alarm_limit = 0;
pad->lower_warning_limit = 0;
pad->upper_warning_limit = 0;
pad->lower_warning_limit = 0;
pad->lower_alarm_limit = 0;
return;
}
@@ -328,10 +329,8 @@ void recGblFwdLink(void *precord)
dbScanPassive(precord,paddr->precord);
}
/*Handle dbPutFieldNotify record completions*/
if(pdbc->ppn) {
/*Note: dbNotifyCancel also handles rpro*/
dbNotifyCompletion(pdbc->ppn);
} else if(pdbc->rpro) {
if(pdbc->ppn) dbNotifyCompletion(pdbc);
if(pdbc->rpro) {
/*If anyone requested reprocessing do it*/
pdbc->rpro = FALSE;
scanOnce(pdbc);
@@ -344,7 +343,6 @@ void recGblFwdLink(void *precord)
void recGblGetTimeStamp(void* prec)
{
struct dbCommon* pr = (struct dbCommon*)prec;
long status;
long nRequest=1;
long options=0;

View File

@@ -38,6 +38,7 @@
#include <stdio.h>
#include <ellLib.h>
#include <taskLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <errMdef.h>
@@ -166,7 +167,7 @@ static void taskwdTask(void)
pname = taskName(pt->id.tid);
if(!pt->suspended) {
struct task_list *ptany,*anynext;
struct task_list *ptany;
pt->suspended = TRUE;
sprintf(message,"task %x %s suspended",pt->id.tid,pname);
@@ -205,7 +206,7 @@ static struct task_list *allocList(void)
FASTLOCK(&alloclock);
if(freeHead) {
(void *)pt = (void *)freeHead;
pt = (struct task_list *)freeHead;
freeHead = freeHead->next;
} else pt = calloc(1,sizeof(struct task_list));
if(pt==NULL) {

986
src/dbtools/BSlib.c Normal file
View File

@@ -0,0 +1,986 @@
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include "BSlib.h"
#ifdef linux
#include <sys/time.h>
#include <sys/resource.h>
#endif
#ifdef vxWorks
#include <vxWorks.h>
#include <in.h>
#include <ioctl.h>
#include <inetLib.h>
#include <taskLib.h>
#include <ioLib.h>
#include <sockLib.h>
#include <selectLib.h>
#else
#include <sys/sockio.h>
#include <sys/time.h>
#include <netdb.h>
#include <fcntl.h>
#endif
#ifdef SOLARIS
#define BSD_COMP
#include <sys/ioctl.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/if.h>
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin);
/* ---------------------------------------------------------------------- */
/* server mode functions */
#ifndef vxWorks /* server mode functions */
static char* filename=(char*)NULL;
/* ----------------------------- */
/* signal catcher for the server */
/* ----------------------------- */
static void catch_sig(int sig)
{
fprintf(stderr,"\nbdt server exiting\n");
unlink(filename);
exit(0);
}
/* -------------------------------- */
/* child reaper for the server mode */
/* -------------------------------- */
static void get_child(int sig)
{
#ifdef SOLARIS
while(waitpid(-1,(int*)NULL,WNOHANG)>0);
#else
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
#endif
#if defined linux || defined SOLARIS
signal(SIGCHLD,get_child); /* for reaping children */
#endif
}
/* ------------------------------- */
/* Clear the signals for a process */
/* ------------------------------- */
int BSserverClearSignals()
{
signal(SIGCHLD,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
return 0;
}
/* ----------------------------------------------------- */
/* Make a unix process into a generic background process */
/* ----------------------------------------------------- */
int BSmakeServer(char** argv)
{
FILE* fd;
if(filename) return -1;
/* set up signal handling for the server */
signal(SIGCHLD,get_child); /* for reaping children */
signal(SIGHUP,catch_sig);
signal(SIGINT,catch_sig);
signal(SIGTERM,catch_sig);
signal(SIGQUIT,catch_sig);
/* disconnect from parent */
switch(fork())
{
case -1: /* error */
perror("Cannot fork");
return -1;
case 0: /* child */
#if defined linux || defined SOLARIS
setpgrp();
#else
setpgrp(0,0);
#endif
setsid();
break;
default: /* parent goes away */
exit(0);
}
/* save process ID */
filename=(char*)malloc(strlen(argv[0])+10);
sprintf(filename,"%s.%d",argv[0],getpid());
fd=fopen(filename,"w");
fprintf(fd,"%d",getpid());
fprintf(stderr,"\npv server pid: %d\n",getpid());
fclose(fd);
return 0;
}
#endif /* server mode functions */
/* --------------------------------------------------------------- */
/* open a bulk data socket to a server given the server IP address */
/* --------------------------------------------------------------- */
BS* BSipOpen(char* address, int Port)
{
struct hostent* pHostent;
unsigned long addr;
BSDATA info;
struct sockaddr_in* tsin;
tsin=(struct sockaddr_in*)&(info.sin);
#ifndef vxWorks
/* Deal with the name -vs- IP number issue. */
if (isdigit(address[0]))
{
#endif
addr=inet_addr(address);
#ifndef vxWorks
}
else
{
if((pHostent=gethostbyname(address))==NULL) return NULL;
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
}
#endif
tsin->sin_port=htons(Port);
tsin->sin_family=AF_INET;
memcpy((char*)&(tsin->sin_addr),(char*)&addr,sizeof(addr));
return BSipOpenData(&info);
}
BS* BSipOpenData(BSDATA* info)
{
struct sockaddr_in tsin;
int osoc;
BS* bdt;
tsin.sin_port=0;
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((osoc=socket(AF_INET,SOCK_STREAM,BS_TCP))<0)
{
perror("BSipOpen: create socket failed");
return (BS*)NULL;
}
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BSipOpen: local address bind failed");
return (BS*)NULL;
}
if(connect(osoc,(struct sockaddr*)&(info->sin),sizeof(info->sin))<0)
{
perror("BSipOpen: connect failed");
close(osoc);
return (BS*)NULL;
}
bdt=(BS*)malloc(sizeof(BS));
bdt->soc=osoc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BSidle;
#ifndef vxWorks
{
int j;
j = fcntl(bdt->soc, F_GETFL, 0);
fcntl(bdt->soc, F_SETFL, j|O_NDELAY);
}
#endif
/* now connected to the bulk data socket on the IOC */
return bdt;
}
/* -------------------------------------- */
/* write size bytes from buffer to socket */
/* -------------------------------------- */
int BSwrite(int soc,void* buffer,int size)
{
int rc;
int total;
unsigned char* data;
fd_set fds;
struct timeval to;
data=(unsigned char*)buffer;
total=size;
to.tv_sec = 5;
to.tv_usec = 0;
do
{
FD_ZERO(&fds);
FD_SET(soc, &fds);
if(select(FD_SETSIZE,NULL,&fds,NULL,&to) != 1)
{
printf("BSwrite: timeout waiting to write data\n");
return -1;
}
/* send block of data */
if((rc=send(soc,(char*)&data[size-total],total,0))<0)
{
if(errno == EINTR)
rc = 0;
else
perror("BSwrite: Send to remote failed");
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* --------------------------------------- */
/* send a message header down a BS socket */
/* --------------------------------------- */
int BSsendHeader(BS* bdt,unsigned short verb,int size)
{
BSmsgHead buf;
if(bdt->state!=BSidle)
{
fprintf(stderr,"BSsendHeader: Interface not idle\n");
bdt->state=BSbad;
return -1;
}
buf.verb=htons(verb);
buf.size=htonl((unsigned long)size);
if(BSwrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
{
fprintf(stderr,"BSsendHeader: write to remote failed");
return -1;
}
if(BSwrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
{
fprintf(stderr,"BSsendHeader: write to remote failed");
return -1;
}
/* don't wait for response if data must go out */
if(size)
{
bdt->remaining_send=size;
bdt->state=BSsData;
}
return 0;
}
/* ------------------------------------------- */
/* send a message data chunk down a BS socket */
/* ------------------------------------------- */
int BSsendData(BS* bdt,void* buffer,int size)
{
int len;
int remaining;
int rc;
if(bdt->state!=BSsData)
{
fprintf(stderr,"BSsendData: Interface not in send data mode\n");
bdt->state=BSbad;
return -1;
}
remaining=bdt->remaining_send-size;
if(remaining<0)
{
fprintf(stderr,"WARNING -- BSsendData: To much data to send\n");
len=bdt->remaining_send;
}
else
len=size;
if (BSwrite(bdt->soc, buffer, len) < 0)
return -1;
bdt->remaining_send-=len;
if(bdt->remaining_send<0)
{
fprintf(stderr,"BSsendData: To much data Sent\n");
bdt->remaining_send=0;
}
if(bdt->remaining_send==0)
bdt->state=BSidle;
return len;
}
int BSflushOutput(BS* bdt)
{
#ifdef vxWorks
ioctl(bdt->soc, FIOWFLUSH, 0);
#endif
return 0;
}
/* ------------------------------------- */
/* Read exactly size bytes from remote */
/* ------------------------------------- */
int BSread(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
fd_set fds;
struct timeval to;
to.tv_sec = 5;
to.tv_usec = 0;
data=(unsigned char*)buffer;
total=size;
do
{
#if 1
/* wait for data chunk */
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, &fds, NULL, NULL, &to) != 1)
{
printf("BSread: timeout waiting for data\n");
return(-1);
}
#endif
if((rc=recv(soc,(char*)&data[size-total],total,0))<0)
{
if(errno==EINTR)
{
printf("BSread: EINTR");
rc=0;
}
else
{
perror("BSread: Receive data chunk failed");
}
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* ------------------------------------- */
/* wait for a message header from remote */
/* ------------------------------------- */
int BSreceiveHeader(BS* bdt,int* verb,int* size)
{
BSmsgHead buf;
/* can only receive header when in the idle state */
if (bdt->state == BSeof)
return -1;
if(bdt->state != BSidle)
{
fprintf(stderr,"BSreceiveHeader: Interface not idle\n");
bdt->state=BSbad;
return -1;
}
if(BSread(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
{
fprintf(stderr,"BSreceiveHeader: Read failed\n");
return -1;
}
if(BSread(bdt->soc,&buf.size,sizeof(buf.size))<0)
{
fprintf(stderr,"BSreceiveHeader: Read failed\n");
return -1;
}
/* copy message data to user */
*verb=ntohs(buf.verb);
*size=ntohl(buf.size);
if(*size)
bdt->state=BSrData;
bdt->remaining_recv=*size;
return 0;
}
/* ------------------------------------------------------------------------
Wait for a chunk of data from remote.
User can continually call this with a maximum size until it return 0.
------------------------------------------------------------------------ */
int BSreceiveData(BS* bdt,void* buffer,int size)
{
int rc;
/* can only receive data when in the receive data state */
switch(bdt->state)
{
case BSrData: break;
case BSidle: return 0;
default:
fprintf(stderr,"BSreceiveData: bad receive state\n");
bdt->state=BSbad;
break;
}
if (bdt->remaining_recv < size)
size = bdt->remaining_recv;
if(BSread(bdt->soc,buffer,size)<0)
{
fprintf(stderr,"BSreceiveData: Read failed\n");
bdt->state = BSeof;
return -1;
}
bdt->remaining_recv-=size;
if(bdt->remaining_recv<0)
{
fprintf(stderr,"BSreceiveData: To much data received\n");
bdt->remaining_recv=0;
}
if(bdt->remaining_recv==0)
bdt->state=BSidle;
return size;
}
/* -------------------- */
/* close the connection */
/* -------------------- */
int BSclose(BS* bdt)
{
int verb,size,done;
/* send a close message out */
if(BSsendHeader(bdt,BS_Close,0)<0)
{
fprintf(stderr,"BSclose: Cannot send close message\n");
return -1;
}
done=0;
do
{
/* check response */
if(BSreceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BSclose: Close message response error\n");
return -1;
}
switch(verb)
{
case BS_Ok:
done=1;
break;
case BS_Error:
fprintf(stderr,"BSclose: Close rejected\n");
return -1;
default: break;
}
}
while(done==0);
BSfreeBS(bdt);
return 0;
}
/* --------------------------------------- */
/* make a listener socket for UDP - simple */
/* --------------------------------------- */
int BSopenListenerUDP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
tsin.sin_port=htons(Port);
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_DGRAM,BS_UDP))<0)
{
perror("BSopenListenerUDP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BSopenListenerUDP: local bind failed");
close(nsoc);
return -1;
}
return nsoc;
}
/* --------------------------------------- */
/* make a listener socket for TCP - simple */
/* --------------------------------------- */
int BSopenListenerTCP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
memset ((void *)&tsin, 0, sizeof(struct sockaddr_in));
tsin.sin_port=htons(Port);
tsin.sin_family=htons(AF_INET);
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_STREAM,BS_TCP))<0)
{
perror("BSopenListenerTCP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BSopenListenerTCP: local bind failed");
close(nsoc);
return -1;
}
listen(nsoc,5);
return nsoc;
}
/* ------------------------------- */
/* make BS from a socket - simple */
/* ------------------------------- */
BS* BSmakeBS(int soc)
{
BS* bdt;
bdt=(BS*)malloc(sizeof(BS));
bdt->soc=soc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BSidle;
return bdt;
}
/* --------------------------- */
/* free a BS and close socket */
/* --------------------------- */
int BSfreeBS(BS* bdt)
{
close(bdt->soc);
free(bdt);
return 0;
}
/*-----------------------------------------------------------------------*/
/*
Next three function adjust the fields of the BSDATA structure.
*/
/*-----------------------------------------------------------------------*/
int BSgetAddressPort(BSDATA* info, char* ip_addr, int* dest_port)
{
char* name;
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
*dest_port=sin->sin_port;
name=inet_ntoa(sin->sin_addr);
strcpy(ip_addr,name);
return 0;
}
int BSsetAddressPort(BSDATA* info, char* ip_addr, int dest_port)
{
BSsetPort(info, dest_port);
return BSsetAddress(info, ip_addr);
}
int BSsetPort(BSDATA* info, int dest_port)
{
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
sin->sin_family=AF_INET;
sin->sin_port=htons(dest_port);
return 0;
}
int BSsetAddress(BSDATA* info, char* ip_addr)
{
struct hostent *pHostent;
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
unsigned long addr;
#ifndef vxWorks
/* Deal with the name -vs- IP number issue. */
if (isdigit(ip_addr[0]))
{
#endif
if((addr=inet_addr(ip_addr))==-1) return -1;
#ifndef vxWorks
}
else
{
if((pHostent=gethostbyname(ip_addr))==NULL) return -1;
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
}
#endif
sin->sin_family=AF_INET;
memcpy((char*)&(sin->sin_addr),(char*)&addr,sizeof(addr));
return 0;
}
/* ----------------------------------------------------------------- */
/*
All this function does is send a broadcast message and return the
addressing info to the caller of a responder to the broadcast.
arguments:
soc - broadcast socket to use for sending data
trys - number of times to send if no response
o_info - outgoing BSDATA, address/port info
i_info - incoming BSDATA, address/port where response came from
omsg/osize - outgoing message and size
imsg/isize - incoming message and buffer size
Returns the number of bytes read.
*/
/* ----------------------------------------------------------------- */
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
void* omsg,int osize,void* imsg,int isize)
{
int i;
int rc=0;
for(i=0;rc==0 && i<trys;i++)
{
/* send out the message */
rc=BSwriteUDP(soc,o_info,omsg,osize);
if(rc<0) return rc;
/* wait for a response */
rc=BSreadUDP(soc,i_info,1,imsg,isize);
}
return rc;
}
int BSbroadcast(int soc,BSDATA* o_info, void* omsg,int osize)
{
int rc;
/* send out the message */
rc=BSwriteUDP(soc,o_info,omsg,osize);
return rc;
}
/* ----------------------------------------------------------------------- */
/*
This function waits for a message and sends out an ACK when it gets one.
addressing info to the caller of a responder to the broadcast.
Lots of arguments:
soc - The socket to send the message down.
info - The socket information telling where the data read came from
(returned to the user).
tout - Timeout for read in seconds. 0=no wait, -1=wait forever.
buf - Buffer to populate with read data.
size - Size of the buf.
returns the length the read message, 0 is timeout, -1 is error
*/
/* ----------------------------------------------------------------------- */
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size)
{
int mlen,rc;
fd_set fds;
struct timeval to;
int error=0;
do
{
FD_ZERO(&fds);
FD_SET(soc, &fds);
if(tout==-1)
rc=select(FD_SETSIZE,&fds,NULL,NULL,NULL);
else
{
to.tv_sec=tout;
to.tv_usec=0;
rc=select(FD_SETSIZE,&fds,NULL,NULL,&to);
}
switch(rc)
{
case -1: /* bad */
switch(errno)
{
case EINTR: break;
default: error=-1; break;
}
break;
case 0: /* timeout */
break;
default: /* data ready */
break;
}
}
while(rc<0 && error==0);
error=0;
if(rc>0)
{
error=0;
do
{
info->len=sizeof(info->sin);
mlen=recvfrom(soc,(char*)buf,size,0, &info->sin,&info->len);
if(mlen<0)
{
switch(errno)
{
case EINTR: break;
default: error=-1; break;
}
}
}
while(mlen<0 && error==0);
if(mlen<0)
rc=-1;
else
rc=mlen;
}
return rc;
}
/*-----------------------------------------------------------------------*/
/*
Write a chuck of data to a UDP socket at an internet address
*/
/*-----------------------------------------------------------------------*/
int BSwriteDataUDP(int soc,int dest_port,char* ip_addr,void* buf,int size)
{
BSDATA data;
BSsetAddress(&data,ip_addr);
BSsetPort(&data,dest_port);
return BSwriteUDP(soc,&data,buf,size);
}
/*-----------------------------------------------------------------------*/
/*
Write a chunk of data to a UDP socket using BSDATA.
Arguments:
*/
/*-----------------------------------------------------------------------*/
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize)
{
int mlen;
mlen=sendto(soc,(char*)obuf,osize,0,&info->sin,sizeof(info->sin));
return mlen;
}
/*-----------------------------------------------------------------------*/
/*
Write/Read a chuck of data to a UDP socket using BSDATA.
Arguments:
soc - socket to send message down and read from
info - address/port to send message to
obuf/osize - outgoing message and size of it.
ibuf/isize - incoming message and size of the buffer.
Returns the number of bytes read, -1 for error.
*/
/*-----------------------------------------------------------------------*/
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize)
{
int done,i,mlen,flen;
struct sockaddr fromsin;
fd_set fds;
struct timeval tout;
done=0;
mlen=0;
for(i=0;i<BS_RETRY_COUNT && done==0;i++)
{
mlen=sendto(soc,(char*)obuf,osize,0,&(info->sin),sizeof(info->sin));
if(mlen<0)
{
printf("send failed\n");
return -1;
}
tout.tv_sec=0;
tout.tv_usec=200000;
FD_ZERO(&fds);
FD_SET(soc,&fds);
switch(select(FD_SETSIZE,&fds,(fd_set*)0,(fd_set*)0,&tout))
{
case 0: /* timeout */ break;
case -1: /* error */
printf("select failed\n");
return -1;
default: /* data ready */
flen=sizeof(fromsin);
mlen=recvfrom(soc,(char*)ibuf,isize,0,&fromsin,&flen);
if(mlen<0) return -1;
done=1;
break;
}
}
if(i>=BS_RETRY_COUNT) return 0;
return mlen;
}
/*-----------------------------------------------------------------------*/
/*
Open a broadcast socket and set port to a default.
*/
/*-----------------------------------------------------------------------*/
int BSipBroadcastOpen(BSDATA* info, int default_dest_port)
{
struct sockaddr_in* sin;
int soc;
sin=(struct sockaddr_in*)&(info->sin);
if( (soc=BSgetBroadcastSocket(0,sin)) <0) return -1;
sin->sin_port=htons(default_dest_port);
return soc;
}
/*-----------------------------------------------------------------------*/
/*
BSgetBroadcastSocket() - return a broadcast socket for a port, return
a sockaddr also.
*/
/*-----------------------------------------------------------------------*/
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin)
{
int on=1;
int soc;
BS bs;
sin->sin_port=htons(port);
sin->sin_family=AF_INET;
sin->sin_addr.s_addr=htonl(INADDR_ANY);
if( (soc=socket(AF_INET,SOCK_DGRAM,BS_UDP)) < 0 )
{
perror("socket create failed");
return -1;
}
setsockopt(soc,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on));
if( bind(soc,(struct sockaddr*)sin,sizeof(struct sockaddr_in)) < 0 )
{
perror("socket bind failed");
close(soc);
return -1;
}
if( BSgetBroadcastAddr(soc,(struct sockaddr*)sin) < 0 )
return -1;
return soc;
}
/*-----------------------------------------------------------------------*/
/*
BSgetBroadcastAddr() - Determine the broadcast address, this is
directly from the Sun Network Programmer's guide.
*/
/*-----------------------------------------------------------------------*/
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin)
{
struct ifconf ifc;
struct ifreq* ifr;
struct ifreq* save;
char buf[BUFSIZ];
int tot,i;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if(ioctl(soc,SIOCGIFCONF,(int)&ifc) < 0)
{ perror("ioctl SIOCGIFCONF failed"); return -1; }
ifr = ifc.ifc_req;
tot = ifc.ifc_len/sizeof(struct ifreq);
save=(struct ifreq*)NULL;
i=0;
do
{
if(ifr[i].ifr_addr.sa_family==AF_INET)
{
if(ioctl(soc,SIOCGIFFLAGS,(int)&ifr[i])<0)
{ perror("ioctl SIOCGIFFLAGS failed"); return -1; }
if( (ifr[i].ifr_flags&IFF_UP) &&
!(ifr[i].ifr_flags&IFF_LOOPBACK) &&
(ifr[i].ifr_flags&IFF_BROADCAST))
{ save=&ifr[i]; }
}
} while( !save && ++i<tot );
if(save)
{
if(ioctl(soc,SIOCGIFBRDADDR,(int)save)<0)
{ perror("ioctl SIOCGIFBRDADDR failed"); return -1; }
memcpy((char*)sin,(char*)&save->ifr_broadaddr,
sizeof(save->ifr_broadaddr));
}
else
return -1;
return 0;
}

188
src/dbtools/BSlib.h Normal file
View File

@@ -0,0 +1,188 @@
#ifndef ___BS_H
#define ___BS_H
/*
* $Log$
*/
/*
Author: Jim Kowalkowski
Date: 9/1/95
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* got from protocols(5) (cheated) or /etc/protocols */
#define BS_UDP 17
#define BS_TCP 6
/* server ports - in the user reserved area - above 50000 */
#define BS_UDP_PORT 50296
#define BS_TCP_PORT 50297
/* message types */
#define BS_Ok 0
#define BS_Error 1
#define BS_Close 2
#define BS_Ping 3
#define BS_Done 4
#define BS_LAST_VERB 4
#define BS_RETRY_COUNT 3
/* protocol states */
typedef enum { BSidle,BSunbound,BSsData,BSrData,BSbad,BSeof } BSstate;
struct bs
{
int soc;
int remaining_send;
int remaining_recv;
BSstate state;
};
typedef struct bs BS;
struct bs_udp_data
{
struct sockaddr sin;
int len;
};
typedef struct bs_udp_data BSDATA;
struct BSmsgHead
{
unsigned short verb;
unsigned long size;
};
typedef struct BSmsgHead BSmsgHead;
typedef unsigned long BS_ULONG;
#define BSgetSocket(BS) (BS->soc)
#define BSgetResidualWrite(BS) (BS->remaining_send)
#define BSgetResidualRead(BS) (BS->remaining_recv)
#define BSgetProtoState(BS) (BS->state)
/* ------------------------------------------------------------------------
Server functions:
BSopenListenerTCP:
Open a socket locally bound to the bulk data transfer TCP server port.
Set the socket up as a listener. Return the open socket.
BSopenListenerUDP:
Open a socket locally bound to the bulk data transfer UDP server port.
Return the open socket.
------------------------------------------------------------------------ */
int BSopenListenerTCP(int Port);
int BSopenListenerUDP(int Port);
int BSopenTCP(BSDATA*);
/* ------------------------------------------------------------------------
Utilities functions:
BSmakeServer:
Available under unix only. Put process in the background, disassociate
process from controlling terminal and parent process, and prepare
signals for reaping children spawned by the process.
BSserverClearSignals:
Clear the signal handlers for a process, set them to default.
BSmakeBS:
Allocate and initialize a BS from a socket.
BSfreeBS:
Close the open socket and free the memory for the BS.
------------------------------------------------------------------------ */
#ifndef vxWorks
int BSmakeServer(char** argv);
int BSserverClearSignals();
#endif
BS* BSmakeBS(int socket); /* make a BS from a socket */
int BSfreeBS(BS* bdt); /* free a BS */
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin);
int BSipBroadcastOpen(BSDATA* info, int default_dest_port);
int BSgetAddressPort(BSDATA* info,char* ip_addr, int* dest_port);
int BSsetAddressPort(BSDATA* info,char* ip_addr, int dest_port);
int BSsetAddress(BSDATA* info,char* ip_addr);
int BSsetPort(BSDATA* info,int dest_port);
/* ------------------------------------------------------------------------
UDP functions:
------------------------------------------------------------------------ */
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize);
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize);
int BSwriteDataUDP(int soc,int dest_port, char* ip_addr,void* obuf,int osize);
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size);
int BSbroadcast(int soc,BSDATA* info,void* buf,int size);
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
void* obuf,int osize,void* ibuf,int isize);
/* ------------------------------------------------------------------------
Client functions:
BSipOpen:
Open a connection to an bulk data transfer given the IP address of the
machine where the server exists. The returned BS is returned unbound,
a connect must be issued before data transactions can take place.
BSclose:
Completely close a connection to a server and free the BS.
------------------------------------------------------------------------ */
BS* BSipOpen(char* address, int port);
BS* BSipOpenData(BSDATA* info);
int BSclose(BS* bdt);
/* ------------------------------------------------------------------------
Client and Server shared functions:
BSsendHeader:
Send a message header out to a connect BS with command and message body
size information.
BSsendData:
Send a portion or all the message body out a connected BS. A header
must have previously been sent with length information. The interface
will only allow the amount of data specified in the header to be sent.
BSwrite:
This call will block until all the data specified in the size parameter
are sent down the socket.
BSread:
This call will block until all the data specified in the size parameter
is read from the socket.
BSreceiveHeader:
Wait until a message header appears at the BS, return the action and
remaining message body size.
BSreceiveData:
Wait for a chunk or the entire body of a message to appear at the BS.
Put the data into the buffer for a maximum size. Return the amount of
data actually received, or zero if there is no data remaining for the
current message.
------------------------------------------------------------------------ */
int BSsendHeader(BS* bdt, unsigned short verb, int size);
int BSsendData(BS* bdt, void* buffer, int size);
int BSreceiveHeader(BS* bdt, int* verb, int* size);
int BSreceiveData(BS* bdt, void* buffer, int size);
int BSread(int socket, void* buffer, int size);
int BSwrite(int socket, void* buffer, int size);
int BSflushOutput(BS* bdt);
#endif

View File

@@ -2,29 +2,45 @@ EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
# USR_CFLAGS = -v
LEX = $(ELEX)
YACC = $(EYACC)
YACCOPT = -l
LEXOPT = -L
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
dbLoadRecords_lex.c dbLoadRecords.c
dbLoadRecords_lex.c dbLoadRecords.c \
../BSlib.c ../PVSserver.c ../rdbapplist.c ../rdbls.o
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
VAR_OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
OBJS = $(VAR_OBJS) BSlib.o PVSserver.o rdbapplist.o rdbls.o
PROD = subtool dbLoadTemplate
PROD = subtool dbLoadTemplate rdbls rdbapplist
TARGETS = PVSserver
include $(EPICS)/config/RULES.Unix
dbLoadTemplate.o: dbLoadTemplate_lex.c
dbLoadRecords.o: dbLoadRecords_lex.c
subtool: dbLoadTemplate.c dbLoadTemplate_lex.c dbVarSub.o
$(RM) $@
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o subtool dbLoadTemplate.c dbVarSub.o -s
PVSserver: PVSserver.o BSlib.o
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
dbLoadTemplate: $(OBJS)
$(LINK.c) -o $@ $(OBJS) $(LDLIBS) -lDb
rdbls: rdbls.o BSlib.o
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
rdbapplist: rdbapplist.o BSlib.o
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
subtool.o: dbLoadTemplate.c dbLoadTemplate_lex.c
$(COMPILE.c) $(CFLAGS) -DSUB_TOOL -o $@ $<
subtool: subtool.o dbVarSub.o
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o $@ $^ -s
dbLoadTemplate: $(VAR_OBJS)
$(LINK.c) -o $@ $^ $(LDLIBS) -lDb
clean::
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \

View File

@@ -8,10 +8,11 @@ YACCOPT = -l
LEXOPT = -L
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
dbLoadRecords_lex.c dbLoadRecords.c
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
dbLoadRecords_lex.c dbLoadRecords.c ../BSlib.c ../PVSvx.c
PROD = dbSubs
LIBOBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o BSlib.o PVSvx.o
LIBNAME = dbSubs
include $(EPICS)/config/RULES.Vx
@@ -29,7 +30,4 @@ clean::
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \
dbLoadRecords.c
dbSubs: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

31
src/dbtools/PVS.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef __PVS_H
#define __PVS_H
#include "BSlib.h"
#define PVS_RETRY_COUNT 4
#define PVS_TRANSFER_SIZE 1024
#define PVS_UDP 17
#define PVS_TCP 6
#define PVS_UDP_PORT 50298
#define PVS_TCP_PORT 50299
#define PVS_UDP_CPORT 50300
#define PVS_Data (BS_LAST_VERB+1)
#define PVS_Alive (BS_LAST_VERB+2)
#define PVS_RecList (BS_LAST_VERB+3)
#define PVS_AppList (BS_LAST_VERB+4)
#define PVS_RecDump (BS_LAST_VERB+5)
#define PVS_LAST_VERB PVS_RecDump
struct pvs_info_packet
{
unsigned short cmd;
char text[90];
};
typedef struct pvs_info_packet PVS_INFO_PACKET;
#define PVS_SET_CMD(pvs_info,command) (pvs_info)->cmd=htons(command)
#endif

263
src/dbtools/PVSserver.c Normal file
View File

@@ -0,0 +1,263 @@
/* only runable on work station now */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
struct PVSnode
{
BSDATA info;
int alive;
struct PVSnode* next;
};
typedef struct PVSnode PVSNODE;
static PVSNODE* ioc_list = (PVSNODE*)NULL;
static int read_pvs(BSDATA* info,int serv,char* sname);
#ifndef PVS_SERVER_PROG
int main(int argc,char** argv)
{
BSDATA info;
int serv;
int rc;
if(argc<4)
{
fprintf(stderr,"usage: %s IOC-name server-number [server-name]\n",
argv[0]);
return -1;
}
serv=atoi(argv[2]);
BSsetAddress(&info,argv[1]);
if(serv>PVS_LAST_VERB)
rc=read_pvs(&info,serv,argv[3]);
else
rc=read_pvs(&info,serv,(char*)NULL);
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
return 0;
}
#else
int main(int argc,char** argv)
{
int soc,mlen;
unsigned short buf,in_buf,ping;
BSDATA info;
PVSNODE* node;
if(BSmakeServer(argv)<0)
{
fprintf(stderr,"Cannot make into a server\n");
return -1;
}
if((soc=BSopenListenerUDP(PVS_UDP_PORT))<0)
{
fprintf(stderr,"Open of UDP listener socket failed\n");
return -1;
}
buf=htons(BS_Ok); /* always sends this out */
ping=htons(BS_Ping); /* always sends this out */
while(1)
{
/* wait forever until a message comes in */
mlen=BSreadUDP(soc,&info,7,&in_buf,sizeof(in_buf));
/* check for errors */
switch(mlen)
{
case 0: /* timeout */
printf("Why did a timeout occur?\n");
/* send out a ping to each of the IOCs in the ioc_list */
for(node=ioc_list;node;node=node->next)
{
mlen=BStransUDP(soc,&(node->info),&ping,sizeof(ping),
&in_buf,sizeof(in_buf));
/* check for errors */
switch(mlen)
{
case 0: /* timeout */
printf("IOC dead\n");
node->alive=0;
break;
case -1: /* error */
printf("Communications failed\n");
break;
default: /* ok */
if(node->alive==0)
{
switch(fork())
{
case -1: /* error */
perror("fork failure");
break;
case 0: /* child */
close(soc);
BSserverClearSignals();
sleep(1);
if(read_pvs(&(node->info))==0)
node->alive=1;
default: /* parent */
break;
}
}
break;
}
}
break;
case -1: /* error */
fprintf(stderr,"Communications failure\n");
break;
default: /* ok */
if(BSwriteUDP(soc,&info,&buf,sizeof(buf))<0)
fprintf(stderr,"respone send failed\n");
else
{
node=(PVSNODE*)malloc(sizeof(PVSNODE));
node->alive=1;
node->info=info;
BSsetPort(&(node->info),PVS_UDP_CPORT);
node->next=ioc_list;
ioc_list=node;
switch(fork())
{
case -1: /* error */
perror("fork failure");
break;
case 0: /* child */
close(soc);
BSserverClearSignals();
sleep(1);
return read_pvs(&info,PVS_RecList,NULL);
default: /* parent */
break;
}
}
break;
}
}
close(soc);
return 0;
}
#endif
static int read_pvs(BSDATA* info,int serv,char* sname)
{
BS* bs;
int verb,size,done,len,i,port,rsize;
char* buffer;
char ip_from[40];
FILE* fd;
BSgetAddressPort(info,ip_from,&port);
/* printf("IOC %s starting\n",ip_from); */
/* verify ioc not already added */
if(access(ip_from,F_OK)==0)
{
/* delete the existing file for this IOC */
unlink(ip_from);
}
done=0;
BSsetPort(info,PVS_TCP_PORT);
if((bs=BSipOpenData(info))==NULL)
{
fprintf(stderr,"Open of socket to IOC failed\n");
return -1;
}
if(serv>PVS_LAST_VERB)
rsize=strlen(sname)+1;
else
rsize=0;
if(BSsendHeader(bs,serv,rsize)<0)
{
fprintf(stderr,"Command send failed\n");
return -1;
}
if(rsize>0)
{
if(BSsendData(bs,sname,rsize)<0)
{
fprintf(stderr,"send of command name failed\n");
return -1;
}
}
#ifdef PVS_SERVER_PROG
if((fd=fopen(ip_from,"w"))==(FILE*)NULL)
{
fprintf(stderr,"Open of name file failed\n");
return -1;
}
#else
fd=stdout;
#endif
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
while(done==0)
{
if(BSreceiveHeader(bs,&verb,&size)<0)
{
fprintf(stderr,"Receive header failed\n");
done=-1;
}
else
{
switch(verb)
{
case PVS_Data: /* read a block of names */
if((len=BSreceiveData(bs,buffer,size))<0)
{
fprintf(stderr,"Receive data failed\n");
}
else
{
for(i=0;i<len;i++)
{
if(buffer[i]==' ') buffer[i]='\n';
}
buffer[len]='\n';
buffer[len+1]='\0';
fputs(buffer,fd);
}
break;
case BS_Done: /* transfers complete */
BSclose(bs);
done=-1;
break;
default:
if(size>0) done=-1;
break;
}
}
}
#ifdef PVS_SERVER_PROG
fclose(fd);
#endif
free(buffer);
return 0;
}

361
src/dbtools/PVSvx.c Normal file
View File

@@ -0,0 +1,361 @@
/* This file not really set up to run under Unix yet, just under vxWorks. */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <iv.h>
#include <taskLib.h>
#include <sysSymTbl.h>
#include <sysLib.h>
#include <symLib.h>
#include <dbStaticLib.h>
extern struct dbBase *pdbBase;
#else
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#endif
static void PVSserver(int want_annouce,char* name);
static int PVSannouce(int want_annouce,char* name);
static void handle_requests(BS* bs);
static void handle_reclist(BS* bs);
static void handle_applist(BS* bs);
static void handle_recdump(BS* bs);
static void handle_spylist(BS* bs);
static void handle_tasklist(BS* bs);
void PVS_test_server(BS* bs);
static char* names = (char*)NULL;
static char* buffer = (char*)NULL;
#ifdef vxWorks
int PVSstart(int want_annouce, char* name)
#else
int main(int argc,char** argv)
#endif
{
#ifndef vxWorks
char* name;
int want_annouce;
#endif
#ifndef vxWorks
if(argc<3)
{
fprintf(stderr,"bad args\n");
fprintf(stderr," usage: %s a_flag host_name\n",
argv[0]);
fprintf(stderr," where\n");
fprintf(stderr," a_flag=0(want),1(don't want) to annouce boot\n");
fprintf(stderr," host_name=PV master host (if one exists)\n");
return -1;
}
name=argv[2];
if(sscanf(argv[1],"%d",&want_annouce)<1)
{
fprintf(stderr,"bad a_flag\n");
return -1;
}
#endif
taskSpawn("PVS",150,VX_FP_TASK|VX_STDIO,5000,
(FUNCPTR)PVSserver,want_annouce,(int)name,0,0,0,0,0,0,0,0);
return 0;
}
static int PVSannouce(int want_annouce,char* name)
{
int soc,mlen;
PVS_INFO_PACKET buf,in_buf;
BSDATA info,in_info;
if(want_annouce==0 && name)
{
if((soc=BSopenListenerUDP(0))<0)
{
printf("Open of UDP socket failed\n");
return -1;
}
if(BSsetAddressPort(&info,name,PVS_UDP_PORT)<0)
{
printf("Set send port failed\n");
return -1;
}
PVS_SET_CMD(&buf,PVS_Alive);
mlen=BStransUDP(soc,&info,&buf,sizeof(buf),&in_buf,sizeof(in_buf));
/* check for errors */
switch(mlen)
{
case 0: /* timeout */
printf("No server running on host\n");
break;
case -1: /* error */
printf("Communications failed\n");
break;
default: /* ok */
break;
}
close(soc);
}
return 0;
}
static void PVSserver(int want_annouce,char* name)
{
fd_set fds,rfds;
int tsoc,usoc,nsoc,len,s;
struct sockaddr stemp;
int stemp_len;
PVS_INFO_PACKET buf;
BSDATA info;
BS* bs;
bs=(BS*)NULL;
buffer=(char*)malloc(100); /* just make the buffer */
names=(char*)malloc(PVS_TRANSFER_SIZE);
if((tsoc=BSopenListenerTCP(PVS_TCP_PORT))<0)
{
printf("PVSserver: Open of TCP listener socket failed\n");
return;
}
if((usoc=BSopenListenerUDP(PVS_UDP_CPORT))<0)
{
printf("PVSserver: Open of UDP listener socket failed\n");
return;
}
FD_ZERO(&fds);
FD_SET(tsoc,&fds);
FD_SET(usoc,&fds);
PVSannouce(want_annouce,name);
while(1)
{
rfds=fds;
if(select(FD_SETSIZE,&rfds,(fd_set*)NULL,(fd_set*)NULL,
(struct timeval*)NULL)<0)
{
printf("PVSserver: Select failure\n");
}
else
{
if(FD_ISSET(tsoc,&rfds))
{
/* handle the request here - single threaded server */
stemp_len=sizeof(stemp);
if((nsoc=accept(tsoc,&stemp,&stemp_len))<0)
printf("PVSserver: Bad accept\n");
else
{
bs=BSmakeBS(nsoc);
handle_requests(bs);
BSfreeBS(bs);
}
}
if(FD_ISSET(usoc,&rfds))
{
/* only pings will come in here for now */
len=BSreadUDP(usoc,&info,0,&buf,sizeof(buf));
if(len<=0)
printf("PVSserver: UDP listener read failure\n");
else
{
if(BSwriteUDP(usoc,&info,&buf,sizeof(buf))<0)
printf("PVSserver: UDP listener ping write failure\n");
}
}
}
}
}
static void handle_reclist(BS* bs)
{
DBENTRY db;
long rc;
char* n;
unsigned long names_len;
int s;
dbInitEntry(pdbBase,&db);
names_len=0;
for(rc=dbFirstRecdes(&db);rc==0;rc=dbNextRecdes(&db))
{
for(rc=dbFirstRecord(&db);rc==0;rc=dbNextRecord(&db))
{
/* collect the names util we excede the max */
n=dbGetRecordName(&db);
s=strlen(n);
if((names_len+s)>PVS_TRANSFER_SIZE)
{
names[names_len++]='\0';
if(BSsendHeader(bs,PVS_Data,names_len)<0)
printf("PVSserver: data cmd failed\n");
else
{
if(BSsendData(bs,names,names_len)<0)
printf("PVSserver: data send failed\n");
}
names_len=0;
}
memcpy(&names[names_len],n,s);
names_len+=s;
names[names_len++]=' ';
}
}
if(names_len>0)
{
names[names_len++]='\0';
if(BSsendHeader(bs,PVS_Data,names_len)<0)
printf("PVSserver: data cmd failed\n");
else
{
if(BSsendData(bs,names,names_len)<0)
printf("PVSserver: data send failed\n");
}
}
BSsendHeader(bs,BS_Done,0);
}
static void handle_requests(BS* bs)
{
int verb,size,notdone,len;
void (*func)(BS*);
SYM_TYPE stype;
notdone=1;
while(notdone)
{
/* at this point I should be getting a command */
if(BSreceiveHeader(bs,&verb,&size)<0)
{
printf("PVSserver: receive header failed\n");
notdone=0;
}
else
{
switch(verb)
{
case PVS_RecList: handle_reclist(bs); break;
case PVS_AppList: handle_applist(bs); break;
case PVS_RecDump: handle_recdump(bs); break;
case BS_Close:
BSsendHeader(bs,BS_Ok,0);
notdone=0;
break;
case PVS_Data: break;
case PVS_Alive: break;
case BS_Ok: break;
case BS_Error: break;
case BS_Ping: break;
case BS_Done: break;
default:
/* custom service */
if(size>0)
{
/* this should be the name of the service */
/* look up the symbol name in buffer and call as
subroutine, passing it the BS */
len=BSreceiveData(bs,&buffer[1],size);
switch(len)
{
case 0: /* timeout */ notdone=0; break;
case -1: /* error */ notdone=0; break;
default:
buffer[0]='_';
if(strncmp(buffer,"_PVS",4)==0)
{
if(symFindByName(sysSymTbl,buffer,
(char**)&func,&stype)==ERROR)
func=(void (*)(BS*))NULL;
if(func)
func(bs);
else
BSsendHeader(bs,BS_Done,0);
}
else
BSsendHeader(bs,BS_Done,0);
}
}
else
printf("PVSserver: unknown command received\n");
}
}
}
}
/* --------------------------------------------------------------- */
struct dbnode
{
char* name;
struct dbnode* next;
};
typedef struct dbnode DBNODE;
extern DBNODE* DbApplList;
void handle_applist(BS* bs)
{
DBNODE* n;
int size,len;
len=0;
for(n=DbApplList;n;n=n->next)
{
len=strlen(n->name)+1;
if(BSsendHeader(bs,PVS_Data,len)<0)
printf("PVSserver: data cmd failed\n");
else
{
if(BSsendData(bs,n->name,len)<0)
printf("PVSserver: data send failed\n");
}
}
BSsendHeader(bs,BS_Done,0);
}
/* --------------------------------------------------------------- */
void handle_recdump(BS* bs)
{
printf("RecDump server invoked\n");
BSsendHeader(bs,BS_Done,0);
}
void PVS_test_server(BS* bs)
{
printf("PVS_test_server invoked\n");
BSsendHeader(bs,BS_Done,0);
}
void handle_spylist(BS* bs)
{
printf("PVS spy list server invoked\n");
}
void handle_tasklist(BS* bs)
{
printf("PVS task list server invoked\n");
}

View File

@@ -49,6 +49,17 @@ static char subst_buffer[VAR_MAX_SUB_SIZE];
static int subst_used;
static int line_num;
struct db_app_node
{
char* name;
struct db_app_node* next;
};
typedef struct db_app_node DB_APP_NODE;
DB_APP_NODE* DbApplList=(DB_APP_NODE*)NULL;
static DB_APP_NODE* DbCurrentListHead=(DB_APP_NODE*)NULL;
static DB_APP_NODE* DbCurrentListTail=(DB_APP_NODE*)NULL;
static int yyerror();
static void sub_pvname(char*,char*);
@@ -65,8 +76,9 @@ extern struct dbBase *pdbBase;
%token <Str> WORD VALUE
%token <Str> FIELD
%left O_BRACE C_BRACE O_PAREN C_PAREN
%left DATABASE CONTAINER RECORD
%left NOWHERE
%left DATABASE RECORD
%left NOWHERE
%token APPL
%union
{
@@ -105,18 +117,39 @@ n_body: O_BRACE records C_BRACE
;
db_components: /* null */
| db_components container
| db_components applic
| db_components record
;
container: CONTAINER c_head c_body
;
applic: APPL O_PAREN VALUE C_PAREN
{
DB_APP_NODE* an=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE*));
c_head: O_PAREN WORD C_PAREN
{ free($2); }
;
if(subst_used)
{
strcpy(subst_buffer,$<Str>3);
if(dbDoSubst(subst_buffer,sizeof(subst_buffer),NULL)!=0)
fprintf(stderr,"dbDoSubst failed\n");
#ifdef vxWorks
an->name=strdup(subst_buffer);
free($3);
#else
printf("\napplication(\"%s\")\n",subst_buffer);
#endif
}
else
{
#ifdef vxWorks
an->name=$<Str>3;
#else
printf("\napplication(\"%s\")\n",$<Str>3);
#endif
}
if(DbCurrentListHead==(DB_APP_NODE*)NULL) DbCurrentListTail=an;
c_body: O_BRACE db_components C_BRACE
an->next=DbCurrentListHead;
DbCurrentListHead=an;
}
;
records: /* null */
@@ -190,13 +223,24 @@ field: FIELD O_PAREN WORD COMMA VALUE C_PAREN
static int yyerror(str)
char *str;
{ fprintf(stderr,"db file parse, Error line %d : %s\n",line_num, yytext); }
#ifdef vxWorks
static char* strdup(char* x)
{
char* c;
c=(char*)malloc(strlen(x)+1);
strcpy(c,x);
return c;
}
#endif
static int is_not_inited = 1;
int dbLoadRecords(char* pfilename, char* pattern, char* container)
int dbLoadRecords(char* pfilename, char* pattern)
{
FILE* fp;
long status;
DB_APP_NODE* an;
#ifdef vxWorks
if(pdbBase==NULL)
@@ -243,6 +287,21 @@ int dbLoadRecords(char* pfilename, char* pattern, char* container)
if(subst_used) dbFreeSubst();
fclose(fp);
if(DbCurrentListHead==(DB_APP_NODE*)NULL)
{
/* set up a default list to put on the master application list */
DbCurrentListHead=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE));
DbCurrentListTail=DbCurrentListHead;
DbCurrentListHead->name=strdup(pfilename);
DbCurrentListHead->next=(DB_APP_NODE*)NULL;
}
DbCurrentListTail->next=DbApplList;
DbApplList=DbCurrentListHead;
DbCurrentListHead=(DB_APP_NODE*)NULL;
DbCurrentListTail=(DB_APP_NODE*)NULL;
return 0;
}
@@ -276,3 +335,14 @@ static void sub_pvname(char* type, char* name)
}
}
#ifdef vxWorks
int dbAppList()
{
DB_APP_NODE* an;
for(an=DbApplList;an;an=an->next)
printf("%s\n",an->name);
return 0;
}
#endif

View File

@@ -1,5 +1,5 @@
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
pvname [a-zA-Z0-9_~\-:\.\[\]<>;]
value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
%{
@@ -12,9 +12,9 @@ value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
"field" { return(FIELD); }
"grecord" { return(RECORD); }
"record" { return(RECORD); }
"container" { return(CONTAINER); }
"database" { return(DATABASE); }
"nowhere" { return(NOWHERE); }
"application" { return(APPL); }
\"{value}*\" { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext+1); yylval.Str[strlen(yylval.Str)-1] = '\0'; return(VALUE); }

View File

@@ -276,9 +276,11 @@ sub_pat: WORD EQUALS WORD
#include "dbLoadTemplate_lex.c"
static int yyerror(str)
char *str;
{ fprintf(stderr,"templ file parse, Error line %d : %s\n",line_num, yytext); }
static int yyerror(char* str)
{
fprintf(stderr,"Substitution file parse error\n");
fprintf(stderr,"line %d:%s\n",line_num,yytext);
}
static int is_not_inited = 1;

View File

@@ -1,5 +1,5 @@
value [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
value [a-zA-Z0-9_~\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
word [a-zA-Z0-9_\.\^~/\*#\[\]%:;!|\-&\$\(\)@\?\+<>]
par [\"\']

116
src/dbtools/rdbapplist.c Normal file
View File

@@ -0,0 +1,116 @@
/* only runable on work station now */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static int read_pvs(BSDATA* info,int serv,char* sname);
int main(int argc,char** argv)
{
BSDATA info;
int rc;
if(argc<2)
{
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
return -1;
}
if(BSsetAddress(&info,argv[1])<0)
{
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
return -1;
}
rc=read_pvs(&info,PVS_AppList,(char*)NULL);
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
return 0;
}
static int read_pvs(BSDATA* info,int serv,char* sname)
{
BS* bs;
int verb,size,done,len,i,port,rsize;
char* buffer;
char ip_from[40];
FILE* fd;
BSgetAddressPort(info,ip_from,&port);
/* verify ioc not already added */
if(access(ip_from,F_OK)==0)
{
/* delete the existing file for this IOC */
unlink(ip_from);
}
done=0;
BSsetPort(info,PVS_TCP_PORT);
if((bs=BSipOpenData(info))==NULL)
{
fprintf(stderr,"Open of socket to IOC failed\n");
return -1;
}
if(serv>PVS_LAST_VERB)
rsize=strlen(sname)+1;
else
rsize=0;
if(BSsendHeader(bs,serv,rsize)<0)
{
fprintf(stderr,"Command send failed\n");
return -1;
}
if(rsize>0)
{
if(BSsendData(bs,sname,rsize)<0)
{
fprintf(stderr,"send of command name failed\n");
return -1;
}
}
fd=stdout;
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
while(done==0)
{
if(BSreceiveHeader(bs,&verb,&size)<0)
{
fprintf(stderr,"Receive header failed\n");
done=-1;
}
else
{
switch(verb)
{
case PVS_Data: /* read a block of names */
if((len=BSreceiveData(bs,buffer,size))<0)
fprintf(stderr,"Receive data failed\n");
else
fputs(buffer,fd);
fputc('\n',fd);
break;
case BS_Done: /* transfers complete */
BSclose(bs);
done=-1;
break;
default:
if(size>0) done=-1;
break;
}
}
}
free(buffer);
return 0;
}

128
src/dbtools/rdbls.c Normal file
View File

@@ -0,0 +1,128 @@
/* only runable on work station now */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static int read_pvs(BSDATA* info,int serv,char* sname);
int main(int argc,char** argv)
{
BSDATA info;
int rc;
if(argc<2)
{
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
return -1;
}
if(BSsetAddress(&info,argv[1])<0)
{
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
return -1;
}
rc=read_pvs(&info,PVS_RecList,(char*)NULL);
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
return 0;
}
static int read_pvs(BSDATA* info,int serv,char* sname)
{
BS* bs;
int verb,size,done,len,i,port,rsize;
char* buffer;
char ip_from[40];
FILE* fd;
BSgetAddressPort(info,ip_from,&port);
/* printf("IOC %s starting\n",ip_from); */
/* verify ioc not already added */
if(access(ip_from,F_OK)==0)
{
/* delete the existing file for this IOC */
unlink(ip_from);
}
done=0;
BSsetPort(info,PVS_TCP_PORT);
if((bs=BSipOpenData(info))==NULL)
{
fprintf(stderr,"Open of socket to IOC failed\n");
return -1;
}
if(serv>PVS_LAST_VERB)
rsize=strlen(sname)+1;
else
rsize=0;
if(BSsendHeader(bs,serv,rsize)<0)
{
fprintf(stderr,"Command send failed\n");
return -1;
}
if(rsize>0)
{
if(BSsendData(bs,sname,rsize)<0)
{
fprintf(stderr,"send of command name failed\n");
return -1;
}
}
fd=stdout;
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
while(done==0)
{
if(BSreceiveHeader(bs,&verb,&size)<0)
{
fprintf(stderr,"Receive header failed\n");
done=-1;
}
else
{
switch(verb)
{
case PVS_Data: /* read a block of names */
if((len=BSreceiveData(bs,buffer,size))<0)
{
fprintf(stderr,"Receive data failed\n");
}
else
{
for(i=0;i<len;i++)
{
if(buffer[i]==' ') buffer[i]='\n';
}
buffer[len]='\n';
buffer[len+1]='\0';
fputs(buffer,fd);
}
break;
case BS_Done: /* transfers complete */
BSclose(bs);
done=-1;
break;
default:
if(size>0) done=-1;
break;
}
}
}
free(buffer);
return 0;
}

View File

@@ -45,10 +45,10 @@ SRCS.c += ../devEventTestIoEvent.c
SRCS.c += ../devHistogramSoft.c
SRCS.c += ../devHistogramTestAsyn.c
SRCS.c += ../devHpe1368a.c
# OBJS += devLiCamac.c
# SRCS.c += ../devLiCamac.c
SRCS.c += ../devLiSoft.c
SRCS.c += ../devLiSymb.c
# OBJS += devLoCamac.c
# SRCS.c += ../devLoCamac.c
SRCS.c += ../devLoSoft.c
SRCS.c += ../devLoSymb.c
# SRCS.c += ../devMbbiCamac.c
@@ -106,113 +106,10 @@ SRCS.c += ../devABBINARY.c
SRCS.c += ../devABStatus.c
SRCS.c += ../devMpc.c
# OBJS += devAaiCamac.o
# OBJS += devAiCamac.o
OBJS += devAiDvx2502.o
OBJS += devAiKscV215.o
OBJS += devAiSoft.o
OBJS += devAiSoftRaw.o
OBJS += devAiSymb.o
OBJS += devAiTestAsyn.o
OBJS += devAiXy566Di.o
OBJS += devAiXy566DiL.o
OBJS += devAiXy566Se.o
# OBJS += devAaoCamac.o
# OBJS += devAoCamac.o
OBJS += devAoSoft.o
OBJS += devAoSoftRaw.o
OBJS += devAoSymb.o
OBJS += devAoTestAsyn.o
OBJS += devAoVmiVme4100.o
OBJS += devApsEg.o
OBJS += devApsEr.o
OBJS += devAt5Vxi.o
OBJS += devAt8Fp.o
OBJS += devAvme9440.o
# OBJS += devBiCamac.o
OBJS += devBiMpv910.o
OBJS += devBiSoft.o
OBJS += devBiSoftRaw.o
OBJS += devBiTestAsyn.o
OBJS += devBiXVme210.o
# OBJS += devBoCamac.o
OBJS += devBoMpv902.o
OBJS += devBoSoft.o
OBJS += devBoSoftRaw.o
OBJS += devBoTestAsyn.o
OBJS += devBoXVme220.o
OBJS += devCommonGpib.o
OBJS += devEventSoft.o
OBJS += devEventTestIoEvent.o
OBJS += devHistogramSoft.o
OBJS += devHistogramTestAsyn.o
OBJS += devHpe1368a.o
# OBJS += devLiCamac.o
OBJS += devLiSoft.o
OBJS += devLiSymb.o
# OBJS += devLoCamac.o
OBJS += devLoSoft.o
OBJS += devLoSymb.o
# OBJS += devMbbiCamac.o
# OBJS += devMbbiDirectCamac.o
OBJS += devMbbiDirectMpv910.o
OBJS += devMbbiDirectSoft.o
OBJS += devMbbiDirectSoftRaw.o
OBJS += devMbbiDirectXVme210.o
OBJS += devMbbiMpv910.o
OBJS += devMbbiSoft.o
OBJS += devMbbiSoftRaw.o
OBJS += devMbbiTestAsyn.o
OBJS += devMbbiXVme210.o
# OBJS += devMbboCamac.o
# OBJS += devMbboDirectCamac.o
OBJS += devMbboDirectMpv902.o
OBJS += devMbboDirectSoft.o
OBJS += devMbboDirectSoftRaw.o
OBJS += devMbboDirectXVme220.o
OBJS += devMbboMpv902.o
OBJS += devMbboSoft.o
OBJS += devMbboSoftRaw.o
OBJS += devMbboTestAsyn.o
OBJS += devMbboXVme220.o
OBJS += devMz8310.o
OBJS += devPtSoft.o
OBJS += devSASoft.o
OBJS += devSiSoft.o
OBJS += devSiSymb.o
OBJS += devSiTestAsyn.o
OBJS += devSmCompumotor1830.o
OBJS += devSmOms6Axis.o
OBJS += devSoSoft.o
OBJS += devSoSymb.o
OBJS += devSoTestAsyn.o
OBJS += devSysmon.o
OBJS += devTimerMz8310.o
OBJS += devVxiTDM.o
# OBJS += devWfCamac.o
OBJS += devWfComet.o
OBJS += devWfDvx2502.o
OBJS += devWfJoergerVtr1.o
OBJS += devWfSoft.o
OBJS += devWfTestAsyn.o
OBJS += devWfXy566Sc.o
OBJS += devWfPentek4261.o
OBJS += devXy240.o
OBJS += devAB1771IFE.o
OBJS += devAB1771IL.o
OBJS += devAB1771IR.o
OBJS += devAB1771IXE.o
OBJS += devAB1771OFE.o
OBJS += devABBINARY.o
OBJS += devABStatus.o
OBJS += devMpc.o
LIBOBJS = $(SRCS.c:../%.c=%.o)
PROD = devSup
LIBNAME = devSup
include $(EPICS)/config/RULES.Vx
$(PROD): $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -137,8 +137,8 @@ LOCAL long init_1771Ofe(struct aoRecord *prec)
"devAiAb1771Ife (init_record) startScan");
break;
}
/*wait for up to 1 seconds*/
for(failed=0; failed<10; failed++) {
/*wait for up to 3 seconds*/
for(failed=0; failed<30; failed++) {
taskDelay(vxTicksPerSecond/10);
drvStatus = (*pabDrv->getStatus)(drvPvt);
if(drvStatus==abSuccess) {

View File

@@ -3,6 +3,9 @@
/*
* $Log$
* Revision 1.24 1995/03/10 16:55:40 winans
* Added waveform writing support
*
* Revision 1.23 1995/01/06 16:55:52 winans
* Added the log parameter to the doc
*
@@ -1302,13 +1305,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -1353,13 +1350,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_aiGpibFinish(pdpvt); /* and finish the processing */
@@ -1404,13 +1395,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -1452,13 +1437,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pao,WRITE_ALARM,VALID_ALARM);
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(IDLE);
}
@@ -1489,13 +1468,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -1540,13 +1513,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_liGpibFinish(pdpvt); /* and finish the processing */
@@ -1590,13 +1557,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -1638,13 +1599,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(plo,WRITE_ALARM,VALID_ALARM);
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(IDLE);
}
@@ -1671,13 +1626,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else /* interpret response that came back */
{
@@ -1720,13 +1669,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_biGpibFinish(pdpvt); /* and finish the processing */
@@ -1773,13 +1716,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -1821,14 +1758,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pbo,WRITE_ALARM,VALID_ALARM);
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(IDLE);
}
@@ -1856,13 +1786,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pmbbi,WRITE_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -1907,13 +1831,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_mbbiGpibFinish(pdpvt); /* and finish the processing */
@@ -1960,13 +1878,7 @@ struct gpibDpvt *pdpvt;
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
}
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -2009,14 +1921,8 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM);
}
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
return(IDLE);
}
@@ -2046,13 +1952,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
else
{
@@ -2097,13 +1997,7 @@ int srqStatus;
{
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
}
devGpibLib_stringinGpibFinish(pdpvt); /* and finish the processing */
@@ -2139,13 +2033,7 @@ struct gpibDpvt *pdpvt;
psi->val[40] = '\0';
psi->udf = FALSE;
}
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}
@@ -2185,14 +2073,8 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pso,WRITE_ALARM,VALID_ALARM);
}
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#if 1
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
#else
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
pdpvt->head.header.callback.priority = priorityLow;
callbackRequest(&pdpvt->head.header.callback);
#endif
return(IDLE);
}
@@ -2225,7 +2107,7 @@ unsigned short val; /* used for EFAST operations only */
bbnode = pdpvt->head.bitBusDpvt->txMsg.node;
/*
* check to see if this node has timed out within last 10 sec
* check to see if this node has timed out within last <timeWindow> ticks
*/
if(tickGet() < (pdpvt->phwpvt->tmoVal + parmBlock->timeWindow) )
{
@@ -2679,8 +2561,7 @@ struct gpibDpvt *pdpvt;
{
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
}
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
return(0);
}

View File

@@ -195,6 +195,7 @@ struct card {
int word_clock;
unsigned long clock_freq;
int soc;
IOSCANPVT ioscanpvt;
};
typedef struct card CARD;
@@ -231,7 +232,6 @@ struct pvt_area {
typedef struct pvt_area PVT_AREA;
static long dev_report(int level);
static long dev_init(int after);
static long dev_init_rec(struct waveformRecord* pr);
static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt);
static long dev_read(struct waveformRecord* pr);
@@ -256,9 +256,9 @@ typedef struct {
} ADC_DSET;
ADC_DSET devWfPentek4261=
{6,dev_report,dev_init,dev_init_rec,dev_ioint_info,dev_read,NULL};
{6,dev_report,NULL,dev_init_rec,dev_ioint_info,dev_read,NULL};
static IOSCANPVT ioscanpvt;
/* this is a bug! there should be one per card! */
static CARD** cards=0;
static void callback(CALLBACK* cback)
@@ -311,14 +311,6 @@ static long dev_report(int level)
return 0;
}
static long dev_init(int after)
{
if(after) return(0);
scanIoInit(&ioscanpvt);
return 0;
}
static long dev_init_rec(struct waveformRecord* pr)
{
volatile ADC* adc_regs;
@@ -524,7 +516,7 @@ static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt)
else /* CMD_DELETED */
buffer_reset(pvt); /* ensure that we are in a good state */
*iopvt=ioscanpvt;
*iopvt=(cards[pvt->card])->ioscanpvt;
return 0;
}
@@ -711,7 +703,7 @@ static void irq_func(void* v)
pvt->adc_regs->trigger=trig|0x02; /* force reset run FF */
if(pr->scan==SCAN_IO_EVENT)
scanIoRequest(ioscanpvt); /* scan EPICS record */
scanIoRequest((cards[pvt->card])->ioscanpvt); /* scan EPICS records */
else
callbackRequest(cb);
}
@@ -754,5 +746,6 @@ void ConfigurePentekADC( int card,
/* card not really present */
cards[card]->in_use=1;
}
scanIoInit(&(cards[card]->ioscanpvt));
}

View File

@@ -15,22 +15,11 @@ SRCS.c += ../devXxDc5009Gpib.c
SRCS.c += ../devXxK263Gpib.c
SRCS.c += ../devXxSkeletonGpib.c
OBJS += devAnalytekGpib.o
OBJS += devXxDg535Gpib.o
OBJS += devBBInteract.o
OBJS += devGpibInteract.o
OBJS += devXxSr620Gpib.o
OBJS += devK486Gpib.o
OBJS += devXxK196Gpib.o
OBJS += devXxDc5009Gpib.o
OBJS += devXxK263Gpib.o
OBJS += devXxSkeletonGpib.o
LIBOBJS = $(SRCS.c:../%.c=%.o)
PROD = devLibOpt $(OBJS)
LIBNAME = devLibOpt
PROD = $(LIBOBJS)
include $(EPICS)/config/RULES.Vx
devLibOpt: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -23,18 +23,7 @@ SRCS.c += ../drvStc.c
SRCS.c += ../drvTime.c
# SRCS.c += ../drvCaenV265.c
TARGETS += drvAb.o
TARGETS += drvAt5Vxi.o
TARGETS += drvEpvxi.o
TARGETS += drvEpvxiMsg.o
TARGETS += drvHp1404a.o
TARGETS += drvHpe1368a.o
TARGETS += drvHpe1445a.o
TARGETS += drvKscV215.o
TARGETS += drvMz8310.o
TARGETS += drvStc.o
TARGETS += drvTime.o
# TARGETS += drvCaenV265.o
TARGETS = $(SRCS.c:../%.c=%.o)
include $(EPICS)/config/RULES.Vx

View File

@@ -253,6 +253,7 @@ typedef struct {
unsigned short baud_rate;
unsigned short int_vector;
unsigned short int_level;
unsigned short autoconfig;
unsigned short scan_list_len;
unsigned char scan_list[64];
} ab_config;
@@ -740,6 +741,7 @@ LOCAL void config_init(ab_link *plink)
p6008 += plink->link;
pconfig->base_address = (void *)p6008;
pconfig->baud_rate = DEF_RATE;
pconfig->autoconfig = FALSE;
pconfig->int_vector = AB_VEC_BASE + plink->link;
pconfig->int_level = AB_INT_LEVEL;
pconfig->scan_list_len = 8;
@@ -763,6 +765,7 @@ int abConfigVme(int link, int base, int vector, int level)
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
@@ -778,6 +781,7 @@ int abConfigBaud(int link, int baud)
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
@@ -785,13 +789,28 @@ int abConfigBaud(int link, int baud)
else pconfig->baud_rate = FAST_RATE;
return(0);
}
int abConfigAuto(int link)
{
ab_link *plink;
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
pconfig->autoconfig = TRUE;
return(0);
}
int abConfigScanList(int link, int scan_list_len, char *scan_list)
{
ab_link *plink;
ab_config *pconfig;
if(link<0 || link>=max_ab_6008s) return(-1);
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
plink = pab_links[link];
if(!plink) plink = allocLink(link);
pconfig = plink->pconfig;
@@ -800,6 +819,49 @@ int abConfigScanList(int link, int scan_list_len, char *scan_list)
memcpy(pconfig->scan_list,scan_list,scan_list_len);
return(0);
}
int abConfigScanListAscii(int link, char *filename,int setRackSize)
{
FILE *fp;
char *scan_list;
char buf[80];
unsigned rack,group,size;
int nItemsRead,nCharsRead,scan_list_len;
scan_list = abCalloc(64,sizeof(char));
fp = fopen(filename,"r");
scan_list_len = 0;
while(fgets(buf,80,fp)) {
if(buf[0] == '#') continue;
nItemsRead = sscanf(buf,"%u %u %n",&rack,&group,&nCharsRead);
if(nItemsRead!=2) {
printf("abConfigScanListAscii: Illegal line %d %s\n",
scan_list_len,buf);
fclose(fp);
return(0);
}
if(!setRackSize) {
size = 0x00;
} else if(strstr(&buf[nCharsRead],"1/4")) {
size = 0x00;
} else if(strstr(&buf[nCharsRead],"1/2")) {
size = 0x40;
} else if(strstr(&buf[nCharsRead],"3/4")) {
size = 0x80;
} else if(strstr(&buf[nCharsRead],"Full")) {
size = 0xc0;
} else {
printf("abConfigScanListAscii: Illegal line %d %s\n",
scan_list_len,buf);
fclose(fp);
return(0);
}
scan_list[scan_list_len] = size | (rack<<2) | group;
scan_list_len++;
}
fclose(fp);
return(abConfigScanList(link,scan_list_len,scan_list));
}
LOCAL int ab_driver_init()
{
@@ -811,6 +873,7 @@ LOCAL int ab_driver_init()
int vxstatus;
long status;
int got_one;
char task_name[50];
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
/* check if any of the cards are there */
@@ -865,7 +928,8 @@ LOCAL int ab_driver_init()
continue;
}
plink->initialized = TRUE;
vxstatus = taskSpawn(ABSCAN_NAME,ABSCAN_PRI,ABSCAN_OPT,
sprintf(task_name,"%s%2.2d",ABSCAN_NAME,link);
vxstatus = taskSpawn(task_name,ABSCAN_PRI,ABSCAN_OPT,
ABSCAN_STACK,(FUNCPTR)abScanTask,(int)plink,
0,0,0,0,0,0,0,0,0);
if(vxstatus < 0){
@@ -874,7 +938,8 @@ LOCAL int ab_driver_init()
}
plink->abScanId = vxstatus;
taskwdInsert(plink->abScanId,NULL,NULL);
vxstatus = taskSpawn(ABDONE_NAME,ABDONE_PRI,ABDONE_OPT,
sprintf(task_name,"%s%2.2d",ABDONE_NAME,link);
vxstatus = taskSpawn(task_name,ABDONE_PRI,ABDONE_OPT,
ABDONE_STACK,(FUNCPTR)abDoneTask,(int)plink,
0,0,0,0,0,0,0,0,0);
if(vxstatus < 0){
@@ -967,7 +1032,19 @@ LOCAL int link_init(ab_link *plink)
not nice, but for now we'll have to assume that all
adapters are needed and put them all in the scan list. */
/* set scan list*/
for(ntry=0; ntry<maxCmdTrys; ntry++) {
if(pconfig->autoconfig) for(ntry=0; ntry<maxCmdTrys; ntry++) {
status = sc_lock(plink);
if(status) continue;
pmb->command = AUTO_CONF;
pmb->data_len = 0;
status = sc_waitcmd(plink);
if(status) continue;
if(pmb->conf_stat != 0) {
sc_conferr(plink);
continue;
}
break;
}else for(ntry=0; ntry<maxCmdTrys; ntry++) {
status = sc_lock(plink);
if(status) continue;
pmb->command = SCAN_LIST;
@@ -983,7 +1060,7 @@ LOCAL int link_init(ab_link *plink)
break;
}
if(ntry>=maxCmdTrys) {
printf("abDrv: SCAN_LIST failed link %hu\n",plink->link);
printf("abDrv: AUTO_CONFIG or SCAN_LIST failed link %hu\n",plink->link);
return(ERROR);
}
sc_unlock(plink);
@@ -1718,6 +1795,7 @@ LOCAL abStatus cardStatus(
plink = pab_links[link];
if(!plink || !plink->initialized) return(abFailure);
padapter = plink->papadapter[adapter];
if(!padapter->adapter_online) return(abAdapterDown);
pcard = padapter->papcard[card];
if(!pcard) return(abNoCard);
if(!padapter->adapter_online) return(abAdapterDown);

View File

@@ -87,5 +87,7 @@ int abConfigNlinks(int nlinks);
int abConfigVme(int link, int base, int vector, int level);
int abConfigBaud(int link, int baud);
int abConfigScanList(int link, int scan_list_len, char *scan_list);
int abConfigScanListAscii(int link, char *filename,int setRackSize);
int abConfigAuto(int link);
#endif /*INCdrvAbh*/

View File

@@ -71,8 +71,8 @@ epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
struct hpe1368a_config{
FAST_LOCK lock; /* mutual exclusion */
unsigned short pending; /* switch position pending int */
unsigned short shadow; /* shadow of actual switch pos */
uint16_t pending; /* switch position pending int */
uint16_t shadow; /* shadow of actual switch pos */
int busy; /* relays active */
IOSCANPVT ioscanpvt;
};

View File

@@ -1044,7 +1044,7 @@ unsigned long npoints
double dacPeakAmplitude;
double dacOffset;
double *pwf;
unsigned short *pdata_port;
uint16_t *pdata_port;
pdata_port = (unsigned short *) epvxiA24Base(la);
pdata_port += (HPE1445_DATA_PORT_OFFSET/sizeof(*pdata_port));

View File

@@ -30,27 +30,7 @@ SRCS.c += ../drvXy220.c
SRCS.c += ../drvXy240.c
SRCS.c += ../drvXy566.c
TARGETS += module_types.o
TARGETS += drvBB232.o
TARGETS += drvBb902.o
TARGETS += drvBb910.o
TARGETS += drvBitBus.o
TARGETS += drvComet.o
TARGETS += drvCompuSm.o
TARGETS += drvDvx.o
TARGETS += drvFp.o
TARGETS += drvFpm.o
TARGETS += drvGpib.o
TARGETS += drvJgvtr1.o
TARGETS += drvMsg.o
TARGETS += drvOms.o
# TARGETS += drvTranServ.o
TARGETS += drvVmi4100.o
TARGETS += drvXy010.o
TARGETS += drvXy210.o
TARGETS += drvXy220.o
TARGETS += drvXy240.o
TARGETS += drvXy566.o
TARGETS = $(SRCS.c:../%.c=%.o)
include $(EPICS)/config/RULES.Vx

View File

@@ -65,6 +65,9 @@
* This driver currently needs work on error message generation.
*
* $Log$
* Revision 1.1 1995/03/30 19:34:56 jba
* Seperated drv files into ansi and old dirs. Added combine dir.
*
* Revision 1.37 1995/03/24 21:24:25 winans
* Probable race condition in PEP TX task. Moved the final transmission
* byte assignment into the point where the busy list is locked. This
@@ -2532,6 +2535,11 @@ STATIC int pepTxTask(int link)
if (bbDebug)
printf("pepTxTask(%d): RAC_RESET_SLAVE sent\n", link);
pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg;
if (bbDebug>30)
printf("pepTxTask(%d): outputting last byte %2.2X\n",
link,*txMsg);
pnode->status = BB_OK;
if (pnode->finishProc != NULL) {

View File

@@ -308,6 +308,10 @@ int smRespId; /* task id */
/* interrupt buffers */
unsigned char sm_responses[MAX_COMPU_MOTORS][RESPBUF_SZ];
unsigned short counts[MAX_COMPU_MOTORS];
/* counts for debugging */
long dbicounts; /* counts number of times through interrupt routine */
long dbrcounts; /* counts number of times through response routine */
long dbscounts; /* counts number of times through send routine */
/* VME memory Short Address Space is set up in gta_init */
static int *compu_addr;
@@ -392,6 +396,7 @@ compu_resp_task()
FOREVER {
/* wait for somebody to wake us up */
semTake (smRespSem, WAIT_FOREVER);
(dbrcounts < 0xFFFF ? dbrcounts++: 0);
/* the response buffer contains: */
/* 0 - motor number */
/* 1 - the command which solicited this response */
@@ -522,7 +527,12 @@ register int mdnum;
/* pointer to the compumotor card interface */
pmtr = pcompu_motors[mdnum];
if (pmtr == 0)
{
intUnlock(key);
return(0);
};
(dbicounts < 0xFFFF ? dbicounts++: 0);
/* place the response byte into the appropriate response buffer */
sm_responses[mdnum][counts[mdnum]] = pmtr->cm_idb;
counts[mdnum]++;
@@ -545,6 +555,7 @@ register int mdnum;
}
intUnlock(key);
return(0);
}
/*
@@ -621,17 +632,18 @@ short trigger = 0;
*
* driver interface to the database library layer
*/
compu_driver(card,value_flag,arg1,arg2)
compu_driver(card, channel, value_flag,arg1,arg2)
register short card;
short channel;
short value_flag;
register int arg1;
register int arg2;
{
register int *pint;
register short *pshort;
short j,i;
short i;
char compu_msg[20];
i = 0;
/* verify the stepper motor driver card is present */
if ((card < 0) || (card > sm_num_cards[CM57_83E]) || (!pcompu_motors[card]))
return (-1);
@@ -661,144 +673,16 @@ register int arg2;
case (SM_MOVE):
if (compu_motor_array[card].mode == VELOCITY_MODE)
return(0);
i = 0;
switch (trigger){
case (0):
/* move the motor */
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (1): /* test sequnce buffer */
compu_msg[i++] = 0xda; /* delete sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd9; /* fill sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd8; /* end sequence buffer */
compu_msg[i++] = 0x41; /* perform sequence buffer */
compu_msg[i++] = 0x01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (2): /* test move buffer */
compu_msg[i++] = 0xc8;
compu_msg[i++] = 0x12;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x40;
compu_msg[i++] = 0x12;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (3): /* test sequence buffer with move buffer */
compu_msg[i++] = 0xc8;
compu_msg[i++] = 0x12;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x04;
compu_msg[i++] = 0x00;
compu_msg[i++] = 0x00;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xda; /* delete sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd9; /* fill sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x40;
compu_msg[i++] = 0x12;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd8; /* end sequence buffer */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x41; /* perform sequence buffer */
compu_msg[i++] = 0x01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
case (4): /* test sequence buffer with move buffer and trigger */
compu_msg[i++] = 0xc8;
compu_msg[i++] = 0x12;
compu_msg[i++] = 0x00;
/* move the motor */
i = 0;
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = compu_motor_data_array[card].velocity;
i += 4;
pint++;
*pint = compu_motor_data_array[card].accel;
i += 4;
pint++;
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xda; /* delete sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd9; /* fill sequence buffer */
compu_msg[i++] = 01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x2c; /* wait for trigger */
compu_msg[i++] = 1; /*trigger 1 */
compu_msg[i++] = 1; /* don't care about state */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x40;
compu_msg[i++] = 0x12;
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0xd8; /* end sequence buffer */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
compu_msg[i++] = 0x41; /* perform sequence buffer */
compu_msg[i++] = 0x01; /* buffer 1 */
compu_send_msg(pcompu_motors[card],compu_msg,i);
i = 0;
break;
}
for (j = 0; j < i; j++){
printf("%x ",compu_msg[j]);
}
/* compu_send_msg(pcompu_motors[card],compu_msg,i);
*/
/* set the motor to active */
compu_motor_array[card].active = TRUE;
@@ -884,6 +768,7 @@ register struct compumotor *pmotor;
register char *pmsg;
register short count;
{
(dbscounts < 0xFFFF ? dbscounts++: 0);
/* write out this command one byte at a time */
while (count){
@@ -969,4 +854,3 @@ VOID compu_sm_reset()
}
}
}

View File

@@ -122,6 +122,9 @@
* for the DMA buffer that is appropriate.
*
* $Log$
* Revision 1.1 1995/03/30 19:35:14 jba
* Seperated drv files into ansi and old dirs. Added combine dir.
*
* Revision 1.22 1995/01/06 17:03:43 winans
* Added some ifdef'd out test code to see if the end of the sequence program
* could be updated to NOT cause an extra sample from port zero to be taken
@@ -181,7 +184,7 @@ static char *SccsId = "$Id$";
#define ADVANCE_HOLD 0xC0
#define RESTART 0x00
/* analogic 2502 memory structure */
/* Analogic 2502 memory structure */
struct dvx_2502
{
unsigned short dev_id; /* device id code (CFF5) */
@@ -205,7 +208,7 @@ struct dvx_inbuf
short *data; /* data buffer */
};
/* analogic 2502 control structure */
/* Analogic 2502 control structure */
struct dvx_rec
{
struct dvx_2502 *pdvx2502; /* pointer to device registers */
@@ -224,6 +227,8 @@ struct dvx_rec
int RearmMode; /* zero if auto-rearm, else manual */
unsigned short ScanRate; /* User settable scan rate */
IOSCANPVT *pioscanpvt;
};
@@ -304,19 +309,19 @@ struct {
static struct dvx_rec dvx[MAX_DVX_CARDS] = {
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0 , NULL
0 , DVX_DRATE, NULL
},
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0, NULL
0, DVX_DRATE, NULL
},
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0, NULL
0, DVX_DRATE, NULL
},
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0, NULL
0, DVX_DRATE, NULL
}
};
@@ -425,6 +430,16 @@ dvx_int(struct dvx_rec *dvxptr)
cptr->csr = dvxptr->csr_shadow;
}
int dvx_SetScanRate(int Card, unsigned int Rate)
{
/* make sure hardware exists */
if ((Card >= ai_num_cards[DVX2502]) || (Card < 0))
return(-1);
dvx[Card].ScanRate = Rate & 0x0000FFFF;
dvx[Card].pdvx2502->samp_rate = dvx[Card].ScanRate;
return(0);
}
int dvx_RearmModeSet(int card, int mode)
{
/* make sure hardware exists */
@@ -672,7 +687,11 @@ LOCAL long dvx_driver_init(void)
/*
* set scan rate and enable external start
*/
#if 0
pDvxA16->samp_rate = DVX_DRATE; /* scan rate of 184 KHz */
#else
pDvxA16->samp_rate = dvx[i].ScanRate; /* Set scan rate */
#endif
dvx[i].csr_shadow |= CSR_M_ESTART; /* enable ext start (shadow csr) */
pDvxA16->csr = dvx[i].csr_shadow; /* enable external start */
dvx[i].mode = RUN_MODE; /* ready to aquire data */
@@ -904,12 +923,17 @@ int sramld(int card)
#endif
/* set scan rate and run it once */
#if 0
dvx[card].pdvx2502->samp_rate = DVX_DRATE;
#else
dvx[card].pdvx2502->samp_rate = dvx[card].ScanRate; /* Set scan rate */
#endif
dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_START;
taskDelay(sysClkRateGet()); /* let scan run */
dvx[card].pdvx2502->csr = dvx[card].csr_shadow; /* restore csr */
}
/*
* dvx_driver
*

View File

@@ -59,6 +59,9 @@
*
*
* $Log$
* Revision 1.3 1995/04/25 15:32:23 winans
* Changed name of HiDEOS link configuration command/function.
*
* Revision 1.2 1995/04/12 19:31:41 winans
* Added support for the HiDEOS system as a GPIB bus transport agent.
*
@@ -974,12 +977,36 @@ char *buffer; /* data to transfer */
int length; /* number of bytes to transfer */
int time; /* time to wait on the DMA operation */
{
int status;
short cnt;
register struct ibregs *b;
char w_imr2;
int temp_addr;
int tmoTmp;
int status = ERROR;
unsigned short cnt;
struct ibregs *b;
char w_imr2;
int temp_addr;
int tmoTmp;
#ifdef NI_GPIB_LOOP_LENGTH
#define NI_GPIB_CHUNKSIZE 0x0ffff
while (length > 0)
{
if (length > NI_GPIB_CHUNKSIZE)
{
cnt = NI_GPIB_CHUNKSIZE;
length -= NI_GPIB_CHUNKSIZE;
}
else
{
cnt = length;
length = 0;
}
#else
cnt = length;
if (cnt > 0x0fffe)
{
errMessage(S_IB_SIZE, "NI-1014 max length (65535) exceeded");
return(ERROR);
}
#endif
if (pNiLink[link]->A24BounceBuffer == NULL)
{
@@ -993,25 +1020,24 @@ int time; /* time to wait on the DMA operation */
logMsg("Got a bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer);
}
if (pNiLink[link]->A24BounceSize < length)
if (pNiLink[link]->A24BounceSize < cnt)
{ /* Reallocate a larger bounce buffer */
devLibA24Free(pNiLink[link]->A24BounceBuffer); /* Loose the old one */
if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(length)) == NULL)
if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(cnt)) == NULL)
{
errMessage(S_IB_A24 ,"niPhysIo ran out of A24 memory!");
pNiLink[link]->A24BounceSize = 0;
pNiLink[link]->A24BounceBuffer = NULL;
return(ERROR);
}
pNiLink[link]->A24BounceSize = length;
pNiLink[link]->A24BounceSize = cnt;
if(ibDebug > 5)
logMsg("Got a new bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer);
}
b = pNiLink[link]->ibregs;
cnt = length;
b->auxmr = AUX_GTS; /* go to standby mode */
b->ch1.ccr = D_SAB; /* halt channel activity */
@@ -1049,7 +1075,7 @@ int time; /* time to wait on the DMA operation */
else /* (dir == READ) */
{
/* We will be writing, copy data into the bounce buffer */
memcpy(pNiLink[link]->A24BounceBuffer, buffer, length);
memcpy(pNiLink[link]->A24BounceBuffer, buffer, cnt);
if (cnt != 1)
pNiLink[link]->DmaStuff->cc_byte = AUX_SEOI; /* send EOI with last byte */
@@ -1231,9 +1257,13 @@ int time; /* time to wait on the DMA operation */
if (dir == READ)
{ /* Copy data from the bounce buffer to the user's buffer */
memcpy(buffer, pNiLink[link]->A24BounceBuffer, length);
memcpy(buffer, pNiLink[link]->A24BounceBuffer, cnt);
}
#ifdef NI_GPIB_LOOP_LENGTH
buffer += NI_GPIB_CHUNKSIZE;
}
#endif
return (status);
}

View File

@@ -338,13 +338,13 @@ register unsigned int val;
/* use structure to handle high and low short swap */
/* get current output */
work = (dio[card].dptr->port6_7 << 16)
+ dio[card].dptr->port4_5;
work = (dio[card].dptr->port4_5 << 16)
+ dio[card].dptr->port6_7;
work = (work & ~mask) | (val & mask);
dio[card].dptr->port6_7 = (unsigned short)(work >> 16);
dio[card].dptr->port4_5 = (unsigned short)work;
dio[card].dptr->port4_5 = (unsigned short)(work >> 16);
dio[card].dptr->port6_7 = (unsigned short)work;
return OK;
}

View File

@@ -9,6 +9,7 @@ SRCS.c += ../calcPerform.c
SRCS.c += ../cvtFast.c
SRCS.c += ../ellLib.c
SRCS.c += ../envSubr.c
SRCS.c += envData.c
SRCS.c += ../errInc.c
SRCS.c += ../errMtst.c
SRCS.c += ../errPrintfUNIX.c
@@ -29,6 +30,7 @@ LIBOBJS += calcPerform.o
LIBOBJS += cvtFast.o
LIBOBJS += ellLib.o
LIBOBJS += envSubr.o
LIBOBJS += envData.o
LIBOBJS += errMtst.o
LIBOBJS += errPrintfUNIX.o
LIBOBJS += errSymLib.o
@@ -54,11 +56,11 @@ errSymTbl.o: errSymTbl.c errInc.o
errSymTbl.c errInc.o: errInc.c
@$(RM) errInc.o
@$(EPICS_BASE)/tools/blderrSymTbl;
@../blderrSymTbl $(EPICS) $(HOST_ARCH) "$(MAKE)"
envSubr.o: envData.h
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
$(EPICS_BASE)/tools/bldEnvData
envData.c: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV \
$(EPICS)/config/CONFIG_SITE_ENV
../bldEnvData $(EPICS)
pre_build:
@test -f errInc.c || ln -s ../errInc.c errInc.c
@@ -67,5 +69,5 @@ tsTest: tsSubr.o
$(LINK.c) -o $@ tsSubr.o -lCom -lDb -lCom -lm -s
clean::
@$(RM) errInc.c errSymTbl.c envData.h
@$(RM) errInc.c errSymTbl.c envData.c

View File

@@ -3,12 +3,12 @@ include Target.include
include $(EPICS)/config/CONFIG_BASE
SRCS.c += ../calcPerform.c
SRCS.c += ../cvtBpt.c
SRCS.c += ../cvtFast.c
SRCS.c += ../gpHashLib.c
SRCS.c += ../freeListLib.c
SRCS.c += ../ellLib.c
SRCS.c += ../envSubr.c
SRCS.c += envData.c
SRCS.c += ../errSymLib.c
SRCS.c += ../nextFieldSubr.c
SRCS.c += ../postfix.c
@@ -21,45 +21,41 @@ SRCS.c += errSymTbl.c
SRCS.c += ../errPrintfVX.c
SRCS.c += ../assertVX.c
OBJS += calcPerform.o
OBJS += cvtBpt.o
OBJS += cvtFast.o
OBJS += ellLib.o
OBJS += envSubr.o
OBJS += errSymLib.o
OBJS += errSymTbl.o
OBJS += nextFieldSubr.o
OBJS += postfix.o
OBJS += bucketLib.o
OBJS += tsSubr.o
OBJS += gpHashLib.o
OBJS += freeListLib.o
OBJS += pal.o
OBJS += paldef.o
OBJS += errPrintfVX.o
OBJS += assertVX.o
LIBOBJS += calcPerform.o
LIBOBJS += cvtFast.o
LIBOBJS += ellLib.o
LIBOBJS += envData.o
LIBOBJS += envSubr.o
LIBOBJS += errSymLib.o
LIBOBJS += errSymTbl.o
LIBOBJS += nextFieldSubr.o
LIBOBJS += postfix.o
LIBOBJS += bucketLib.o
LIBOBJS += tsSubr.o
LIBOBJS += gpHashLib.o
LIBOBJS += freeListLib.o
LIBOBJS += pal.o
LIBOBJS += paldef.o
LIBOBJS += errPrintfVX.o
LIBOBJS += assertVX.o
PROD = libCom
LIBNAME = libCom
include $(EPICS)/config/RULES.Vx
clean::
@$(RM) errInc.c errSymTbl.c envData.h
@$(RM) errInc.c errSymTbl.c envData.c
build: errSymTbl.o errInc.o
errSymTbl.c errInc.o: errInc.c
@$(RM) errInc.o
@$(EPICS_BASE)/tools/blderrSymTbl
../blderrSymTbl $(EPICS) $(HOST_ARCH) "$(MAKE)"
envSubr.o: envData.h
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
$(EPICS_BASE)/tools/bldEnvData
envData.c: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV \
$(EPICS)/config/CONFIG_SITE_ENV
../bldEnvData $(EPICS)
pre_build:
@test -f errInc.c || ln -s ../errInc.c errInc.c
libCom: $(OBJS)
$(RM) $@
$(LINK.c) $@ $(OBJS) $(LDLIBS)

View File

@@ -26,6 +26,7 @@
*
* Modification Log:
* -----------------
* $Log$
*/
#include <stdlib.h>
@@ -58,7 +59,7 @@ void epicsAssert (const char *pFile, const unsigned line, const char *pMsg)
"Please contact the author of this software or else send the text of\n");
epicsPrintf (
"this message to \"tech_talk@aps.anl.gov\"\n");
"this message to \"tech-talk@aps.anl.gov\"\n");
abort ();
}

View File

@@ -26,6 +26,7 @@
*
* Modification Log:
* -----------------
* $Log$
***************************************************************************
*/
@@ -64,7 +65,7 @@ void epicsAssert (const char *pFile, const unsigned line, const char *pMsg)
taskId);
epicsPrintf (
"to the author or \"tech_talk@aps.anl.gov\"\n");
"to the author or \"tech-talk@aps.anl.gov\"\n");
taskSuspend (taskId);
}

613
src/libCom/bdt.c Normal file
View File

@@ -0,0 +1,613 @@
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef linux
#include <sys/resource.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <in.h>
#include <inetLib.h>
#include <taskLib.h>
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include "bdt.h"
/* ---------------------------------------------------------------------- */
/* server mode functions */
#ifndef vxWorks /* server mode functions */
static char* filename=(char*)NULL;
/* ----------------------------- */
/* signal catcher for the server */
/* ----------------------------- */
static void catch_sig(int sig)
{
fprintf(stderr,"\nbdt server exiting\n");
unlink(filename);
exit(0);
}
/* -------------------------------- */
/* child reaper for the server mode */
/* -------------------------------- */
static void get_child(int sig)
{
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
#ifdef linux
signal(SIGCHLD,get_child); /* for reaping children */
#endif
}
/* ------------------------------- */
/* Clear the signals for a process */
/* ------------------------------- */
int BdtServerClearSignals()
{
signal(SIGCHLD,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
return 0;
}
/* ----------------------------------------------------- */
/* Make a unix process into a generic background process */
/* ----------------------------------------------------- */
int BdtMakeServer(char** argv)
{
FILE* fd;
if(filename) return -1;
/* set up signal handling for the server */
signal(SIGCHLD,get_child); /* for reaping children */
signal(SIGHUP,catch_sig);
signal(SIGINT,catch_sig);
signal(SIGTERM,catch_sig);
signal(SIGQUIT,catch_sig);
/* disconnect from parent */
switch(fork())
{
case -1: /* error */
perror("Cannot fork");
return -1;
case 0: /* child */
#ifdef linux
setpgrp();
#else
setpgrp(0,0);
#endif
setsid();
break;
default: /* parent goes away */
exit(0);
}
/* save process ID */
filename=(char*)malloc(strlen(argv[0])+10);
sprintf(filename,"%s.%d",argv[0],getpid());
fd=fopen(filename,"w");
fprintf(fd,"%d",getpid());
fprintf(stderr,"\npv server pid: %d\n",getpid());
fclose(fd);
return 0;
}
#endif /* server mode functions */
/* ------------------------------------------ */
/* unimplemented channel access open function */
/* ------------------------------------------ */
BDT* BdtPvOpen(char* name)
{
return (BDT*)NULL;
}
/* --------------------------------------------------------------- */
/* open a bulk data socket to a server given the server IP address */
/* --------------------------------------------------------------- */
BDT* BdtIpOpen(char* address, int Port)
{
struct sockaddr_in tsin;
unsigned long addr;
int osoc;
BDT* bdt;
/* request the process variables (bulk data?) */
addr=inet_addr(address);
tsin.sin_port=0;
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtIpOpen: create socket failed");
return (BDT*)NULL;
}
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtIpOpen: local address bind failed");
return (BDT*)NULL;
}
tsin.sin_port=htons(Port);
memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr));
if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0)
{
perror("BdtIpOpen: connect failed");
close(osoc);
return (BDT*)NULL;
}
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=osoc;
bdt->pending_delta=0;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtUnbound;
/* now connected to the bulk data socket on the IOC */
return bdt;
}
/* -------------------------------------- */
/* write size bytes from buffer to socket */
/* -------------------------------------- */
int BdtWrite(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
data=(unsigned char*)buffer;
total=size;
do
{
/* send block of data */
if((rc=send(soc,&data[size-total],total,0))<0)
{
if(errno==EINTR)
rc=0;
else
{ perror("BdtWrite: Send to remote failed"); }
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* --------------------------------------- */
/* send a message header down a BDT socket */
/* --------------------------------------- */
int BdtSendHeader(BDT* bdt,unsigned short verb,int size)
{
BdtMsgHead buf;
if(bdt->state!=BdtIdle)
{
fprintf(stderr,"BdtSendHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
buf.verb=htons(verb);
buf.size=htonl((unsigned long)size);
if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
{
fprintf(stderr,"BdtSendHeader: write to remote failed");
return -1;
}
/* don't wait for response if data must go out */
if(size)
{
bdt->remaining_send=size;
bdt->state=BdtSData;
}
return 0;
}
/* ------------------------------------------- */
/* send a message data chunk down a BDT socket */
/* ------------------------------------------- */
int BdtSendData(BDT* bdt,void* buffer,int size)
{
int len,remaining,rc;
if(bdt->state!=BdtSData)
{
fprintf(stderr,"BdtSendData: Interface not in send data mode\n");
bdt->state=BdtBad;
return -1;
}
remaining=bdt->remaining_send-size;
if(remaining<0)
{
fprintf(stderr,"BdtSendData: To much data to send\n");
len=bdt->remaining_send;
}
else
len=size;
/* this function should loop until size bytes is sent */
/* send out the chunk */
if((rc=send(bdt->soc,(char*)buffer,len,0))<0)
{
perror("BdtSendData: Send data chunk to remote failed");
return -1;
}
bdt->remaining_send-=rc;
if(bdt->remaining_send<0)
{
fprintf(stderr,"BdtSendData: To much data Sent\n");
bdt->remaining_send=0;
}
if(bdt->remaining_send==0)
bdt->state=BdtIdle;
return rc;
}
/* ------------------------------------------------------------------------
report if data is pending from remote
clear the pending data condition
------------------------------------------------------------------------ */
int BdtPvDeltaPending(BDT* bdt)
{
int rc = bdt->pending_delta;
bdt->pending_delta=0;
return rc;
}
/* ------------------------------------- */
/* Read exactly size bytes from remote */
/* ------------------------------------- */
int BdtRead(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
data=(unsigned char*)buffer;
total=size;
do
{
/* wait for data chunk */
if((rc=recv(soc,&data[size-total],total,0))<0)
{
if(errno==EINTR)
rc=0;
else
{ perror("BdtRead: Receive data chunk failed"); }
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* ------------------------------------- */
/* wait for a message header from remote */
/* ------------------------------------- */
int BdtReceiveHeader(BDT* bdt,int* verb,int* size)
{
BdtMsgHead buf;
/* can only receive header when in the idle state */
if (bdt->state == BdtEof)
return -1;
if(bdt->state != BdtIdle)
{
fprintf(stderr,"BdtReceiveHeader: Interface not idle\n");
bdt->state=BdtBad;
return -1;
}
if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0)
{
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
return -1;
}
/* copy message data to user */
*verb=ntohs(buf.verb);
*size=ntohl(buf.size);
if(*size)
bdt->state=BdtRData;
bdt->remaining_recv=*size;
return 0;
}
/* ------------------------------------------------------------------------
Wait for a chunk of data from remote.
User can continually call this with a maximum size until it return 0.
------------------------------------------------------------------------ */
int BdtReceiveData(BDT* bdt,void* buffer,int size)
{
int rc;
/* can only receive data when in the receive data state */
switch(bdt->state)
{
case BdtRData: break;
case BdtIdle: return 0;
default:
fprintf(stderr,"BdtReceiveData: bad receive state\n");
bdt->state=BdtBad;
break;
}
if(BdtRead(bdt->soc,buffer,size)<0)
{
fprintf(stderr,"BdtReceiveData: Read failed\n");
bdt->state = BdtEof;
return -1;
}
bdt->remaining_recv-=size;
if(bdt->remaining_recv<0)
{
fprintf(stderr,"BdtReceiveData: To much data received\n");
bdt->remaining_recv=0;
}
if(bdt->remaining_recv==0)
bdt->state=BdtIdle;
return size;
}
/* ------------------------------------------------------ */
/* connect to a process variable, useful if raw open used */
/* ------------------------------------------------------ */
int BdtServiceConnect(BDT* bdt, char* service_name)
{
int len,rc,size,verb;
if(bdt->state!=BdtUnbound)
{
fprintf(stderr,"BdtServiceConnect: can only bind to one service\n");
return -1;
}
bdt->state=BdtIdle;
len=strlen(service_name)+1;
/* send out connect message */
if(BdtSendHeader(bdt,BDT_Connect,len)<0)
{
fprintf(stderr,"BdtServiceConnect: send of connect header failed\n");
bdt->state=BdtUnbound;
return -1;
}
/* send out the process variable to connect to */
if(BdtSendData(bdt,service_name,len)<0)
{
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
bdt->state=BdtUnbound;
return -1;
}
rc=0;
/* wait for response from connect to process variable */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtServiceConnect: receive reponse failed\n");
bdt->state=BdtUnbound;
return -1;
}
/* check response */
switch(verb)
{
case BDT_Ok:
rc=0;
break;
case BDT_Error:
fprintf(stderr,"BdtServiceConnect: connection rejected\n");
bdt->state=BdtUnbound;
rc=-1;
break;
default:
fprintf(stderr,"BdtServiceConnect: unknown response from remote\n");
bdt->state=BdtUnbound;
rc=-1;
break;
}
return rc;
}
/* -------------------- */
/* close the connection */
/* -------------------- */
int BdtClose(BDT* bdt)
{
int verb,size,done;
/* send a close message out */
if(BdtSendHeader(bdt,BDT_Close,0)<0)
{
fprintf(stderr,"BdtClose: Cannot send close message\n");
return -1;
}
done=0;
do
{
/* check response */
if(BdtReceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BdtClose: Close message response error\n");
return -1;
}
switch(verb)
{
case BDT_Ok:
done=1;
break;
case BDT_Error:
fprintf(stderr,"BdtClose: Close rejected\n");
return -1;
break;
default: break;
}
}
while(done==0);
bdt->state=BdtUnbound;
free(bdt);
return 0;
}
/* --------------------------------------- */
/* make a listener socket for UDP - simple */
/* --------------------------------------- */
int BdtOpenListenerUDP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
tsin.sin_port=htons(Port);
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0)
{
perror("BdtOpenListenerUDP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerUDP: local bind failed");
close(nsoc);
return -1;
}
return nsoc;
}
/* --------------------------------------- */
/* make a listener socket for TCP - simple */
/* --------------------------------------- */
int BdtOpenListenerTCP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
memset (&tsin, 0, sizeof(struct sockaddr_in));
tsin.sin_port=htons(Port);
tsin.sin_family=htons(AF_INET);
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
{
perror("BdtOpenListenerTCP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BdtOpenListenerTCP: local bind failed");
close(nsoc);
return -1;
}
listen(nsoc,5);
return nsoc;
}
/* ------------------------------- */
/* make BDT from a socket - simple */
/* ------------------------------- */
BDT* BdtMakeBDT(int soc)
{
BDT* bdt;
bdt=(BDT*)malloc(sizeof(BDT));
bdt->soc=soc;
bdt->pending_delta=0;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BdtIdle;
return bdt;
}
/* --------------------------- */
/* free a BDT and close socket */
/* --------------------------- */
int BdtFreeBDT(BDT* bdt)
{
close(bdt->soc);
free(bdt);
return 0;
}
/* ------------------------------------------------- */
/* connect to a generic service on the remote server */
/* ------------------------------------------------- */
int BdtPvConnect(BDT* bdt, char* pv_name)
{
char* data;
int len,rc;
len=strlen(pv_name)+strlen(BDT_PV_SERVICE)+2;
data=(char*)malloc(len);
sprintf(data,"%s %s",BDT_PV_SERVICE,pv_name);
rc=BdtServiceConnect(bdt,data);
free(data);
return rc;
}

108
src/libCom/bldEnvData Executable file
View File

@@ -0,0 +1,108 @@
#!/bin/sh
#
# base/tools $Id$
# Author: Andrew Johnson (RGO)
# Date: 14-Mar-95
#
# Experimental Physics and Industrial Control System (EPICS)
#
# $Log$
# Revision 1.1 1995/08/17 20:22:09 jba
# Moved bldEnvData,blderrSymTbl, makeStatTbl to libCom dir
#
# Revision 1.3 1995/08/14 19:27:24 jhill
# extern => epicsShareExtern
#
# Revision 1.2 1995/05/04 09:49:24 anj
# Added CONFIG_SITE_ENV, changed envData to .c file
#
# Revision 1.1 1995/04/24 16:02:29 anj
# Moved environment parameter defaults to config/CONFIG_ENV
#
#
# tool to build envData.c from envDefs.h and config/CONFIG*ENV
# Usage bldEnvData
HERE=`/bin/pwd`
cd $1
EPICS=`/bin/pwd`
cd ${HERE}
SRC=${EPICS}/base/include/envDefs.h
ENV_DATA=${EPICS}/config/CONFIG_ENV
SITE_DATA=${EPICS}/config/CONFIG_SITE_ENV
OBJ=envData.c
TOOL=`basename $0`
# Start by creating a list of the ENV_PARAM declarations
PARAMS=`sed -n -e 's/;//' \
-e 's/^[ ]*epicsShareExtern[ ][ ]*ENV_PARAM[ ][ ]*//p' \
${SRC}`
# Create a new header file
rm -rf ${OBJ}
cat >${OBJ} <<!EOF
/* ${HERE}/${OBJ}
*
* created by ${TOOL}
*
* from:
* ${SRC}
* ${ENV_DATA}
* ${SITE_DATA}
*
* `date`
*
*/
#include <envDefs.h>
!EOF
# Make sure no corresponding shell environment variables
unset ${PARAMS}
# Read the default values from the config file into shell variables
. ${ENV_DATA}
. ${SITE_DATA}
# Scan through the parameters to create the definition
for ENV in ${PARAMS}
do
# Get the default, complain if not present
if [ `set | grep -c ${ENV}=` = 0 ];
then
echo No default value for ${ENV}
DEFAULT=""
else
VAR='$'${ENV}
DEFAULT=`eval echo ${VAR}`
fi
# Add this definition to the header file
# echo ${ENV} = ${DEFAULT}
echo ENV_PARAM ${ENV}'={"'${ENV}'","'${DEFAULT}'"};' >>${OBJ}
done
# Now create an array pointing to all parameters
cat >>${OBJ} <<!EOF
ENV_PARAM* env_param_list[EPICS_ENV_VARIABLE_COUNT+1] = {
!EOF
# Contents are the addresses of each parameter
for ENV in ${PARAMS}
do
echo ' &'${ENV}, >>${OBJ}
done
# Finally finish list with 0
cat >>${OBJ} <<!EOF
0
};
!EOF
exit 0

118
src/libCom/blderrSymTbl Executable file
View File

@@ -0,0 +1,118 @@
#!/bin/sh
#
# base/tools $Id$
# Author: Robert Zieman (ANL)
# Date: 6/03/91
#
# Experimental Physics and Industrial Control System (EPICS)
#
# Copyright 1991, the Regents of the University of California,
# and the University of Chicago Board of Governors.
#
# This software was produced under U.S. Government contracts:
# (W-7405-ENG-36) at the Los Alamos National Laboratory,
# and (W-31-109-ENG-38) at Argonne National Laboratory.
#
# Initial development by:
# The Controls and Automation Group (AT-8)
# Ground Test Accelerator
# Accelerator Technology Division
# Los Alamos National Laboratory
#
# Co-developed with
# The Controls and Computing Group
# Accelerator Systems Division
# Advanced Photon Source
# Argonne National Laboratory
#
# Modification Log:
# -----------------
# .00 mm-dd-yy iii Comment
# .01 05-04-94 pg HPUX port modifications.
# .02 08-25-94 mda use makedepend for HP or Alpha if no GCC
# .03 04-28-95 anj use GetVar and case for host arch
# ...
#
# tool to rebuild errSymTbl.c when errInc.c or it's depends change
# Usage blderrSymTbl EPICS HOST_ARCH MAKE VXLIST - IOC and commmon
# Usage blderrSymTbl EPICS HOST_ARCH MAKE - just common
if [ "x" = "x$4" ]; then
DEF="XXX"
else
DEF="${4}"
fi
TMPMAKEFILE=/tmp/tmpmakefile
SFILES=/tmp/sfiles
EPICS=$1
HOST_ARCH=$2
MAKE=$3
case $HOST_ARCH in
alpha | hp700 | Linux)
# Use gcc if it can be found, or makedepend
GCC=`which gcc`
if [ -x "$GCC" ]; then
FILES=`"$GCC" -M -D$DEF -I../../../include \
errInc.c 2>/dev/null \
| sed -e 's/errInc\.o.*: errInc\.c//' -e 's/\\\//'`
else
MAKEDEPEND=`which makedepend`
if [ -x "$MAKEDEPEND" ]; then
FILES=`"$MAKEDEPEND" -f- -D$DEF -I../../../include \
errInc.c 2>/dev/null | sed -e 's/errInc.o://' -e 's/\\\//'`
else
echo Neither GCC or MAKEDEPEND found.
exit 1
fi
fi
;;
solaris)
# use -xM option of ACC to list dependencies
CC=`$EPICS/base/tools/GetVar $EPICS ACC $HOST_ARCH`
FILES=`$CC -xM -D$DEF -I../../../include errInc.c \
| grep "errInc.o" | grep -v "errInc.c" \
| sed -e 's/errInc\.o://'`
;;
sun4)
# use -M option of Sun compiler to list make dependencies
FILES=`cc -M -D$DEF -I../../../include errInc.c 2>/dev/null \
| grep "errInc.o" | grep -v "errInc.c" \
| sed -e 's/errInc\.o://'`
;;
*)
# Unrecognised host architecture
echo $0: host architecture not supported
exit 1
esac
# files with S_ defines
grep "^#define[ ]*S_" $FILES /dev/null \
| sed -e 's-:.*--' | sort -u >$SFILES
# create a tmpmakefile
cat $SFILES | (awk '
BEGIN {print "errInc.o : errInc.c \\"}
{print " "$0" \\" }
END {print " ../../../include/errMdef.h"}
') > $TMPMAKEFILE
cat >> $TMPMAKEFILE <<!addon
/bin/rm -f errSymTbl.c
../makeStatTbl \`cat $SFILES\` >errSymTbl.c
/bin/rm -f errInc.o
touch errInc.o
!addon
$MAKE -f $TMPMAKEFILE
/bin/rm -f $TMPMAKEFILE $SFILES
exit 0

View File

@@ -119,17 +119,17 @@ main()
pb = bucketCreate(8);
if(!pb){
return BUCKET_FAILURE;
return -1;
}
id1 = 0x1000a432;
pValSave1 = "fred";
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
pValSave2 = "jane";
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
start = clock();
for(i=0; i<LOOPS; i++){
@@ -166,7 +166,7 @@ main()
bucketShow(pb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
#endif
@@ -364,8 +364,8 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
pb->hashIdNBits = nbits;
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
if(!pb->pTable){
free(pb);
if (!pb->pTable) {
free (pb);
return NULL;
}
return pb;
@@ -376,9 +376,9 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
* bucketFree()
*/
#ifdef __STDC__
int bucketFree(BUCKET *prb)
int bucketFree (BUCKET *prb)
#else
int bucketFree(prb)
int bucketFree (prb)
BUCKET *prb;
#endif
{
@@ -389,7 +389,7 @@ BUCKET *prb;
* deleting a bucket with entries in use
* will cause memory leaks and is not allowed
*/
assert(prb->nInUse==0);
assert (prb->nInUse==0);
/*
* free the free list
@@ -400,10 +400,10 @@ BUCKET *prb;
free (pi);
pi = pni;
}
free(prb->pTable);
free(prb);
free (prb->pTable);
free (prb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -425,6 +425,8 @@ int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
{
BUCKETID hashid;
ITEM **ppi;
ITEM **ppiExists;
ITEM *pi;
/*
@@ -436,9 +438,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
prb->pFreeItems = pi->pItem;
}
else {
pi = (ITEM *) malloc(sizeof(ITEM));
pi = (ITEM *) malloc (sizeof(ITEM));
if(!pi){
return BUCKET_FAILURE;
return S_bucket_noMemory;
}
}
@@ -450,12 +452,20 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
pi->pApp = pApp;
pi->pId = pId;
pi->type = pBSET->type;
assert((hashid & ~prb->hashIdMask) == 0);
pi->pItem = prb->pTable[hashid];
assert ((hashid & ~prb->hashIdMask) == 0);
ppi = &prb->pTable[hashid];
/*
* Dont reuse a resource id !
*/
ppiExists = (*pBSET->pCompare) (ppi, pId);
if (ppiExists) {
return S_bucket_idInUse;
}
pi->pItem = *ppi;
prb->pTable[hashid] = pi;
prb->nInUse++;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -489,7 +499,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
ppi = &prb->pTable[hashid];
ppi = (*pBSET->pCompare) (ppi, pId);
if(!ppi){
return BUCKET_FAILURE;
return S_bucket_uknId;
}
prb->nInUse--;
pi = *ppi;
@@ -501,7 +511,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
pi->pItem = prb->pFreeItems;
prb->pFreeItems = pi;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -521,7 +531,7 @@ void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
{
return bucketLookupItem(prb, &BSET[bidtString], pId);
}
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
LOCAL void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
@@ -611,7 +621,7 @@ BUCKET *pb;
stdDev,
maxEntries);
return BUCKET_SUCCESS;
return S_bucket_success;
}

View File

@@ -119,17 +119,17 @@ main()
pb = bucketCreate(8);
if(!pb){
return BUCKET_FAILURE;
return -1;
}
id1 = 0x1000a432;
pValSave1 = "fred";
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
pValSave2 = "jane";
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
assert(s == BUCKET_SUCCESS);
assert (s == S_bucket_success);
start = clock();
for(i=0; i<LOOPS; i++){
@@ -166,7 +166,7 @@ main()
bucketShow(pb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
#endif
@@ -364,8 +364,8 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
pb->hashIdNBits = nbits;
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
if(!pb->pTable){
free(pb);
if (!pb->pTable) {
free (pb);
return NULL;
}
return pb;
@@ -376,9 +376,9 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
* bucketFree()
*/
#ifdef __STDC__
int bucketFree(BUCKET *prb)
int bucketFree (BUCKET *prb)
#else
int bucketFree(prb)
int bucketFree (prb)
BUCKET *prb;
#endif
{
@@ -389,7 +389,7 @@ BUCKET *prb;
* deleting a bucket with entries in use
* will cause memory leaks and is not allowed
*/
assert(prb->nInUse==0);
assert (prb->nInUse==0);
/*
* free the free list
@@ -400,10 +400,10 @@ BUCKET *prb;
free (pi);
pi = pni;
}
free(prb->pTable);
free(prb);
free (prb->pTable);
free (prb);
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -425,6 +425,8 @@ int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
{
BUCKETID hashid;
ITEM **ppi;
ITEM **ppiExists;
ITEM *pi;
/*
@@ -436,9 +438,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
prb->pFreeItems = pi->pItem;
}
else {
pi = (ITEM *) malloc(sizeof(ITEM));
pi = (ITEM *) malloc (sizeof(ITEM));
if(!pi){
return BUCKET_FAILURE;
return S_bucket_noMemory;
}
}
@@ -450,12 +452,20 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
pi->pApp = pApp;
pi->pId = pId;
pi->type = pBSET->type;
assert((hashid & ~prb->hashIdMask) == 0);
pi->pItem = prb->pTable[hashid];
assert ((hashid & ~prb->hashIdMask) == 0);
ppi = &prb->pTable[hashid];
/*
* Dont reuse a resource id !
*/
ppiExists = (*pBSET->pCompare) (ppi, pId);
if (ppiExists) {
return S_bucket_idInUse;
}
pi->pItem = *ppi;
prb->pTable[hashid] = pi;
prb->nInUse++;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -489,7 +499,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
ppi = &prb->pTable[hashid];
ppi = (*pBSET->pCompare) (ppi, pId);
if(!ppi){
return BUCKET_FAILURE;
return S_bucket_uknId;
}
prb->nInUse--;
pi = *ppi;
@@ -501,7 +511,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
pi->pItem = prb->pFreeItems;
prb->pFreeItems = pi;
return BUCKET_SUCCESS;
return S_bucket_success;
}
@@ -521,7 +531,7 @@ void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
{
return bucketLookupItem(prb, &BSET[bidtString], pId);
}
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
LOCAL void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId)
{
BUCKETID hashid;
ITEM **ppi;
@@ -611,7 +621,7 @@ BUCKET *pb;
stdDev,
maxEntries);
return BUCKET_SUCCESS;
return S_bucket_success;
}

View File

@@ -151,7 +151,8 @@ int cvtDoubleToString(
/* can this routine handle this conversion */
if (precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) {
if (precision > 8 || flt_value > 1e16 || flt_value < -1e16) {
sprintf(pstr_value,"%12.5e\0",flt_value);
sprintf(pstr_value,"%*.*e\0",precision+7,precision,
flt_value);
} else {
sprintf(pstr_value,"%.0f\0",flt_value);
}

View File

@@ -151,7 +151,8 @@ int cvtDoubleToString(
/* can this routine handle this conversion */
if (precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) {
if (precision > 8 || flt_value > 1e16 || flt_value < -1e16) {
sprintf(pstr_value,"%12.5e\0",flt_value);
sprintf(pstr_value,"%*.*e\0",precision+7,precision,
flt_value);
} else {
sprintf(pstr_value,"%.0f\0",flt_value);
}

Some files were not shown because too many files have changed in this diff Show More