Compress::Raw::Zlib doesn't need ppport.h in core [REVISED]
[p5sagit/p5-mst-13.2.git] / cygwin / cygwin.c
CommitLineData
5db16f6a 1/*
2 * Cygwin extras
3 */
4
5#include "EXTERN.h"
6#include "perl.h"
7#undef USE_DYNAMIC_LOADING
8#include "XSUB.h"
9
6b49d266 10#include <unistd.h>
b4bcd662 11#include <process.h>
49fd6edc 12#include <sys/cygwin.h>
6d7e4387 13#include <alloca.h>
5db16f6a 14
b4bcd662 15/*
16 * pp_system() implemented via spawn()
17 * - more efficient and useful when embedding Perl in non-Cygwin apps
18 * - code mostly borrowed from djgpp.c
19 */
20static int
21do_spawnvp (const char *path, const char * const *argv)
22{
acfe0abc 23 dTHX;
b4bcd662 24 Sigsave_t ihand,qhand;
25 int childpid, result, status;
26
ec1aec95 27 rsignal_save(SIGINT, (Sighandler_t) SIG_IGN, &ihand);
28 rsignal_save(SIGQUIT, (Sighandler_t) SIG_IGN, &qhand);
b4bcd662 29 childpid = spawnvp(_P_NOWAIT,path,argv);
30 if (childpid < 0) {
31 status = -1;
411caa50 32 if(ckWARN(WARN_EXEC))
f98bc0c6 33 Perl_warner(aTHX_ packWARN(WARN_EXEC),"Can't spawn \"%s\": %s",
b4bcd662 34 path,Strerror (errno));
b4bcd662 35 } else {
36 do {
37 result = wait4pid(childpid, &status, 0);
38 } while (result == -1 && errno == EINTR);
39 if(result < 0)
40 status = -1;
41 }
42 (void)rsignal_restore(SIGINT, &ihand);
43 (void)rsignal_restore(SIGQUIT, &qhand);
44 return status;
45}
46
47int
48do_aspawn (SV *really, void **mark, void **sp)
49{
acfe0abc 50 dTHX;
b4bcd662 51 int rc;
52 char **a,*tmps,**argv;
53 STRLEN n_a;
54
55 if (sp<=mark)
56 return -1;
57 a=argv=(char**) alloca ((sp-mark+3)*sizeof (char*));
58
59 while (++mark <= sp)
60 if (*mark)
667e2948 61 *a++ = SvPVx((SV *)*mark, n_a);
b4bcd662 62 else
63 *a++ = "";
64 *a = Nullch;
65
66 if (argv[0][0] != '/' && argv[0][0] != '\\'
67 && !(argv[0][0] && argv[0][1] == ':'
68 && (argv[0][2] == '/' || argv[0][2] != '\\'))
69 ) /* will swawnvp use PATH? */
70 TAINT_ENV(); /* testing IFS here is overkill, probably */
71
72 if (really && *(tmps = SvPV(really, n_a)))
73 rc=do_spawnvp (tmps,(const char * const *)argv);
74 else
75 rc=do_spawnvp (argv[0],(const char *const *)argv);
76
77 return rc;
78}
79
80int
81do_spawn (char *cmd)
82{
acfe0abc 83 dTHX;
b4bcd662 84 char **a,*s,*metachars = "$&*(){}[]'\";\\?>|<~`\n";
85 const char *command[4];
86
87 while (*cmd && isSPACE(*cmd))
88 cmd++;
89
90 if (strnEQ (cmd,"/bin/sh",7) && isSPACE (cmd[7]))
91 cmd+=5;
92
93 /* save an extra exec if possible */
94 /* see if there are shell metacharacters in it */
95 if (strstr (cmd,"..."))
96 goto doshell;
97 if (*cmd=='.' && isSPACE (cmd[1]))
98 goto doshell;
99 if (strnEQ (cmd,"exec",4) && isSPACE (cmd[4]))
100 goto doshell;
101 for (s=cmd; *s && isALPHA (*s); s++) ; /* catch VAR=val gizmo */
102 if (*s=='=')
103 goto doshell;
104
105 for (s=cmd; *s; s++)
106 if (strchr (metachars,*s))
107 {
108 if (*s=='\n' && s[1]=='\0')
109 {
110 *s='\0';
111 break;
112 }
113 doshell:
114 command[0] = "sh";
115 command[1] = "-c";
116 command[2] = cmd;
117 command[3] = NULL;
118
119 return do_spawnvp("sh",command);
120 }
121
a02a5408 122 Newx (PL_Argv,(s-cmd)/2+2,char*);
b4bcd662 123 PL_Cmd=savepvn (cmd,s-cmd);
124 a=PL_Argv;
125 for (s=PL_Cmd; *s;) {
126 while (*s && isSPACE (*s)) s++;
127 if (*s)
128 *(a++)=s;
129 while (*s && !isSPACE (*s)) s++;
130 if (*s)
131 *s++='\0';
132 }
133 *a=Nullch;
134 if (!PL_Argv[0])
135 return -1;
136
137 return do_spawnvp(PL_Argv[0],(const char * const *)PL_Argv);
138}
5db16f6a 139
140/* see also Cwd.pm */
5db16f6a 141XS(Cygwin_cwd)
142{
143 dXSARGS;
144 char *cwd;
145
146 if(items != 0)
147 Perl_croak(aTHX_ "Usage: Cwd::cwd()");
47dafe4d 148 if((cwd = getcwd(NULL, -1))) {
5db16f6a 149 ST(0) = sv_2mortal(newSVpv(cwd, 0));
a236cecb 150 free(cwd);
6be3b590 151#ifndef INCOMPLETE_TAINTS
152 SvTAINTED_on(ST(0));
153#endif
5db16f6a 154 XSRETURN(1);
155 }
156 XSRETURN_UNDEF;
157}
158
49fd6edc 159XS(XS_Cygwin_pid_to_winpid)
160{
161 dXSARGS;
d2dc0126 162 dXSTARG;
163 pid_t pid, RETVAL;
164
49fd6edc 165 if (items != 1)
166 Perl_croak(aTHX_ "Usage: Cygwin::pid_to_winpid(pid)");
d2dc0126 167
168 pid = (pid_t)SvIV(ST(0));
169
49fd6edc 170 if ((RETVAL = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, pid)) > 0) {
171 XSprePUSH; PUSHi((IV)RETVAL);
172 XSRETURN(1);
173 }
174 XSRETURN_UNDEF;
175}
176
49fd6edc 177XS(XS_Cygwin_winpid_to_pid)
178{
179 dXSARGS;
d2dc0126 180 dXSTARG;
181 pid_t pid, RETVAL;
182
49fd6edc 183 if (items != 1)
184 Perl_croak(aTHX_ "Usage: Cygwin::winpid_to_pid(pid)");
d2dc0126 185
186 pid = (pid_t)SvIV(ST(0));
187
49fd6edc 188 if ((RETVAL = cygwin32_winpid_to_pid(pid)) > 0) {
189 XSprePUSH; PUSHi((IV)RETVAL);
190 XSRETURN(1);
191 }
192 XSRETURN_UNDEF;
193}
194
195
5db16f6a 196void
197init_os_extras(void)
198{
199 char *file = __FILE__;
78ff2d7b 200 CV *cv;
5db16f6a 201 dTHX;
202
203 newXS("Cwd::cwd", Cygwin_cwd, file);
49fd6edc 204 newXS("Cygwin::winpid_to_pid", XS_Cygwin_winpid_to_pid, file);
205 newXS("Cygwin::pid_to_winpid", XS_Cygwin_pid_to_winpid, file);
78ff2d7b 206
207 if ((cv = get_cv("Win32CORE::bootstrap", 0))) {
208 dSP;
209 PUSHMARK(SP);
210 (void)call_sv((SV *)cv, G_EVAL|G_DISCARD|G_VOID);
211 }
5db16f6a 212}