aboutsummaryrefslogtreecommitdiff
path: root/unix/os/zgcmdl.c
blob: 2624ec73e4aea68a8b3a90df168c16d0a2915d16 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdio.h>
#define	import_kernel
#define	import_knames
#define import_spp
#include <iraf.h>

extern	char *environ[];
#ifdef	MACOSX
extern  char ***_NSGetArgv();
extern  int *_NSGetArgc();
#endif

#ifdef LINUXPPC
#define xargc	f__xargc
#define xargv	f__xargv
#endif

#ifdef LINUX
extern	char **xargv;		/* defined in getarg(3f); requires libU77! */
extern	int xargc;
#else
static	char **xargv = NULL;
static	int xargc = 0;
#endif

/* ZGCMDL -- Get the host system command line used to invoke this process.
 * There does not seem to be any straightforward way to do this for UNIX,
 * but the argc,argv info is evidently pushed on the stack immediately before
 * the environment list, so we can locate the ARGV array by searching back
 * up the stack a bit.  This is very host OS dependent.
 */
int
ZGCMDL (
  PKCHAR  *cmd,				/* receives the command line	*/
  XINT	  *maxch,			/* maxch chars out		*/
  XINT	  *status
)
{
	register char *ip, *op;
	register int   n;
	char	**argv;

#ifdef	MACOSX
	argv = *_NSGetArgv();
	xargc = *_NSGetArgc();
	xargv = argv;

#else
	unsigned int  *ep;
	register int  narg;


	if (!(argv = xargv)) {
	    /* Locate the ARGV array.  This assumes that argc,argv are
	     * stored in memory immediately preceeding the environment
	     * list, i.e.,
	     *
	     *	argc
	     *	argv[0]
	     *	argv[1]
	     *	  ...
	     *	argv[argc-1]
	     *	NULL
	     *      env[0]			<- environ
	     *      env[1]
	     *	  ...
	     *
	     * !! NOTE !! - This is very system dependent!
	     */
	    ep = ((unsigned int *) *environ) - 1;
	    for (narg=0;  *(ep-1) != (unsigned int)narg;  narg++)
		--ep;
	    xargc = narg;
	    argv = (char **)ep;
	}
#endif

	/* Reconstruct the argument list.
	 */
	for (op=(char *)cmd, n = *maxch, argv++;  n >= 0 && *argv;  argv++) {
	    if (op > (char *)cmd && --n >= 0)
		*op++ = ' ';
	    for (ip = *argv;  --n >= 0 && (*op = *ip++);  op++)
		;
	}

	*op = EOS;
	*status = op - (char *)cmd;

	return (XOK);
}