Subversion Repositories SvarDOS

Rev

Rev 538 | Rev 575 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 538 Rev 543
Line 22... Line 22...
22
 * DEALINGS IN THE SOFTWARE.
22
 * DEALINGS IN THE SOFTWARE.
23
 */
23
 */
24
 
24
 
25
#include <string.h> /* memset() */
25
#include <string.h> /* memset() */
26
 
26
 
-
 
27
#include "env.h"
27
#include "helpers.h"
28
#include "helpers.h"
28
#include "rmodinit.h"
29
#include "rmodinit.h"
29
 
30
 
30
#include "redir.h"
31
#include "redir.h"
31
 
32
 
32
static unsigned short oldstdout = 0xffff;
33
static unsigned short oldstdout = 0xffff;
33
 
34
 
34
 
35
 
-
 
36
/* compute a filename to be used for pipes */
-
 
37
static unsigned short gentmpfile(char *s) {
-
 
38
  unsigned short err = 0;
-
 
39
  /* do I have a %temp% path? */
-
 
40
  /* TODO */
-
 
41
 
-
 
42
  /* if fails, then use truename(\) */
-
 
43
  if (file_truename(".\\", s) != 0) *s = 0;
-
 
44
 
-
 
45
  /* create file */
-
 
46
  _asm {
-
 
47
    mov ah, 0x5a
-
 
48
    mov dx, s
-
 
49
    xor cx, cx /* file attributes */
-
 
50
    int 0x21
-
 
51
    jnc CLOSEFILE
-
 
52
    mov err, ax
-
 
53
    jmp DONE
-
 
54
    /* close file handle */
-
 
55
    CLOSEFILE:
-
 
56
    mov ah, 0x3e
-
 
57
    mov bx, ax
-
 
58
    int 0x21
-
 
59
    DONE:
-
 
60
  }
-
 
61
  return(err);
-
 
62
}
-
 
63
 
-
 
64
#include <stdio.h>
35
/* parse commandline and performs necessary redirections. cmdline is
65
/* parse commandline and performs necessary redirections. cmdline is
36
 * modified so all redirections are cut out. */
66
 * modified so all redirections are cut out.
-
 
67
 * piped commands are move to awaitingcmd for later execution
-
 
68
 * returns 0 on success, DOS err on failure */
37
void redir_parsecmd(struct redir_data *d, char *cmdline) {
69
unsigned short redir_parsecmd(struct redir_data *d, char *cmdline, char far *awaitingcmd) {
38
  unsigned short i;
70
  unsigned short i;
39
  unsigned short pipescount = 0;
71
  unsigned short pipescount = 0;
40
 
72
 
41
  /* NOTE:
73
  /* NOTES:
42
   *
74
   *
43
   * 1. while it is possible to type a command with multiple
75
   * 1. while it is possible to type a command with multiple
44
   *    redirections, MSDOS executes only the last redirection.
76
   *    redirections, MSDOS executes only the last redirection.
45
   *
77
   *
46
   * 2. the order in which >, < and | are provided on the command line does
78
   * 2. the order in which >, < and | are provided on the command line does
47
   *    not seem to matter for MSDOS. piped commands are executed first (in
79
   *    not seem to matter for MSDOS. piped commands are executed first (in
48
   *    the order they appear) and the result of the last one is redirected to
80
   *    the order they appear) and the result of the last one is redirected to
49
   *    whenever the last > points at.
81
   *    whenever the last > points at.
-
 
82
   *    stdin redirection (<) is (obviously) applied to the first command only
50
   */
83
   */
51
 
84
 
52
  /* preset oldstdout to 0xffff in case no redirection is required */
85
  /* preset oldstdout to 0xffff in case no redirection is required */
53
  oldstdout = 0xffff;
86
  oldstdout = 0xffff;
54
 
87
 
55
  /* clear out the redir_data struct */
88
  /* clear out the redir_data struct */
56
  memset(d, 0, sizeof(*d));
89
  memset(d, 0, sizeof(*d));
57
 
90
 
-
 
91
  *awaitingcmd = 0;
-
 
92
 
58
  /* parse the command line and fill struct with pointers */
93
  /* parse the command line and fill struct with pointers */
59
  for (i = 0;; i++) {
94
  for (i = 0;; i++) {
60
    if (cmdline[i] == '>') {
95
    if (cmdline[i] == '>') {
61
      cmdline[i] = 0;
96
      cmdline[i] = 0;
62
      if (cmdline[i + 1] == '>') {
97
      if (cmdline[i + 1] == '>') {
Line 79... Line 114...
79
      }
114
      }
80
    } else if (cmdline[i] == 0) {
115
    } else if (cmdline[i] == 0) {
81
      break;
116
      break;
82
    }
117
    }
83
  }
118
  }
-
 
119
 
-
 
120
  /* if pipes present, write them to awaitingcmd (and stdout redirection too) */
-
 
121
  if (pipescount != 0) {
-
 
122
    static char tmpfile[130];
-
 
123
    for (i = 0; i < pipescount; i++) {
-
 
124
      if (i != 0) _fstrcat(awaitingcmd, "|");
-
 
125
      _fstrcat(awaitingcmd, d->pipes[i]);
-
 
126
    }
-
 
127
    /* append stdout redirection so I don't forget about it for the last command of the pipe queue */
-
 
128
    if (d->stdoutfile != NULL) {
-
 
129
      if (d->stdout_openflag == 0x11) {
-
 
130
        _fstrcat(awaitingcmd, ">>");
-
 
131
      } else {
-
 
132
        _fstrcat(awaitingcmd, ">");
-
 
133
      }
-
 
134
      d->stdoutfile = NULL;
-
 
135
    }
-
 
136
    /* redirect stdin of next command from a temp file (that is used as my output) */
-
 
137
    _fstrcat(awaitingcmd, "<");
-
 
138
    i = gentmpfile(tmpfile);
-
 
139
    if (i != 0) return(i);
-
 
140
    _fstrcat(awaitingcmd, tmpfile);
-
 
141
    /* same file is used as my stdout */
-
 
142
    d->stdoutfile = tmpfile;
-
 
143
    d->stdout_openflag = 0x12;
-
 
144
    /* TODO I need to remember that the tmp file must be removed... */
-
 
145
/*    outputnl("awaitingcmd:");
-
 
146
    for (i = 0; awaitingcmd[i] != 0; i++) printf("%c", awaitingcmd[i]);
-
 
147
    printf("\r\n");*/
-
 
148
  }
-
 
149
  return(0);
84
}
150
}
85
 
151
 
86
 
152
 
87
/* apply stdin/stdout redirections defined in redir_data, returns 0 on success */
153
/* apply stdout redirections defined in redir_data, returns 0 on success */
88
int redir_apply(const struct redir_data *d) {
154
int redir_apply(const struct redir_data *d) {
89
  if (d->stdinfile != NULL) {
-
 
90
    outputnl("ERROR: stdin redirection is not supported yet");
-
 
91
    return(-1);
-
 
92
  }
-
 
93
 
155
 
94
  if (d->stdoutfile != NULL) {
156
  if (d->stdoutfile != NULL) {
95
    unsigned short openflag = d->stdout_openflag;
157
    unsigned short openflag = d->stdout_openflag;
96
    unsigned short errcode = 0;
158
    unsigned short errcode = 0;
97
    unsigned short handle = 0;
159
    unsigned short handle = 0;
Line 154... Line 216...
154
 
216
 
155
  return(0);
217
  return(0);
156
}
218
}
157
 
219
 
158
 
220
 
159
/* restores previous stdout/stdin handlers if they have been redirected */
221
/* restores previous stdout handle if is has been redirected */
160
void redir_revert(void) {
222
void redir_revert(void) {
161
  _asm {
223
  _asm {
162
    /* if oldstdout is 0xffff then not redirected */
224
    /* if oldstdout is 0xffff then not redirected */
163
    cmp word ptr [oldstdout], 0xffff
225
    cmp word ptr [oldstdout], 0xffff
164
    je DONE
226
    je DONE