[comp.lang.c] Appending environment variable to system calls

racine@yunexus.yorku.ca (Jeff Racine) (04/02/91)

I wish to be able to set an environment variable (the path to a file)
and then to execute a program using the system() function in the
following fashion:

	char *s;
	s=getenv("FOO");
	system("FOO/FUBAR");

or something like that. I am using Turbo-C running under MS-DOS, and
the manuals do not seem to help me :-).

I know this is a simple problem and that I am missing something
obvious (such as I should not be using the system() function). I would
really like some help on this approach (or rather the correct
aproach).

Any help would be greatly appreciated.
--------------------------------------------------------------------
Jeff Racine        
racine@nexus.yorku.ca   
racine@yunexus.UUCP

jinx@milton.u.washington.edu (Everyone Knows JINX) (04/02/91)

racine@yunexus.yorku.ca (Jeff Racine) writes:

>I wish to be able to set an environment variable (the path to a file)
>and then to execute a program using the system() function in the
>following fashion:

>	char *s;
>	s=getenv("FOO");
>	system("FOO/FUBAR");

>or something like that. I am using Turbo-C running under MS-DOS, and
>the manuals do not seem to help me :-).

>I know this is a simple problem and that I am missing something
>obvious (such as I should not be using the system() function). I would
>really like some help on this approach (or rather the correct
>aproach).

To do this, I always did something like:

s = getenv("FOO");
sprintf (command_line, "%s/FUBAR", s);
system(command_line);

It uses an extra variable, but... 

jwm712@unhd.unh.edu (Jonathan W Miner) (04/02/91)

In article <22200@yunexus.YorkU.CA> racine@yunexus.yorku.ca (Jeff Racine) writes:
>I wish to be able to set an environment variable (the path to a file)
>and then to execute a program using the system() function in the
>following fashion:
>
>	char *s;
>	s=getenv("FOO");
>	system("FOO/FUBAR");
>
> [ stuff deleted ]
>Jeff Racine        
>racine@nexus.yorku.ca   
>racine@yunexus.UUCP

        The following may do what you want:

        char *s;
        char temp[256];
        s=getenv("FOO");
        sprintf(temp,"%s/FUBAR",s);
        system(temp);

Better ways probably exist, take a look at the exec functioins.
Jon.

        


-- 
Jonathan Miner        | I don't speak for UNH, and UNH does not 
jwm712@unhd.unh.edu   | speak for me! 
(603)868-3416         | Hacking to survive......

brendan@cs.widener.edu (Brendan Kehoe) (04/02/91)

In <22200@yunexus.YorkU.CA>, racine@yunexus.yorku.ca writes:
>I wish to be able to set an environment variable (the path to a file)
>and then to execute a program using the system() function in the
>following fashion:
>
>	char *s;
>	s=getenv("FOO");
>	system("FOO/FUBAR");

  Try:

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  #define PROGRAM "FUBAR"

  main(argc, argv)
       int argc;
       char **argv;
  {
    char *s, *t;
    if ((s = getenv("FOO")) == (char *)NULL)
      {
	fprintf(stderr, "%s: no such variable FOO\n", *argv);
	exit(1);
      }
    t = (char *) malloc(strlen(s) + strlen(PROGRAM) + 1);
    sprintf(t, "%s/%s", s, PROGRAM);
    if (system(t) < 0)
      {
	perror("system");
	exit(1);
      }
  }

	

  No guarantees -- I just typed it, didn't try it. :-)

Brendan
-- 
     Brendan Kehoe - Widener Sun Network Manager - brendan@cs.widener.edu
  Widener University in Chester, PA                A Bloody Sun-Dec War Zone
 Now that we know he has ID, we could give him an account. finger bush@cs....

cschmidt@lynx.northeastern.edu (04/07/91)

> I wish to be able to set an environment variable (the path to a file)
> and then to execute a program using the system() function in the
> following fashion [under DOS]:
>
>     char *s;
>     s=getenv("FOO");
>     system("FOO/FUBAR");

This brings to mind the following terrific idea.  The DOS environment
can be used to implement "logical names" in a manner similar to
logical names on VMS.  I have been doing this for years with great
success.

All my DOS programs allow you to use "logical names" in place of
actual directory names and file names.  To illustrate how this
technique works, suppose I were to define a symbol as follows:

        SET H=C:\TC\INCLUDE\*.H
    or
        SET I=C:\TC\INCLUDE\
    or
        SET TC=C:\TC\

I could then use my DOS File Manager program to access header files in
the directory C:\TC\INCLUDE\ by typing:

        FM H:
    or
        FM I:.H
    or
        FM TC:\INCLUDE\.H

The rule is that wherever a colon appears in a file specification, if
the token to the left of the colon is an environment symbol, then the
colon and the symbol are replaced by the translation.  It's basically
just a macro processor.  The colon can be followed by the remaining
portion of a complete path or file specification.  Alternatively, the
logical name itself might define a complete file specification.

Syntactically, the logical name is identical to the drive name portion
of a complete DOS file specification, except that logical names are
not limited to a single letter.  If the logical name is found in the
DOS environment, the logical name and the colon are replaced by the
translation; otherwise, the logical name and the colon remain in
place, so actual drive names are not affected.

Logical names can be defined in terms of other logical names.  Logical
name translation is repeated until no candidate logical name is found
in the resulting translation (signaled by the absence of a colon), or
until no translation is found in the DOS environment, or until the
maximum number of iterations is reached.  A maximum of eight
iterations avoids looping indefinitely in the case of circular
definitions.  Wherever translation produces consecutive backslashes,
one of the backslashes is deleted, which is helpful when referring to
nested directories.

Returning to the original problem, if you write a function named
"translate" or whatever that returns a pointer to a string containing
its input parameter with logical names translated, the solution to
your problem might look something like this:

        system (translate ("FOO:FUBAR"));

(In practice, I do not usually approve of functions that return
pointers to internal static strings, but that is another issue.  Also,
an application with a hard-coded logical name should probably test
whether that logical name is defined before trying to use it.)

As an additional advantage, this technique is portable to VMS and Unix
(I think).  I do know that Unix has environment variables, and I know
of no conflict that might result from using the colon this way in Unix
file specifications.  (Corrections on this point will be gratefully
received.)  Logical names seem much simpler to me that Unix "file
links", which are usually used to accomplish the same thing.  (Logical
names are more powerful in some respects than links, and vice versa.)

I think Microsoft should provide full support for logical names as
defined here, in both DOS and OS/2 and in their compiler runtime
libraries, and of course in their application products.  Microsoft
could then phase out the numerous, cumbersome, less powerful features
they added to DOS to accomplish the same thing.

Programmers and users have always been dissatisfied with the methods
DOS provides for programs to find their data files.  The sheer number
of methods that have appeared in successive versions of DOS indicates
the failure of any one method to provide an adequate solution.  The
logical name method is both simpler and more powerful than all other
methods combined.  If all DOS programs supported logical names, the
DOS commands APPEND, ASSIGN, JOIN, and SUBST would never be needed.
Users would be provided with a single, versatile method that would
work across application, and across platform as well.

In the meantime, you and your customers will benefit if you add
logical name support to all your DOS programs.  I would like to know
what you think about that.  It has worked wonderfully well in the many
DOS applications I have written.

Christopher Schmidt
cschmidt@lynx.northeastern.edu

ckp@grebyn.com (Checkpoint Technologies) (04/08/91)

In article <memo.895702@lynx.northeastern.edu> cschmidt@lynx.northeastern.edu writes:
>> I wish to be able to set an environment variable (the path to a file)
>> and then to execute a program using the system() function in the
>> following fashion [under DOS]:
>>
>>     char *s;
>>     s=getenv("FOO");
>>     system("FOO/FUBAR");
>
>This brings to mind the following terrific idea.  The DOS environment
>can be used to implement "logical names" in a manner similar to
>logical names on VMS.  I have been doing this for years with great
>success.
> [ describes a way to assign a path spec to a drive letter. ]

Yes yes yes.  I work with many machines with assignments (most every DEC
operating system, AmigaDOS) and they are great.  I also work with Unix
(though not DOS) and have found ways to survive using environment
variables instead.  I prefer to have assigns than not have them.
-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                ckp@grebyn.com      \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/