home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gawk-2.15.6-src.tgz / tar.out / fsf / gawk / vms / vms_misc.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  211 lines

  1. /*
  2.  * vms_misc.c -- sustitute code for missing/different run-time library routines.
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1991-1993 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. #define creat creat_dummy    /* one of gcc-vms's headers has bad prototype */
  27. #include "awk.h"
  28. #undef creat
  29. #include <fab.h>
  30. #ifndef O_RDONLY
  31. #include <fcntl.h>
  32. #endif
  33. #include <rmsdef.h>
  34. #include <ssdef.h>
  35. #include <stsdef.h>
  36.  
  37.     /*
  38.      * VMS uses a completely different status scheme (odd => success,
  39.      * even => failure), so we'll trap calls to exit() and alter the
  40.      * exit status code.  [VAXC can't handle this as a macro.]
  41.      */
  42. #ifdef exit
  43. # undef exit
  44. #endif
  45. void
  46. vms_exit( int final_status )
  47. {
  48.     exit(final_status == 0 ? SS$_NORMAL : (SS$_ABORT | STS$M_INHIB_MSG));
  49. }
  50. #define exit(v) vms_exit(v)
  51.  
  52.     /*
  53.      * In VMS's VAXCRTL, strerror() takes an optional second argument.
  54.      *  #define strerror(errnum) strerror(errnum,vaxc$errno)
  55.      * is all that's needed, but VAXC can't handle that (gcc can).
  56.      * [The 2nd arg is used iff errnum == EVMSERR.]
  57.      */
  58. #ifdef strerror
  59. # undef strerror
  60. #endif
  61. /* vms_strerror() -- convert numeric error code into text string */
  62. char *
  63. vms_strerror( int errnum )
  64. {
  65.     extern char *strerror P((int,...));
  66.     return ( errnum != EVMSERR ? strerror(errnum)
  67.                    : strerror(EVMSERR, vaxc$errno) );
  68. }
  69. # define strerror(v) vms_strerror(v)
  70.  
  71.     /*
  72.      * Miscellaneous utility routine, not part of the run-time library.
  73.      */
  74. /* vms_strdup() - allocate some new memory and copy a string into it */
  75. char *
  76. vms_strdup( const char *str )
  77. {
  78.     char *result;
  79.     int len = strlen(str);
  80.  
  81.     emalloc(result, char *, len+1, "strdup");
  82.     return strcpy(result, str);
  83. }
  84.  
  85.     /*
  86.      * VAXCRTL does not contain unlink().  This replacement has limited
  87.      * functionality which is sufficient for GAWK's needs.  It works as
  88.      * desired even when we have the file open.
  89.      */
  90. /* unlink(file) -- delete a file (ignore soft links) */
  91. int
  92. unlink( const char *file_spec ) {
  93.     char tmp[255+1];            /*(should use alloca(len+2+1)) */
  94.     extern int delete(const char *);
  95.  
  96.     strcpy(tmp, file_spec);        /* copy file name */
  97.     if (strchr(tmp, ';') == NULL)
  98.     strcat(tmp, ";0");        /* append version number */
  99.     return delete(tmp);
  100. }
  101.  
  102.     /*
  103.      * Work-around an open(O_CREAT+O_TRUNC) bug (screwed up modification
  104.      * and creation dates when new version is created), and also use some
  105.      * VMS-specific file options.  Note:  optional 'prot' arg is completely
  106.      * ignored; gawk doesn't need it.
  107.      */
  108. #ifdef open
  109. # undef open
  110. #endif
  111. extern int creat P((const char *,int,...));
  112. extern int open  P((const char *,int,unsigned,...));
  113.  
  114. /* vms_open() - open a file, possibly creating it */
  115. int
  116. vms_open( const char *name, int mode, ... )
  117. {
  118.     int result;
  119.  
  120.     if (mode == (O_WRONLY|O_CREAT|O_TRUNC))
  121.     result = creat(name, 0, "shr=nil", "mbc=32");
  122.     else {
  123.     struct stat stb;
  124.     const char *mbc, *shr = "shr=get";
  125.  
  126.     if (stat((char *)name, &stb) < 0) {    /* assume DECnet */
  127.         mbc = "mbc=8";
  128.     } else {    /* ordinary file; allow full sharing iff record format */
  129.         mbc = "mbc=32";
  130.         if (stb.st_fab_rfm < FAB$C_STM) shr = "shr=get,put,upd";
  131.     }
  132.     result = open(name, mode, 0, shr, mbc, "mbf=2");
  133.     }
  134.  
  135.     /* This is only approximate; the ACP -> RMS -> VAXCRTL interface
  136.        discards too much potentially useful status information...  */
  137.     if (result < 0 && errno == EVMSERR
  138.            && (vaxc$errno == RMS$_ACC || vaxc$errno == RMS$_CRE))
  139.     errno = EMFILE;    /* redirect() should close 1 file & try again */
  140.  
  141.     return result;
  142. }
  143.  
  144.     /*
  145.      * Check for attempt to (re-)open known file.
  146.      */
  147. /* vms_devopen() - check for "SYS$INPUT" or "SYS$OUTPUT" or "SYS$ERROR" */
  148. int
  149. vms_devopen( const char *name, int mode )
  150. {
  151.     FILE *file = NULL;
  152.  
  153.     if (STREQ(name, "/dev/null"))
  154.     return open("NL:", mode, 0);    /* "/dev/null" => "NL:" */
  155.     else if (STREQ(name, "/dev/tty"))
  156.     return open("TT:", mode, 0);    /* "/dev/tty" => "TT:" */
  157.     else if (strncasecmp(name, "SYS$", 4) == 0) {
  158.     name += 4;        /* skip "SYS$" */
  159.     if (strncasecmp(name, "INPUT", 5) == 0 && (mode & O_WRONLY) == 0)
  160.         file = stdin,  name += 5;
  161.     else if (strncasecmp(name, "OUTPUT", 6) == 0 && (mode & O_WRONLY) != 0)
  162.         file = stdout,  name += 6;
  163.     else if (strncasecmp(name, "ERROR", 5) == 0 && (mode & O_WRONLY) != 0)
  164.         file = stderr,  name += 5;
  165.     if (*name == ':')  name++;    /* treat trailing colon as optional */
  166.     }
  167.     /* note: VAXCRTL stdio has extra level of indirection (*file) */
  168.     return (file && *file && *name == '\0') ? fileno(file) : -1;
  169. }
  170.  
  171.     /*
  172.      * VMS has no timezone support.
  173.      */
  174. /* these are global for use by missing/strftime.c */
  175. char   *tzname[2] = { "local", "" };
  176. int     daylight = 0;
  177.  
  178. /* dummy to satisfy linker */
  179. void tzset()
  180. {
  181.     return;
  182. }
  183.  
  184. /* getpgrp() -- there's no such thing as process group under VMS;
  185.  *        job tree might be close enough to be useful though.
  186.  */
  187. int getpgrp()
  188. {
  189.     return 0;
  190. }
  191.  
  192. /*----------------------------------------------------------------------*/
  193. #ifdef NO_VMS_ARGS      /* real code is in "vms/vms_args.c" */
  194. void vms_arg_fixup( int *argc, char ***argv ) { return; }    /* dummy */
  195. #endif
  196.  
  197. #ifdef NO_VMS_PIPES     /* real code is in "vms/vms_popen.c" */
  198. FILE *popen( const char *command, const char *mode ) {
  199.     fatal(" Cannot open pipe `%s' (not implemented)", command);
  200.     return NULL;
  201. }
  202. int pclose( FILE *current ) {
  203.     fatal(" Cannot close pipe #%d (not implemented)", fileno(current));
  204.     return -1;
  205. }
  206. int fork( void ) {
  207.     fatal(" Cannot fork process (not implemented)");
  208.     return -1;
  209. }
  210. #endif /*NO_VMS_PIPES*/
  211.