|
Okay... for those of you who requested the functions for working
with select, here I've got some. I'm very pressed for time today,
so I just quickly grabbed this source (these is made up of items
from a few different /COPY members and service programs)
I'll quickly put some sample code in here -- but the sample code
is NOT TESTED, so please just use it to get an idea :)
Also, because I cut & pasted from a few different source files,
theres a risk that some of the variables here weren't defined.
Hopefully you'll be able to figure them out :)
If this isn't clear enough, please let me know and I'll make a
better example, with tested code, etc :)
>From the Header (/COPY) File(s):
----------------------------------------------------------------------
****************************************************************
** This initializes a set of socket descriptors
** (for use with the select() function)
**
** FDSet = the set of descriptors to intialize (all off)
****************************************************************
D FD_SETSIZE C CONST(200)
D FD_ZERO PR
D FDSet 28A
****************************************************************
** This sets a socket descriptor (in a set) ON.
** (for use with the select() function)
**
** FD = descriptor to set on
** FDSet = descriptor set that you wanted to set it on in.
****************************************************************
D FD_SET PR
D FD 10I 0
D FDSet 28A
****************************************************************
** This sets a socket descriptor (in a set) OFF
** (for use with the select() function)
**
** FD = descriptor to set off
** FDSet = descriptor set that you wanted to set it off in.
****************************************************************
D FD_CLR PR
D FD 10I 0
D FDSet 28A
****************************************************************
** This tests whether a socket descriptor is ON or OFF
** (for use with the select() function)
**
** FD = descriptor to test
** FDSet = descriptor set that you wanted to test it in.
**
** returns *ON if the descriptor is set. (was set with FD_SET)
** or *OFF if the descriptor is off. (was set with FD_CLR)
****************************************************************
D FD_ISSET PR 1A
D FD 10I 0
D FDSet 28A
**
** Time Value Structure (for the select() function, etc)
**
** contrains a structure for specifying a wait time on
** a select() function...
**
** tv_sec = seconds. tv_usec = microseconds
**
D p_timeval S *
D timeval DS based(p_timeval)
D tv_sec 10I 0
D tv_usec 10I 0
** select() -- wait for events on multiple sockets
**
** int select(int max_descriptor,
** fd_set *read_set,
** fd_set *write_set,
** fd_set *exception_set,
** struct timeval *wait_time)
**
D Select PR 10I 0 extproc('select')
D max_desc 10I 0 VALUE
D read_set * VALUE
D write_set * VALUE
D except_set * VALUE
D wait_Time * VALUE
>From my serivce program that I use when working with select:
----------------------------------------------------------------------
D CalcBitPos PR
D peDescr 10I 0
D peByteNo 5I 0
D peBitMask 1A
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P* Set a File Descriptor in a set ON... for use w/Select()
P*
P* peFD = descriptor to set on
P* peFDSet = descriptor set
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P FD_SET B EXPORT
D FD_SET PI
D peFD 10I 0
D peFDSet 28A
D wkByteNo S 5I 0
D wkMask S 1A
D wkByte S 1A
C callp CalcBitPos(peFD:wkByteNo:wkMask)
c eval wkByte = %subst(peFDSet:wkByteNo:1)
c biton wkMask wkByte
c eval %subst(peFDSet:wkByteNo:1) = wkByte
P E
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P* Set a File Descriptor in a set OFF... for use w/Select()
P*
P* peFD = descriptor to set off
P* peFDSet = descriptor set
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P FD_CLR B EXPORT
D FD_CLR PI
D peFD 10I 0
D peFDSet 28A
D wkByteNo S 5I 0
D wkMask S 1A
D wkByte S 1A
C callp CalcBitPos(peFD:wkByteNo:wkMask)
c eval wkByte = %subst(peFDSet:wkByteNo:1)
c bitoff wkMask wkByte
c eval %subst(peFDSet:wkByteNo:1) = wkByte
P E
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P* Determine if a file desriptor is on or off...
P*
P* peFD = descriptor to set off
P* peFDSet = descriptor set
P*
P* Returns *ON if its on, or *OFF if its off.
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P FD_ISSET B EXPORT
D FD_ISSET PI 1A
D peFD 10I 0
D peFDSet 28A
D wkByteNo S 5I 0
D wkMask S 1A
D wkByte S 1A
C callp CalcBitPos(peFD:wkByteNo:wkMask)
c eval wkByte = %subst(peFDSet:wkByteNo:1)
c testb wkMask wkByte
c return *IN88
P E
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P* Clear All descriptors in a set. (also initializes at start)
P*
P* peFDSet = descriptor set
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P FD_ZERO B EXPORT
D FD_ZERO PI
D peFDSet 28A
C eval peFDSet = *ALLx'00'
P E
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
p* This is used by the FD_SET/FD_CLR/FD_ISSET procedures to
p* determine which byte in the 28-char string to check,
p* and a bitmask to check the individual bit...
p*
p* peDescr = descriptor to check in the set.
p* peByteNo = byte number (returned)
p* peBitMask = bitmask to set on/off or test
P*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P CalcBitPos B
D CalcBitPos PI
D peDescr 10I 0
D peByteNo 5I 0
D peBitMask 1A
D dsMakeMask DS
D dsZeroByte 1 1A
D dsMask 2 2A
D dsBitMult 1 2U 0 INZ(0)
C peDescr div 32 wkGroup 5 0
C mvr wkByteNo 2 0
C div 8 wkByteNo 2 0
C mvr wkBitNo 2 0
C eval wkByteNo = 4 - wkByteNo
c eval peByteNo = (wkGroup * 4) + wkByteNo
c eval dsBitMult = 2 ** wkBitNo
c eval dsZeroByte = x'00'
c eval peBitMask = dsMask
P E
Sample of using these:
----------------------------------------------------------------------
D sockset S 28A
D p_sockset S *
D maxsock S 10I 0
D tvbuffer S 8A
C* assume "sock" is the result of a successful socket()
C* function, and has already been connected with connect()
C* or accept().
C eval p_sockset = %addr(sockset)
C eval maxsock = sock
c*
c*
C* set number of seconds and
C* microseconds to wait...
c eval p_timeval = %addr(tvbuffer)
c eval tv_sec = 5
c eval tv_usec = 0
C*
c*
C* zero all descriptors, then
C* turn on the one we want to
C* wait for...
C*
C* since select() will modify the
C* contents of sockset, we need
C* to make sure we do this each
c* time we call select()...
C callp FD_ZERO(sockset)
c callp FD_SET(sock: sockset)
c*
c*
C* wait for data to read on the socket...
C* pass *NULL for the write/except set, we only want
c* to check for READ...
C eval X = select(maxsock:
c p_sockset: *NULL: *NULL:
c p_timeval)
C*
C* select() will have changed sockset
C* to indicate which sockets have data
C* to read. Use FD_ISSET to determine
C* if sock is one of them...
c if X > 0
c and FD_ISSET(sock: sockset) = *ON
c** theres data to read on this socket,
C** so go ahead and recv() here...
c endif
c*
c*
c if X < 1
c** timeout or error occurred
C** we can handle that here...
c endif
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This is the RPG/400 Discussion Mailing List! To submit a new *
* message, send your mail to "RPG400-L@midrange.com". To unsubscribe *
* from this list send email to MAJORDOMO@midrange.com and specify *
* 'unsubscribe RPG400-L' in the body of your message. Questions should *
* be directed to the list owner / operator: david@midrange.com *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.