home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / bcfamily / source / getenv.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-12  |  2.8 KB  |  97 lines

  1. //
  2. //      *******************************************************************
  3. //        JdeBP C++ Library Routines          General Public Licence v1.00
  4. //            Copyright (c) 1991,1992     Jonathan de Boyne Pollard
  5. //      *******************************************************************
  6. //
  7. // Part of FamAPI.LIB
  8. //
  9.  
  10. #include "famapi.h"
  11. #include "dosdos.h"
  12.  
  13. //
  14. //    Obtain environment selector
  15. //
  16. USHORT _APICALL
  17. DosGetEnv    ( unsigned short far *PtrEnvSelector,
  18.               unsigned short far *PtrCommandOffset )
  19. {
  20.     USHORT PSPSeg ;
  21.     USHORT err = DosDosQPSPSeg(&PSPSeg) ;
  22.  
  23.     if (err) return err ;
  24.  
  25.     struct psp far *psp = (struct psp far *)MK_FP(PSPSeg, 0) ;
  26.  
  27.     //
  28.     // Scan through the environment segment to find command line.
  29.     //
  30.     UCHAR far *env = (UCHAR far *)MK_FP((USHORT)psp->environment, 0) ;
  31.  
  32.     while (*env++) { while (*env++) ; }    // Skip environment strings
  33.  
  34.     //
  35.     //    To convert a DOS environment segment into an OS/2 environment
  36.     //    segment, we need to lose the 0x0001 marker, shift the program name
  37.     //    up, and append an empty string (argv[0]) and the command tail
  38.     //    to the segment.  This involves reallocating the segment, and
  39.     //    must be done only once.
  40.     //
  41.     //    We can be sure of a 0x0001 marker because this Family API library
  42.     //    is for use on DOS 3.3 or later only.
  43.     //
  44.     static UCHAR changed = 0 ;
  45.     if (!changed) {
  46.         changed = 1 ;
  47.  
  48.         unsigned char far *ptr = env ;        // Save position
  49.         ptr += sizeof(USHORT) ;                // Skip string count
  50.         while (*env++ = *ptr++) {}            // Copy full pathname down
  51.  
  52.         *PtrCommandOffset = FP_OFF(env) ;
  53.  
  54.         USHORT CmdLen = psp->cmdlen ;
  55.         USHORT NewSize = FP_OFF(ptr) + 1 + CmdLen + 1 ;
  56.  
  57.         if (DosReallocSeg ( NewSize, FP_SEG(env) ) ) {
  58.             //
  59.             //    The segment will not expand in place, so allocate
  60.             //    a new one.
  61.             //
  62.             USHORT NewEnvSeg ;
  63.             if ( err = DosAllocSeg(NewSize, &NewEnvSeg, 0) ) {
  64.                 //
  65.                 //    PANIC ! We cannot append the command line. Return an
  66.                 //    out of memory error, and since we have a sizeof(USHORT)
  67.                 //    to spare anyway, make two empty strings with it.
  68.                 //    The caller will have to deal with this situation.
  69.                 //
  70.                 *env++ = 0 ;
  71.                 *env++ = 0 ;
  72.                 return err ;
  73.             } else {
  74.                 UCHAR far *p = (UCHAR far *)MK_FP(NewEnvSeg, 0) ;
  75.                 UCHAR far *q = (UCHAR far *)MK_FP(FP_SEG(env), 0) ;
  76.                 while (NewSize--) *p++ = *q++ ;
  77.                 psp->environment = NewEnvSeg ;    // So DOS knows about it
  78.                 DosFreeSeg(FP_SEG(env)) ;        // Release old segment
  79.                 env = (UCHAR far *)MK_FP(NewEnvSeg, FP_OFF(env)) ;
  80.             }
  81.         }
  82.         *env++ = 0 ;                        // argv[0] is empty
  83.         ptr = &psp->cmdline[0] ;
  84.         while (CmdLen--) *env++ = *ptr++ ;    // copy command tail
  85.         *env++ = 0 ;                        // and NUL terminate it
  86.  
  87.         *PtrEnvSelector = FP_SEG(env) ;
  88.  
  89.     } else {
  90.         while (*env++) {}                    // Skip full pathname
  91.         *PtrCommandOffset = FP_OFF(env) ;
  92.         *PtrEnvSelector = FP_SEG(env) ;
  93.     }
  94.  
  95.     return err ;
  96. }
  97.