aboutsummaryrefslogtreecommitdiffstats
path: root/pc/popen.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2010-07-16 12:54:45 +0300
committerArnold D. Robbins <arnold@skeeve.com>2010-07-16 12:54:45 +0300
commitf20ab7c3039a4023f41372bfe4bde3b16d481df7 (patch)
tree4425de8c6177df655f165cb61d70d0acb5fdc968 /pc/popen.c
parent6607eb3d5e40b98d2acc8f6b0d6a0b5a4b0f56bd (diff)
downloadegawk-f20ab7c3039a4023f41372bfe4bde3b16d481df7.tar.gz
egawk-f20ab7c3039a4023f41372bfe4bde3b16d481df7.tar.bz2
egawk-f20ab7c3039a4023f41372bfe4bde3b16d481df7.zip
Move to gawk-3.0.4.
Diffstat (limited to 'pc/popen.c')
-rw-r--r--pc/popen.c143
1 files changed, 140 insertions, 3 deletions
diff --git a/pc/popen.c b/pc/popen.c
index c2eca24d..88de3e29 100644
--- a/pc/popen.c
+++ b/pc/popen.c
@@ -1,4 +1,4 @@
-#include "popen.h"
+#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
@@ -11,6 +11,11 @@
#endif
#endif
+#if defined(WIN32) && defined(_MSC_VER)
+#define popen _popen
+#define pclose _pclose
+#endif
+
#ifndef _NFILE
#define _NFILE 40
#endif
@@ -24,6 +29,121 @@ struct {
pipemode pmode;
} pipes[_NFILE];
+
+/*
+ * For systems where system() and popen() do not follow SHELL:
+ * 1. Write command to temp file. Temp filename must have slashes
+ * compatible with SHELL (if set) or COMSPEC.
+ * 2. Convert slashes in SHELL (if present) to be compatible with COMSPEC.
+ * Currently, only MSC (running under DOS) and MINGW versions are managed.
+ */
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+static int
+unixshell(p)
+char *p;
+{
+ static char *shell[] = {"sh", "bash", "csh", "tcsh", "sh32", "sh16", "ksh", NULL};
+ char **shellp = shell, *s, *q;
+
+ if (p == NULL) return (0);
+ s = p = strdup(p);
+ if ((q = strrchr(p, '\\')) != NULL)
+ p = q + 1;
+ if ((q = strrchr(p, '/')) != NULL)
+ p = q + 1;
+ if ((q = strchr(p, '.')) != NULL)
+ *q = '\0';
+ strlwr(p);
+ do {
+ if (strcmp(*shellp, p) == 0) break;
+ } while (*++shellp);
+ free(s);
+ return(*shellp ? 1 : 0);
+}
+
+static char *
+slashify(p, s)
+char *p, *s;
+{
+ if (unixshell(s))
+ while (s = strchr(p, '\\')) *s = '/';
+ else
+ while (s = strchr(p, '/')) *s = '\\';
+ return(p);
+}
+
+static char *
+scriptify(command)
+char *command;
+{
+ FILE *fp;
+ char *cmd, *name, *s, *p;
+ int i;
+
+ if((name = tempnam(".", "pip")) == NULL) return(NULL);
+ p = getenv("COMSPEC"); s = getenv("SHELL");
+ cmd = malloc(strlen(name) + (s ? strlen(s) : 0) + 9); *cmd = '\0';
+ if (s) {
+ slashify(strcpy(cmd, s), p);
+ p = s;
+ }
+ slashify(name, p);
+ if (! unixshell(p)) {
+ realloc(name, strlen(name) + 5);
+ strcat(name, ".bat");
+ }
+ if (s) sprintf(cmd + strlen(cmd), " %cc ", unixshell(s) ? '-' : '/');
+ strcpy(p = cmd + strlen(cmd), name); free(name);
+
+ i = strlen(command);
+ if ( ((fp = fopen(p, "wb")) == NULL) || (fwrite(command, 1, i, fp) < i)
+ || (fputc('\n', fp) == EOF)) {
+ cmd = NULL;
+ }
+ if (fp) fclose(fp);
+ return(cmd);
+}
+
+static void
+unlink_and_free(cmd)
+char *cmd;
+{
+ char *s;
+
+ if (s = strrchr(cmd, ' '))
+ s++;
+ else
+ s = cmd;
+ unlink(s); free(cmd);
+}
+
+int
+os_system(cmd)
+char *cmd;
+{
+ char *s;
+ int i;
+
+#if defined(OS2)
+ if (_osmode == OS2_MODE)
+ return(system(cmd));
+#endif
+
+ if ((cmd = scriptify(cmd)) == NULL) return(1);
+ if (s = getenv("SHELL"))
+ i = spawnlp(P_WAIT, s, s, cmd + strlen(s), NULL);
+ else
+ i = system(cmd);
+ unlink_and_free(cmd);
+ return(i);
+}
+#else
+#define os_system(cmd) system(cmd)
+#endif
+
+
FILE *
os_popen( char *command, char *mode ) {
FILE *current;
@@ -45,6 +165,15 @@ os_popen( char *command, char *mode ) {
curmode = writing;
else
return NULL;
+
+#if defined(__MINGW32__) || (defined(_MSC_VER) && defined(WIN32))
+ current = popen(command = scriptify(command), mode);
+ cur = fileno(current);
+ pipes[cur].pmode = curmode;
+ pipes[cur].command = command;
+ return(current);
+#endif
+
/*
** get a name to use.
*/
@@ -55,11 +184,12 @@ os_popen( char *command, char *mode ) {
** output.
*/
if(curmode == reading) {
+ FILE *fp;
if ((cur = dup(fileno(stdout))) == -1)
return NULL;
if ((current = freopen(name, "w", stdout)) == NULL)
return NULL;
- system(command);
+ os_system(command);
if (dup2(cur, fileno(stdout)) == -1)
return NULL;
close(cur);
@@ -85,6 +215,13 @@ os_pclose( FILE * current) {
return(pclose(current));
#endif
+#if defined(__MINGW32__) || (defined(_MSC_VER) && defined(WIN32))
+ rval = pclose(current);
+ pipes[cur].pmode = unopened;
+ unlink_and_free(pipes[cur].command);
+ return rval;
+#endif
+
/*
** check for an open file.
*/
@@ -106,7 +243,7 @@ os_pclose( FILE * current) {
rval = -1;
if ((fd = dup(fileno(stdin))) != -1) {
if (current = freopen(pipes[cur].name, "r", stdin)) {
- rval = system(pipes[cur].command);
+ rval = os_system(pipes[cur].command);
fclose(current);
if (dup2(fd, fileno(stdin)) == -1) rval = -1;
close(fd);