/* $Id: vms.c,v 1.11 1999/06/22 12:32:07 levitte Exp $ */ /* This file contains all the VMS-specific things we might need */ #include "gnu_extras.h" #include #include #include #include #include #include #include #include #include "fish.h" #include "vms.h" #include "util.h" /* TTY specific things */ tty_s *tty_open(const char *name, int *status) { tty_s *tty = xmalloc(sizeof(tty_s)); tty->name.dsc$w_length = strlen(name); tty->name.dsc$b_dtype = DSC$K_DTYPE_T; tty->name.dsc$b_class = DSC$K_CLASS_S; tty->name.dsc$a_pointer = xstrdup(name); *status = sys$assign(&(tty->name),&(tty->channel),0,0); if (!(*status & 1)) { xfree(tty); } return tty; } int tty_close(tty_s *tty, int *status) { sys$dassgn(tty->channel); tty_release(tty,status); return 1; } int tty_release(tty_s *tty, int *status) { xfree(tty->name.dsc$a_pointer); xfree(tty); return 1; } int tty_io_cancel(tty_s *tty, int *status) { return (*status = sys$cancel(tty->channel)) & 1; } tty_s *tty_dup(tty_s *tty) { tty_s *tty2 = xmalloc(sizeof(tty_s)); memcpy(tty2, tty, sizeof(tty_s)); tty2->name.dsc$a_pointer = xstrdup(tty->name.dsc$a_pointer); return tty2; } int tty_setflags(tty_s *tty, int flags, int flags2, int *status) { tty->tty_char.basic_chars |= flags; tty->tty_char.extended_chars |= flags2; return 1; } int tty_clearflags(tty_s *tty, int flags, int flags2, int *status) { tty->tty_char.basic_chars &= ~(flags); tty->tty_char.extended_chars &= ~(flags2); return 1; } int tty_copychar(tty_s *tty, tty_s *from) { memcpy(&tty->tty_char,&from->tty_char,sizeof(from->tty_char)); return 1; } int tty_sensemode(tty_s *tty, int *status) { return (*status = sys$qiow(0, tty->channel, IO$_SENSEMODE, 0, 0, 0, &tty->tty_char, sizeof(tty->tty_char), 0, 0, 0, 0)) & 1; } int tty_setmode(tty_s *tty, int *status) { return (*status = sys$qiow(0, tty->channel, IO$_SETMODE, 0, 0, 0, &tty->tty_char, sizeof(tty->tty_char), 0, 0, 0, 0)) & 1; } tty_s *tty_noecho(const char *name, int *status) { tty_s *tty = tty_open(name, status); tty_s *tty2 = 0; int dummy; if (!tty_sensemode(tty, status)) { tty_release(tty, &dummy); tty_close(tty2, &dummy); return 0; } tty2 = tty_dup(tty); tty_setflags(tty,TT$M_NOECHO,0,&dummy); if (!tty_setmode(tty, status)) { tty_release(tty, &dummy); tty_close(tty2, &dummy); return 0; } tty_release(tty, &dummy); return tty2; } tty_s *tty_echo(const char *name, int *status) { tty_s *tty = tty_open(name, status); tty_s *tty2 = 0; int dummy; if (!tty_sensemode(tty, status)) { tty_release(tty, &dummy); tty_close(tty2, &dummy); return 0; } tty2 = tty_dup(tty); tty_clearflags(tty,TT$M_NOECHO,0,&dummy); if (!tty_setmode(tty, status)) { tty_release(tty, &dummy); tty_close(tty2, &dummy); return 0; } tty_release(tty, &dummy); return tty2; } int read_prompted(const char *name, const char *prompt, char *bufaddr, unsigned long bufsize, int purged, int echo, int *status) { tty_s *tty = tty_open(name, status); int dummy; int function = (purged ? IO$M_PURGE : 0) | (echo ? 0 : IO$M_NOECHO) | IO$_READPROMPT; unsigned long buflen; struct { unsigned short status; unsigned short buflen; unsigned short terminator; unsigned short terminatorsize; } iosb; struct itemlist3 { unsigned short buflen; unsigned short itemcode; void *bufaddr; unsigned long *resultlen; } il3[] = { { 0, SYI$_MAXBUF, 0, 0 }, { 0, 0, 0, 0 }, }; il3[0].buflen = sizeof(dummy); il3[0].bufaddr = &dummy; il3[0].resultlen = 0; *status = sys$getsyiw(0, 0, 0, il3, 0, 0, 0); if (bufsize > dummy) bufsize = dummy; /* The logic above should give me what I want, but doesn't, so let's settle for something low. */ if (bufsize > 500) bufsize = 500; *status = sys$qiow(0, tty->channel, function, &iosb, 0, 0, /* P1 */ bufaddr, /* P2 */ bufsize, /* P3 */ 0, /* P4 */ 0, /* P5 */ prompt, /* P6 */ strlen(prompt)); tty_close(tty, &dummy); tty_release(tty, &dummy); if (!$VMS_STATUS_SUCCESS(*status)) lib$signal(*status); *status = iosb.status; bufaddr[iosb.buflen] = '\0'; return $VMS_STATUS_SUCCESS(*status); } /* C correspondents to certain VMS routines */ /* like lib$put_output(), but takes a NUL-terminated char* instead of a string descriptor */ int lib_put_output(char *str) { struct dsc$descriptor_s dsc; dsc.dsc$b_dtype = DSC$K_DTYPE_T; dsc.dsc$b_class = DSC$K_CLASS_S; dsc.dsc$w_length = strlen(str); dsc.dsc$a_pointer = str; return lib$put_output(&dsc); } /* Emacs local variables Local variables: eval: (set-c-style "BSD") end: */