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