1*c2c66affSColin Finck /* @(#)saveargs.c 1.16 10/11/18 Copyright 1995-2010 J. Schilling */
2*c2c66affSColin Finck /*
3*c2c66affSColin Finck * save argc, argv for command error printing routines
4*c2c66affSColin Finck *
5*c2c66affSColin Finck * Copyright (c) 1995-2010 J. Schilling
6*c2c66affSColin Finck */
7*c2c66affSColin Finck /*
8*c2c66affSColin Finck * The contents of this file are subject to the terms of the
9*c2c66affSColin Finck * Common Development and Distribution License, Version 1.0 only
10*c2c66affSColin Finck * (the "License"). You may not use this file except in compliance
11*c2c66affSColin Finck * with the License.
12*c2c66affSColin Finck *
13*c2c66affSColin Finck * See the file CDDL.Schily.txt in this distribution for details.
14*c2c66affSColin Finck *
15*c2c66affSColin Finck * When distributing Covered Code, include this CDDL HEADER in each
16*c2c66affSColin Finck * file and include the License file CDDL.Schily.txt from this distribution.
17*c2c66affSColin Finck */
18*c2c66affSColin Finck
19*c2c66affSColin Finck #include <schily/mconfig.h>
20*c2c66affSColin Finck #include <schily/standard.h>
21*c2c66affSColin Finck #include <schily/string.h>
22*c2c66affSColin Finck #include <schily/stdlib.h>
23*c2c66affSColin Finck #include <schily/avoffset.h>
24*c2c66affSColin Finck #include <schily/schily.h>
25*c2c66affSColin Finck #include <schily/dlfcn.h>
26*c2c66affSColin Finck
27*c2c66affSColin Finck #if !defined(AV_OFFSET) || !defined(FP_INDIR)
28*c2c66affSColin Finck # ifdef HAVE_SCANSTACK
29*c2c66affSColin Finck # undef HAVE_SCANSTACK
30*c2c66affSColin Finck # endif
31*c2c66affSColin Finck #endif
32*c2c66affSColin Finck
33*c2c66affSColin Finck #ifdef HAVE_VAR___PROGNAME
34*c2c66affSColin Finck extern char *__progname;
35*c2c66affSColin Finck #ifdef HAVE_VAR___PROGNAME_FULL
36*c2c66affSColin Finck extern char *__progname_full;
37*c2c66affSColin Finck #else
38*c2c66affSColin Finck #define __progname_full __progname
39*c2c66affSColin Finck #endif
40*c2c66affSColin Finck #endif
41*c2c66affSColin Finck
42*c2c66affSColin Finck static int ac_saved;
43*c2c66affSColin Finck static char **av_saved;
44*c2c66affSColin Finck static char *av0_saved;
45*c2c66affSColin Finck static char *av0_name_saved;
46*c2c66affSColin Finck static char *progpath_saved;
47*c2c66affSColin Finck static char *progname_saved;
48*c2c66affSColin Finck
49*c2c66affSColin Finck static char av0_sp[32]; /* av0 space, avoid malloc() in most cases */
50*c2c66affSColin Finck static char prn_sp[32]; /* name space, avoid malloc() in most cases */
51*c2c66affSColin Finck static char dfl_str[] = "?";
52*c2c66affSColin Finck
53*c2c66affSColin Finck LOCAL void save_av0 __PR((char *av0));
54*c2c66affSColin Finck LOCAL void init_progname __PR((void));
55*c2c66affSColin Finck LOCAL void init_arginfo __PR((void));
56*c2c66affSColin Finck
57*c2c66affSColin Finck EXPORT void
save_args(ac,av)58*c2c66affSColin Finck save_args(ac, av)
59*c2c66affSColin Finck int ac;
60*c2c66affSColin Finck char *av[];
61*c2c66affSColin Finck {
62*c2c66affSColin Finck ac_saved = ac;
63*c2c66affSColin Finck av_saved = av;
64*c2c66affSColin Finck save_av0(av[0]);
65*c2c66affSColin Finck }
66*c2c66affSColin Finck
67*c2c66affSColin Finck LOCAL void
save_av0(av0)68*c2c66affSColin Finck save_av0(av0)
69*c2c66affSColin Finck char *av0;
70*c2c66affSColin Finck {
71*c2c66affSColin Finck int slen;
72*c2c66affSColin Finck char *p;
73*c2c66affSColin Finck
74*c2c66affSColin Finck if (av0_saved && av0_saved != av0_sp)
75*c2c66affSColin Finck free(av0_saved);
76*c2c66affSColin Finck
77*c2c66affSColin Finck slen = strlen(av0) + 1;
78*c2c66affSColin Finck
79*c2c66affSColin Finck if (slen <= (int)sizeof (av0_sp))
80*c2c66affSColin Finck av0_saved = av0_sp;
81*c2c66affSColin Finck else
82*c2c66affSColin Finck av0_saved = malloc(slen);
83*c2c66affSColin Finck
84*c2c66affSColin Finck if (av0_saved) {
85*c2c66affSColin Finck strcpy(av0_saved, av0);
86*c2c66affSColin Finck av0 = av0_saved;
87*c2c66affSColin Finck }
88*c2c66affSColin Finck
89*c2c66affSColin Finck if ((p = strrchr(av0, '/')) == NULL)
90*c2c66affSColin Finck av0_name_saved = av0;
91*c2c66affSColin Finck else
92*c2c66affSColin Finck av0_name_saved = ++p;
93*c2c66affSColin Finck }
94*c2c66affSColin Finck
95*c2c66affSColin Finck EXPORT int
saved_ac()96*c2c66affSColin Finck saved_ac()
97*c2c66affSColin Finck {
98*c2c66affSColin Finck if (av_saved == NULL)
99*c2c66affSColin Finck init_arginfo();
100*c2c66affSColin Finck
101*c2c66affSColin Finck return (ac_saved);
102*c2c66affSColin Finck }
103*c2c66affSColin Finck
104*c2c66affSColin Finck EXPORT char **
saved_av()105*c2c66affSColin Finck saved_av()
106*c2c66affSColin Finck {
107*c2c66affSColin Finck if (av_saved == NULL)
108*c2c66affSColin Finck init_arginfo();
109*c2c66affSColin Finck
110*c2c66affSColin Finck return (av_saved);
111*c2c66affSColin Finck }
112*c2c66affSColin Finck
113*c2c66affSColin Finck EXPORT char *
saved_av0()114*c2c66affSColin Finck saved_av0()
115*c2c66affSColin Finck {
116*c2c66affSColin Finck if (av0_saved == NULL)
117*c2c66affSColin Finck init_arginfo();
118*c2c66affSColin Finck
119*c2c66affSColin Finck return (av0_saved);
120*c2c66affSColin Finck }
121*c2c66affSColin Finck
122*c2c66affSColin Finck EXPORT void
set_progname(name)123*c2c66affSColin Finck set_progname(name)
124*c2c66affSColin Finck const char *name;
125*c2c66affSColin Finck {
126*c2c66affSColin Finck int slen;
127*c2c66affSColin Finck char *p;
128*c2c66affSColin Finck
129*c2c66affSColin Finck if (progpath_saved && progpath_saved != prn_sp)
130*c2c66affSColin Finck free(progpath_saved);
131*c2c66affSColin Finck
132*c2c66affSColin Finck slen = strlen(name) + 1;
133*c2c66affSColin Finck
134*c2c66affSColin Finck if (slen <= sizeof (prn_sp))
135*c2c66affSColin Finck progpath_saved = prn_sp;
136*c2c66affSColin Finck else
137*c2c66affSColin Finck progpath_saved = malloc(slen);
138*c2c66affSColin Finck
139*c2c66affSColin Finck if (progpath_saved) {
140*c2c66affSColin Finck strcpy(progpath_saved, name);
141*c2c66affSColin Finck name = progpath_saved;
142*c2c66affSColin Finck }
143*c2c66affSColin Finck
144*c2c66affSColin Finck if ((p = strrchr(name, '/')) == NULL)
145*c2c66affSColin Finck progname_saved = (char *)name;
146*c2c66affSColin Finck else
147*c2c66affSColin Finck progname_saved = ++p;
148*c2c66affSColin Finck }
149*c2c66affSColin Finck
150*c2c66affSColin Finck EXPORT char *
get_progname()151*c2c66affSColin Finck get_progname()
152*c2c66affSColin Finck {
153*c2c66affSColin Finck if (progname_saved)
154*c2c66affSColin Finck return (progname_saved);
155*c2c66affSColin Finck if (av0_name_saved == NULL)
156*c2c66affSColin Finck init_progname();
157*c2c66affSColin Finck if (av0_name_saved)
158*c2c66affSColin Finck return (av0_name_saved);
159*c2c66affSColin Finck return (dfl_str);
160*c2c66affSColin Finck }
161*c2c66affSColin Finck
162*c2c66affSColin Finck EXPORT char *
get_progpath()163*c2c66affSColin Finck get_progpath()
164*c2c66affSColin Finck {
165*c2c66affSColin Finck if (progpath_saved)
166*c2c66affSColin Finck return (progpath_saved);
167*c2c66affSColin Finck if (av0_saved == NULL)
168*c2c66affSColin Finck init_progname();
169*c2c66affSColin Finck if (av0_saved)
170*c2c66affSColin Finck return (av0_saved);
171*c2c66affSColin Finck return (dfl_str);
172*c2c66affSColin Finck }
173*c2c66affSColin Finck
174*c2c66affSColin Finck LOCAL void
init_progname()175*c2c66affSColin Finck init_progname()
176*c2c66affSColin Finck {
177*c2c66affSColin Finck #if defined(HAVE_SCANSTACK) || defined(HAVE_GETPROGNAME)
178*c2c66affSColin Finck char *progname;
179*c2c66affSColin Finck #endif
180*c2c66affSColin Finck
181*c2c66affSColin Finck if (av0_name_saved == NULL)
182*c2c66affSColin Finck init_arginfo();
183*c2c66affSColin Finck if (av0_name_saved)
184*c2c66affSColin Finck return;
185*c2c66affSColin Finck #ifdef HAVE_GETPROGNAME
186*c2c66affSColin Finck progname = (char *)getprogname();
187*c2c66affSColin Finck if (progname) {
188*c2c66affSColin Finck save_av0(progname);
189*c2c66affSColin Finck return;
190*c2c66affSColin Finck }
191*c2c66affSColin Finck #endif
192*c2c66affSColin Finck #ifdef HAVE_VAR___PROGNAME
193*c2c66affSColin Finck if (__progname_full) {
194*c2c66affSColin Finck save_av0(__progname_full);
195*c2c66affSColin Finck return;
196*c2c66affSColin Finck }
197*c2c66affSColin Finck #endif
198*c2c66affSColin Finck #ifdef HAVE_SCANSTACK
199*c2c66affSColin Finck progname = getav0(); /* scan stack to get argv[0] */
200*c2c66affSColin Finck if (progname) {
201*c2c66affSColin Finck save_av0(progname);
202*c2c66affSColin Finck return;
203*c2c66affSColin Finck }
204*c2c66affSColin Finck #endif
205*c2c66affSColin Finck }
206*c2c66affSColin Finck
207*c2c66affSColin Finck LOCAL void
init_arginfo()208*c2c66affSColin Finck init_arginfo()
209*c2c66affSColin Finck {
210*c2c66affSColin Finck #if defined(HAVE_DLINFO) && defined(HAVE_DLOPEN_IN_LIBC) && defined(RTLD_DI_ARGSINFO)
211*c2c66affSColin Finck Dl_argsinfo args;
212*c2c66affSColin Finck
213*c2c66affSColin Finck if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0 ||
214*c2c66affSColin Finck args.dla_argc <= 0 ||
215*c2c66affSColin Finck args.dla_argv[0] == NULL)
216*c2c66affSColin Finck return;
217*c2c66affSColin Finck
218*c2c66affSColin Finck if (av_saved == NULL)
219*c2c66affSColin Finck save_args(args.dla_argc, args.dla_argv);
220*c2c66affSColin Finck #endif
221*c2c66affSColin Finck }
222