OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libc/] [sys/] [go32/] [exec.c] - Blame information for rev 40

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 lampret
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <errno.h>
5
#include <fcntl.h>
6
#include "go32.h"
7
#include "dpmi.h"
8
/*#include "process.h"*/
9
#if 1
10
#define P_WAIT          1
11
#define P_NOWAIT        2       /* always generates error */
12
#define P_OVERLAY       3
13
#endif
14
extern const char **environ;
15
#define environ ((const char **)environ)
16
 
17
#define scan_ptr() \
18
        char const **ptr; \
19
        for (ptr = &argv0; *ptr; ptr++); \
20
        ptr = (char const **)(*++ptr);
21
 
22
int execl(const char *path, const char *argv0, ...)
23
{
24
  return spawnve(P_OVERLAY, path, &argv0, environ);
25
}
26
 
27
int execle(const char *path, const char *argv0, ... /*, const char **envp */)
28
{
29
  scan_ptr();
30
  return spawnve(P_OVERLAY, path, &argv0, ptr);
31
}
32
 
33
int execlp(const char *path, const char *argv0, ...)
34
{
35
  return spawnvpe(P_OVERLAY, path, &argv0, environ);
36
}
37
 
38
int execlpe(const char *path, const char *argv0, ... /*, const char **envp */)
39
{
40
  scan_ptr();
41
  return spawnvpe(P_OVERLAY, path, &argv0, ptr);
42
}
43
 
44
/*-------------------------------------------------*/
45
 
46
int execv(const char *path, const char **argv)
47
{
48
  return spawnve(P_OVERLAY, path, argv, environ);
49
}
50
 
51
int execve(const char *path, const char **argv, const char **envp)
52
{
53
  return spawnve(P_OVERLAY, path, argv, envp);
54
}
55
 
56
int execvp(const char *path, const char **argv)
57
{
58
  return spawnvpe(P_OVERLAY, path, argv, environ);
59
}
60
 
61
int execvpe(const char *path, const char **argv, const char **envp)
62
{
63
  return spawnvpe(P_OVERLAY, path, argv, envp);
64
}
65
 
66
/*-------------------------------------------------*/
67
 
68
int spawnl(int mode, const char *path, const char *argv0, ...)
69
{
70
  return spawnve(mode, path, &argv0, environ);
71
}
72
 
73
int spawnle(int mode, const char *path, const char *argv0, ... /*, const char **envp */)
74
{
75
  scan_ptr();
76
  return spawnve(mode, path, &argv0, ptr);
77
}
78
 
79
int spawnlp(int mode, const char *path, const char *argv0, ...)
80
{
81
  return spawnvpe(mode, path, &argv0, environ);
82
}
83
 
84
int spawnlpe(int mode, const char *path, const char *argv0, ... /*, const char **envp */)
85
{
86
  scan_ptr();
87
  return spawnvpe(mode, path, &argv0, ptr);
88
}
89
 
90
/*-------------------------------------------------*/
91
 
92
typedef struct {
93
  u_short eseg;
94
  u_short argoff;
95
  u_short argseg;
96
  u_short fcb1_off;
97
  u_short fcb1_seg;
98
  u_short fcb2_off;
99
  u_short fcb2_seg;
100
} Execp;
101
 
102
static Execp parm;
103
 
104
static u_long tbuf;
105
 
106
static u_long talloc(size_t amt)
107
{
108
  u_long rv = tbuf;
109
  tbuf += amt;
110
  return rv;
111
}
112
 
113
static int direct_exec_tail(const char *program, const char *args, const char **envp)
114
{
115
  _go32_dpmi_registers r;
116
  u_long program_la;
117
  u_long arg_la;
118
  u_long parm_la;
119
  u_long env_la, env_e_la;
120
  char arg_header[3];
121
  int i;
122
 
123
  program_la = talloc(strlen(program)+1);
124
  arg_la = talloc(strlen(args)+3);
125
  parm_la = talloc(sizeof(Execp));
126
 
127
  dosmemput(program, strlen(program)+1, program_la);
128
 
129
  arg_header[0] = strlen(args);
130
  arg_header[1] = '\r';
131
  dosmemput(arg_header, 1, arg_la);
132
  dosmemput(args, strlen(args), arg_la+1);
133
  dosmemput(arg_header+1, 1, arg_la+1+strlen(args));
134
 
135
  do {
136
    env_la = talloc(1);
137
  } while (env_la & 15);
138
  talloc(-1);
139
  for (i=0; envp[i]; i++)
140
  {
141
    env_e_la = talloc(strlen(envp[i])+1);
142
    dosmemput(envp[i], strlen(envp[i])+1, env_e_la);
143
  }
144
  arg_header[0] = 0;
145
  arg_header[1] = 1;
146
  arg_header[2] = 0;
147
  dosmemput(arg_header, 3, talloc(3));
148
  env_e_la = talloc(strlen(program)+1);
149
  dosmemput(program, strlen(program)+1, env_e_la);
150
 
151
  parm.eseg = env_la / 16;
152
  parm.argseg = arg_la / 16;
153
  parm.argoff = arg_la & 15;
154
  dosmemput(&parm, sizeof(parm), parm_la);
155
 
156
  memset(&r, 0, sizeof(r));
157
  r.x.ax = 0x4b00;
158
  r.x.ds = program_la / 16;
159
  r.x.dx = program_la & 15;
160
  r.x.es = parm_la / 16;
161
  r.x.bx = parm_la & 15;
162
  _go32_dpmi_simulate_int(0x21, &r);
163
  if (r.x.flags & 1)
164
  {
165
    errno = r.x.ax;
166
    return -1;
167
  }
168
 
169
  memset(&r, 0, sizeof(r));
170
  r.h.ah = 0x4d;
171
  _go32_dpmi_simulate_int(0x21, &r);
172
 
173
  if (r.x.flags & 1)
174
  {
175
    errno = r.x.ax;
176
    return -1;
177
  }
178
  return r.x.ax;
179
}
180
 
181
static int direct_exec(const char *program, const char **argv, const char **envp)
182
{
183
  int i, arglen;
184
  char *args, *argp;
185
 
186
  tbuf = _go32_info_block.linear_address_of_transfer_buffer;
187
 
188
  arglen = 0;
189
  for (i=1; argv[i]; i++)
190
    arglen += strlen(argv[i]) + 1;
191
  args = (char *)malloc(arglen+1);
192
  argp = args;
193
  for (i=1; argv[i]; i++)
194
  {
195
    const char *p = argv[i];
196
    if (argp - args > 125)
197
      break;
198
    *argp++ = ' ';
199
    while (*p)
200
    {
201
      if (argp - args > 125)
202
        break;
203
      *argp++ = *p++;
204
    }
205
  }
206
  *argp = 0;
207
 
208
  return direct_exec_tail(program, args, envp);
209
}
210
 
211
typedef struct {
212
  char magic[16];
213
  int struct_length;
214
  char go32[16];
215
} StubInfo;
216
#define STUB_INFO_MAGIC "StubInfoMagic!!"
217
 
218
static int go32_exec(const char *program, const char **argv, const char **envp)
219
{
220
  int is_stubbed = 0;
221
  int found_si = 0;
222
  StubInfo si;
223
  unsigned short header[3];
224
  int pf, has_dot, i;
225
  char *go32, *sip;
226
  const char *pp, *pe;
227
  char rpath[80], *rp;
228
  int stub_offset, argc;
229
 
230
  int si_la, rm_la, rm_seg;
231
  short *rm_argv;
232
  char cmdline[34];
233
 
234
  pf = open(program, O_RDONLY|O_BINARY);
235
 
236
  read(pf, header, sizeof(header));
237
  if (header[0] == 0x010b || header[0] == 0x014c)
238
  {
239
    is_stubbed = 1;
240
  }
241
  else if (header[0] == 0x5a4d)
242
  {
243
    int header_offset = (long)header[2]*512L;
244
    if (header[1])
245
      header_offset += (long)header[1] - 512L;
246
    lseek(pf, header_offset - 4, 0);
247
    read(pf, &stub_offset, 4);
248
    header[0] = 0;
249
    read(pf, header, sizeof(header));
250
    if (header[0] == 0x010b)
251
      is_stubbed = 1;
252
    if (header[0] == 0x014c)
253
      is_stubbed = 1;
254
    lseek(pf, stub_offset, 0);
255
    read(pf, &si, sizeof(si));
256
    if (memcmp(STUB_INFO_MAGIC, si.magic, 16) == 0)
257
      found_si = 1;
258
  }
259
  if (!is_stubbed)
260
  {
261
    close(pf);
262
    return direct_exec(program, argv, envp);
263
  }
264
 
265
  if (found_si)
266
    go32 = si.go32;
267
  else
268
    go32 = "go32.exe";
269
  has_dot = 0;
270
  for (i=0; go32[i]; i++)
271
    if (go32[i] == '.')
272
      has_dot = 1;
273
  if (!has_dot)
274
    strcpy(go32+i, ".exe");
275
  for (i=0; envp[i]; i++)
276
    if (strncmp(envp[i], "PATH=", 5) == 0)
277
      pp = envp[i]+5;
278
  strcpy(rpath, go32);
279
  while (access(rpath, 0))
280
  {
281
    char *ptr;
282
    rp = rpath;
283
    for (pe=pp; *pe && *pe != ';'; pe++)
284
      *rp++ = *pe;
285
    pp = pe+1;
286
    if (rp > rpath && rp[-1] != '/' && rp[-1] != '\\' && rp[-1] != ':')
287
      *rp++ = '/';
288
    for (ptr = go32; *ptr; ptr++)
289
      *rp++ = *ptr;
290
    *rp = 0;
291
    if (access(rpath, 0) == 0)
292
      break;
293
    if (*pe == 0)
294
      return direct_exec(program, argv, envp); /* give up and just run it */
295
  }
296
 
297
  if (found_si)
298
  {
299
    lseek(pf, stub_offset, 0);
300
    sip = (char *)malloc(si.struct_length);
301
    read(pf, sip, si.struct_length);
302
  }
303
  close(pf);
304
 
305
  argv[0] = program; /* since that's where we really found it */
306
 
307
  tbuf = _go32_info_block.linear_address_of_transfer_buffer;
308
 
309
  if (found_si)
310
  {
311
    si_la = talloc(si.struct_length);
312
    dosmemput(sip, si.struct_length, si_la);
313
    free(sip);
314
  }
315
 
316
  for (argc=0; argv[argc]; argc++);
317
  rm_la = talloc(2*(argc+1));
318
  rm_seg = (_go32_info_block.linear_address_of_transfer_buffer >> 4) & 0xffff;
319
  rm_argv = (short *)malloc((argc+1) * sizeof(short));
320
  for (i=0; i<argc; i++)
321
  {
322
    int sl = strlen(argv[i]) + 1;
323
    int q = talloc(sl);
324
    dosmemput(argv[i], sl, q);
325
    rm_argv[i] = (q - (rm_seg<<4)) & 0xffff;
326
  }
327
  rm_argv[i] = 0;
328
  dosmemput(rm_argv, 2*(argc+1), rm_la);
329
 
330
  sprintf(cmdline, " !proxy %04x %04x %04x %04x %04x",
331
    argc, rm_seg, (rm_la - (rm_seg<<4))&0xffff,
332
    rm_seg, (si_la - (rm_seg<<4))&0xffff);
333
  if (!found_si)
334
    cmdline[22] = 0; /* remove stub information */
335
 
336
  return direct_exec_tail(rpath, cmdline, envp);
337
}
338
 
339
static int command_exec(const char *program, const char **argv, const char **envp)
340
{
341
  const char *comspec=0;
342
  char *cmdline;
343
  char *newargs[3];
344
  int cmdlen;
345
  int i;
346
 
347
  cmdlen = strlen(program) + 4;
348
  for (i=0; argv[i]; i++)
349
    cmdlen += strlen(argv[i]) + 1;
350
  cmdline = (char *)malloc(cmdlen);
351
 
352
  strcpy(cmdline, "/c ");
353
  for (i=0; program[i]; i++)
354
  {
355
    if (program[i] == '/')
356
      cmdline[i+3] = '\\';
357
    else
358
      cmdline[i+3] = program[i];
359
  }
360
  cmdline[i+3] = 0;
361
  for (i=1; argv[i]; i++)
362
  {
363
    strcat(cmdline, " ");
364
    strcat(cmdline, argv[i]);
365
  }
366
  for (i=0; envp[i]; i++)
367
    if (strncmp(envp[i], "COMSPEC=", 8) == 0)
368
      comspec = envp[i]+8;
369
  if (!comspec)
370
    for (i=0; environ[i]; i++)
371
      if (strncmp(environ[i], "COMSPEC=", 8) == 0)
372
        comspec = environ[i]+8;
373
  if (!comspec)
374
    comspec = "c:/command.com";
375
  newargs[0] = comspec;
376
  newargs[1] = cmdline;
377
  newargs[2] = 0;
378
  i = direct_exec(comspec, (const char **)newargs, envp);
379
  free(cmdline);
380
  return i;
381
}
382
 
383
static int script_exec(const char *program, const char **argv, const char **envp)
384
{
385
  return go32_exec(program, argv, envp);
386
}
387
 
388
static struct {
389
  char *extension;
390
  int (*interp)(const char *, const char **, const char **);
391
} interpreters[] = {
392
  { ".com", direct_exec },
393
  { ".exe", go32_exec },
394
  { ".bat", command_exec },
395
  { 0,      script_exec }
396
};
397
#define INTERP_NO_EXT 3
398
 
399
int spawnv(int mode, const char *path, const char **argv)
400
{
401
  return spawnve(mode, path, argv, environ);
402
}
403
 
404
int spawnve(int mode, const char *path, const char **argv, const char **envp)
405
{
406
  /* This is the one that does the work! */
407
  int i = -1;
408
  char rpath[80], *rp, *rd=0;
409
  fflush(stdout); /* just in case */
410
  for (rp=rpath; *path; *rp++ = *path++)
411
  {
412
    if (*path == '.')
413
      rd = rp;
414
    if (*path == '\\' || *path == '/')
415
      rd = 0;
416
  }
417
  *rp = 0;
418
  if (rd)
419
  {
420
    for (i=0; interpreters[i].extension; i++)
421
      if (strcasecmp(rd, interpreters[i].extension) == 0)
422
        break;
423
  }
424
  while (access(rpath, 0))
425
  {
426
    i++;
427
    if (interpreters[i].extension == 0 || rd)
428
    {
429
      errno = ENOENT;
430
      return -1;
431
    }
432
    strcpy(rp, interpreters[i].extension);
433
  }
434
  if (i == -1)
435
    i = INTERP_NO_EXT;
436
  i = interpreters[i].interp(rpath, argv, envp);
437
  if (mode == P_OVERLAY)
438
    exit(i);
439
  return i;
440
}
441
 
442
int spawnvp(int mode, const char *path, const char **argv)
443
{
444
  return spawnvpe(mode, path, argv, environ);
445
}
446
 
447
int spawnvpe(int mode, const char *path, const char **argv, const char **envp)
448
{
449
  const char *pp, *pe, *ptr;
450
  char rpath[80], *rp, *rd;
451
  int hasdot = 0, i, tried_dot = 0;
452
 
453
  for (ptr=path; *ptr; ptr++)
454
  {
455
    if (*ptr == '.')
456
      hasdot = 1;
457
    if (*ptr == '/' || *ptr == '\\' || *ptr == ':')
458
      return spawnve(mode, path, argv, envp);
459
  }
460
 
461
  pp = 0;
462
  for (i=0; envp[i]; i++)
463
    if (strncmp(envp[i], "PATH=", 5) == 0)
464
      pp = envp[i] + 5;
465
  if (pp == 0)
466
    return spawnve(mode, path, argv, envp);
467
 
468
  while (1)
469
  {
470
    if (!tried_dot)
471
    {
472
      rp = rpath;
473
      pe = pp;
474
      tried_dot = 1;
475
    }
476
    else
477
    {
478
      rp = rpath;
479
      for (pe = pp; *pe && *pe != ';'; pe++)
480
        *rp++ = *pe;
481
      pp = pe+1;
482
      if (rp > rpath && rp[-1] != '/' && rp[-1] != '\\' && rp[-1] != ':')
483
        *rp++ = '/';
484
    }
485
    for (ptr = path; *ptr; ptr++)
486
      *rp++ = *ptr;
487
    *rp = 0;
488
 
489
    if (hasdot)
490
    {
491
      if (access(rpath, 0) == 0)
492
        return spawnve(mode, rpath, argv, envp);
493
    }
494
    else
495
    {
496
      for (i=0; interpreters[i].extension; i++)
497
      {
498
        strcpy(rp, interpreters[i].extension);
499
        if (access(rpath, 0) == 0)
500
          return spawnve(mode, rpath, argv, envp);
501
      }
502
    }
503
    if (*pe == 0)
504
    {
505
      errno = ENOENT;
506
      return -1;
507
    }
508
  }
509
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.