I am trying to get comfortable with VMS' native API. Here is my attempt at a Hello, World program.
#define __NEW_STARLET 1
#include <stdlib.h>
#include <string.h>
#include <STARLET.H>
#include <IOSBDEF.H>
#include <IODEF.H>
#include <DESCRIP.H>
IOSB iosb;
unsigned int status;
void *tt;
unsigned short int channel;
unsigned int writes(char *s)
{
$DESCRIPTOR(tt, "SYS$OUTPUT");
status = sys$assign(&tt, &channel, 0, 0, 0);
int length = strlen(s);
status = sys$qiow(0, channel, IO$_WRITEVBLK, &iosb, 0, 0, s, length, 0, 0, 0, 0);
return status;
}
unsigned int writesln(char *s)
{
status = writes(s);
status = writes("\r\n");
return status;
}
unsigned int reads(char *s, int length)
{
$DESCRIPTOR(tt, "SYS$INPUT");
status = sys$assign(&tt, &channel, 0, 0, 0);
status = sys$qiow(0, channel, IO$_READVBLK, &iosb, 0, 0, s, length, 0, 0, 0, 0);
length = strlen(s);
s[length - 1] = 0; // remove the carriage return from the input
return status;
}
int main()
{
writesln("Hello from sys$qiow! What is your name?");
int length = 16;
char *s = malloc(length);
reads(s, length);
writesln("");
writes("Hello, ");
writes(s);
writesln(".");
free(s);
return 0;
}
It appears to work:
One problem was that IO$_READVBLK added the carriage return of the return key to the string s. Hence I have to remove it to avoid this:
It took me a while to figure that one out. IO$_READVBLK fills s with "Andrew#" where "#" is a carriage return. The answer written by the program is hence "Hello, Andrew#.", with the carriage return (represented here by "#") moving the cursor back to the beginning of the line where the "." then overwrites the "H".
The solution was to find the carriage return and overwrite it with a 0 so the string ends without a carriage return.