This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Cleanup from prior patch (Charles Lane?):
[perl5.git] / cygwin / cygwin.c
CommitLineData
5db16f6a
EF
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>
ee8c7f54 11#include <process.h>
5db16f6a 12
ee8c7f54
CB
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{
21 dTHXo;
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;
30 if(ckWARN(WARN_EXEC)) {
31 dTHR;
32 Perl_warner(aTHX_ WARN_EXEC,"Can't spawn \"%s\": %s",
33 path,Strerror (errno));
34 }
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{
50 dTHXo;
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)
61 *a++ = SvPVx(*mark, n_a);
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{
83 dTHXo;
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
122 New (1303,PL_Argv,(s-cmd)/2+2,char*);
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
EF
139
140/* see also Cwd.pm */
141static
142XS(Cygwin_cwd)
143{
144 dXSARGS;
145 char *cwd;
146
147 if(items != 0)
148 Perl_croak(aTHX_ "Usage: Cwd::cwd()");
ee8c7f54 149 if((cwd = getcwd(NULL, 0))) {
5db16f6a
EF
150 ST(0) = sv_2mortal(newSVpv(cwd, 0));
151 safesysfree(cwd);
152 XSRETURN(1);
153 }
154 XSRETURN_UNDEF;
155}
156
157void
158init_os_extras(void)
159{
160 char *file = __FILE__;
161 dTHX;
162
163 newXS("Cwd::cwd", Cygwin_cwd, file);
164}