1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*
* Cygwin extras
*/
#include "EXTERN.h"
#include "perl.h"
#undef USE_DYNAMIC_LOADING
#include "XSUB.h"
#include <unistd.h>
#include <process.h>
/*
* pp_system() implemented via spawn()
* - more efficient and useful when embedding Perl in non-Cygwin apps
* - code mostly borrowed from djgpp.c
*/
static int
do_spawnvp (const char *path, const char * const *argv)
{
dTHX;
Sigsave_t ihand,qhand;
int childpid, result, status;
rsignal_save(SIGINT, SIG_IGN, &ihand);
rsignal_save(SIGQUIT, SIG_IGN, &qhand);
childpid = spawnvp(_P_NOWAIT,path,argv);
if (childpid < 0) {
status = -1;
if(ckWARN(WARN_EXEC))
Perl_warner(aTHX_ packWARN(WARN_EXEC),"Can't spawn \"%s\": %s",
path,Strerror (errno));
} else {
do {
result = wait4pid(childpid, &status, 0);
} while (result == -1 && errno == EINTR);
if(result < 0)
status = -1;
}
(void)rsignal_restore(SIGINT, &ihand);
(void)rsignal_restore(SIGQUIT, &qhand);
return status;
}
int
do_aspawn (SV *really, void **mark, void **sp)
{
dTHX;
int rc;
char **a,*tmps,**argv;
STRLEN n_a;
if (sp<=mark)
return -1;
a=argv=(char**) alloca ((sp-mark+3)*sizeof (char*));
while (++mark <= sp)
if (*mark)
*a++ = SvPVx(*mark, n_a);
else
*a++ = "";
*a = Nullch;
if (argv[0][0] != '/' && argv[0][0] != '\\'
&& !(argv[0][0] && argv[0][1] == ':'
&& (argv[0][2] == '/' || argv[0][2] != '\\'))
) /* will swawnvp use PATH? */
TAINT_ENV(); /* testing IFS here is overkill, probably */
if (really && *(tmps = SvPV(really, n_a)))
rc=do_spawnvp (tmps,(const char * const *)argv);
else
rc=do_spawnvp (argv[0],(const char *const *)argv);
return rc;
}
int
do_spawn (char *cmd)
{
dTHX;
char **a,*s,*metachars = "$&*(){}[]'\";\\?>|<~`\n";
const char *command[4];
while (*cmd && isSPACE(*cmd))
cmd++;
if (strnEQ (cmd,"/bin/sh",7) && isSPACE (cmd[7]))
cmd+=5;
/* save an extra exec if possible */
/* see if there are shell metacharacters in it */
if (strstr (cmd,"..."))
goto doshell;
if (*cmd=='.' && isSPACE (cmd[1]))
goto doshell;
if (strnEQ (cmd,"exec",4) && isSPACE (cmd[4]))
goto doshell;
for (s=cmd; *s && isALPHA (*s); s++) ; /* catch VAR=val gizmo */
if (*s=='=')
goto doshell;
for (s=cmd; *s; s++)
if (strchr (metachars,*s))
{
if (*s=='\n' && s[1]=='\0')
{
*s='\0';
break;
}
doshell:
command[0] = "sh";
command[1] = "-c";
command[2] = cmd;
command[3] = NULL;
return do_spawnvp("sh",command);
}
New (1303,PL_Argv,(s-cmd)/2+2,char*);
PL_Cmd=savepvn (cmd,s-cmd);
a=PL_Argv;
for (s=PL_Cmd; *s;) {
while (*s && isSPACE (*s)) s++;
if (*s)
*(a++)=s;
while (*s && !isSPACE (*s)) s++;
if (*s)
*s++='\0';
}
*a=Nullch;
if (!PL_Argv[0])
return -1;
return do_spawnvp(PL_Argv[0],(const char * const *)PL_Argv);
}
/* see also Cwd.pm */
static
XS(Cygwin_cwd)
{
dXSARGS;
char *cwd;
if(items != 0)
Perl_croak(aTHX_ "Usage: Cwd::cwd()");
if((cwd = getcwd(NULL, -1))) {
ST(0) = sv_2mortal(newSVpv(cwd, 0));
safesysfree(cwd);
#ifndef INCOMPLETE_TAINTS
SvTAINTED_on(ST(0));
#endif
XSRETURN(1);
}
XSRETURN_UNDEF;
}
void
init_os_extras(void)
{
char *file = __FILE__;
dTHX;
newXS("Cwd::cwd", Cygwin_cwd, file);
}
|