[comp.lang.c] system

bcf2303@dcrbg1.UUCP (Wing Chow) (01/16/88)

can someone give me an example of how to use 'system' in a c program?

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/18/88)

In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes:
>can someone give me an example of how to use 'system' in a c program?

	...
	fflush( stdout );
	if ( system( "date" ) != 0 )	/* print a time stamp on stdout */
		error( "cannot execute \"date\" command" );
	...

lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (01/19/88)

In article <7118@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes:
>>can someone give me an example of how to use 'system' in a c program?
>
>	...
>	fflush( stdout );
>	if ( system( "date" ) != 0 )	/* print a time stamp on stdout */
>		error( "cannot execute \"date\" command" );
>	...


System is probably one of the most abused functions in the C
library.  This is an example of poor use, sorry Mr. Gwyn.  There
are security problems with system() on UNIX.  If the program user
sets their PATH so that it searches other than "non-standard"
directories before searching "standard" there is the potentional
for running the wrong program.  This is deadly if the program using
system() is setuid/setgid.

What to do about it?  When the program starts up, reset the PATH
and IFS environment variables to something sensible, use full
path names (unfortunately you will lose portability here) to the
programs you are executing.  Pathnames can be isolated in a
header file so this isn't a big issue.

-- 
Larry Cipriani, AT&T Networks Systems (by day) Ohio State University (by night)
Domain: lvc@tut.cis.ohio-state.edu
Path: ...!cbosgd!osu-cis!tut.cis.ohio-state.edu!lvc (yes its right)

pmd@cbdkc1.ATT.COM (Paul Dubuc) (01/20/88)

In article <4790@tut.cis.ohio-state.edu> (Lawrence V. Cipriani) writes:
}>>can someone give me an example of how to use 'system' in a c program?
}>
}>	...
}>	fflush( stdout );
}>	if ( system( "date" ) != 0 )	/* print a time stamp on stdout */
}>		error( "cannot execute \"date\" command" );
}>	...
}
}System is probably one of the most abused functions in the C
}library.  This is an example of poor use, sorry Mr. Gwyn.  There
}are security problems with system() on UNIX.  If the program user
}sets their PATH so that it searches other than "non-standard"
}directories before searching "standard" there is the potential
}for running the wrong program.  This is deadly if the program using
}system() is setuid/setgid.
}
}What to do about it?  When the program starts up, reset the PATH
}and IFS environment variables to something sensible, use full
}path names (unfortunately you will lose portability here) to the
}programs you are executing.  Pathnames can be isolated in a
}header file so this isn't a big issue.

Larry's cautions about the use of system() are well put, but these
"abuses" are not inherent in that function.  The same problems
exist with the alternative of using the exec() family of system calls
(speaking UNIX Sys V, here).  Full path names must be specified with most
of them (there's the loss of portability) except the "execvp()" and "execlp()"
forms which use PATH, and are subject to the same security problems
as system().  Unfortunately, you have to use these latter forms
if what you want to exec might be a shell procedure (you get ENOEXEC)
with the others in this case).

The abuse that is inherent in system() is the fact that system()
spawns another copy of the shell and runs your command under that shell.
Needless to say this can be a tremendous waste in overhead if you don't
need the facilities of the subshell to run the command (as in the
above example).  System() is also tempting to use because you don't
have to go through the fork()/exec()/wait() sequence and handle all
the possible outcomes correctly.  (System() gives you less control of
your child process, so there is less you have to look after, but the
same results may be achieved more efficiently by isolating the
fork()/exec()/wait() procedure in a subroutine.)
-- 

Paul Dubuc	{ihnp4,cbosgd}!cbdkc1!pmd

gp@picuxa.UUCP (Greg Pasquariello X1190) (01/20/88)

In article <127@dcrbg1.UUCP>, bcf2303@dcrbg1.UUCP (Wing Chow) writes:
> 
> can someone give me an example of how to use 'system' in a c program?

'System()' is a way to call an external process from within your C code.
The way you use it, is to pass it the process name e.g. system("ls -l"), or
system("sh -c") or if your forced to be running DOS (:-)) system("command");
This will have the effect of stopping your program, executing the command, and
returning control to your program.  On a UNIX system this is (almost) equi-
vilent to a:
		if(!fork())
			execlp("/bin/sh","sh","-c",command,0);
		wait()

Hope this helps.

Greg Pasquariello

miket@ccicpg.UUCP (Mike Tracy) (01/20/88)

In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes:
>
>can someone give me an example of how to use 'system' in a c program?



The best example I have is the mkdir command.  Since a normal
user can not create a directory. The mkdir (under Unix) is a SUID root
program. That is, when the program is envoked its effective user id is
that of the super user (stupid user :-)) root.

To make a directory from you C program (unless your program is
SUID root) you must use the system call (with the appropriate checks
for success).

	system( "mkdir mydir" );


Michael D. Tracy	Computer Consoles Incorporated
(714)458-7282		9801 Muirlands Boulevard
			Irvine, CA 92718
{allegra!hplabs!felix,seismo!rlgvax}!ccicpg!miket

ok@quintus.UUCP (Richard A. O'Keefe) (01/20/88)

In article <4790@tut.cis.ohio-state.edu>, lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) writes:
> In article <7118@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
> >	fflush( stdout );
> >	if ( system( "date" ) != 0 )	/* print a time stamp on stdout */
> >		error( "cannot execute \"date\" command" );
> >	...
> 
> 
> System is probably one of the most abused functions in the C
> library.  This is an example of poor use, sorry Mr. Gwyn.  There
> are security problems with system() on UNIX.  If the program user
> sets their PATH so that it searches other than "non-standard"
> directories before searching "standard" there is the potentional
> for running the wrong program.  This is deadly if the program using
> system() is setuid/setgid.
> 
> What to do about it?  When the program starts up, reset the PATH
> and IFS environment variables to something sensible, use full
> path names (unfortunately you will lose portability here) to the
> programs you are executing.  Pathnames can be isolated in a
> header file so this isn't a big issue.
> 
There is a better way.  Instead of calling
	system("date")
you call
	system("PATH=/bin:/usr/bin date")
in System V, or
	system("PATH=/usr/ucb:/bin:/usr/bin date")
in 4.xBSD.  To keep system-dependency to one place, do

cat >safesys.c <<'EOF'
#include <assert.h>
#ifdef	SUN
#define	CMDSIZ 10240
#define STDENV "IFS= PATH=/usr/ucb:/bin:/usr/bin:/usr/5bin "
#else
#ifdef	BSD
#define	CMDSIZ 10240
#define STDENV "IFS= PATH=/usr/ucb:/bin:/usr/bin "
#else
/* assume USG */
#define CMDSIZ 10240 /* check your manual! */
#define STDENV "IFS= PATH=/bin:/usr/bin "
#endif
#endif

int safe_system(command)
    char *command;
    {
	char buffer[CMDSIZ];
	static char stdenv[] = STDENV;

	assert(sizeof stdenv + strlen(command) <= sizeof buffer);
	sprintf(buffer, "%s%.*s", stdenv,
	     sizeof buffer - sizeof stdenv, command);
	return system(buffer);
    }
EOF

A still better approach is to have safe_system() do a fork(),
and have the child process reset its environment, do
	seteuid(getuid())
	setegid(getgid())
and finally call system().
That takes more code than I care to include here.

There isn't any special security problem with system().
The security problem is with setuid/setgid programs.
If your program offers the user the opportunity to enter a UNIX
command, the user will be *extremely* unhappy to find that he
can't run any of his programs because you have smashed the $PATH
variable!

If your program wants to run a utility for its OWN benefit,
where it cares that a specific program documented in the UNIX
commands manual should be run, use safe_system().
If your program wants to run another program on behalf of the
user, it should use system() and should NOT alter the $PATH variable.

kers@otter.HP.COM (Christopher Dollin) (01/21/88)

[someone has said that "mkdir" must be system-ed].

Duh ... well, in HP-UX, -mkdir- is a system call. But the manual says that
some implementations "may run mkdir" from a library routine.

If -mkdir- (in a program) isn't a system call, how does -mkdir- (the program)
work? How come it wasn't a system call anyway?

Regards, | "Those who understand Unix are compelled to prefect it".
Kers     | (to prefect - to perfect, as in Ford Prefects use of "safe". 

pmd@cbdkc1.ATT.COM (Paul Dubuc) (01/21/88)

In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes:
}In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes:
}>
}>can someone give me an example of how to use 'system' in a c program?
}
}The best example I have is the mkdir command.  Since a normal
}user can not create a directory. The mkdir (under Unix) is a SUID root
}program. That is, when the program is envoked its effective user id is
}that of the super user (stupid user :-)) root.
}
}To make a directory from you C program (unless your program is
}SUID root) you must use the system call (with the appropriate checks
}for success).
}
}	system( "mkdir mydir" );

No, you don't have to you system() for this. You can use fork()/exec().
See my previous article on this subject.  For the reasons I gave in
that article, system() is best reserved for running command strings that
need the facilities of the shell (pipelines, redirection, metacharacter
translation, etc.).

However, running mkdir from a C program either way brings up an interesting
example of another problem.  Suppose I (pmd) have a program that runs set-uid
to user 'joe'.  This program exec's mkdir to create a directory.  If it
then tries to change the mode, owner or group on the directory it just
created, it can't.  Why?  Because mkdir runs set-uid to root, creates
the directory and then sets the owner to the real user ID of the process
(pmd in my case).  My program is running as 'joe' and can't change
the mode, owner or group on any directory it creates because it is not
the owner (and not 'root' either).  This is a problem because it's good
practice for programs that create directories to be selective about the
permissions of those directories and the lack of a solution means your
program may be "broken" by merely setting the set-uid bit*.  It's also a
needless security risk to make the program set-uid to root just to avoid
this problem.

I know how much readers of this group like puzzles, so I won't detail the
solution (it's fairly simple, anyway).  For my solution, I implemented a
mkdir() subroutine that runs the mkdir command (with fork() and exec(),
not system()) and takes mode, owner and group specifications as arguments,
so the whole proceedure is isolated to one routine.  This allows a safe,
easy way to create directories independent of the real or effective user ID
of the calling process.

--
* The set-uid bit is patented by Dennis Ritchie.
-- 

Paul Dubuc	{ihnp4,cbosgd}!cbdkc1!pmd

swarbric@tramp.Colorado.EDU (SWARBRICK FRANCIS JOHN) (01/21/88)

In article <452@picuxa.UUCP> gp@picuxa.UUCP (Greg Pasquariello X1190) writes:
>		if(!fork())
>			execlp("/bin/sh","sh","-c",command,0);
>		wait()

Just curious, but what do fork() and wait() do?  I have Turbo C, and it has
execlp(), but neither of the other two.  Does it have something to do with
the fact that UNIX is multiuser, while MS-DOS is not?

------------------------------------------------------------------
Frank Swarbrick                   |  "Ignorance and prejudice --
swarbric@tramp.UUCP               |   And fear walk and in hand."
swarbric@tramp.Colorado.EDU       |                         --RUSH
...!{hao|nbires}!boulder!tramp!swarbric

usenet@lll-winken.llnl.gov (Usenet News Administrator) (01/21/88)

>>	fflush( stdout );
>>	if ( system( "date" ) != 0 )	/* print a time stamp on stdout */
>>		error( "cannot execute \"date\" command" );
>>	...
>
>System is probably one of the most abused functions in the C
>library.  
>
From: washer@lll-crg.llnl.gov (Jim Washer)
Path: lll-crg.llnl.gov!washer


 system is nice for things like
	system("mkdir xyz" )
    since non-superusers cannot make a directory from a program thru
    standard system call. ( At least I think thats true )

    jim washer
    lll-crg!isaac!washer

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/22/88)

In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU (SWARBRICK FRANCIS JOHN) writes:
>Just curious, but what do fork() and wait() do?  I have Turbo C, and it has
>execlp(), but neither of the other two.  Does it have something to do with
>the fact that UNIX is multiuser, while MS-DOS is not?

Yes, exactly.  fork() creates a duplicate process image that shares the
same open files; it returns 0 in the "child" process and the child's ID
number in the "parent" process, both of which are then concurrently
executing.  exec() simply overlays a process image from a file on top
of the currently executing one, then starts execution at its new entry
point; the process ID remains unchanged.  The combination of the two
effectively "spawns" a new subprocess.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/22/88)

In article <7152@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>>...the fact that UNIX is multiuser...
>Yes, exactly.

Before someone picks on this, it's not EXACTLY correct -- it's
the multitasking nature of UNIX that's involved with fork and exec.
Of course, the multiuser environment relies on this..

pmd@cbdkc1.ATT.COM (Paul Dubuc) (01/22/88)

In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU (SWARBRICK FRANCIS JOHN) writes:
}In article <452@picuxa.UUCP> gp@picuxa.UUCP (Greg Pasquariello X1190) writes:
}>		if(!fork())
}>			execlp("/bin/sh","sh","-c",command,0);
}>		wait()
}
}Just curious, but what do fork() and wait() do?  I have Turbo C, and it has
}execlp(), but neither of the other two.  Does it have something to do with
}the fact that UNIX is multiuser, while MS-DOS is not?

Close.  It has to do with UNIX being multiprocessing.  On UNIX, fork()
clones the process into two virtually identical processes.  execlp()
overlays the currently running process with the one specified by the
arguments.  Wait() waits for a "child" process to terminate.  Although
it's not very clear in this example, only the child process does the
execlp(), the parent executes the wait() which returns when the child
terminates.  (Fork() returns 0 to the child; the process ID of the child
(a positive integer) to the parent).

The execlp() in Turbo C probably acts similarly to system() on UNIX.
It stops the calling program, runs the subprogram, and resumes the calling
program when that's done.  In UNIX a parent process does not have to
wait for the subprocess (child) to finish before continuing.
-- 

Paul Dubuc	{ihnp4,cbosgd}!cbdkc1!pmd

shannon@intelisc.UUCP (Shannon Nelson) (01/23/88)

In article <2771@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes:
>In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes:
>}
>}The best example I have [of system()] is the mkdir command.  Since a normal
>}user can not create a directory. The mkdir (under Unix) is a SUID root
>}program...
>}
>}To make a directory from you C program [...] you must use the system call
>}
>}	system( "mkdir mydir" );
>
>No, you don't have to you system() for this. You can use fork()/exec().


I may be showing my ignorance, but what ever happened to the mkdir()
call?  In my manuals (Xenix, sysVr3, Pyramid OSx) neither the call nor
the command say anything about set-uid to root.  A quick ls -l of
/bin/mkdir confirms this.  As long as the effective user id has write
permission in the target directory, both "mkdir(path, mod)" and
"mkdir path" should be successful.  Given this, and the overhead inherent
in system(), why are you not using mkdir()?


-- 
============================================================================
Shannon Nelson   ...!tektronix!ogcvax!intelisc!shannon
(503) 629-7607   "Live, from iSC Evaluation ..."

Intel disclaims all knowledge of my existence.

) Seaman) (01/23/88)

In article <2771@cbdkc1.ATT.COM>, pmd@cbdkc1.ATT.COM (Paul Dubuc) writes:
< 
< In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes:
< }In article <127@dcrbg1.UUCP> bcf2303@dcrbg1.UUCP (Wing Chow) writes:
< }>
< }>can someone give me an example of how to use 'system' in a c program?
< }
< }The best example I have is the mkdir command...
< }
< }	system( "mkdir mydir" );
< No, you don't have to you system() for this. You can use fork()/exec().
< 
< Paul Dubuc	{ihnp4,cbosgd}!cbdkc1!pmd

You are correct about using fork()/exec() to call mkdir, at least in
System V.

As for what system is good for, try this one:

You have a program, which accepts input from a user (or a user created
file), then wants to 'fork and exec' their input as a command.  If
their command is a binary executable, no problem.  You can parse
their input to determine command and arguments, initialize appropriate
arrays, and call fork()/exec().  But, if their command is a shell
script, exec() will fail.  A script must be exec'ed as an argument
to the appropriate shell (/bin/sh, /bin/csh, /bin/ksh, etc.).  You
can make a few tests in your program, to see what kind of file
it is (assuming you can find it), and then appropriately call their
program directly, or as an argument to the shell.  However, it is
sometimes easier (when you aren't sure), and involves less coding
(if you are in a hurry), to use system().  Some benchmarks I have
tried showed little performance improvement of a program that used
fork()/exec(), versus one that used system().

Don't get me wrong.  I *do* use fork()/exec()/wait() whenever possible,
but sometimes...

-- 
Chris Seaman            |    o\  /o
crs@cpsc6a.att.com <or> |      ||         See "Attack of the Killer Smiley"!
..!ihnp4!cpsc6a!crs     |   \vvvvvv/     Coming Soon to a newsgroup near you!
                        |    \____/ 

tim@amdcad.AMD.COM (Tim Olson) (01/23/88)

In article <2788@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes:

| Close.  It has to do with UNIX being multiprocessing.  On UNIX, fork()

Minor nit here.  'multiprocessing' is usually the term reserved for
hardware with multiple physical processors.  I think you meant
'multitasking' or 'multiprogramming', which are interchangably used to
refer to systems that run multiple processes (independant of the number
of processors).

	-- Tim Olson
	Advanced Micro Devices
	(tim@amdcad.amd.com)
	

daveb@laidbak.UUCP (Dave Burton) (01/24/88)

In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU writes:
>Just curious, but what do fork() and wait() do?  I have Turbo C, and it has
>execlp(), but neither of the other two.  Does it have something to do with
>the fact that UNIX is multiuser, while MS-DOS is not?

Close. Multitasking.
Very basicly, fork() creates a new process and wait() waits for
its completion. MSDOS does not have the capability of a fork(),
so no wait() is needed. exec() overlays one process with another,
which MSDOS can do.
-- 
--------------------"Well, it looked good when I wrote it"---------------------
 Verbal: Dave Burton                        Net: ...!ihnp4!laidbak!daveb
 V-MAIL: (312) 505-9100 x325            USSnail: 1901 N. Naper Blvd.
#include <disclaimer.h>                          Naperville, IL  60540

ok@quintus.UUCP (Richard A. O'Keefe) (01/24/88)

In article <447@cpsc6b.cpsc6a.att.com>,
crs@cpsc6b.cpsc6a.att.com (Chris (I'm Outta Here!) Seaman) writes that:
>                                  But, if their command is a shell
> script, exec() will fail.  A script must be exec'ed as an argument
> to the appropriate shell (/bin/sh, /bin/csh, /bin/ksh, etc.).

BSD UNIX doesn't have this restriction; that is a System V "feature".
Which is, of course, the point of system(): the fork/exec approach
isn't exactly the same in all versions of UNIX.  system() fits nicely
with popen() too.  {Why isn't there a popen() which gives me *two*
stdio streams, one to each end of the command?}

This is more appropriate for comp.unix.questions.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/25/88)

In article <569@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>>But, if their command is a shell script, exec() will fail.
>BSD UNIX doesn't have this restriction; that is a System V "feature".

This Berkeley feature requires that the script start with
an appropriate #! line; not all scripts do.  The #! line
contains system-specific (non-portable) instructions, in
general.  For example, someone just reported a problem
when he used a copy of one of my #!/usr/5bin/sh scripts
on a Sun workstation (which didn't have /usr/5bin/sh).

>{Why isn't there a popen() which gives me *two*
>stdio streams, one to each end of the command?}

Because this isn't generally helpful; if you don't carefully
design an IPC protocol, deadlock can easily result.
If you keep your "packets" below the pipe buffer size,
and use a strict alternation of (write, then read), then
such a connection should work.  But a naive programmer
will just get in trouble with such a facility.

nather@ut-sally.UUCP (Ed Nather) (01/25/88)

In article <1317@laidbak.UUCP>, daveb@laidbak.UUCP (Dave Burton) writes:
> In article <3920@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU writes:

> 
> Very basicly, fork() creates a new process and wait() waits for
> its completion. MSDOS does not have the capability of a fork(),
> so no wait() is needed. exec() overlays one process with another,
> which MSDOS can do.
> -- 

MS-DOS can do the same thing (create a new process and wait for it to
finish) -- it's called "spawn()".  Look for it in your favorite manual.





-- 
Ed Nather
Astronomy Dept, U of Texas @ Austin
{allegra,ihnp4}!{noao,ut-sally}!utastro!nather
nather@astro.AS.UTEXAS.EDU

mlandau@bbn.com (Matt Landau) (01/25/88)

In comp.lang.c (<10202@ut-sally.UUCP>), nather@ut-sally.UUCP (Ed Nather) writes:
>MS-DOS can do the same thing (create a new process and wait for it to
>finish) -- it's called "spawn()".  Look for it in your favorite manual.

The fundamental difference between Unix fork() and creation of child
processes in MS-DOS is twofold:

  (1)  When a child is created by fork(), both child and parent continue
       to run, unless the parent explicitly calls wait() to wait for the
       child to terminate.  MS-DOS is single-tasking, so creation of a 
       child process normally involves suspending the parent (but there
       are ways you can get around this and fake multitasking).

  (2)  More importantly, fork() creates a child process by *copying the 
       parent's address space* -- the child is an exact copy of the parent 
       until they take divergent execution paths.  The child process is 
       typically overlaid almost immediately by a call to exec(), but this 
       is by no means required.  MS-DOS has no way to copy a process's
       address space.
--
 Matt Landau			Waiting for a flash of enlightenment
 mlandau@bbn.com			  in all this blood and thunder

henry@utzoo.uucp (Henry Spencer) (01/26/88)

> I may be showing my ignorance, but what ever happened to the mkdir() call?

Alas, you are showing your ignorance:  only some versions of Unix have
mkdir() as a system call.  Mind you, there is no excuse for not having
it as a library function if you don't have the system call, but many
older Unixes have neither.
-- 
Those who do not understand Unix are |  Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly.    | {allegra,ihnp4,decvax,utai}!utzoo!henry

maart@cs.vu.nl (Maarten Litmaath) (01/28/88)

In article <1017@uokmax.UUCP> rmtodd@uokmax.UUCP () writes:
\My understanding is that mkdir() was made into a system call in BSD (probably
\because they had just changed the directory format).

The 'old' mkdir program has a serious security bug (to become su).
-- 
Floating eye exception --             |Maarten Litmaath @ Free U Amsterdam:
                          Core dumped |maart@cs.vu.nl, mcvax!botter!ark!maart

dsill@NSWC-OAS.arpa (Dave Sill) (01/29/88)

In article <1670009@otter.HP.COM> Christopher Dollin <kers@otter.HP.COM> writes:
>If -mkdir- (in a program) isn't a system call, how does -mkdir- (the program)
>work?

It uses mknod to make the directory, its dot ".", and its dot-dot "..".

>How come it wasn't a system call anyway?

Because mknod must be run by the super-user.  It's purpose is creating
special files.

?) Seaman) (01/30/88)

In article henry@utzoo.uucp (Henry Spencer) writes:
< > I may be showing my ignorance, but what ever happened to the mkdir() call?
< 
< Alas, you are showing your ignorance:  only some versions of Unix have
< mkdir() as a system call.  Mind you, there is no excuse for not having
< it as a library function if you don't have the system call, but many
< older Unixes have neither.
< -- 
< Henry Spencer @ U of Toronto Zoology

Actually, there is not much reason for worrying about whether or not
there is a library function for mkdir on most (all?) System V boxes,
since the mkdir system call is reserved for the super user alone.  In the
standard System V world, you will find that even the 'mkdir' command is
setuid to root.

-- 
Chris Seaman            |    o\  /o
crs@cpsc6a.att.com <or> |      ||         See "Attack of the Killer Smiley"!
..!ihnp4!cpsc6a!crs     |   \vvvvvv/     Coming Soon to a newsgroup near you!
                        |    \____/ 

guy@gorodish.Sun.COM (Guy Harris) (01/30/88)

(This long ago ceased to be a C-related discussion; it is now a UNIX-related
discussion.  It is now being redirected to comp.unix.questions.)

> Actually, there is not much reason for worrying about whether or not
> there is a library function for mkdir on most (all?) System V boxes,
> since the mkdir system call is reserved for the super user alone.

WRONG.  It is not a privileged system call in S5R3.

> In the standard System V world, you will find that even the 'mkdir' command
> is setuid to root.

Not in S5R3.1, at least, and probably not in S5R3.  On the 3B2/400s we have
here, running S5R3.1, "/bin/mkdir" is not set-UID, and it works just fine.

In S5 systems *prior* to S5R3, it is set-UID "root" because it has to use the
privileged "mknod" system call.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

wong@llama.rtech.UUCP (J. Wong) (01/30/88)

In article <224@intelisc.UUCP> shannon@intelisc.UUCP (Shannon Nelson) writes:
>In article <2771@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes:
>>In article <9472@ccicpg.UUCP> miket@ccicpg.UUCP (Mike Tracy) writes:
>>}
>I may be showing my ignorance, but what ever happened to the mkdir()
>call?  In my manuals (Xenix, sysVr3, Pyramid OSx) neither the call nor
>the command say anything about set-uid to root.

I believe that in System V and other non-BSD systems (especially version 7)
only super-users could create links to directories.  Since the . and .. entries
were really just links to the directory and its parent both "mkdir" and "rmdir"
had to be set-UID to be able to create a `Unix' directory (i.e., the system
call didn't create these links, but "mkdir" did!)
				J. Wong		ucbvax!mtxinu!rtech!wong

****************************************************************
You start a conversation, you can't even finish it.
You're talking alot, but you're not saying anything.
When I have nothing to say, my lips are sealed.
Say something once, why say it again.		- David Byrne

wes@obie.UUCP (Barnacle Wes) (01/30/88)

On System V, directories are made with the system call mknod(2).
To make the directory '/usr/fool' with rwxrwxr-x permissions,
you would use:

	mknod("/usr/fool", 040775, 0);

The mode bits are: 040000: make directory, 0775: permission bits.

daveb@geac.UUCP (David Collier-Brown) (01/30/88)

In article <1185@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
|In article <1017@uokmax.UUCP> rmtodd@uokmax.UUCP () writes:
||My understanding is that mkdir() was made into a system call in BSD (probably
||because they had just changed the directory format).
|
|The 'old' mkdir program has a serious security bug (to become su).
  The "new, secure" rename system call, on the other hand, has a serious
functionality bug: it panics, dumps core and cross-links two
directories in Utrix 2.x if one tries to move a directory to a
mis-specified location.
  Setuid was **invented** to deal with the security/functionality
tradeoff in a workable way.  To claim that it is more than a
security **risk** is to mistakenly trivialize the problems T & R faced.

 --dave (do you want software written by grad students, or salesmen?) c-b
-- 
 David Collier-Brown.                 {mnetor yunexus utgpu}!geac!daveb
 Geac Computers International Inc.,   |  Computer Science loses its
 350 Steelcase Road,Markham, Ontario, |  memory (if not its mind) 
 CANADA, L3R 1B3 (416) 475-0525 x3279 |  every 6 months.

jay@splut.UUCP (Jay Maynard) (02/01/88)

In article <224@intelisc.UUCP>, shannon@intelisc.UUCP (Shannon Nelson) writes:
> I may be showing my ignorance, but what ever happened to the mkdir()
> call?  In my manuals (Xenix, sysVr3, Pyramid OSx) [...]
                                   ^^
> [...]  Given this, and the overhead inherent in system(), why are you
> not using mkdir()?

My SVr2 doesn't have it, and I suspect that lots of other Unixes (Unix?
Unices? What _is_ the plural of Unix, anyway?) don't either.

-- 
Jay Maynard, K5ZC (@WB5BBW)...>splut!< | GEnie: JAYMAYNARD  CI$: 71036,1603
uucp: {uunet!nuchat,academ!uhnix1,{ihnp4,bellcore,killer}!tness1}!splut!jay
Never ascribe to malice that which can adequately be explained by stupidity.
The opinions herein are shared by none of my cats, much less anyone else.

rikki)) (02/02/88)

From article <2794@cbdkc1.ATT.COM>, by pmd@cbdkc1.ATT.COM (Paul Dubuc):
> In article <447@cpsc6b.cpsc6a.att.com> (Chris (I'm Outta Here!) Seaman) writes:
> }As for what system is good for, try this one:

How about if an application which is really a command interpreter but
allows the user to escape to the shell to do things like "!write joe"?
Back in the middle ages before the "system" call existed, we invariably
included a routine in our applications to do that -- it simply forked
/bin/sh (passing the parsed arguments), exec'd, and waited.  It was
invariable named "execute" or "system".  Seemed like a useful thing.

-- 
Rikki Welsh
Centel Information Systems
5515 Security Lane, Rockville, Maryland, 20852, (301) 984-3636
UUCP:	decuac!macom1!rikki

pmd@cbdkc1.ATT.COM (Paul Dubuc) (02/02/88)

In article <7@obie.UUCP> wes@obie.UUCP (Barnacle Wes) writes:
}On System V, directories are made with the system call mknod(2).
}To make the directory '/usr/fool' with rwxrwxr-x permissions,
}you would use:
}
}	mknod("/usr/fool", 040775, 0);
}
}The mode bits are: 040000: make directory, 0775: permission bits.

It's already been mentioned that System Vr3 has a mkdir() call, but
in the older systems, this still won't do the whole job of making
a directory.  After the mknod(), you need two calls to link() to make
it properly:

	link("/usr/fool", "/usr/fool/.");
	link("/usr", "/usr/fool/..");

This *still* requires the calling program to have super-user permission,
so I think the solution of using a routine that exec's the mkdir comand
is better.  I never understood why making directories was a super user
priviledge.  Can someone enlighten me?  Since they changed it in r3 of
sys V, there must not have been a good reason.


-- 

Paul Dubuc	{ihnp4,cbosgd}!cbdkc1!pmd

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/08/88)

In article <2824@cbdkc1.ATT.COM> pmd@cbdkc1.UUCP (Paul Dubuc) writes:
>After the mknod(), you need two calls to link() to make it properly:
[...]
>I never understood why making directories was a super user priviledge.

Because, if the links weren't done right, the directory hierarchy could
be turned into a royal mess.  Therefore only a limited amount of
(presumably carefully-checked) code was permitted to make directories,
and everything else had to ask the privileged process to help get it
right.  Indeed, this is the main point of the "superuser" on UNIX;
far from being a security problem, as you read in various places, it
is the minimum mechanism that is absolutely necessary to ensure that
important system operations are carried out securely.  Unfortunately
a lot of people who don't grok simplicity are working to pile a mess
of more conventional layered security features on UNIX.  Too bad.

ftw@datacube.UUCP (02/11/88)

pmd@cbdkc1.UUCP writes:

> Because many of us are still fooling around with older versions of UNIX
> (e.g., sysVr2) that don't have a standard mkdir() routine.  There is a mknod()
> system call but it needs su permission and is clumsy for making directories
> (needing to be called 3 times to do it right).
> -- 

> Paul Dubuc	{ihnp4,cbosgd}!cbdkc1!pmd

I was able to do that with one mknod() and two calls to link().  (Okay,
Name That Tune! 8-)



				Farrell T. Woods 

Datacube Inc. Systems / Software Group	4 Dearborn Rd. Peabody, Ma 01960
VOICE:	617-535-6644;	FAX: (617) 535-5643;  TWX: (710) 347-0125
INTERNET: ftw@datacube.COM
UUCP: {rutgers, ihnp4, mirror}!datacube!ftw

"OS/2 -- Half an operating system"

ftw@datacube.UUCP (02/11/88)

gwyn@brl-smoke.UUCP writes:

> Because, if the links weren't done right, the directory hierarchy could
> be turned into a royal mess.

Ah, yes.  It's amazing how quickly our Pyramid came to its knees when I was
in the Sys V universe, ran a program with a defective "mkdir()", and then
tried to use the newly created directory...


				Farrell T. Woods 

Datacube Inc. Systems / Software Group	4 Dearborn Rd. Peabody, Ma 01960
VOICE:	617-535-6644;	FAX: (617) 535-5643;  TWX: (710) 347-0125
INTERNET: ftw@datacube.COM
UUCP: {rutgers, ihnp4, mirror}!datacube!ftw

"OS/2 -- Half an operating system"

det@hawkmoon.MN.ORG (Derek E. Terveer) (01/21/89)

Has anyone encountered a problem with the Microsoft C 5.0 compiler always
returning a 0 from the system() call, no matter what the actual command
executed by system() returns?

Is there a fix for this or am i misunderstanding something fundamental about
the way the system() call works in msc5.0?  (Like the command.com always
returning the 0, which system(), in turn, returns to my program?)

I'm trying to determine whether or not the executed command succeeded or not by
looking at the completion code from system, ala:

	char buf[BUFSIZ];

	sprintf(buf,"rnews < D_elricf.3aa");
	if (!system(buf)) perror(buf);

and i'm having a hard time of it since system() always (seems) to return 0!

derek
-- 
Derek Terveer 	    det@hawkmoon.MN.ORG || ..!uunet!rosevax!elric!hawkmoon!det
		    w(612)681-6986   h(612)688-0667

"A proper king is crowned" -- Thomas B. Costain

jeenglis@nunki.usc.edu (Joe English) (01/24/89)

In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
>Has anyone encountered a problem with the Microsoft C 5.0 compiler always
>returning a 0 from the system() call, no matter what the actual command
>executed by system() returns?

That, unfortunately, is right.  system() returns the exit status of
command.com (in Turbo C, anyway, and I suspect that MSC works the same
way), and command.com doesn't return an error code if the called
program fails. (!)  (system() also returns non-zero if command.com could
not be loaded for lack of memory.)

The way to get the return status of the program you're interested in
is to use one of the exec or spawn functions, which call the DOS
load/exec syscall and bypass command.com.  It's possible, though a bit
more work, to do redirection with these as well (check out dup() and
dup2()); the only thing you can't do is call command.com-resident
functions like copy and type.


Joe English
jeenglis@nunki.usc.edu

alexande@drivax.DRI (Mark Alexander) (01/25/89)

One possible solution to the problem of COMMAND.COM always returning
zero is that used by NDMAKE.  The basic idea is to construct on the
fly a little batch file that gets passed to COMMAND.COM.  Before you
call system(), though, you create a little zero-length temporary file.
The batch file runs the subprogram, then checks the errorlevel.  If
the errorlevel is 0, it deletes the temporary file.  Then the main
program gets control again and checks the existence of the temporary
file: if it still exists, an error occurred.

The batch file would look something like this:
	prog [parms...] [<infile] [>outfile]
	if errorlevel 1 goto done
	del tempfile
	:done
-- 
Mark Alexander	(amdahl!drivax!alexande)

bkbarret@sactoh0.UUCP (Brent K. Barrett) (01/25/89)

In article <2439@nunki.usc.edu>, jeenglis@nunki.usc.edu (Joe English) writes:
> 
> In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
> >Has anyone encountered a problem with the Microsoft C 5.0 compiler always
> >returning a 0 from the system() call, no matter what the actual command
> >executed by system() returns?
> 
> That, unfortunately, is right.  system() returns the exit status of
> command.com (in Turbo C, anyway, and I suspect that MSC works the same
> way), and command.com doesn't return an error code if the called
> program fails. (!)  (system() also returns non-zero if command.com could
> not be loaded for lack of memory.)
> 
 That may not be entirely correct, at least as far as TC goes. In
Turbo C 2.0 (and, I believe, 1.5, even though it was not
documented), system() will return 0 if command.com was successfully
loaded, and -1 if command.com was not found. I do not know the ANSI
standard on this beast (if indeed there is one), but since MSC and
TC both have it functioning this way, I'm going to assume it's
ANSI. 
 
 You are correct that spawn()/exec() should be used to return the
proper errorlevels. I ran into this exact same problem a few days
ago when I wanted to run a small utility program externally from a
larger program without removing the larger program from memory. An
errorlevel had to be returned and system() didn't seem to want to
do it. I was confused by the TC 1.0 manual and the 2.0 THELP. The
manual stated that the errorlevel was returned, while the THELP
indicated the true condition. Since I only ordered the upgrade to
2.0, I did not receive a full 2.0 manual, and only have the 1.0
description of system(). Fortunately for me, a Borland beta tester
is easily accessable.
                                  
-- 
 "Somebody help me! I'm trapped in this computer!"
  
 Brent Barrett ..pacbell!sactoh0!bkbarret GEMAIL: B.K.BARRETT

wietse@wzv.UUCP (Wietse Z. Venema) (01/25/89)

In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
>Has anyone encountered a problem with the Microsoft C 5.0 compiler always
>returning a 0 from the system() call, no matter what the actual command
>executed by system() returns?

Command.com always returns a zero status. There are two alternatives:

(a) Do not use a shell, but use the spawnlp() functions. These are
    similar to the unix execlp() functions, but instead of over-
    laying the calling process they just suspend it.

(b) Use a different shell. This may not be practical if your program
    is to be used on other machines.

In case of alternative (a) you will have to do your own i/o redirection
handling.  Caveat:  in some cases I had to save the positions of all
stdio streams open for reading from files, and restore them after the
system() routine terminated.
-- 
work:	wswietse@eutrc3.uucp	| Eindhoven University of Technology
work:	wswietse@heitue5.bitnet	| Mathematics and Computing Science
home:	wietse@wzv.uucp		| 5600 MB Eindhoven, The Netherlands

bobmon@iuvax.cs.indiana.edu (RAMontante) (01/25/89)

[ The "system()" returns 0 after invoking COMMAND.COM,
  in MSC and TC on MSDOS machines ]

<646@sactoh0.UUCP> bkbarret@sactoh0.UUCP (Brent K. Barrett):
>
> That may not be entirely correct, at least as far as TC goes. In
>Turbo C 2.0 (and, I believe, 1.5, even though it was not
>documented), system() will return 0 if command.com was successfully
>loaded, and -1 if command.com was not found. I do not know the ANSI
>standard on this beast (if indeed there is one), but since MSC and
>TC both have it functioning this way, I'm going to assume it's
>ANSI. 

"System()" in Turbo C is specifically defined to "...invoke COMMAND.COM
to execute a command...".  In TCv1.5 the return value is described as
the exit status of COMMAND.COM.  Unfortunately (but not surprisingly)
COMMAND.COM exits with a 0 if it successfully loads and runs, whether
the executable file that it was supposed to execute was successful or
not.  So the only information that you can get back from COMMAND.COM is
whether it (loaded and) ran, or crashed the whole dam' machine; nothing
about what it did while it was running.  This has nothing to do with
ANSI, which doesn't specify the behavior of MSDOS.  The C "system()"
call is doing what it should, but what it receives from the operating
system isn't any use to anyone (except in the case of a missing
COMMAND.COM file).

> You are correct that spawn()/exec() should be used to return the
>proper errorlevels.

No problem here, as COMMAND.COM isn't involved.  The executed file is
responsible for returning a meaningful value to spawn() / exec().

ray@ole.UUCP (Ray Berry) (01/26/89)

value from the last program it executed.  There are times when it would be
handy to be able to interrogate that number from the command line.  Does
anyone know a way to do this?   The location of the variable?

       Obviously a short shell could be written in c to execute it and
print the value, but it seems as though it the ERRORLEVEL variable must
be present somewhere in memory. 
	


-- 
Ray Berry  KB7HT uucp: ...{uw-beaver|uiucuxc}tikal!ole!ray CS: 73407,3152 
Seattle Silicon Corp. 3075 112th Ave NE. Bellevue WA 98004 (206) 828 4422

bright@Data-IO.COM (Walter Bright) (01/26/89)

In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
>Has anyone encountered a problem with the Microsoft C 5.0 compiler always
>returning a 0 from the system() call, no matter what the actual command
>executed by system() returns?

system("command") on MS-DOS is usually implemented by running COMMAND.COM
with the argument "/c command". The system() call returns the value that
COMMAND.COM returns. COMMAND.COM does not return the exit status of the
command that it executed, so it's a DOS bug, not a compiler library bug.

The correct solution is to use the spawn() function. spawn() also uses
less memory and executes faster than system(). The only caveats are that
spawn() cannot execute COMMAND.COM's built-in commands like TYPE and DIR,
and spawn() does not do the < | > redirection.

ked@garnet.berkeley.edu (Earl H. Kinmonth) (01/26/89)

In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
>Has anyone encountered a problem with the Microsoft C 5.0 compiler always
>returning a 0 from the system() call, no matter what the actual command
>executed by system() returns?

The same brain dead result occurs with the Turbo C system call.  Presumably
the problem is in command.com.  I wrote my own system() using spawn to get
around this.

Remember, you don't get to be a multi-billion dollar company by doing this
for the conveience of users.

scm@datlog.co.uk ( Steve Mawer ) (01/26/89)

In article <782@hawkmoon.MN.ORG> det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
>Has anyone encountered a problem with the Microsoft C 5.0 compiler always
>returning a 0 from the system() call, no matter what the actual command
>executed by system() returns?
>
>and i'm having a hard time of it since system() always (seems) to return 0!
>

According to my Microsoft manual "The system function returns the value
0 if string is successfully executed.  A return value of -1 indicates an
error ..." and cites the error reasons as being

    E2BIG   - arg list > 128 bytes or env info >32K
    ENOENT  - can't find COMMAND.COM
    ENOEXEC - COMMAND.COM file can't be executed
    ENOMEM  - insufficient memory to execute the command, etc.

What it returns is whether its exec succeeded, not the exec'd command's
status.  I have been burned by this problem, too, and haven't got a
solution. (Anyone?)

-- 
Steve C. Mawer        <scm@datlog.co.uk> or < {backbone}!ukc!datlog!scm >
                       Voice:  +44 1 863 0383 (x2153)

sme@computing-maths.cardiff.ac.uk (Simon Elliott) (02/01/89)

In article <782@hawkmoon.MN.ORG>, det@hawkmoon.MN.ORG (Derek E. Terveer) writes:
> Has anyone encountered a problem with the Microsoft C 5.0 compiler always
> returning a 0 from the system() call, no matter what the actual command
> executed by system() returns?
  
> -- 
> Derek Terveer  det@hawkmoon.MN.ORG || ..!uunet!rosevax!elric!hawkmoon!det

The problem is that system works by constructing a "command /c yourcommand",
thus letting commnad.com do the work of looking down the path, etc.
command.com _always_ succeeds, so system returns 0, always.  You have to do
the work yourself, and use one of the spawn/exec functions if you want
meaningful status information.

I have used this behaviour of command.com in makefiles when i want to
clean up files which may not be there.  Some versions of make will croak
if the file is not there, since the 'del' is a builtin, but command /c del
will always succeed, and the make continues.




-- 
--------------------------------------------------------------------------
Simon Elliott            Internet: sme%v1.cm.cf.ac.uk@cunyvm.cuny.edu
UWCC Computer Centre     JANET:    sme@uk.ac.cf.cm.v1
40/41 Park Place         UUCP:     {backbones}!mcvax!ukc!reading!cf-cm!sme
Cardiff, Wales           PHONE:    +44 222 874300

tp1l+@andrew.cmu.edu (Thomas W. Pope) (02/03/91)

   I am writing a short program to put into my autoexec file, allowing me
to select a shorter autoexec by hitting a key.  For this I tried to use the
system() command to run either of two batch files.  The command works fine, but
the program stays resident after that call, adding 64k to my memory usage.
   The Turbo C manuals say that the system command will run batch files fine,
but it seems to terminate withour clearing memory every time I try it...  Does
anyone know how I could make these calls from my program???  I have tried the
following calls:


   system(default)              system(call default)
   execvp("default.bat")        execvp("dobat.exe",default.bat")
the system calls all ran the batch files correctly, but the program still
didn't exit gracefully.  The execvp() calls wouldn't recognise either the
batch files or the dobat.exe with the batch files as parameters.
   Any help would be greatly appreciated...


  Thanks in advance

   -Thomas Pope

P.S.  Dobat.exe is a shareware program that allows you to call a batch file
      from within another batch file, and return to the calling file
      when finished.

jdb@reef.cis.ufl.edu (Brian K. W. Hook) (02/04/91)

In article <obetOdy00UzxA2Ya89@andrew.cmu.edu> tp1l+@andrew.cmu.edu (Thomas W. Pope) writes:
|>
|>   I am writing a short program to put into my autoexec file, allowing me
|>to select a shorter autoexec by hitting a key.  For this I tried to use the
|>system() command to run either of two batch files.  The command works fine, but
|>the program stays resident after that call, adding 64k to my memory usage.
|>   The Turbo C manuals say that the system command will run batch files fine,
|>but it seems to terminate withour clearing memory every time I try it...  Does
|>anyone know how I could make these calls from my program???  I have tried the
|>following calls:
|>
|>
|>   system(default)              system(call default)
|>   execvp("default.bat")        execvp("dobat.exe",default.bat")

I know that in DOS if you call a batch file from another batch file that it
will not return unless you state specifically that what you are doing is
calling a BAT file....e.g.

CALL DEFAULT.BAT

Does your program get past the system() command?  If not, then it is likely
that it is getting stuck after that .BAT file....the system() command
executes a command and then returns to the calling process, so I would
presume that you would want to return....if you don't want to return to
the calling process don't use system()....in other words, if you are
chaining your main program to your batch program, without returning to
the main program, don't use system().

Execxx (xx are the various incarnations you can use) should work, but I
am not familiar enough with them....have you considered using errorlevels?
The DOS manual states how errorlevels are used, and errorlevels are very
easy to set with a program...it's simply the return value of main().

E.g. (not sure if syntax is exact)

getbat
if errorlevel==1 call bat1.bat
if errorlevel==2 call bat2.bat

However, I believe that errorlevel evaluates to true if the current errorlevel
is equal to or higher than what you are comparing it to....so that example
isn't exactly correct....

Hope this muddle sort of helped,

comp.os.msdos.programmer might be able to help out a bit more.

hp@vmars.tuwien.ac.at (Peter Holzer) (02/10/91)

tp1l+@andrew.cmu.edu (Thomas W. Pope) writes:


>   I am writing a short program to put into my autoexec file, allowing me
>to select a shorter autoexec by hitting a key.  For this I tried to use the
>system() command to run either of two batch files.  The command works fine, but
>the program stays resident after that call, adding 64k to my memory usage.
>   The Turbo C manuals say that the system command will run batch files fine,
>but it seems to terminate withour clearing memory every time I try it...  Does
>anyone know how I could make these calls from my program???  I have tried the
>following calls:


>   system(default)              system(call default)
Shouldn't this be:
system ("default"); and system ("call default"); ?

Apart from that, does your batchfile invoke any TSRs? If it does, it
will fragment your memory, and DOS will report only the largest chunk as
free memory, although it can use the rest as well.

Your memory looks something like that (low addresses at the bottom:

	    
	Command.com
	DOS

Start your program:

	yourprog.exe
	Command.com
	DOS

system ("default"):

	command.com -c default
	yourprog.exe
	Command.com
	DOS

default now executes some TSR, e.g. sidekick:

	sidekick
	command.com -c default
	yourprog.exe
	Command.com
	DOS

default terminates, thus command.com and system terminate, too:

	sidekick
	<empty space>
	yourprog.exe
	Command.com
	DOS

Then your program terminates:

	sidekick
	<empty space>
	<empty space>
	Command.com
	DOS

So you have sidekick floating around somewhere in mid-memory, with a
whole of ~64kB below it and a larger hole above it. DOS will always use
the largest available whole and it cannot split a program to use
multiple wholes so you have wasted those 64kB :-(.

--
|    _  | Peter J. Holzer                       | Think of it   |
| |_|_) | Technical University Vienna           | as evolution  |
| | |   | Dept. for Real-Time Systems           | in action!    |
| __/   | hp@vmars.tuwien.ac.at                 |     Tony Rand |

francis@atmos.cse.ogi.edu (Francis Moraes) (06/10/91)

I compiled the following program using Turbo C under all of its memory
models:

main()
{
   system("vtsr");
}

Vtsr is a program that lists the programs in memory and the amount of memory
allocated to it. The amount of memory in kilobytes used by this program are
given below for each of the memory models:

model	memory usage
====================
tiny	64.2
small	66.7
compact	9.0
medium	66.8
large	10.0
huge	10.0

I think it is interesting that the memory models that use far pointers for
data have smaller memory usage than those with near data pointers. Does anyone
know why this is so?  The same problem exists with the exec() function. I
hope this isn't a stupid question. Send me mail or post as you see fit. If
I get enough mail I will post a summary.

francis@atmos.ogi.edu