1 #include <libc/stubs.h>
12 #include <sys/fsext.h>
18 #if DJGPP==2 && DJGPP_MINOR<2
20 /* XXX I should rewrite this stuff someday. ML */
22 /* This is from popen.c */
24 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
25 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
26 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
28 /* hold file pointer, descriptor, command, mode, temporary file name,
29 and the status of the command */
34 char *command, mode[10], temp_name[L_tmpnam];
35 struct pipe_list *next;
38 /* static, global list pointer */
39 static struct pipe_list *pl = NULL;
42 popen (const char *cm, const char *md) /* program name, pipe mode */
47 if ((l1 = (struct pipe_list *) malloc (sizeof (struct pipe_list))) == NULL)
50 /* zero out elements to we'll get here */
55 /* stick in elements we know already */
57 strcpy (l1->mode, md);
58 if (tmpnam (l1->temp_name) == NULL)
61 /* if can save the program name, build temp file */
62 if ((l1->command = malloc(strlen(cm)+1)))
64 strcpy(l1->command, cm);
65 /* if caller wants to read */
66 if (l1->mode[0] == 'r')
69 if ((l1->fd = dup (fileno (stdout))) == EOF)
71 else if (!(l1->fp = freopen (l1->temp_name, "wb", stdout)))
76 if ((l1->exit_status = system (cm)) == EOF)
79 /* reopen real stdout */
80 if (dup2 (l1->fd, fileno (stdout)) == EOF)
83 /* open file for reader */
84 l1->fp = fopen (l1->temp_name, l1->mode);
88 /* if caller wants to write */
89 if (l1->mode[0] == 'w')
91 l1->fp = fopen (l1->temp_name, l1->mode);
96 return l1->fp; /* return == NULL ? ERROR : OK */
102 struct pipe_list *l1, *l2; /* list pointers */
103 int retval=0; /* function return value */
105 /* if pointer is first node */
108 /* save node and take it out the list */
113 /* if more than one node in list */
116 /* find right node */
117 for (l2 = pl, l1 = pl->next; l1; l2 = l1, l1 = l2->next)
121 /* take node out of list */
127 /* if FILE not in list - return error */
130 /* close the (hopefully) popen()ed file */
133 /* if pipe was opened to write */
134 if (l1->mode[0] == 'w')
137 if ((l1->fd = dup (fileno (stdin))) == EOF)
140 /* open temp stdin */
141 if (!(l1->fp = freopen (l1->temp_name, "rb", stdin)))
145 if ((retval = system (l1->command)) != EOF)
148 if (dup2 (l1->fd, fileno (stdin)) == EOF)
154 /* if pipe was opened to read, return the exit status we saved */
155 if (l1->mode[0] == 'r')
156 retval = l1->exit_status;
161 remove (l1->temp_name); /* remove temporary file */
162 free (l1->command); /* dealloc memory */
163 free (l1); /* dealloc memory */
165 return retval; /* retval==0 ? OK : ERROR */
172 #define EXECF_SPAWN 0
176 convretcode (int rc,char *prog,int fl)
178 if (rc < 0 && dowarn)
179 warn ("Can't %s \"%s\": %s",fl ? "exec" : "spawn",prog,Strerror (errno));
188 do_aspawn (SV *really,SV **mark,SV **sp)
192 char **a,*tmps,**argv;
196 a=argv=(char**) alloca ((sp-mark+3)*sizeof (char*));
200 *a++ = SvPVx(*mark, na);
205 if (argv[0][0] != '/' && argv[0][0] != '\\'
206 && !(argv[0][0] && argv[0][1] == ':'
207 && (argv[0][2] == '/' || argv[0][2] != '\\'))
208 ) /* will swawnvp use PATH? */
209 TAINT_ENV(); /* testing IFS here is overkill, probably */
211 if (really && *(tmps = SvPV(really, na)))
212 rc=spawnvp (P_WAIT,tmps,argv);
214 rc=spawnvp (P_WAIT,argv[0],argv);
216 return convretcode (rc,argv[0],EXECF_SPAWN);
219 #define EXTRA "\x00\x00\x00\x00\x00\x00"
222 do_spawn2 (char *cmd,int execf)
224 char **a,*s,*shell,*metachars;
227 if ((shell=getenv("SHELL"))==NULL && (shell=getenv("COMSPEC"))==NULL)
228 shell="c:\\command.com" EXTRA;
230 unixysh=_is_unixy_shell (shell);
231 metachars=unixysh ? "$&*(){}[]'\";\\?>|<~`\n" EXTRA : "*?[|<>\"\\" EXTRA;
233 while (*cmd && isSPACE(*cmd))
236 if (strnEQ (cmd,"/bin/sh",7) && isSPACE (cmd[7]))
239 /* save an extra exec if possible */
240 /* see if there are shell metacharacters in it */
241 if (strstr (cmd,"..."))
245 if (*cmd=='.' && isSPACE (cmd[1]))
247 if (strnEQ (cmd,"exec",4) && isSPACE (cmd[4]))
249 for (s=cmd; *s && isALPHA (*s); s++) ; /* catch VAR=val gizmo */
254 if (strchr (metachars,*s))
256 if (*s=='\n' && s[1]=='\0')
262 if (execf==EXECF_EXEC)
263 return convretcode (execl (shell,shell,unixysh ? "-c" : "/c",cmd,NULL),cmd,execf);
264 return convretcode (system (cmd),cmd,execf);
267 New (1303,Argv,(s-cmd)/2+2,char*);
268 Cmd=savepvn (cmd,s-cmd);
271 while (*s && isSPACE (*s)) s++;
274 while (*s && !isSPACE (*s)) s++;
282 if (execf==EXECF_EXEC)
283 rc=execvp (Argv[0],Argv);
285 rc=spawnvp (P_WAIT,Argv[0],Argv);
286 return convretcode (rc,Argv[0],execf);
292 return do_spawn2 (cmd,EXECF_SPAWN);
298 do_spawn2 (cmd,EXECF_EXEC);
311 #define MAXOPENGLOBS 10
313 static struct globinfo myglobs[MAXOPENGLOBS];
315 static struct globinfo *
319 for (ic=0; ic<MAXOPENGLOBS; ic++)
320 if (myglobs[ic].fd==fd)
326 glob_handler (__FSEXT_Fnumber n,int *rv,va_list args)
334 char *p1,*pattern,*name=va_arg (args,char*);
338 if (strnNE (name,"/dev/dosglob/",13))
340 if ((gi=searchfd (-1)) == NULL)
343 pattern=alloca (strlen (name+=13)+1);
344 strcpy (pattern,name);
351 if ((p1=strchr (pattern,' '))!=NULL)
353 glob (pattern,ic,0,&pglob);
355 if ((pattern=p1)!=NULL)
358 for (ic=len=0; ic<pglob.gl_pathc; ic++)
359 len+=1+strlen (pglob.gl_pathv[ic]);
362 if ((gi->matches=p1=(char*) malloc (gi->size=len))==NULL)
364 for (ic=0; ic<pglob.gl_pathc; ic++)
366 strcpy (p1,pglob.gl_pathv[ic]);
372 if ((gi->matches=strdup (name))==NULL)
374 gi->size=strlen (name)+1;
377 gi->fd=*rv=__FSEXT_alloc_fd (glob_handler);
382 int fd=va_arg (args,int);
383 char *buf=va_arg (args,char*);
384 size_t siz=va_arg (args,size_t);
386 if ((gi=searchfd (fd))==NULL)
390 if (siz+ic>=gi->size)
392 memcpy (buf,ic+gi->matches,siz);
399 int fd=va_arg (args,int);
401 if ((gi=searchfd (fd))==NULL)
419 croak ("Usage: Dos::GetCwd()");
421 char tmp[PATH_MAX+2];
422 ST(0)=sv_newmortal ();
423 if (getcwd (tmp,PATH_MAX+1)!=NULL)
424 sv_setpv ((SV*)ST(0),tmp);
433 XSRETURN_IV (_USE_LFN);
439 char *file = __FILE__;
443 newXS ("Dos::GetCwd",dos_GetCwd,file);
444 newXS ("Dos::UseLFN",dos_UseLFN,file);
446 /* install my File System Extension for globbing */
447 __FSEXT_add_open_handler (glob_handler);
448 memset (myglobs,-1,sizeof (myglobs));
451 static char *perlprefix;
453 #define PERL5 "/perl5"
455 char *djgpp_pathexp (const char *p)
457 static char expp[PATH_MAX];
458 strcpy (expp,perlprefix);
462 strcat (expp,"/bin");
465 strcat (expp,"/lib" PERL5 "/site");
468 strcat (expp,"/lib" PERL5);
475 Perl_DJGPP_init (int *argcp,char ***argvp)
479 perlprefix=strdup (**argvp);
481 if ((p=strrchr (perlprefix,'/'))!=NULL)
484 if (strEQ (p-4,"/bin"))
488 strcpy (perlprefix,"..");