Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ksh93/sh/main.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1982-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* David Korn <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* UNIX shell
23
*
24
* S. R. Bourne
25
* Rewritten By David Korn
26
* AT&T Labs
27
*
28
*/
29
30
#include <ast.h>
31
#include <sfio.h>
32
#include <stak.h>
33
#include <ls.h>
34
#include <fcin.h>
35
#include "defs.h"
36
#include "variables.h"
37
#include "path.h"
38
#include "io.h"
39
#include "jobs.h"
40
#include "shlex.h"
41
#include "shnodes.h"
42
#include "history.h"
43
#include "timeout.h"
44
#include "FEATURE/time"
45
#include "FEATURE/pstat"
46
#include "FEATURE/execargs"
47
#include "FEATURE/externs"
48
#ifdef _hdr_nc
49
# include <nc.h>
50
#endif /* _hdr_nc */
51
52
#define CMD_LENGTH 64
53
54
/* These routines are referenced by this module */
55
static void exfile(Shell_t*, Sfio_t*,int);
56
static void chkmail(Shell_t *shp, char*);
57
#if defined(_lib_fork) && !defined(_NEXT_SOURCE)
58
static void fixargs(char**,int);
59
#else
60
# define fixargs(a,b)
61
#endif
62
63
#ifndef environ
64
extern char **environ;
65
#endif
66
67
static struct stat lastmail;
68
static time_t mailtime;
69
static char beenhere = 0;
70
71
#ifdef _lib_sigvec
72
void clearsigmask(register int sig)
73
{
74
struct sigvec vec;
75
if(sigvec(sig,NIL(struct sigvec*),&vec)>=0 && vec.sv_mask)
76
{
77
vec.sv_mask = 0;
78
sigvec(sig,&vec,NIL(struct sigvec*));
79
}
80
}
81
#endif /* _lib_sigvec */
82
83
#ifdef PATH_BFPATH
84
#define PATHCOMP NIL(Pathcomp_t*)
85
#else
86
#define PATHCOMP ""
87
#endif
88
89
/*
90
* search for file and exfile() it if it exists
91
* 1 returned if file found, 0 otherwise
92
*/
93
94
int sh_source(Shell_t *shp, Sfio_t *iop, const char *file)
95
{
96
char* oid;
97
char* nid;
98
int fd;
99
100
if (!file || !*file || (fd = path_open(shp,file, PATHCOMP)) < 0)
101
{
102
REGRESS(source, "sh_source", ("%s:ENOENT", file));
103
return 0;
104
}
105
oid = error_info.id;
106
nid = error_info.id = strdup(file);
107
shp->st.filename = path_fullname(shp,stakptr(PATH_OFFSET));
108
REGRESS(source, "sh_source", ("%s", file));
109
exfile(shp, iop, fd);
110
error_info.id = oid;
111
free(nid);
112
return 1;
113
}
114
115
#ifdef S_ISSOCK
116
#define REMOTE(m) (S_ISSOCK(m)||!(m))
117
#else
118
#define REMOTE(m) !(m)
119
#endif
120
121
int sh_main(int ac, char *av[], Shinit_f userinit)
122
{
123
register char *name;
124
register int fdin;
125
register Sfio_t *iop;
126
register Shell_t *shp;
127
struct stat statb;
128
int i, rshflag; /* set for restricted shell */
129
char *command;
130
free(malloc(64*1024));
131
#ifdef _lib_sigvec
132
/* This is to clear mask that may be left on by rlogin */
133
clearsigmask(SIGALRM);
134
clearsigmask(SIGHUP);
135
clearsigmask(SIGCHLD);
136
#endif /* _lib_sigvec */
137
#ifdef _hdr_nc
138
_NutConf(_NC_SET_SUFFIXED_SEARCHING, 1);
139
#endif /* _hdr_nc */
140
fixargs(av,0);
141
shp = sh_init(ac,av,userinit);
142
time(&mailtime);
143
if(rshflag=sh_isoption(SH_RESTRICTED))
144
sh_offoption(SH_RESTRICTED);
145
if(sigsetjmp(*((sigjmp_buf*)shp->jmpbuffer),0))
146
{
147
/* begin script execution here */
148
sh_reinit((char**)0);
149
shp->gd->pid = getpid();
150
shp->gd->ppid = getppid();
151
}
152
shp->fn_depth = shp->dot_depth = 0;
153
command = error_info.id;
154
/* set pidname '$$' */
155
srand(shp->gd->pid&0x7fff);
156
if(nv_isnull(PS4NOD))
157
nv_putval(PS4NOD,e_traceprompt,NV_RDONLY);
158
path_pwd(shp,1);
159
iop = (Sfio_t*)0;
160
#if SHOPT_BRACEPAT
161
sh_onoption(SH_BRACEEXPAND);
162
#endif
163
if((beenhere++)==0)
164
{
165
sh_onstate(SH_PROFILE);
166
((Lex_t*)shp->lex_context)->nonstandard = 0;
167
if(shp->gd->ppid==1)
168
shp->login_sh++;
169
if(shp->login_sh >= 2)
170
sh_onoption(SH_LOGIN_SHELL);
171
/* decide whether shell is interactive */
172
if(!sh_isoption(SH_INTERACTIVE) && !sh_isoption(SH_TFLAG) && !sh_isoption(SH_CFLAG) &&
173
sh_isoption(SH_SFLAG) && tty_check(0) && tty_check(ERRIO))
174
sh_onoption(SH_INTERACTIVE);
175
if(sh_isoption(SH_INTERACTIVE))
176
{
177
sh_onoption(SH_BGNICE);
178
sh_onoption(SH_RC);
179
}
180
if(!sh_isoption(SH_RC) && (sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX)
181
#if SHOPT_REMOTE
182
|| !fstat(0, &statb) && REMOTE(statb.st_mode)
183
#endif
184
))
185
sh_onoption(SH_RC);
186
for(i=0; i<elementsof(shp->offoptions.v); i++)
187
shp->options.v[i] &= ~shp->offoptions.v[i];
188
if(sh_isoption(SH_INTERACTIVE))
189
{
190
#ifdef SIGXCPU
191
signal(SIGXCPU,SIG_DFL);
192
#endif /* SIGXCPU */
193
#ifdef SIGXFSZ
194
signal(SIGXFSZ,SIG_DFL);
195
#endif /* SIGXFSZ */
196
sh_onoption(SH_MONITOR);
197
}
198
job_init(shp,sh_isoption(SH_LOGIN_SHELL));
199
if(sh_isoption(SH_LOGIN_SHELL))
200
{
201
/* system profile */
202
sh_source(shp, iop, e_sysprofile);
203
if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED))
204
{
205
char **files = shp->gd->login_files;
206
while ((name = *files++) && !sh_source(shp, iop, sh_mactry(shp,name)));
207
}
208
}
209
/* make sure PWD is set up correctly */
210
path_pwd(shp,1);
211
if(!sh_isoption(SH_NOEXEC))
212
{
213
if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED) && sh_isoption(SH_RC))
214
{
215
#if SHOPT_BASH
216
if(sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX))
217
{
218
#if SHOPT_SYSRC
219
sh_source(shp, iop, e_bash_sysrc);
220
#endif
221
sh_source(shp, iop, shp->gd->rcfile ? shp->gd->rcfile : sh_mactry(shp,(char*)e_bash_rc));
222
}
223
else
224
#endif
225
{
226
if(name = sh_mactry(shp,nv_getval(ENVNOD)))
227
name = *name ? strdup(name) : (char*)0;
228
#if SHOPT_SYSRC
229
if(!strmatch(name, "?(.)/./*"))
230
sh_source(shp, iop, e_sysrc);
231
#endif
232
if(name)
233
{
234
sh_source(shp, iop, name);
235
free(name);
236
}
237
}
238
}
239
else if(sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_PRIVILEGED))
240
sh_source(shp, iop, e_suidprofile);
241
}
242
shp->st.cmdname = error_info.id = command;
243
sh_offstate(SH_PROFILE);
244
if(rshflag)
245
sh_onoption(SH_RESTRICTED);
246
/* open input file if specified */
247
if(shp->comdiv)
248
{
249
shell_c:
250
iop = sfnew(NIL(Sfio_t*),shp->comdiv,strlen(shp->comdiv),0,SF_STRING|SF_READ);
251
}
252
else
253
{
254
name = error_info.id;
255
error_info.id = shp->shname;
256
if(sh_isoption(SH_SFLAG))
257
fdin = 0;
258
else
259
{
260
char *sp;
261
/* open stream should have been passed into shell */
262
if(strmatch(name,e_devfdNN))
263
{
264
#if !_WINIX
265
char *cp;
266
int type;
267
#endif
268
fdin = (int)strtol(name+8, (char**)0, 10);
269
if(fstat(fdin,&statb)<0)
270
errormsg(SH_DICT,ERROR_system(1),e_open,name);
271
#if !_WINIX
272
/*
273
* try to undo effect of solaris 2.5+
274
* change for argv for setuid scripts
275
*/
276
if(((type = sh_type(cp = av[0])) & SH_TYPE_SH) && (!(name = nv_getval(L_ARGNOD)) || !((type = sh_type(cp = name)) & SH_TYPE_SH)))
277
{
278
av[0] = (type & SH_TYPE_LOGIN) ? cp : path_basename(cp);
279
/* exec to change $0 for ps */
280
execv(pathshell(),av);
281
/* exec fails */
282
shp->st.dolv[0] = av[0];
283
fixargs(shp->st.dolv,1);
284
}
285
#endif
286
name = av[0];
287
sh_offoption(SH_VERBOSE);
288
sh_offoption(SH_XTRACE);
289
}
290
else
291
{
292
int isdir = 0;
293
if((fdin=sh_open(name,O_RDONLY,0))>=0 &&(fstat(fdin,&statb)<0 || S_ISDIR(statb.st_mode)))
294
{
295
close(fdin);
296
isdir = 1;
297
fdin = -1;
298
}
299
else
300
shp->st.filename = path_fullname(shp,name);
301
sp = 0;
302
if(fdin < 0 && !strchr(name,'/'))
303
{
304
#ifdef PATH_BFPATH
305
if(path_absolute(shp,name,NIL(Pathcomp_t*)))
306
sp = stakptr(PATH_OFFSET);
307
#else
308
sp = path_absolute(shp,name,NIL(char*));
309
#endif
310
if(sp)
311
{
312
if((fdin=sh_open(sp,O_RDONLY,0))>=0)
313
shp->st.filename = path_fullname(shp,sp);
314
}
315
}
316
if(fdin<0)
317
{
318
if(isdir)
319
errno = EISDIR;
320
error_info.id = av[0];
321
if(sp || errno!=ENOENT)
322
errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_open,name);
323
/* try sh -c 'name "$@"' */
324
sh_onoption(SH_CFLAG);
325
shp->comdiv = (char*)malloc(strlen(name)+7);
326
name = strcopy(shp->comdiv,name);
327
if(shp->st.dolc)
328
strcopy(name," \"$@\"");
329
goto shell_c;
330
}
331
if(fdin==0)
332
fdin = sh_iomovefd(fdin);
333
}
334
shp->readscript = shp->shname;
335
}
336
error_info.id = name;
337
shp->comdiv--;
338
#if SHOPT_ACCT
339
sh_accinit();
340
if(fdin != 0)
341
sh_accbegin(error_info.id);
342
#endif /* SHOPT_ACCT */
343
}
344
}
345
else
346
{
347
fdin = shp->infd;
348
fixargs(shp->st.dolv,1);
349
}
350
if(sh_isoption(SH_INTERACTIVE))
351
sh_onstate(SH_INTERACTIVE);
352
nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY);
353
exfile(shp,iop,fdin);
354
sh_done(shp,0);
355
/* NOTREACHED */
356
return(0);
357
}
358
359
/*
360
* iop is not null when the input is a string
361
* fdin is the input file descriptor
362
*/
363
364
static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
365
{
366
time_t curtime;
367
Shnode_t *t;
368
int maxtry=IOMAXTRY, tdone=0, execflags;
369
int states,jmpval;
370
struct checkpt buff;
371
sh_pushcontext(shp,&buff,SH_JMPERREXIT);
372
/* open input stream */
373
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
374
if(!iop)
375
{
376
if(fno > 0)
377
{
378
int r;
379
if(fno < 10 && ((r=sh_fcntl(fno,F_DUPFD,10))>=10))
380
{
381
shp->fdstatus[r] = shp->fdstatus[fno];
382
sh_close(fno);
383
fno = r;
384
}
385
fcntl(fno,F_SETFD,FD_CLOEXEC);
386
shp->fdstatus[fno] |= IOCLEX;
387
iop = sh_iostream((void*)shp,fno);
388
}
389
else
390
iop = sfstdin;
391
}
392
else
393
fno = -1;
394
shp->infd = fno;
395
if(sh_isstate(SH_INTERACTIVE))
396
{
397
if(nv_isnull(PS1NOD))
398
nv_putval(PS1NOD,(shp->gd->euserid?e_stdprompt:e_supprompt),NV_RDONLY);
399
sh_sigdone();
400
if(sh_histinit((void*)shp))
401
sh_onoption(SH_HISTORY);
402
}
403
else
404
{
405
if(!sh_isstate(SH_PROFILE))
406
{
407
buff.mode = SH_JMPEXIT;
408
sh_onoption(SH_TRACKALL);
409
sh_offoption(SH_MONITOR);
410
}
411
sh_offstate(SH_INTERACTIVE);
412
sh_offstate(SH_MONITOR);
413
sh_offstate(SH_HISTORY);
414
sh_offoption(SH_HISTORY);
415
}
416
states = sh_getstate();
417
jmpval = sigsetjmp(buff.buff,0);
418
if(jmpval)
419
{
420
Sfio_t *top;
421
sh_iorestore((void*)shp,0,jmpval);
422
hist_flush(shp->gd->hist_ptr);
423
sfsync(shp->outpool);
424
shp->st.execbrk = shp->st.breakcnt = 0;
425
/* check for return from profile or env file */
426
if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT))
427
{
428
sh_setstate(states);
429
goto done;
430
}
431
if(!sh_isoption(SH_INTERACTIVE) || sh_isstate(SH_FORKED) || (jmpval > SH_JMPERREXIT && job_close(shp) >=0))
432
{
433
sh_offstate(SH_INTERACTIVE);
434
sh_offstate(SH_MONITOR);
435
goto done;
436
}
437
exitset();
438
/* skip over remaining input */
439
if(top = fcfile())
440
{
441
while(fcget()>0);
442
fcclose();
443
while(top=sfstack(iop,SF_POPSTACK))
444
sfclose(top);
445
}
446
/* make sure that we own the terminal */
447
#ifdef SIGTSTP
448
tcsetpgrp(job.fd,shp->gd->pid);
449
#endif /* SIGTSTP */
450
}
451
/* error return here */
452
sfclrerr(iop);
453
sh_setstate(states);
454
shp->st.optindex = 1;
455
opt_info.offset = 0;
456
shp->st.loopcnt = 0;
457
shp->trapnote = 0;
458
shp->intrap = 0;
459
error_info.line = 1;
460
shp->inlineno = 1;
461
shp->binscript = 0;
462
if(sfeof(iop))
463
goto eof_or_error;
464
/* command loop */
465
while(1)
466
{
467
shp->nextprompt = 1;
468
sh_freeup(shp);
469
stakset(NIL(char*),0);
470
sh_offstate(SH_STOPOK);
471
sh_offstate(SH_ERREXIT);
472
sh_offstate(SH_VERBOSE);
473
sh_offstate(SH_TIMING);
474
sh_offstate(SH_GRACE);
475
sh_offstate(SH_TTYWAIT);
476
if(sh_isoption(SH_VERBOSE))
477
sh_onstate(SH_VERBOSE);
478
sh_onstate(SH_ERREXIT);
479
/* -eim flags don't apply to profiles */
480
if(sh_isstate(SH_PROFILE))
481
{
482
sh_offstate(SH_INTERACTIVE);
483
sh_offstate(SH_ERREXIT);
484
sh_offstate(SH_MONITOR);
485
}
486
if(sh_isstate(SH_INTERACTIVE) && !tdone)
487
{
488
register char *mail;
489
#ifdef JOBS
490
sh_offstate(SH_MONITOR);
491
if(sh_isoption(SH_MONITOR))
492
sh_onstate(SH_MONITOR);
493
if(job.pwlist)
494
{
495
job_walk(sfstderr,job_list,JOB_NFLAG,(char**)0);
496
job_wait((pid_t)0);
497
}
498
#endif /* JOBS */
499
if((mail=nv_getval(MAILPNOD)) || (mail=nv_getval(MAILNOD)))
500
{
501
time(&curtime);
502
if ((curtime - mailtime) >= sh_mailchk)
503
{
504
chkmail(shp,mail);
505
mailtime = curtime;
506
}
507
}
508
if(shp->gd->hist_ptr)
509
hist_eof(shp->gd->hist_ptr);
510
/* sets timeout for command entry */
511
shp->timeout = shp->st.tmout;
512
#if SHOPT_TIMEOUT
513
if(shp->timeout <= 0 || shp->timeout > SHOPT_TIMEOUT)
514
shp->timeout = SHOPT_TIMEOUT;
515
#endif /* SHOPT_TIMEOUT */
516
shp->inlineno = 1;
517
error_info.line = 1;
518
shp->trapnote = 0;
519
if(buff.mode == SH_JMPEXIT)
520
{
521
buff.mode = SH_JMPERREXIT;
522
#ifdef DEBUG
523
errormsg(SH_DICT,ERROR_warn(0),"%d: mode changed to JMP_EXIT",getpid());
524
#endif
525
}
526
}
527
errno = 0;
528
if(tdone || !sfreserve(iop,0,0))
529
{
530
eof_or_error:
531
if(sh_isstate(SH_INTERACTIVE) && !sferror(iop))
532
{
533
if(--maxtry>0 && sh_isoption(SH_IGNOREEOF) &&
534
!sferror(sfstderr) && (shp->fdstatus[fno]&IOTTY))
535
{
536
sfclrerr(iop);
537
errormsg(SH_DICT,0,e_logout);
538
continue;
539
}
540
else if(job_close(shp)<0)
541
continue;
542
}
543
if(errno==0 && sferror(iop) && --maxtry>0)
544
{
545
sfclrlock(iop);
546
sfclrerr(iop);
547
continue;
548
}
549
goto done;
550
}
551
shp->exitval = sh.savexit;
552
maxtry = IOMAXTRY;
553
if(sh_isstate(SH_INTERACTIVE) && shp->gd->hist_ptr)
554
{
555
job_wait((pid_t)0);
556
hist_eof(shp->gd->hist_ptr);
557
sfsync(sfstderr);
558
}
559
if(sh_isoption(SH_HISTORY))
560
sh_onstate(SH_HISTORY);
561
job.waitall = job.curpgid = 0;
562
error_info.flags |= ERROR_INTERACTIVE;
563
t = (Shnode_t*)sh_parse(shp,iop,0);
564
if(!sh_isstate(SH_INTERACTIVE) && !sh_isoption(SH_CFLAG))
565
error_info.flags &= ~ERROR_INTERACTIVE;
566
shp->readscript = 0;
567
if(sh_isstate(SH_INTERACTIVE) && shp->gd->hist_ptr)
568
hist_flush(shp->gd->hist_ptr);
569
sh_offstate(SH_HISTORY);
570
if(t)
571
{
572
execflags = sh_state(SH_ERREXIT)|sh_state(SH_INTERACTIVE);
573
/* The last command may not have to fork */
574
if(!sh_isstate(SH_PROFILE) && sh_isoption(SH_CFLAG) &&
575
(fno<0 || !(shp->fdstatus[fno]&(IOTTY|IONOSEEK)))
576
&& !sfreserve(iop,0,0))
577
{
578
execflags |= sh_state(SH_NOFORK);
579
}
580
shp->st.execbrk = 0;
581
sh_exec(t,execflags);
582
if(shp->forked)
583
{
584
sh_offstate(SH_INTERACTIVE);
585
goto done;
586
}
587
/* This is for sh -t */
588
if(sh_isoption(SH_TFLAG) && !sh_isstate(SH_PROFILE))
589
tdone++;
590
}
591
}
592
done:
593
sh_popcontext(shp,&buff);
594
if(sh_isstate(SH_INTERACTIVE))
595
{
596
sfputc(sfstderr,'\n');
597
job_close(shp);
598
}
599
if(jmpval == SH_JMPSCRIPT)
600
siglongjmp(*shp->jmplist,jmpval);
601
else if(jmpval == SH_JMPEXIT)
602
sh_done(shp,0);
603
if(fno>0)
604
sh_close(fno);
605
if(shp->st.filename)
606
free((void*)shp->st.filename);
607
shp->st.filename = 0;
608
}
609
610
611
/* prints out messages if files in list have been modified since last call */
612
static void chkmail(Shell_t *shp, char *files)
613
{
614
register char *cp,*sp,*qp;
615
register char save;
616
struct argnod *arglist=0;
617
int offset = staktell();
618
char *savstak=stakptr(0);
619
struct stat statb;
620
if(*(cp=files) == 0)
621
return;
622
sp = cp;
623
do
624
{
625
/* skip to : or end of string saving first '?' */
626
for(qp=0;*sp && *sp != ':';sp++)
627
if((*sp == '?' || *sp=='%') && qp == 0)
628
qp = sp;
629
save = *sp;
630
*sp = 0;
631
/* change '?' to end-of-string */
632
if(qp)
633
*qp = 0;
634
do
635
{
636
/* see if time has been modified since last checked
637
* and the access time <= the modification time
638
*/
639
if(stat(cp,&statb) >= 0 && statb.st_mtime >= mailtime
640
&& statb.st_atime <= statb.st_mtime)
641
{
642
/* check for directory */
643
if(!arglist && S_ISDIR(statb.st_mode))
644
{
645
/* generate list of directory entries */
646
path_complete(shp,cp,"/*",&arglist);
647
}
648
else
649
{
650
/*
651
* If the file has shrunk,
652
* or if the size is zero
653
* then don't print anything
654
*/
655
if(statb.st_size &&
656
( statb.st_ino != lastmail.st_ino
657
|| statb.st_dev != lastmail.st_dev
658
|| statb.st_size > lastmail.st_size))
659
{
660
/* save and restore $_ */
661
char *save = shp->lastarg;
662
shp->lastarg = cp;
663
errormsg(SH_DICT,0,sh_mactry(shp,qp?qp+1:(char*)e_mailmsg));
664
shp->lastarg = save;
665
}
666
lastmail = statb;
667
break;
668
}
669
}
670
if(arglist)
671
{
672
cp = arglist->argval;
673
arglist = arglist->argchn.ap;
674
}
675
else
676
cp = 0;
677
}
678
while(cp);
679
if(qp)
680
*qp = '?';
681
*sp++ = save;
682
cp = sp;
683
}
684
while(save);
685
stakset(savstak,offset);
686
}
687
688
#undef EXECARGS
689
#undef PSTAT
690
#if defined(_hdr_execargs) && defined(pdp11)
691
# include <execargs.h>
692
# define EXECARGS 1
693
#endif
694
695
#if defined(_lib_pstat) && defined(_sys_pstat)
696
# include <sys/pstat.h>
697
# define PSTAT 1
698
#endif
699
700
#if defined(_lib_fork) && !defined(_NEXT_SOURCE)
701
/*
702
* fix up command line for ps command
703
* mode is 0 for initialization
704
*/
705
static void fixargs(char **argv, int mode)
706
{
707
#if EXECARGS
708
*execargs=(char *)argv;
709
#else
710
static char *buff;
711
static int command_len;
712
register char *cp;
713
int offset=0,size;
714
# ifdef PSTAT
715
union pstun un;
716
if(mode==0)
717
{
718
struct pst_static st;
719
un.pst_static = &st;
720
if(pstat(PSTAT_STATIC, un, sizeof(struct pst_static), 1, 0)<0)
721
return;
722
command_len = st.command_length;
723
return;
724
}
725
stakseek(command_len+2);
726
buff = stakseek(0);
727
# else
728
if(mode==0)
729
{
730
buff = argv[0];
731
while(cp = *argv++)
732
command_len += strlen(cp)+1;
733
if(environ && *environ==buff+command_len)
734
{
735
for(argv=environ; cp = *argv; cp++)
736
{
737
if(command_len > CMD_LENGTH)
738
{
739
command_len = CMD_LENGTH;
740
break;
741
}
742
*argv++ = strdup(cp);
743
command_len += strlen(cp)+1;
744
}
745
}
746
command_len -= 1;
747
return;
748
}
749
# endif /* PSTAT */
750
if(command_len==0)
751
return;
752
while((cp = *argv++) && offset < command_len)
753
{
754
if(offset + (size=strlen(cp)) >= command_len)
755
size = command_len - offset;
756
memcpy(buff+offset,cp,size);
757
offset += size;
758
buff[offset++] = ' ';
759
}
760
buff[offset-1] = 0;
761
# ifdef PSTAT
762
un.pst_command = stakptr(0);
763
pstat(PSTAT_SETCMD,un,0,0,0);
764
# endif /* PSTAT */
765
#endif /* EXECARGS */
766
}
767
#endif /* _lib_fork */
768
769