/* @(#)iodev0.c 17.1.1.1 (ES0-DMD) 01/25/02 17:35:23 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME iodev0.c .LANGUAGE C .AUTHOR IPG-ESO Garching .CATEGORY Host operating system interfaces. TBD .COMMENTS Dumb Devices .VERSION 1.0 10-Jan-1990: Creation .VERSION 1.1 18-May-1990: 2 parametesr for ioclose .ENVIRONMENT VAX/VMS ------------------------------------------------------------*/ static char class_name[] = "dumb"; /* e.g. null device */ #include #include #include /* Contains definitions of READ / WRITE, etc... */ #include /* VMS QIO function codes */ #include /* VMS status code definitions */ #include /* VMS descriptor macro */ #include struct iolist *iodev1(); /* Next io routines in list */ MID_EXTERN int oserror; /* MIDAS os-error status */ MID_EXTERN int vmserror; /* translated by osmsg() */ #define L dsc$w_length #define S dsc$a_pointer #define SET_STRING(dsc,str,l) dsc.S = str, dsc.L = l \ /* Set address & length of a string */ static short chan; static struct dsc$descriptor_s sdv = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0}; struct IOSB { unsigned short int iostatus; unsigned short int length; unsigned long int info; }; static struct IOSB iosb; /* The i/o status block */ #define CheckVMS if (!(vmserror&1)) { oserror = EIO; return(-1);} /*======================================================================*/ static int io1 (op, buffer, length) /*+++++++++++++ .PURPOSE Interface to SYS$QIOW, with test of main returned status .RETURNS Byte count / -1 .REMARK --------------*/ int op; /* IN: The operation to perform */ char *buffer; /* OUT: Buffer address */ int length; /* IN: Buffer length */ { register int l; if (oserror) return(-1); iosb.iostatus = 0, iosb.length = 0; vmserror = SYS$QIOW (0,chan,op,&iosb,0,0,buffer,length,0,0,0,0); l = iosb.length; if (!(vmserror & 1)) oserror = EIO, l = -1; return(l); } /*======================================================================*/ static int io2 (op, buffer, length) /*+++++++++++++ .PURPOSE Interface to SYS$QIOW, with test of 2 returned codes .RETURNS Length / -1 if error / 0 for EOF .REMARK --------------*/ int op; /* IN: The operation to perform */ char *buffer; /* OUT: Buffer address */ int length; /* IN: Buffer length */ { register int l; l = io1(op, buffer, length); if (oserror == 0) { switch(iosb.iostatus) { case SS$_NORMAL: break; #if 0 /* Following cases ignored here */ case SS$_DATAOVERUN: if (l == length) l++; break; case SS$_ENDOFTAPE: oserrmsg = "Physical End reached"; oserror = -1; break; case SS$_FORMAT: /* This happens with virgin sectors on ODs. */ break; #endif case SS$_ENDOFVOLUME: case SS$_ENDOFFILE: l = 0; break; /* No error */ default: oserror = EIO; vmserror = iosb.iostatus; break; } } return (oserror ? -1 : l); } static int iorew(fd) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Go to sector #0 .RETURNS 0 (success) / -1 (error) ------------------------------------------------------------*/ int fd; /* IN: File Descriptor */ { return(0); } static int ioinfo(fd, s, fileno, blkno) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Retrieve Info concerning an opened device .RETURNS 0 (success) / -1 (error) ------------------------------------------------------------*/ int fd; /* IN: File Descriptor */ struct osustat *s; /* OUT: The filled components */ int *fileno; /* OUT: Where we are */ long *blkno; /* OUT: Where we are */ { oserror = 0; if (fileno) { *fileno = -1; *blkno = -1; /* Unknown ... */ } s->usize = 0; s->blocksize = 0; s->density = 0; s->isda = 0; return(0); } static int ioopen(name, mode, den) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Open Raw Disk Tape .RETURNS File descriptor / -1 (error) .REMARKS ------------------------------------------------------------*/ char *name; /* IN: Physical name of tape device */ int mode; /* IN: Open mode */ int den; /* IN: Density. Not used */ { int l; oserror = 0; /* Add the : if necessary */ sdv.S = name; sdv.L = l = strlen(name); if (name[l-1] != ':') name[l] = ':', sdv.L += 1; /* Assign the device */ vmserror = SYS$ASSIGN(&sdv,&chan,0,0); name[l] = '\0'; CheckVMS return(chan); } static int ioclose(fd, option) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Close the Device .RETURNS 0 (success) / -1 (failure) ------------------------------------------------------------*/ int fd; /* IN: Tape file descriptor */ int option; /* IN: Option OPU_DISMOUNT */ { oserror=0; vmserror = SYS$DASSGN(fd); CheckVMS return(oserror ? -1 : 0); } static int ioread(fd, buffer, size) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Read a buffer from a dumb device .RETURNS Bytes read / -1 if error .REMARKS 0 Bytes read, means EOF ------------------------------------------------------------*/ int fd; /* IN: Tape device file descriptor */ char *buffer; /* OUT: Buffer for reading */ int size; /* IN: Length of bytes to be read */ { int stat; oserror = 0, chan = fd; return (io2(IO$_READLBLK, buffer, size)); } static int iowrite(fd, buffer, size) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Write a block to a DA device .RETURNS Bytes written / -1 if error .REMARKS 0 Bytes read, means ??? ------------------------------------------------------------*/ int fd; /* IN: Tape device file descriptor */ char *buffer; /* IN: Buffer for reading */ int size; /* IN: Length of bytes to be read */ { int stat; oserror = 0, chan = fd; return (io2(IO$_WRITELBLK, buffer, size)); } /*===================================================================== * Definition of the structure returned to osu *=====================================================================*/ static OPITEM list_of_functions[] = { { U_OPEN, ioopen}, /* Open (name, mode) */ { U_CLOSE, ioclose}, { U_INFO, ioinfo}, { U_READ, ioread}, { U_WRITE, iowrite}, { U_REWIND, iorew} }; static struct iolist this_dev = { iodev1, /* Next iodev in List */ class_name, /* How it's written in DEVCAPFILE */ sizeof(list_of_functions)/sizeof(list_of_functions[0]), list_of_functions }; struct iolist *iodev0() /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Get All definitions concerning this class of Devices .RETURNS The iolist .REMARKS ------------------------------------------------------------*/ { return(&this_dev); }