home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD2.mdf
/
c
/
tools
/
make
/
make_pd
/
msdos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-02-01
|
5KB
|
164 lines
/* msdos.c */
/*
Microsoft C-dependent functions for Make. Originally written by Rahul
Dhesi for Atoz in 1986. Modified for use with the P.D. make utility
in February 1987. Released to the public domain.
*/
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h> /* function definitions: getenv() and others */
#include "intdos.h" /* registers for MS-DOS interrupts */
#include <process.h> /* function definitions: spawn()/exec()/system() */
int break_hit; /* flag set on user interrupt */
int handle_break(); /* routine to set flag on user interrupt */
int (*oldsignal)(); /* to save old signal() handler */
/*******************/
/*
dosswitch() accepts a character specifying a switch character. If
the character is null, dosswitch() simply returns the current DOS
switch character. If it is not null, the DOS switch character is set
to the received character and the newly-set character returned by DOS
is returned as the function value.
*/
unsigned int dosswitch (switchar)
int switchar;
{
union REGS regs;
if (switchar == '\0')
regs.h.al = 0; /* get switch character code */
else {
regs.h.al = 1; /* set switch character code */
regs.h.dl = switchar; /* char to set switch to */
}
regs.h.ah = 0x37; /* get or set switch DOS call */
intdos (®s, ®s);
return ((unsigned int) regs.h.dl); /* return current switch char */
}
/*******************/
/*
subp() executes a subprocess then returns. It breaks up the received
command line into a command name (first word) and a parameter list
(rest of string) before executing the subprocess. The environment
of the subprocess is a copy of the parent's environment. Return
value is -1 if the subprocess could not be created, otherwise it is
the exit status of the subprocess. The command interpreter is NOT
executed, so DOS commands such as DIR canot be directly used here.
*/
int subp (command)
char *command;
{
int status;
char progname[80];
char args[128];
int i, j;
progname[0] = '\0';
args[0] = '\0';
/* skip leading white space */
i = 0;
while (command[i] == ' ' || command[i] == '\t')
i++;
/* progname gets program name, args gets rest of command string */
while (command[i] != ' '&& command[i] != '\t' && command[i] != '\0') {
progname[i] = command[i];
i++;
}
progname[i] = '\0';
while (command[i] == ' ' || command[i] == '\t')
i++;
for (j = 0; command[i] != '\0'; )
args[j++] = command[i++];
args[j] = '\0';
#ifdef DEBUG
printf ("subp: progname=[%s], args=[%s].\n", progname, args);
#endif
if (args[0] == '\0')
status = spawnlp (P_WAIT, progname, progname, NULL);
else
status = spawnlp (P_WAIT, progname, progname, args, NULL);
return (status);
}
/*******************/
/* system() executes a system command but, unlike the system() function
in the Microsoft C library, it doesn't choke if the DOS switch character
is not "/". Return value is -1 on error, 0 otherwise.
Due to serious bugs in MS-DOS, commands executed by COMMAND.COM never
return an error status. To overcome this problem, this implementation
of system() attempts to execute the supplied command string directly
on the assumption that it holds the name of an executable program
with parameters. If this attempted execution fails, system() then
invokes the command interpreter. This way we manage to make executable
programs return an error status anyway.
To help allow the user to interrupt command execution, we trap the
user interrupt vector and monitor it. If a user interrupt occurred
during command execution, we return an error status even if the
command was correctly executed. This doesn't always work.
*/
int system(cmd)
char *cmd;
{
int status;
char *comspec;
static char comswitch[] = "/C ";
break_hit = 0;
/* trap user interrupts */
oldsignal = signal (SIGINT, handle_break);
(void) kbhit();
/* Try direct execution. If succeded, return its status */
status = subp (cmd);
if (status != -1) { /* not -1 means executed */
goto finish;
}
/* Reach here if direct execution not possible. Call shell */
comspec = getenv ("COMSPEC");
if (comspec == NULL) {
signal (SIGINT, oldsignal); /* restore old signal handler */
return (-1);
}
if (cmd == NULL || *cmd == '\0') {
status = spawnlp (P_WAIT, comspec, comspec, NULL);
goto finish;
} else {
comswitch[0] = dosswitch ('\0');
status = spawnlp (P_WAIT, comspec, comspec, comswitch, cmd, NULL);
goto finish;
}
finish:
(void) kbhit();
signal (SIGINT, oldsignal); /* restore old signal handler */
if (break_hit)
return (256);
else
return (status);
}
int handle_break()
{
oldsignal = signal (SIGINT, handle_break);
break_hit++;
}