~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to pc/popen.c

  • Committer: Arnold D. Robbins
  • Date: 2010-07-16 09:54:45 UTC
  • Revision ID: git-v1:f20ab7c3039a4023f41372bfe4bde3b16d481df7
Tags: gawk-3.0.4
Move to gawk-3.0.4.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include "popen.h"
 
1
#include <stdio.h>
2
2
#include <stdlib.h>
3
3
#include <io.h>
4
4
#include <string.h>
11
11
#endif
12
12
#endif
13
13
 
 
14
#if defined(WIN32) && defined(_MSC_VER)
 
15
#define popen _popen
 
16
#define pclose _pclose
 
17
#endif
 
18
 
14
19
#ifndef _NFILE
15
20
#define _NFILE 40
16
21
#endif
24
29
    pipemode pmode;
25
30
} pipes[_NFILE];
26
31
 
 
32
 
 
33
/*
 
34
 * For systems where system() and popen() do not follow SHELL:
 
35
 *  1. Write command to temp file.  Temp filename must have slashes
 
36
 *     compatible with SHELL (if set) or COMSPEC.
 
37
 *  2. Convert slashes in SHELL (if present) to be compatible with COMSPEC.
 
38
 * Currently, only MSC (running under DOS) and MINGW versions are managed.
 
39
 */
 
40
 
 
41
#if defined(_MSC_VER) || defined(__MINGW32__)
 
42
 
 
43
static int
 
44
unixshell(p)
 
45
char *p;
 
46
{
 
47
  static char *shell[] = {"sh", "bash", "csh", "tcsh", "sh32", "sh16", "ksh", NULL};
 
48
  char **shellp = shell, *s, *q;
 
49
 
 
50
  if (p == NULL) return (0);
 
51
  s = p = strdup(p);
 
52
  if ((q = strrchr(p, '\\')) != NULL)
 
53
    p = q + 1;
 
54
  if ((q = strrchr(p, '/')) != NULL)
 
55
    p = q + 1;
 
56
  if ((q = strchr(p, '.')) != NULL)
 
57
    *q = '\0';
 
58
  strlwr(p);
 
59
  do {
 
60
    if (strcmp(*shellp, p) == 0) break;
 
61
  } while (*++shellp);
 
62
  free(s);
 
63
  return(*shellp ? 1 : 0);
 
64
}
 
65
 
 
66
static char *
 
67
slashify(p, s)
 
68
char *p, *s;
 
69
{
 
70
  if (unixshell(s))
 
71
    while (s = strchr(p, '\\')) *s = '/';
 
72
  else
 
73
    while (s = strchr(p, '/')) *s = '\\';
 
74
  return(p);
 
75
}
 
76
 
 
77
static char *
 
78
scriptify(command)
 
79
char *command;
 
80
{
 
81
  FILE *fp;
 
82
  char *cmd, *name, *s, *p;
 
83
  int i;
 
84
 
 
85
  if((name = tempnam(".", "pip")) == NULL) return(NULL);
 
86
  p = getenv("COMSPEC"); s = getenv("SHELL");
 
87
  cmd = malloc(strlen(name) + (s ? strlen(s) : 0) + 9); *cmd = '\0';
 
88
  if (s) {
 
89
    slashify(strcpy(cmd, s), p);
 
90
    p = s;
 
91
  }
 
92
  slashify(name, p);
 
93
  if (! unixshell(p)) {
 
94
    realloc(name, strlen(name) + 5);
 
95
    strcat(name, ".bat");
 
96
  }
 
97
  if (s) sprintf(cmd + strlen(cmd), " %cc ", unixshell(s) ? '-' : '/');
 
98
  strcpy(p = cmd + strlen(cmd), name); free(name);
 
99
 
 
100
  i = strlen(command);
 
101
  if ( ((fp = fopen(p, "wb")) == NULL) || (fwrite(command, 1, i, fp) < i)
 
102
       || (fputc('\n', fp) == EOF)) {
 
103
    cmd = NULL; 
 
104
  }
 
105
  if (fp) fclose(fp); 
 
106
  return(cmd);
 
107
}
 
108
 
 
109
static void
 
110
unlink_and_free(cmd)
 
111
char *cmd;
 
112
{
 
113
  char *s;
 
114
 
 
115
  if (s = strrchr(cmd, ' '))
 
116
    s++;
 
117
  else
 
118
    s = cmd;
 
119
  unlink(s); free(cmd);
 
120
}
 
121
 
 
122
int
 
123
os_system(cmd)
 
124
char *cmd;
 
125
{
 
126
  char *s;
 
127
  int i;
 
128
 
 
129
#if defined(OS2)
 
130
  if (_osmode == OS2_MODE)
 
131
    return(system(cmd));
 
132
#endif
 
133
 
 
134
  if ((cmd = scriptify(cmd)) == NULL) return(1);
 
135
  if (s = getenv("SHELL"))
 
136
    i = spawnlp(P_WAIT, s, s, cmd + strlen(s), NULL);
 
137
  else
 
138
    i = system(cmd);
 
139
  unlink_and_free(cmd);
 
140
  return(i);
 
141
}
 
142
#else
 
143
#define os_system(cmd) system(cmd)
 
144
#endif
 
145
 
 
146
 
27
147
FILE *
28
148
os_popen( char *command, char *mode ) {
29
149
    FILE *current;
45
165
        curmode = writing;
46
166
    else
47
167
        return NULL;
 
168
 
 
169
#if defined(__MINGW32__) || (defined(_MSC_VER) && defined(WIN32))
 
170
    current = popen(command = scriptify(command), mode);
 
171
    cur = fileno(current);
 
172
    pipes[cur].pmode = curmode;
 
173
    pipes[cur].command = command;
 
174
    return(current);
 
175
#endif
 
176
 
48
177
    /*
49
178
    ** get a name to use.
50
179
    */
55
184
    ** output.
56
185
    */
57
186
    if(curmode == reading) {
 
187
        FILE *fp;
58
188
        if ((cur = dup(fileno(stdout))) == -1)
59
189
            return NULL;
60
190
        if ((current = freopen(name, "w", stdout)) == NULL)
61
191
            return NULL;
62
 
        system(command);
 
192
        os_system(command);
63
193
        if (dup2(cur, fileno(stdout)) == -1)
64
194
            return NULL;
65
195
        close(cur);
85
215
      return(pclose(current));
86
216
#endif
87
217
 
 
218
#if defined(__MINGW32__) || (defined(_MSC_VER) && defined(WIN32))
 
219
    rval = pclose(current);
 
220
    pipes[cur].pmode = unopened;
 
221
    unlink_and_free(pipes[cur].command);
 
222
    return rval;
 
223
#endif
 
224
 
88
225
    /*
89
226
    ** check for an open file.
90
227
    */
106
243
        rval = -1;
107
244
        if ((fd = dup(fileno(stdin))) != -1) {
108
245
          if (current = freopen(pipes[cur].name, "r", stdin)) {
109
 
            rval = system(pipes[cur].command);
 
246
            rval = os_system(pipes[cur].command);
110
247
            fclose(current);
111
248
            if (dup2(fd, fileno(stdin)) == -1) rval = -1;
112
249
            close(fd);