diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 12:54:45 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 12:54:45 +0300 |
commit | f20ab7c3039a4023f41372bfe4bde3b16d481df7 (patch) | |
tree | 4425de8c6177df655f165cb61d70d0acb5fdc968 /pc/popen.c | |
parent | 6607eb3d5e40b98d2acc8f6b0d6a0b5a4b0f56bd (diff) | |
download | egawk-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.c | 143 |
1 files changed, 140 insertions, 3 deletions
@@ -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); |