[Info-vax] OpenVMS Development Annoyances
Stephen Hoffman
seaohveh at hoffmanlabs.invalid
Tue May 7 11:30:52 EDT 2019
On 2019-05-07 05:40:55 +0000, Dave Froble said:
>
> On Monday, May 6, 2019 at 10:51:44 AM UTC-5, Stephen Hoffman wrote:
>>
>> On OpenVMS, itemlists shove a whole lot of complexity and overhead of
>> the flexible API—and a whole lot of source code glue—into the user
>> code, as part of maintaining API compatibility.
>>
>> As for examples? I know well how to use itemlists. I routinely
>> encounter and routinely write pages of source code to do a few simple
>> system service API calls, too.
>>
>> And the itemlist APIs can fail at even that upward-compatibility task,
>> with fixed-length buffers being ubiquitous. Which means a two-pass
>> call, with added memory allocation and deallocation glue code.
>>
>> We all always get all of our memory allocation and memory deallocation
>> entirely right, too. I'm not the only one that's ever made mistakes
>> here, whether leaks or missing access checks—itemlists are really fun
>> across mode changes. And I know I'm not alone here with these
>> mistakes, having fixed various leaks and itemlist parsing written by
>> other folks. It's forty years in and we still don't have a freaking
>> itemlist parser-generator? Ah well, what I'm using elsewhere
>> eliminates this mess, and is a whole lot less glue code for callers to
>> write.
[expurgated—deletia—clippage]
> Ok, an item list:
>
> Record Socket_Options ! Socket characteristics
> Word Protocol%
> String Typ$=1
> String AF$=1
> End Record
>
>
> So, Ok, lots of definitions, but, it's done once, and put in an include
> file. Then any program can use the include file.
>
> DECLARE SOCKET_OPTIONS SOCKOPT ! Socket characteristics
>
> A simple variable definition then gives one an item list.
>
> 130 !************************************************
> ! Create Connection Socket
> !************************************************
>
> SOCKOPT::PROTOCOL% = TCPIP$C_TCP ! Socket
> characteristic
> s
> SOCKOPT::TYP$ = CHR$(TCPIP$C_STREAM)
> SOCKOPT::AF$ = CHR$(TCPIP$C_AF_INET)
>
> Stat% = SYS$QIOW( , ! Event flag &
> CH% By Value, ! VMS channel &
> IO$_SETMODE By Value, ! Operation &
> IOSB::Stat%, ! I/O status block &
> , ! AST routine &
> , ! AST parameter &
> SOCKOPT::PROTOCOL%, ! P1 &
> , ! P2 &
> , ! P3 &
> , ! P4 &
> , ! P5 &
> ) ! P6
>
> If ( Stat% And SS$_NORMAL ) = 0%
> Then Call VMSERR( Stat% , E$ )
> E$ = "Unable to queue create connection socket - " + E$
> E% = -1%
> SaveStat% = Stat%
> GoTo Deassign_Channel
> End If
>
> If ( IOSB::Stat% And SS$_NORMAL ) = 0%
> Then Call VMSERR( IOSB::Stat% , E$ )
> E$ = "Unable to create connection socket - " + E$
> E% = -1%
> SaveStat% = IOSB::Stat%
> GoTo Deassign_Channel
> End If
>
> One might notice that a large part of the code is in the error
> handling. Sorry, nobody is going to talk me out of that. Assume
> nothing. Expect anything. Prepare for anything.
>
> Basically, one defines a RECORD / STRUCTURE.
> Then declare a variable of that RECORD / STRUCTURE.
> Set the pieces of the variable as needed.
> Call the system service.
> Handle the result.
>
> One note, the above code was extracted from a subprogram, so arguments
> to the subprogram are included in the code. Could be simpler without
> that. IOSB is another RECORD, not included above.
>
> Have I cluttered up c.o.v enough?
You're not seeing it, David. I know I didn't see it. Not until I saw
a vendor working toward the removal of source code baggage; of removing
boiler-plate and glue code. Itemlists are particularly egregious here,
though PQLs and among my most "favorite" calls
SMG$CREATE_MENU_WITH_GREAT_API_COMPLEXITY are all certainly awaiting
the unwary. Are itemlists simple to code? Sure. But look at how much
app source code is associated with a system call. In the case of
itemlists, all that code is an OpenVMS developer pushing chunks of the
requirements around OpenVMS-style API compatibility into the user app
source code. And you picked an example that doesn't have an itemlist
structure, basically a version of a C socket options buffer. And to be
flexible around buffer-size changes for if (when) those requirements
arise, there needs to be doubled system service calls and memory
allocation and deallocation handling and that's usually app source
code, and there quite commonly aren't those doubled calls. When I look
at itemlists now, all I see is piles of source code. App source
code—glue code—that's necessary for how OpenVMS APIs operate now and
for the foreseeable future, unfortunately. Gobs of code that long-time
developers often don't notice.
The following Swift code
https://developer.apple.com/videos/play/wwdc2018/715/ performs a DNS
translation, creates a TLS connection to the specified host on the
specified port (a mail server IMAP port), supports both IPv4 and IPv6,
and handles the common errors:
// Create an outbound connection
import Network
let connection = NWConnection(host: "mail.example.com", port: .imaps,
using: .tls)
connection.stateUpdateHandler = { (newState) in
switch(newState) {
case .ready:
// Handle connection established
case .waiting(let error):
// Handle connection waiting for network
case .failed(let error):
// Handle fatal connection error
default:
break;
}
}
connection.start(queue: myQueue)
...
Note that the code doesn't have to futz with records or data structures
or socket options structures, nor with DNS, nor with TLS, nor with the
root certificates for commercial certificates.
The Apple Network Framework is fairly new, and I've just started
working with it. Here's a walk-through of an Apple example from
Objective C:
https://developer.apple.com/documentation/network/implementing_netcat_with_network_framework?language=objc
Apple has lots of these examples posted, both accessible from the web
and also from within the Xcode IDE environment.
Here's an example that fetches the current host name, and with an
equivalent that'll feature itemlists on OpenVMS:
[[NSHost currentHost] localizedName];
Here's a DNS lookup:
[[NSHost hostWithName:@”www.example.com”]
ps: For folks looking to swipe some networking ideas elsewhere? Here
from Microsoft Windows, have a look at I/O Completion Ports.
https://docs.microsoft.com/en-us/windows/desktop/fileio/i-o-completion-ports
pps: Apple also has a habit of trying stuff and tossing out what
doesn't work, which can be disconcerting for those of us accustomed to
keeping problem code around forever. VSI is going to be dragged toward
this same replace-deprecate-and-remove approach too, though they won't
like it. The alternative here would be worse for them and for OpenVMS.
Ubiquitous-forever-compatibility is just not sustainable with the
business environment VSI is presently working within.
ppps: no, I don't ever expect to see itemlists and the old APIs
removed. There are far too many folks that haven't adopted easier APIs
in the decades since they've become available, and there's far too much
code using the existing APIs. That code will be around for many years.
That code will continue to be as glue-filled as it is now, and
modified and new code will be glue-filled, if there are no better
alternatives available. Though I would expect to see a few specific
cases of API changes or removals, per the "pps" above.
--
Pure Personal Opinion | HoffmanLabs LLC
More information about the Info-vax
mailing list