home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / gnuawk.zip / vms / vms_misc.c < prev    next >
C/C++ Source or Header  |  1997-05-06  |  7KB  |  218 lines

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