xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/bltins/shiocmd_solaris.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2007 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                  Common Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*b30d1939SAndy Fiddaman *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
18*b30d1939SAndy Fiddaman *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman 
22*b30d1939SAndy Fiddaman #include	<shell.h>
23*b30d1939SAndy Fiddaman #include	<stdio.h>
24*b30d1939SAndy Fiddaman #include	<stdbool.h>
25*b30d1939SAndy Fiddaman #include	<option.h>
26*b30d1939SAndy Fiddaman #include	<stk.h>
27*b30d1939SAndy Fiddaman #include	<tm.h>
28*b30d1939SAndy Fiddaman #include	"name.h"
29*b30d1939SAndy Fiddaman #undef nv_isnull
30*b30d1939SAndy Fiddaman #ifndef SH_DICT
31*b30d1939SAndy Fiddaman #   define SH_DICT     "libshell"
32*b30d1939SAndy Fiddaman #endif
33*b30d1939SAndy Fiddaman #include	<poll.h>
34*b30d1939SAndy Fiddaman 
35*b30d1939SAndy Fiddaman #define sh_contexttoshb(context)	((Shbltin_t*)(context))
36*b30d1939SAndy Fiddaman #define sh_contexttoshell(context)	((context)?(sh_contexttoshb(context)->shp):(NULL))
37*b30d1939SAndy Fiddaman 
38*b30d1939SAndy Fiddaman /*
39*b30d1939SAndy Fiddaman  * time formatting related
40*b30d1939SAndy Fiddaman */
41*b30d1939SAndy Fiddaman struct dctime
42*b30d1939SAndy Fiddaman {
43*b30d1939SAndy Fiddaman 	Namfun_t	fun;
44*b30d1939SAndy Fiddaman 	Namval_t 	*format;
45*b30d1939SAndy Fiddaman 	char		buff[256]; /* Must be large enougth for |tmfmt()| */
46*b30d1939SAndy Fiddaman };
47*b30d1939SAndy Fiddaman 
get_time(Namval_t * np,Namfun_t * nfp)48*b30d1939SAndy Fiddaman static char *get_time(Namval_t* np, Namfun_t* nfp)
49*b30d1939SAndy Fiddaman {
50*b30d1939SAndy Fiddaman 	struct dctime *dp = (struct dctime*)nfp;
51*b30d1939SAndy Fiddaman 	time_t t = nv_getn(np,nfp);
52*b30d1939SAndy Fiddaman 	char *format = nv_getval(dp->format);
53*b30d1939SAndy Fiddaman 	tmfmt(dp->buff,sizeof(dp->buff),format,(time_t*)0);
54*b30d1939SAndy Fiddaman 	return(dp->buff);
55*b30d1939SAndy Fiddaman }
56*b30d1939SAndy Fiddaman 
put_time(Namval_t * np,const char * val,int flag,Namfun_t * nfp)57*b30d1939SAndy Fiddaman static void put_time(Namval_t* np, const char* val, int flag, Namfun_t* nfp)
58*b30d1939SAndy Fiddaman {
59*b30d1939SAndy Fiddaman 	struct dctime *dp = (struct dctime*)nfp;
60*b30d1939SAndy Fiddaman 	char *last;
61*b30d1939SAndy Fiddaman 	if(val)
62*b30d1939SAndy Fiddaman 	{
63*b30d1939SAndy Fiddaman 		int32_t t;
64*b30d1939SAndy Fiddaman 		if(flag&NV_INTEGER)
65*b30d1939SAndy Fiddaman 		{
66*b30d1939SAndy Fiddaman 			if(flag&NV_LONG)
67*b30d1939SAndy Fiddaman 				t = *(Sfdouble_t*)val;
68*b30d1939SAndy Fiddaman 			else
69*b30d1939SAndy Fiddaman 				t = *(double*)val;
70*b30d1939SAndy Fiddaman 		}
71*b30d1939SAndy Fiddaman 		else
72*b30d1939SAndy Fiddaman 		{
73*b30d1939SAndy Fiddaman 			t = tmdate(val, &last, (time_t*)0);
74*b30d1939SAndy Fiddaman 			if(*last)
75*b30d1939SAndy Fiddaman 				errormsg(SH_DICT, ERROR_exit(1),"%s: invalid date/time string", val);
76*b30d1939SAndy Fiddaman 		}
77*b30d1939SAndy Fiddaman 		nv_putv(np, (char*)&t,NV_INTEGER, nfp);
78*b30d1939SAndy Fiddaman 	}
79*b30d1939SAndy Fiddaman 	else
80*b30d1939SAndy Fiddaman 	{
81*b30d1939SAndy Fiddaman 		nv_unset(dp->format);
82*b30d1939SAndy Fiddaman 		free((void*)dp->format);
83*b30d1939SAndy Fiddaman 		nv_putv(np, val, flag, nfp);
84*b30d1939SAndy Fiddaman 	}
85*b30d1939SAndy Fiddaman }
86*b30d1939SAndy Fiddaman 
create_time(Namval_t * np,const char * name,int flags,Namfun_t * nfp)87*b30d1939SAndy Fiddaman static Namval_t *create_time(Namval_t *np, const char *name, int flags, Namfun_t *nfp)
88*b30d1939SAndy Fiddaman {
89*b30d1939SAndy Fiddaman 	struct dctime *dp = (struct dctime*)nfp;
90*b30d1939SAndy Fiddaman 	if(strcmp(name, "format"))
91*b30d1939SAndy Fiddaman 		return((Namval_t*)0);
92*b30d1939SAndy Fiddaman 	return(dp->format);
93*b30d1939SAndy Fiddaman }
94*b30d1939SAndy Fiddaman 
95*b30d1939SAndy Fiddaman static const Namdisc_t timedisc =
96*b30d1939SAndy Fiddaman {
97*b30d1939SAndy Fiddaman         sizeof(struct dctime),
98*b30d1939SAndy Fiddaman         put_time,
99*b30d1939SAndy Fiddaman         get_time,
100*b30d1939SAndy Fiddaman         0,
101*b30d1939SAndy Fiddaman         0,
102*b30d1939SAndy Fiddaman         create_time,
103*b30d1939SAndy Fiddaman };
104*b30d1939SAndy Fiddaman 
105*b30d1939SAndy Fiddaman 
make_time(Namval_t * np)106*b30d1939SAndy Fiddaman static Namval_t *make_time(Namval_t* np)
107*b30d1939SAndy Fiddaman {
108*b30d1939SAndy Fiddaman 	int offset = stktell(stkstd);
109*b30d1939SAndy Fiddaman 	char *name = nv_name(np);
110*b30d1939SAndy Fiddaman 	struct dctime *dp = newof(NULL,struct dctime,1,0);
111*b30d1939SAndy Fiddaman 	if(!dp)
112*b30d1939SAndy Fiddaman 		return((Namval_t*)0);
113*b30d1939SAndy Fiddaman 	sfprintf(stkstd,"%s.format\0",name);
114*b30d1939SAndy Fiddaman 	sfputc(stkstd,0);
115*b30d1939SAndy Fiddaman 	dp->format = nv_search(stkptr(stkstd,offset),sh.var_tree,NV_ADD);
116*b30d1939SAndy Fiddaman 	dp->fun.disc = &timedisc;
117*b30d1939SAndy Fiddaman 	nv_stack(np,&dp->fun);
118*b30d1939SAndy Fiddaman 	return(np);
119*b30d1939SAndy Fiddaman }
120*b30d1939SAndy Fiddaman 
121*b30d1939SAndy Fiddaman /*
122*b30d1939SAndy Fiddaman  * mode formatting related
123*b30d1939SAndy Fiddaman */
get_mode(Namval_t * np,Namfun_t * nfp)124*b30d1939SAndy Fiddaman static char *get_mode(Namval_t* np, Namfun_t* nfp)
125*b30d1939SAndy Fiddaman {
126*b30d1939SAndy Fiddaman 	mode_t mode = nv_getn(np,nfp);
127*b30d1939SAndy Fiddaman 	return(fmtperm(mode));
128*b30d1939SAndy Fiddaman }
129*b30d1939SAndy Fiddaman 
put_mode(Namval_t * np,const char * val,int flag,Namfun_t * nfp)130*b30d1939SAndy Fiddaman static void put_mode(Namval_t* np, const char* val, int flag, Namfun_t* nfp)
131*b30d1939SAndy Fiddaman {
132*b30d1939SAndy Fiddaman 	if(val)
133*b30d1939SAndy Fiddaman 	{
134*b30d1939SAndy Fiddaman 		int32_t mode;
135*b30d1939SAndy Fiddaman 		char *last;
136*b30d1939SAndy Fiddaman 		if(flag&NV_INTEGER)
137*b30d1939SAndy Fiddaman 		{
138*b30d1939SAndy Fiddaman 			if(flag&NV_LONG)
139*b30d1939SAndy Fiddaman 				mode = *(Sfdouble_t*)val;
140*b30d1939SAndy Fiddaman 			else
141*b30d1939SAndy Fiddaman 				mode = *(double*)val;
142*b30d1939SAndy Fiddaman 		}
143*b30d1939SAndy Fiddaman 		else
144*b30d1939SAndy Fiddaman 		{
145*b30d1939SAndy Fiddaman 			mode = strperm(val, &last,0);
146*b30d1939SAndy Fiddaman 			if(*last)
147*b30d1939SAndy Fiddaman 				errormsg(SH_DICT, ERROR_exit(1),"%s: invalid mode string", val);
148*b30d1939SAndy Fiddaman 		}
149*b30d1939SAndy Fiddaman 		nv_putv(np,(char*)&mode,NV_INTEGER,nfp);
150*b30d1939SAndy Fiddaman 	}
151*b30d1939SAndy Fiddaman 	else
152*b30d1939SAndy Fiddaman 		nv_putv(np,val,flag,nfp);
153*b30d1939SAndy Fiddaman }
154*b30d1939SAndy Fiddaman 
155*b30d1939SAndy Fiddaman static const Namdisc_t modedisc =
156*b30d1939SAndy Fiddaman {
157*b30d1939SAndy Fiddaman 	0,
158*b30d1939SAndy Fiddaman         put_mode,
159*b30d1939SAndy Fiddaman         get_mode,
160*b30d1939SAndy Fiddaman };
161*b30d1939SAndy Fiddaman 
make_mode(Namval_t * np)162*b30d1939SAndy Fiddaman static Namval_t *make_mode(Namval_t* np)
163*b30d1939SAndy Fiddaman {
164*b30d1939SAndy Fiddaman 	char *name = nv_name(np);
165*b30d1939SAndy Fiddaman 	Namfun_t *nfp = newof(NULL,Namfun_t,1,0);
166*b30d1939SAndy Fiddaman 	if(!nfp)
167*b30d1939SAndy Fiddaman 		return((Namval_t*)0);
168*b30d1939SAndy Fiddaman 	nfp->disc = &modedisc;
169*b30d1939SAndy Fiddaman 	nv_stack(np,nfp);
170*b30d1939SAndy Fiddaman 	return(np);
171*b30d1939SAndy Fiddaman }
172*b30d1939SAndy Fiddaman 
173*b30d1939SAndy Fiddaman /*
174*b30d1939SAndy Fiddaman  *  field related typese and functions
175*b30d1939SAndy Fiddaman  */
176*b30d1939SAndy Fiddaman typedef struct _field_
177*b30d1939SAndy Fiddaman {
178*b30d1939SAndy Fiddaman 	char		*name;		/* field name */
179*b30d1939SAndy Fiddaman 	int		flags;		/* flags */
180*b30d1939SAndy Fiddaman 	short		offset;		/* offset of field into data */
181*b30d1939SAndy Fiddaman 	short		size;		/* size of field */
182*b30d1939SAndy Fiddaman 	Namval_t	*(*make)(Namval_t*);	/* discipline constructor */
183*b30d1939SAndy Fiddaman } Shfield_t;
184*b30d1939SAndy Fiddaman 
185*b30d1939SAndy Fiddaman /*
186*b30d1939SAndy Fiddaman  * lookup field in field table
187*b30d1939SAndy Fiddaman  */
sh_findfield(Shfield_t * ftable,int nelem,const char * name)188*b30d1939SAndy Fiddaman static Shfield_t *sh_findfield(Shfield_t *ftable, int nelem, const char *name)
189*b30d1939SAndy Fiddaman {
190*b30d1939SAndy Fiddaman 	Shfield_t *fp = ftable;
191*b30d1939SAndy Fiddaman 	register int i,n;
192*b30d1939SAndy Fiddaman 	register const char *cp;
193*b30d1939SAndy Fiddaman 	for(cp=name; *cp; cp++)
194*b30d1939SAndy Fiddaman 	{
195*b30d1939SAndy Fiddaman 		if(*cp=='.')
196*b30d1939SAndy Fiddaman 			break;
197*b30d1939SAndy Fiddaman 	}
198*b30d1939SAndy Fiddaman 	n = cp-name;
199*b30d1939SAndy Fiddaman 	for(i=0; i < nelem; i++,fp++)
200*b30d1939SAndy Fiddaman 	{
201*b30d1939SAndy Fiddaman 		if(memcmp(fp->name,name,n)==0 && fp->name[n]==0)
202*b30d1939SAndy Fiddaman 			return(fp);
203*b30d1939SAndy Fiddaman 	}
204*b30d1939SAndy Fiddaman 	return(0);
205*b30d1939SAndy Fiddaman }
206*b30d1939SAndy Fiddaman 
207*b30d1939SAndy Fiddaman /*
208*b30d1939SAndy Fiddaman  * class types and functions
209*b30d1939SAndy Fiddaman  */
210*b30d1939SAndy Fiddaman 
211*b30d1939SAndy Fiddaman typedef struct _class_
212*b30d1939SAndy Fiddaman {
213*b30d1939SAndy Fiddaman 	int		nelem;		/* number of elements */
214*b30d1939SAndy Fiddaman 	int		dsize;		/* size for data structure */
215*b30d1939SAndy Fiddaman 	Shfield_t 	*fields;	/* field description table */
216*b30d1939SAndy Fiddaman } Shclass_t;
217*b30d1939SAndy Fiddaman 
218*b30d1939SAndy Fiddaman struct dcclass
219*b30d1939SAndy Fiddaman {
220*b30d1939SAndy Fiddaman 	Namfun_t	fun;
221*b30d1939SAndy Fiddaman 	Shclass_t	sclass;
222*b30d1939SAndy Fiddaman };
223*b30d1939SAndy Fiddaman 
sh_newnode(register Shfield_t * fp,Namval_t * np)224*b30d1939SAndy Fiddaman static Namval_t *sh_newnode(register Shfield_t *fp, Namval_t *np)
225*b30d1939SAndy Fiddaman {
226*b30d1939SAndy Fiddaman 	char *val = np->nvalue + fp->offset;
227*b30d1939SAndy Fiddaman 	char *name = nv_name(np);
228*b30d1939SAndy Fiddaman 	register Namval_t *nq;
229*b30d1939SAndy Fiddaman 	int offset = stktell(stkstd);
230*b30d1939SAndy Fiddaman 	sfprintf(stkstd,"%s.%s\0",name,fp->name);
231*b30d1939SAndy Fiddaman 	sfputc(stkstd,0);
232*b30d1939SAndy Fiddaman 	nq = nv_search(stkptr(stkstd,offset),sh.var_tree,NV_ADD);
233*b30d1939SAndy Fiddaman 	if(fp->size<0)
234*b30d1939SAndy Fiddaman 		val = *(char**)val;
235*b30d1939SAndy Fiddaman 	nv_putval(nq,val,fp->flags|NV_NOFREE);
236*b30d1939SAndy Fiddaman 	if(fp->make)
237*b30d1939SAndy Fiddaman 		(*fp->make)(nq);
238*b30d1939SAndy Fiddaman 	return(nq);
239*b30d1939SAndy Fiddaman }
240*b30d1939SAndy Fiddaman 
fieldcreate(Namval_t * np,const char * name,int flags,Namfun_t * nfp)241*b30d1939SAndy Fiddaman static Namval_t *fieldcreate(Namval_t *np, const char *name, int flags, Namfun_t *nfp)
242*b30d1939SAndy Fiddaman {
243*b30d1939SAndy Fiddaman 	struct dcclass *dcp = (struct dcclass*)nfp;
244*b30d1939SAndy Fiddaman 	Shclass_t *sp = &dcp->sclass;
245*b30d1939SAndy Fiddaman 	Shfield_t *fp = sh_findfield(sp->fields,sp->nelem,name);
246*b30d1939SAndy Fiddaman 	Namval_t *nq,**nodes = (Namval_t**)(dcp+1);
247*b30d1939SAndy Fiddaman 	int n = fp-sp->fields;
248*b30d1939SAndy Fiddaman 	int len =  strlen(fp->name);
249*b30d1939SAndy Fiddaman 	void *data = (void*)np->nvalue;
250*b30d1939SAndy Fiddaman 	if(!(nq=nodes[n]))
251*b30d1939SAndy Fiddaman 	{
252*b30d1939SAndy Fiddaman 		nodes[n] = nq = sh_newnode(fp,np);
253*b30d1939SAndy Fiddaman 		nfp->last = "";
254*b30d1939SAndy Fiddaman 	}
255*b30d1939SAndy Fiddaman 	if(name[len]==0)
256*b30d1939SAndy Fiddaman 		return(nq);
257*b30d1939SAndy Fiddaman 	return(nq);
258*b30d1939SAndy Fiddaman }
259*b30d1939SAndy Fiddaman 
genvalue(Sfio_t * out,Shclass_t * sp,int indent,Namval_t * npar)260*b30d1939SAndy Fiddaman static void genvalue(Sfio_t *out, Shclass_t *sp, int indent, Namval_t *npar)
261*b30d1939SAndy Fiddaman {
262*b30d1939SAndy Fiddaman 	Shfield_t *fp = sp->fields;
263*b30d1939SAndy Fiddaman 	Namval_t *np, **nodes= (Namval_t**)(sp+1);
264*b30d1939SAndy Fiddaman 	register int i,isarray;
265*b30d1939SAndy Fiddaman 	if(out)
266*b30d1939SAndy Fiddaman 	{
267*b30d1939SAndy Fiddaman 		sfwrite(out,"(\n",2);
268*b30d1939SAndy Fiddaman 		indent++;
269*b30d1939SAndy Fiddaman 	}
270*b30d1939SAndy Fiddaman 	for(i=0; i < sp->nelem; i++,fp++)
271*b30d1939SAndy Fiddaman 	{
272*b30d1939SAndy Fiddaman #if 0
273*b30d1939SAndy Fiddaman 		/* handle recursive case */
274*b30d1939SAndy Fiddaman #endif
275*b30d1939SAndy Fiddaman 		if(!(np=nodes[i]) && out)
276*b30d1939SAndy Fiddaman 			np = sh_newnode(fp,npar);
277*b30d1939SAndy Fiddaman 		if(np)
278*b30d1939SAndy Fiddaman 		{
279*b30d1939SAndy Fiddaman 			isarray=0;
280*b30d1939SAndy Fiddaman 			if(nv_isattr(np,NV_ARRAY))
281*b30d1939SAndy Fiddaman 			{
282*b30d1939SAndy Fiddaman 				isarray=1;
283*b30d1939SAndy Fiddaman 				if(array_elem(nv_arrayptr(np))==0)
284*b30d1939SAndy Fiddaman 					isarray=2;
285*b30d1939SAndy Fiddaman 				else
286*b30d1939SAndy Fiddaman 					nv_putsub(np,(char*)0,ARRAY_SCAN);
287*b30d1939SAndy Fiddaman 			}
288*b30d1939SAndy Fiddaman 			sfnputc(out,'\t',indent);
289*b30d1939SAndy Fiddaman 			sfputr(out,fp->name,(isarray==2?'\n':'='));
290*b30d1939SAndy Fiddaman 			if(isarray)
291*b30d1939SAndy Fiddaman 			{
292*b30d1939SAndy Fiddaman 				if(isarray==2)
293*b30d1939SAndy Fiddaman 					continue;
294*b30d1939SAndy Fiddaman 				sfwrite(out,"(\n",2);
295*b30d1939SAndy Fiddaman 				sfnputc(out,'\t',++indent);
296*b30d1939SAndy Fiddaman 			}
297*b30d1939SAndy Fiddaman 			while(1)
298*b30d1939SAndy Fiddaman 			{
299*b30d1939SAndy Fiddaman 				char *fmtq;
300*b30d1939SAndy Fiddaman 				if(isarray)
301*b30d1939SAndy Fiddaman 				{
302*b30d1939SAndy Fiddaman 					sfprintf(out,"[%s]",sh_fmtq(nv_getsub(np)));
303*b30d1939SAndy Fiddaman 					sfputc(out,'=');
304*b30d1939SAndy Fiddaman 				}
305*b30d1939SAndy Fiddaman 				if(!(fmtq=nv_getval(np)) || !(fmtq=sh_fmtq(fmtq)))
306*b30d1939SAndy Fiddaman 					fmtq = "";
307*b30d1939SAndy Fiddaman 				sfputr(out,fmtq,'\n');
308*b30d1939SAndy Fiddaman 				if(!nv_nextsub(np))
309*b30d1939SAndy Fiddaman 					break;
310*b30d1939SAndy Fiddaman 				sfnputc(out,'\t',indent);
311*b30d1939SAndy Fiddaman 			}
312*b30d1939SAndy Fiddaman 			if(isarray)
313*b30d1939SAndy Fiddaman 			{
314*b30d1939SAndy Fiddaman 				sfnputc(out,'\t',--indent);
315*b30d1939SAndy Fiddaman 				sfwrite(out,")\n",2);
316*b30d1939SAndy Fiddaman 			}
317*b30d1939SAndy Fiddaman 		}
318*b30d1939SAndy Fiddaman 	}
319*b30d1939SAndy Fiddaman 	if(out)
320*b30d1939SAndy Fiddaman 	{
321*b30d1939SAndy Fiddaman 		if(indent>1)
322*b30d1939SAndy Fiddaman 			sfnputc(out,'\t',indent-1);
323*b30d1939SAndy Fiddaman 		sfputc(out,')');
324*b30d1939SAndy Fiddaman 	}
325*b30d1939SAndy Fiddaman }
326*b30d1939SAndy Fiddaman 
walk_class(register Namval_t * np,int dlete,struct dcclass * dcp)327*b30d1939SAndy Fiddaman static char *walk_class(register Namval_t *np, int dlete, struct dcclass *dcp)
328*b30d1939SAndy Fiddaman {
329*b30d1939SAndy Fiddaman 	static Sfio_t *out;
330*b30d1939SAndy Fiddaman 	Sfio_t *outfile;
331*b30d1939SAndy Fiddaman 	int savtop = stktell(stkstd);
332*b30d1939SAndy Fiddaman 	char *savptr =  stkfreeze(stkstd,0);
333*b30d1939SAndy Fiddaman 	if(dlete)
334*b30d1939SAndy Fiddaman 		outfile = 0;
335*b30d1939SAndy Fiddaman 	else if(!(outfile=out))
336*b30d1939SAndy Fiddaman                 outfile = out =  sfnew((Sfio_t*)0,(char*)0,-1,-1,SF_WRITE|SF_STRING);
337*b30d1939SAndy Fiddaman 	else
338*b30d1939SAndy Fiddaman 		sfseek(outfile,0L,SEEK_SET);
339*b30d1939SAndy Fiddaman 	genvalue(outfile,&dcp->sclass,0,np);
340*b30d1939SAndy Fiddaman 	stkset(stkstd,savptr,savtop);
341*b30d1939SAndy Fiddaman 	if(!outfile)
342*b30d1939SAndy Fiddaman 		return((char*)0);
343*b30d1939SAndy Fiddaman 	sfputc(out,0);
344*b30d1939SAndy Fiddaman 	return((char*)out->_data);
345*b30d1939SAndy Fiddaman }
346*b30d1939SAndy Fiddaman 
get_classval(Namval_t * np,Namfun_t * nfp)347*b30d1939SAndy Fiddaman static char *get_classval(Namval_t* np, Namfun_t* nfp)
348*b30d1939SAndy Fiddaman {
349*b30d1939SAndy Fiddaman 	return(walk_class(np,0,(struct dcclass *)nfp));
350*b30d1939SAndy Fiddaman }
351*b30d1939SAndy Fiddaman 
put_classval(Namval_t * np,const char * val,int flag,Namfun_t * nfp)352*b30d1939SAndy Fiddaman static void put_classval(Namval_t* np, const char* val, int flag, Namfun_t* nfp)
353*b30d1939SAndy Fiddaman {
354*b30d1939SAndy Fiddaman 	walk_class(np,1,(struct dcclass *)nfp);
355*b30d1939SAndy Fiddaman 	if(nfp = nv_stack(np,(Namfun_t*)0))
356*b30d1939SAndy Fiddaman 	{
357*b30d1939SAndy Fiddaman 		free((void*)nfp);
358*b30d1939SAndy Fiddaman 		if(np->nvalue && !nv_isattr(np,NV_NOFREE))
359*b30d1939SAndy Fiddaman 			free((void*)np->nvalue);
360*b30d1939SAndy Fiddaman 	}
361*b30d1939SAndy Fiddaman 	if(val)
362*b30d1939SAndy Fiddaman 		nv_putval(np,val,flag);
363*b30d1939SAndy Fiddaman }
364*b30d1939SAndy Fiddaman 
365*b30d1939SAndy Fiddaman static const Namdisc_t classdisc =
366*b30d1939SAndy Fiddaman {
367*b30d1939SAndy Fiddaman         sizeof(struct dcclass),
368*b30d1939SAndy Fiddaman         put_classval,
369*b30d1939SAndy Fiddaman         get_classval,
370*b30d1939SAndy Fiddaman         0,
371*b30d1939SAndy Fiddaman         0,
372*b30d1939SAndy Fiddaman 	fieldcreate
373*b30d1939SAndy Fiddaman };
374*b30d1939SAndy Fiddaman 
mkclass(Namval_t * np,Shclass_t * sp)375*b30d1939SAndy Fiddaman static int mkclass(Namval_t *np, Shclass_t *sp)
376*b30d1939SAndy Fiddaman {
377*b30d1939SAndy Fiddaman 	struct dcclass *tcp = newof(NULL,struct dcclass,1,sp->nelem*sizeof(Namval_t*));
378*b30d1939SAndy Fiddaman 	if(!tcp)
379*b30d1939SAndy Fiddaman 		return(0);
380*b30d1939SAndy Fiddaman 	memset((void*)(tcp+1),0,sp->nelem*sizeof(Namval_t*));
381*b30d1939SAndy Fiddaman 	tcp->fun.disc = &classdisc;
382*b30d1939SAndy Fiddaman 	tcp->sclass = *sp;
383*b30d1939SAndy Fiddaman 	np->nvalue = (char*)calloc(sp->dsize,1);
384*b30d1939SAndy Fiddaman 	nv_stack(np,&tcp->fun);
385*b30d1939SAndy Fiddaman 	return(1);
386*b30d1939SAndy Fiddaman }
387*b30d1939SAndy Fiddaman 
388*b30d1939SAndy Fiddaman /*
389*b30d1939SAndy Fiddaman  * ====================from here down is file class specific
390*b30d1939SAndy Fiddaman  */
391*b30d1939SAndy Fiddaman static struct stat *Sp;
392*b30d1939SAndy Fiddaman 
393*b30d1939SAndy Fiddaman struct filedata
394*b30d1939SAndy Fiddaman {
395*b30d1939SAndy Fiddaman 	struct stat	statb;
396*b30d1939SAndy Fiddaman 	int		fd;
397*b30d1939SAndy Fiddaman 	char		*name;
398*b30d1939SAndy Fiddaman };
399*b30d1939SAndy Fiddaman 
400*b30d1939SAndy Fiddaman static Shfield_t filefield[] =
401*b30d1939SAndy Fiddaman {
402*b30d1939SAndy Fiddaman 	{ "atime", NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_atime), sizeof(Sp->st_atime), make_time},
403*b30d1939SAndy Fiddaman 	{ "ctime", NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_ctime), sizeof(Sp->st_ctime), make_time},
404*b30d1939SAndy Fiddaman 	{ "dev",   NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_dev),sizeof(Sp->st_dev)},
405*b30d1939SAndy Fiddaman 	{ "fd",    NV_INTEGER|NV_RDONLY, offsetof(struct filedata,fd), 		sizeof(int)},
406*b30d1939SAndy Fiddaman 	{ "gid",   NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_gid), sizeof(Sp->st_gid)},
407*b30d1939SAndy Fiddaman 	{ "ino",   NV_LONG|NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_ino), sizeof(Sp->st_ino)},
408*b30d1939SAndy Fiddaman 	{ "mode",  NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_mode), sizeof(Sp->st_mode), make_mode},
409*b30d1939SAndy Fiddaman 	{ "mtime", NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_mtime), sizeof(Sp->st_mtime), make_time},
410*b30d1939SAndy Fiddaman 	{ "name",   NV_RDONLY, offsetof(struct filedata,name), 	-1 },
411*b30d1939SAndy Fiddaman 	{ "nlink", NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_nlink), sizeof(Sp->st_nlink)},
412*b30d1939SAndy Fiddaman 	{ "size",  NV_LONG|NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_size), sizeof(Sp->st_size)},
413*b30d1939SAndy Fiddaman 	{ "uid",   NV_INTEGER|NV_RDONLY, offsetof(struct stat,st_uid), sizeof(Sp->st_uid)}
414*b30d1939SAndy Fiddaman };
415*b30d1939SAndy Fiddaman 
416*b30d1939SAndy Fiddaman static Shclass_t Fileclass =
417*b30d1939SAndy Fiddaman {
418*b30d1939SAndy Fiddaman 	sizeof(filefield)/sizeof(*filefield),
419*b30d1939SAndy Fiddaman 	sizeof(struct filedata),
420*b30d1939SAndy Fiddaman 	filefield
421*b30d1939SAndy Fiddaman };
422*b30d1939SAndy Fiddaman 
423*b30d1939SAndy Fiddaman 
424*b30d1939SAndy Fiddaman #define letterbit(bit)	(1<<((bit)-'a'))
425*b30d1939SAndy Fiddaman 
426*b30d1939SAndy Fiddaman static const char sh_optopen[] =
427*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: open (AT&T Labs Research) 2007-05-07 $\n]"
428*b30d1939SAndy Fiddaman "[-author?David Korn <dgk@research.att.com>]"
429*b30d1939SAndy Fiddaman "[-author?Roland Mainz <roland.mainz@nrubsig.org>]"
430*b30d1939SAndy Fiddaman "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
431*b30d1939SAndy Fiddaman "[+NAME? open - create a shell variable corresponding to a file]"
432*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bopen\b creates the compound variable \avar\a corresponding "
433*b30d1939SAndy Fiddaman 	"to the file given by the pathname \afile\a.  The elements of \avar\a "
434*b30d1939SAndy Fiddaman 	"are the names of elements in the \astat\a structure with the \bst_\b "
435*b30d1939SAndy Fiddaman 	"prefix removed.]"
436*b30d1939SAndy Fiddaman "[+?\afile\a is opened (based on \b-r\b and/or \b-w\b) and the variable "
437*b30d1939SAndy Fiddaman 	"\avar\a\b.fd\b is the file descriptor.]"
438*b30d1939SAndy Fiddaman "[a:append?Open for append.]"
439*b30d1939SAndy Fiddaman "[b:binary?Open in binary mode"
440*b30d1939SAndy Fiddaman #ifndef O_BINARY
441*b30d1939SAndy Fiddaman 	" (not supported/ignored on this platform)"
442*b30d1939SAndy Fiddaman #endif
443*b30d1939SAndy Fiddaman 	".]"
444*b30d1939SAndy Fiddaman "[t:text?Open in text mode"
445*b30d1939SAndy Fiddaman #ifndef O_TEXT
446*b30d1939SAndy Fiddaman 	" (not supported/ignored on this platform)"
447*b30d1939SAndy Fiddaman #endif
448*b30d1939SAndy Fiddaman 	".]"
449*b30d1939SAndy Fiddaman "[c:create?Open for create.]"
450*b30d1939SAndy Fiddaman "[i:inherit?Open without the close-on-exec bit set.]"
451*b30d1939SAndy Fiddaman "[I:noinherit?Open with the close-on-exec bit set.]"
452*b30d1939SAndy Fiddaman "[r:read?Open with read access.]"
453*b30d1939SAndy Fiddaman "[w:write?Open with write access.]"
454*b30d1939SAndy Fiddaman "[m:mode]:[mode:=rwrwrw?Open with access mode \amode\a.]"
455*b30d1939SAndy Fiddaman "[x:exclusive?Open exclusive.]"
456*b30d1939SAndy Fiddaman 
457*b30d1939SAndy Fiddaman "[N:nofollow?If the path names a symbolic link, open fails with ELOOP "
458*b30d1939SAndy Fiddaman #ifndef O_NOFOLLOW
459*b30d1939SAndy Fiddaman 	" (not supported/ignored on this platform)"
460*b30d1939SAndy Fiddaman #endif
461*b30d1939SAndy Fiddaman 	".]"
462*b30d1939SAndy Fiddaman "[S:sync?Write I/O operations on the file descriptor complete as "
463*b30d1939SAndy Fiddaman 	"defined by synchronized I/O file integrity completion"
464*b30d1939SAndy Fiddaman #ifndef O_SYNC
465*b30d1939SAndy Fiddaman 	" (not supported/ignored on this platform)"
466*b30d1939SAndy Fiddaman #endif
467*b30d1939SAndy Fiddaman 	".]"
468*b30d1939SAndy Fiddaman "[T:trunc?If the file exists and is a regular file, and  the  file "
469*b30d1939SAndy Fiddaman         "is successfully opened read/write or write-only, its length is "
470*b30d1939SAndy Fiddaman         "truncated to 0 and the mode and owner are unchanged.  It "
471*b30d1939SAndy Fiddaman         "has  no  effect on FIFO special files or terminal device "
472*b30d1939SAndy Fiddaman         "files.   Its   effect   on   other   file    types    is "
473*b30d1939SAndy Fiddaman         "implementation-dependent.  The  result  of using -T "
474*b30d1939SAndy Fiddaman         "with read-only files is undefined"
475*b30d1939SAndy Fiddaman #ifndef O_TRUNC
476*b30d1939SAndy Fiddaman 	" (not supported/ignored on this platform)"
477*b30d1939SAndy Fiddaman #endif
478*b30d1939SAndy Fiddaman 	".]"
479*b30d1939SAndy Fiddaman "\n"
480*b30d1939SAndy Fiddaman "\nvar file\n"
481*b30d1939SAndy Fiddaman "\n"
482*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
483*b30d1939SAndy Fiddaman         "[+0?Success.]"
484*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
485*b30d1939SAndy Fiddaman "}"
486*b30d1939SAndy Fiddaman "[+SEE ALSO?\btmpfile\b(1),\bdup\b(1),\bclose\b(1),\bstat\b(1),\bpoll\b(1),\bstat\b(2)]"
487*b30d1939SAndy Fiddaman ;
488*b30d1939SAndy Fiddaman 
489*b30d1939SAndy Fiddaman 
b_open(int argc,char * argv[],Shbltin_t * context)490*b30d1939SAndy Fiddaman extern int b_open(int argc, char *argv[], Shbltin_t *context)
491*b30d1939SAndy Fiddaman {
492*b30d1939SAndy Fiddaman 	register Namval_t *np;
493*b30d1939SAndy Fiddaman 	register int n,oflag=0;
494*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
495*b30d1939SAndy Fiddaman 	struct filedata *fdp;
496*b30d1939SAndy Fiddaman 	mode_t mode = 0666;
497*b30d1939SAndy Fiddaman 	long flags = 0;
498*b30d1939SAndy Fiddaman 	int fd = -1;
499*b30d1939SAndy Fiddaman 	char *arg;
500*b30d1939SAndy Fiddaman 
501*b30d1939SAndy Fiddaman 	while (n = optget(argv, sh_optopen)) switch (n)
502*b30d1939SAndy Fiddaman 	{
503*b30d1939SAndy Fiddaman 	    case 'r':
504*b30d1939SAndy Fiddaman 	    case 'w':
505*b30d1939SAndy Fiddaman 	    case 'i':
506*b30d1939SAndy Fiddaman 		flags |= letterbit(n);
507*b30d1939SAndy Fiddaman 		break;
508*b30d1939SAndy Fiddaman 	    case 'I':
509*b30d1939SAndy Fiddaman 		flags &= ~(letterbit('i'));
510*b30d1939SAndy Fiddaman 		break;
511*b30d1939SAndy Fiddaman 	    case 'b':
512*b30d1939SAndy Fiddaman #ifdef O_BINARY
513*b30d1939SAndy Fiddaman 		oflag |= O_BINARY;
514*b30d1939SAndy Fiddaman #endif
515*b30d1939SAndy Fiddaman 		break;
516*b30d1939SAndy Fiddaman 	    case 't':
517*b30d1939SAndy Fiddaman #ifdef O_TEXT
518*b30d1939SAndy Fiddaman 		oflag |= O_TEXT;
519*b30d1939SAndy Fiddaman #endif
520*b30d1939SAndy Fiddaman 		break;
521*b30d1939SAndy Fiddaman 	    case 'N':
522*b30d1939SAndy Fiddaman #ifdef O_NOFOLLOW
523*b30d1939SAndy Fiddaman 		oflag |= O_NOFOLLOW;
524*b30d1939SAndy Fiddaman #endif
525*b30d1939SAndy Fiddaman 		break;
526*b30d1939SAndy Fiddaman 	    case 'T':
527*b30d1939SAndy Fiddaman #ifdef O_TRUNC
528*b30d1939SAndy Fiddaman 		oflag |= O_TRUNC;
529*b30d1939SAndy Fiddaman #endif
530*b30d1939SAndy Fiddaman 		break;
531*b30d1939SAndy Fiddaman 	    case 'x':
532*b30d1939SAndy Fiddaman 		oflag |= O_EXCL;
533*b30d1939SAndy Fiddaman 		break;
534*b30d1939SAndy Fiddaman 	    case 'c':
535*b30d1939SAndy Fiddaman 		oflag |= O_CREAT;
536*b30d1939SAndy Fiddaman 		break;
537*b30d1939SAndy Fiddaman 	    case 'a':
538*b30d1939SAndy Fiddaman 		oflag |= O_APPEND;
539*b30d1939SAndy Fiddaman 		break;
540*b30d1939SAndy Fiddaman 	    case 'S':
541*b30d1939SAndy Fiddaman #ifdef O_SYNC
542*b30d1939SAndy Fiddaman 		oflag |= O_SYNC;
543*b30d1939SAndy Fiddaman #endif
544*b30d1939SAndy Fiddaman 		break;
545*b30d1939SAndy Fiddaman 	    case 'm':
546*b30d1939SAndy Fiddaman 		mode = strperm(arg = opt_info.arg, &opt_info.arg, mode);
547*b30d1939SAndy Fiddaman 		if (*opt_info.arg)
548*b30d1939SAndy Fiddaman 			errormsg(SH_DICT, ERROR_system(1), "%s: invalid mode", arg);
549*b30d1939SAndy Fiddaman 	    	break;
550*b30d1939SAndy Fiddaman 	    case ':':
551*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, 2, "%s", opt_info.arg);
552*b30d1939SAndy Fiddaman 		break;
553*b30d1939SAndy Fiddaman 	    case '?':
554*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
555*b30d1939SAndy Fiddaman 		break;
556*b30d1939SAndy Fiddaman 	}
557*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
558*b30d1939SAndy Fiddaman 	argv += opt_info.index;
559*b30d1939SAndy Fiddaman 	if(argc!=2 || !(flags&(letterbit('r')|letterbit('w'))))
560*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
561*b30d1939SAndy Fiddaman 
562*b30d1939SAndy Fiddaman 	if(flags&letterbit('r'))
563*b30d1939SAndy Fiddaman 	{
564*b30d1939SAndy Fiddaman 		if(flags&letterbit('w'))
565*b30d1939SAndy Fiddaman 			oflag |= O_RDWR;
566*b30d1939SAndy Fiddaman 		else
567*b30d1939SAndy Fiddaman 			oflag |= O_RDONLY;
568*b30d1939SAndy Fiddaman 	}
569*b30d1939SAndy Fiddaman 	else if(flags&letterbit('w'))
570*b30d1939SAndy Fiddaman 		oflag |= O_WRONLY;
571*b30d1939SAndy Fiddaman 
572*b30d1939SAndy Fiddaman 	fd = sh_open(argv[1], oflag, mode);
573*b30d1939SAndy Fiddaman 	if(fd<0)
574*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: open failed", argv[1]);
575*b30d1939SAndy Fiddaman 
576*b30d1939SAndy Fiddaman 	if(!(flags&letterbit('i')))
577*b30d1939SAndy Fiddaman 		fcntl(fd, F_SETFL, 0);
578*b30d1939SAndy Fiddaman 
579*b30d1939SAndy Fiddaman 	np = nv_open(argv[0], shp->var_tree, NV_ARRAY|NV_VARNAME|NV_NOASSIGN);
580*b30d1939SAndy Fiddaman 	if(!nv_isnull(np))
581*b30d1939SAndy Fiddaman 		nv_unset(np);
582*b30d1939SAndy Fiddaman 	mkclass(np, &Fileclass);
583*b30d1939SAndy Fiddaman 	fdp = (struct filedata*)np->nvalue;
584*b30d1939SAndy Fiddaman 	fstat(fd, &fdp->statb);
585*b30d1939SAndy Fiddaman 	fdp->fd = fd;
586*b30d1939SAndy Fiddaman 	fdp->name = strdup(argv[1]);
587*b30d1939SAndy Fiddaman 	return(0);
588*b30d1939SAndy Fiddaman }
589*b30d1939SAndy Fiddaman 
590*b30d1939SAndy Fiddaman static const char sh_optclose[] =
591*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: close (AT&T Labs Research) 2007-04-21 $\n]"
592*b30d1939SAndy Fiddaman "[-author?Roland Mainz <roland.mainz@nrubsig.org>]"
593*b30d1939SAndy Fiddaman "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
594*b30d1939SAndy Fiddaman "[+NAME? close - close a file descriptor]"
595*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bclose\b closes the file descriptor specified by fd.]"
596*b30d1939SAndy Fiddaman "\n"
597*b30d1939SAndy Fiddaman "\nfd\n"
598*b30d1939SAndy Fiddaman "\n"
599*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
600*b30d1939SAndy Fiddaman         "[+0?Success.]"
601*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
602*b30d1939SAndy Fiddaman "}"
603*b30d1939SAndy Fiddaman "[+SEE ALSO?\bopen\b(1),\bdup\b(1),\btmpfile\b(1),\bpoll\b(1),\bstat\b(1)]"
604*b30d1939SAndy Fiddaman ;
605*b30d1939SAndy Fiddaman 
b_close(int argc,char * argv[],Shbltin_t * context)606*b30d1939SAndy Fiddaman extern int b_close(int argc, char *argv[], Shbltin_t *context)
607*b30d1939SAndy Fiddaman {
608*b30d1939SAndy Fiddaman 	register int n=0;
609*b30d1939SAndy Fiddaman 	int fd = -1;
610*b30d1939SAndy Fiddaman 
611*b30d1939SAndy Fiddaman 	while (n = optget(argv, sh_optclose)) switch (n)
612*b30d1939SAndy Fiddaman 	{
613*b30d1939SAndy Fiddaman 	    case ':':
614*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, 2, "%s", opt_info.arg);
615*b30d1939SAndy Fiddaman 		break;
616*b30d1939SAndy Fiddaman 	    case '?':
617*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
618*b30d1939SAndy Fiddaman 		break;
619*b30d1939SAndy Fiddaman 	}
620*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
621*b30d1939SAndy Fiddaman 	argv += opt_info.index;
622*b30d1939SAndy Fiddaman 	if(argc!=1)
623*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
624*b30d1939SAndy Fiddaman 
625*b30d1939SAndy Fiddaman 	errno = 0;
626*b30d1939SAndy Fiddaman 	fd = strtol(argv[0], (char **)NULL, 0);
627*b30d1939SAndy Fiddaman 	if (errno != 0 || fd < 0)
628*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: invalid descriptor", argv[0]);
629*b30d1939SAndy Fiddaman 
630*b30d1939SAndy Fiddaman         n = sh_close(fd);
631*b30d1939SAndy Fiddaman 
632*b30d1939SAndy Fiddaman 	if (n < 0)
633*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: close error", argv[0]);
634*b30d1939SAndy Fiddaman 
635*b30d1939SAndy Fiddaman 	return(n==0?0:1);
636*b30d1939SAndy Fiddaman }
637*b30d1939SAndy Fiddaman 
638*b30d1939SAndy Fiddaman 
639*b30d1939SAndy Fiddaman static const char sh_opttmpfile[] =
640*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: tmpfile (AT&T Labs Research) 2007-05-07 $\n]"
641*b30d1939SAndy Fiddaman "[-author?Roland Mainz <roland.mainz@nrubsig.org>]"
642*b30d1939SAndy Fiddaman "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
643*b30d1939SAndy Fiddaman "[+NAME? tmpfile - create a shell variable corresponding to a temporary file]"
644*b30d1939SAndy Fiddaman "[+DESCRIPTION?\btmpfile\b creates the compound variable \avar\a corresponding "
645*b30d1939SAndy Fiddaman 	"to a temporary file.  The elements of \avar\a "
646*b30d1939SAndy Fiddaman 	"are the names of elements in the \astat\a structure with the \bst_\b "
647*b30d1939SAndy Fiddaman 	"prefix removed.]"
648*b30d1939SAndy Fiddaman "[i:inherit?Open without the close-on-exec bit set.]"
649*b30d1939SAndy Fiddaman "[I:noinherit?Open with the close-on-exec bit set.]"
650*b30d1939SAndy Fiddaman "\n"
651*b30d1939SAndy Fiddaman "\nvar\n"
652*b30d1939SAndy Fiddaman "\n"
653*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
654*b30d1939SAndy Fiddaman         "[+0?Success.]"
655*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
656*b30d1939SAndy Fiddaman "}"
657*b30d1939SAndy Fiddaman "[+SEE ALSO?\bopen\b(1),\bdup\b(1),\bclose\b(1),\bstat\b(1),\bstat\b(2)]"
658*b30d1939SAndy Fiddaman ;
659*b30d1939SAndy Fiddaman 
660*b30d1939SAndy Fiddaman 
b_tmpfile(int argc,char * argv[],Shbltin_t * context)661*b30d1939SAndy Fiddaman extern int b_tmpfile(int argc, char *argv[], Shbltin_t *context)
662*b30d1939SAndy Fiddaman {
663*b30d1939SAndy Fiddaman 	register Namval_t *np;
664*b30d1939SAndy Fiddaman 	register int n;
665*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
666*b30d1939SAndy Fiddaman 	struct filedata *fdp;
667*b30d1939SAndy Fiddaman 	bool inherit = false;
668*b30d1939SAndy Fiddaman 	FILE *file = NULL;
669*b30d1939SAndy Fiddaman 	int ffd, fd = -1;
670*b30d1939SAndy Fiddaman 	while (n = optget(argv, sh_opttmpfile)) switch (n)
671*b30d1939SAndy Fiddaman 	{
672*b30d1939SAndy Fiddaman 	    case 'i':
673*b30d1939SAndy Fiddaman 		inherit = true;
674*b30d1939SAndy Fiddaman 		break;
675*b30d1939SAndy Fiddaman 	    case 'I':
676*b30d1939SAndy Fiddaman 		inherit = false;
677*b30d1939SAndy Fiddaman 		break;
678*b30d1939SAndy Fiddaman 	    case ':':
679*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, 2, "%s", opt_info.arg);
680*b30d1939SAndy Fiddaman 		break;
681*b30d1939SAndy Fiddaman 	    case '?':
682*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
683*b30d1939SAndy Fiddaman 		break;
684*b30d1939SAndy Fiddaman 	}
685*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
686*b30d1939SAndy Fiddaman 	argv += opt_info.index;
687*b30d1939SAndy Fiddaman 	if(argc!=1)
688*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
689*b30d1939SAndy Fiddaman 
690*b30d1939SAndy Fiddaman 	file = tmpfile();
691*b30d1939SAndy Fiddaman 	if(!file)
692*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: tmpfile failed", argv[1]);
693*b30d1939SAndy Fiddaman 	ffd = fileno(file);
694*b30d1939SAndy Fiddaman 	fd = sh_dup(ffd);
695*b30d1939SAndy Fiddaman 	if(fd<0)
696*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: tmpfile failed", argv[1]);
697*b30d1939SAndy Fiddaman 	fclose(file);
698*b30d1939SAndy Fiddaman 
699*b30d1939SAndy Fiddaman 	if(!inherit)
700*b30d1939SAndy Fiddaman 		fcntl(fd, F_SETFL, 0);
701*b30d1939SAndy Fiddaman 
702*b30d1939SAndy Fiddaman 	np = nv_open(argv[0], shp->var_tree, NV_ARRAY|NV_VARNAME|NV_NOASSIGN);
703*b30d1939SAndy Fiddaman 	if(!nv_isnull(np))
704*b30d1939SAndy Fiddaman 		nv_unset(np);
705*b30d1939SAndy Fiddaman 	mkclass(np,&Fileclass);
706*b30d1939SAndy Fiddaman 	fdp = (struct filedata*)np->nvalue;
707*b30d1939SAndy Fiddaman 
708*b30d1939SAndy Fiddaman 	fstat(fd, &fdp->statb);
709*b30d1939SAndy Fiddaman 	fdp->fd = fd;
710*b30d1939SAndy Fiddaman 	fdp->name = NULL;
711*b30d1939SAndy Fiddaman 	return(0);
712*b30d1939SAndy Fiddaman }
713*b30d1939SAndy Fiddaman 
714*b30d1939SAndy Fiddaman static const char sh_optdup[] =
715*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: dup (AT&T Labs Research) 2007-05-07 $\n]"
716*b30d1939SAndy Fiddaman "[-author?Roland Mainz <roland.mainz@nrubsig.org>]"
717*b30d1939SAndy Fiddaman "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
718*b30d1939SAndy Fiddaman "[+NAME? dup - duplicate an open file descriptor]"
719*b30d1939SAndy Fiddaman "[+DESCRIPTION?The \bdup\b commands returns a new file descriptor having the "
720*b30d1939SAndy Fiddaman      "following in common with the original open file descriptor "
721*b30d1939SAndy Fiddaman      "fd: same open file (or pipe), same file pointer (that is, both  file descriptors "
722*b30d1939SAndy Fiddaman      "share one file pointer) same access mode (read, write or read/write). "
723*b30d1939SAndy Fiddaman      "The file descriptor returned is the lowest one available.]"
724*b30d1939SAndy Fiddaman "[i:inherit?Open without the close-on-exec bit set.]"
725*b30d1939SAndy Fiddaman "[I:noinherit?Open with the close-on-exec bit set.]"
726*b30d1939SAndy Fiddaman "\n"
727*b30d1939SAndy Fiddaman "\nvar fd\n"
728*b30d1939SAndy Fiddaman "\n"
729*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
730*b30d1939SAndy Fiddaman         "[+0?Success.]"
731*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
732*b30d1939SAndy Fiddaman "}"
733*b30d1939SAndy Fiddaman "[+SEE ALSO?\bopen\b(1),\btmpfile\b(1),\bclose\b(1),\bpoll\b(1),\bstat\b(1)]"
734*b30d1939SAndy Fiddaman ;
735*b30d1939SAndy Fiddaman 
736*b30d1939SAndy Fiddaman 
b_dup(int argc,char * argv[],Shbltin_t * context)737*b30d1939SAndy Fiddaman extern int b_dup(int argc, char *argv[], Shbltin_t *context)
738*b30d1939SAndy Fiddaman {
739*b30d1939SAndy Fiddaman 	register Namval_t *np;
740*b30d1939SAndy Fiddaman 	register int n;
741*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
742*b30d1939SAndy Fiddaman 	struct filedata *fdp;
743*b30d1939SAndy Fiddaman 	bool inherit = false;
744*b30d1939SAndy Fiddaman 	int ffd, fd = -1;
745*b30d1939SAndy Fiddaman 	while (n = optget(argv, sh_optdup)) switch (n)
746*b30d1939SAndy Fiddaman 	{
747*b30d1939SAndy Fiddaman 	    case 'i':
748*b30d1939SAndy Fiddaman 		inherit = true;
749*b30d1939SAndy Fiddaman 		break;
750*b30d1939SAndy Fiddaman 	    case 'I':
751*b30d1939SAndy Fiddaman 		inherit = false;
752*b30d1939SAndy Fiddaman 		break;
753*b30d1939SAndy Fiddaman 	    case ':':
754*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, 2, "%s", opt_info.arg);
755*b30d1939SAndy Fiddaman 		break;
756*b30d1939SAndy Fiddaman 	    case '?':
757*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
758*b30d1939SAndy Fiddaman 		break;
759*b30d1939SAndy Fiddaman 	}
760*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
761*b30d1939SAndy Fiddaman 	argv += opt_info.index;
762*b30d1939SAndy Fiddaman 	if(argc!=2)
763*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
764*b30d1939SAndy Fiddaman 
765*b30d1939SAndy Fiddaman 	errno = 0;
766*b30d1939SAndy Fiddaman 	ffd = strtol(argv[1], (char **)NULL, 0);
767*b30d1939SAndy Fiddaman 	if (errno != 0 || ffd < 0)
768*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: invalid fd", argv[1]);
769*b30d1939SAndy Fiddaman 
770*b30d1939SAndy Fiddaman 	fd = sh_dup(ffd);
771*b30d1939SAndy Fiddaman 	if(fd<0)
772*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: dup failed", argv[1]);
773*b30d1939SAndy Fiddaman 
774*b30d1939SAndy Fiddaman 	if(!inherit)
775*b30d1939SAndy Fiddaman 		fcntl(fd,F_SETFL,0);
776*b30d1939SAndy Fiddaman 
777*b30d1939SAndy Fiddaman 	np = nv_open(argv[0],shp->var_tree,NV_ARRAY|NV_VARNAME|NV_NOASSIGN);
778*b30d1939SAndy Fiddaman 	if(!nv_isnull(np))
779*b30d1939SAndy Fiddaman 		nv_unset(np);
780*b30d1939SAndy Fiddaman 	mkclass(np, &Fileclass);
781*b30d1939SAndy Fiddaman 	fdp = (struct filedata*)np->nvalue;
782*b30d1939SAndy Fiddaman 
783*b30d1939SAndy Fiddaman 	fstat(fd, &fdp->statb);
784*b30d1939SAndy Fiddaman 	fdp->fd = fd;
785*b30d1939SAndy Fiddaman 	fdp->name = NULL;
786*b30d1939SAndy Fiddaman 	return(0);
787*b30d1939SAndy Fiddaman }
788*b30d1939SAndy Fiddaman 
789*b30d1939SAndy Fiddaman static const char sh_optstat[] =
790*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: stat (AT&T Labs Research) 2007-05-07 $\n]"
791*b30d1939SAndy Fiddaman "[-author?David Korn <dgk@research.att.com>]"
792*b30d1939SAndy Fiddaman "[-author?Roland Mainz <roland.mainz@nrubsig.org>]"
793*b30d1939SAndy Fiddaman "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
794*b30d1939SAndy Fiddaman "[+NAME? stat - get file status]"
795*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bstat\b creates the compound variable \avar\a corresponding "
796*b30d1939SAndy Fiddaman 	"to the file given by the pathname \afile\a.  The elements of \avar\a "
797*b30d1939SAndy Fiddaman 	"are the names of elements in the \astat\a structure with the \bst_\b "
798*b30d1939SAndy Fiddaman 	"prefix removed.]"
799*b30d1939SAndy Fiddaman "[l:lstat?If the the named file is a symbolic link returns information about "
800*b30d1939SAndy Fiddaman 	"the link itself.]"
801*b30d1939SAndy Fiddaman "\n"
802*b30d1939SAndy Fiddaman "\nvar file\n"
803*b30d1939SAndy Fiddaman "\n"
804*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
805*b30d1939SAndy Fiddaman         "[+0?Success.]"
806*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
807*b30d1939SAndy Fiddaman "}"
808*b30d1939SAndy Fiddaman "[+SEE ALSO?\bopen\b(1),\btmpfile\b(1),\bdup\b(1),\bclose\b(1),\bpoll\b(1),\bstat\b(2),\blstat\b(2)]"
809*b30d1939SAndy Fiddaman ;
810*b30d1939SAndy Fiddaman 
811*b30d1939SAndy Fiddaman 
b_stat(int argc,char * argv[],Shbltin_t * context)812*b30d1939SAndy Fiddaman extern int b_stat(int argc, char *argv[], Shbltin_t *context)
813*b30d1939SAndy Fiddaman {
814*b30d1939SAndy Fiddaman 	register Namval_t *np;
815*b30d1939SAndy Fiddaman 	register int n;
816*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
817*b30d1939SAndy Fiddaman 	struct filedata *fdp;
818*b30d1939SAndy Fiddaman 	long flags = 0;
819*b30d1939SAndy Fiddaman 	struct stat statb;
820*b30d1939SAndy Fiddaman 	while (n = optget(argv, sh_optstat)) switch (n)
821*b30d1939SAndy Fiddaman 	{
822*b30d1939SAndy Fiddaman 	    case 'l':
823*b30d1939SAndy Fiddaman 		flags |= letterbit(n);
824*b30d1939SAndy Fiddaman 		break;
825*b30d1939SAndy Fiddaman 	    case ':':
826*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, 2, "%s", opt_info.arg);
827*b30d1939SAndy Fiddaman 		break;
828*b30d1939SAndy Fiddaman 	    case '?':
829*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
830*b30d1939SAndy Fiddaman 		break;
831*b30d1939SAndy Fiddaman 	}
832*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
833*b30d1939SAndy Fiddaman 	argv += opt_info.index;
834*b30d1939SAndy Fiddaman 	if(argc!=2)
835*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
836*b30d1939SAndy Fiddaman 
837*b30d1939SAndy Fiddaman 	if(flags&letterbit('l'))
838*b30d1939SAndy Fiddaman 	{
839*b30d1939SAndy Fiddaman 		if(lstat(argv[1], &statb) < 0)
840*b30d1939SAndy Fiddaman 			errormsg(SH_DICT, ERROR_system(1), "%s: stat failed", argv[1]);
841*b30d1939SAndy Fiddaman 	}
842*b30d1939SAndy Fiddaman 	else
843*b30d1939SAndy Fiddaman 	{
844*b30d1939SAndy Fiddaman 		if(stat(argv[1], &statb) < 0)
845*b30d1939SAndy Fiddaman 			errormsg(SH_DICT, ERROR_system(1), "%s: stat failed", argv[1]);
846*b30d1939SAndy Fiddaman 
847*b30d1939SAndy Fiddaman 	}
848*b30d1939SAndy Fiddaman 
849*b30d1939SAndy Fiddaman 	np = nv_open(argv[0],shp->var_tree,NV_ARRAY|NV_VARNAME|NV_NOASSIGN);
850*b30d1939SAndy Fiddaman 	if(!nv_isnull(np))
851*b30d1939SAndy Fiddaman 		nv_unset(np);
852*b30d1939SAndy Fiddaman 	mkclass(np,&Fileclass);
853*b30d1939SAndy Fiddaman 	fdp = (struct filedata*)np->nvalue;
854*b30d1939SAndy Fiddaman 	fdp->statb = statb;
855*b30d1939SAndy Fiddaman 	fdp->fd = -1;
856*b30d1939SAndy Fiddaman 	fdp->name = strdup(argv[1]);
857*b30d1939SAndy Fiddaman 	return(0);
858*b30d1939SAndy Fiddaman }
859*b30d1939SAndy Fiddaman 
860*b30d1939SAndy Fiddaman 
861*b30d1939SAndy Fiddaman static const char sh_optrewind[] =
862*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: rewind (AT&T Labs Research) 2007-05-07 $\n]"
863*b30d1939SAndy Fiddaman "[-author?Roland Mainz <roland.mainz@nrubsig.org>]"
864*b30d1939SAndy Fiddaman "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
865*b30d1939SAndy Fiddaman "[+NAME? rewind - reset file position indicator in a stream]"
866*b30d1939SAndy Fiddaman "[+DESCRIPTION?The \brewind\b command will move the file pointer of fd to position 0.]"
867*b30d1939SAndy Fiddaman "\n"
868*b30d1939SAndy Fiddaman "\nfd\n"
869*b30d1939SAndy Fiddaman "\n"
870*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
871*b30d1939SAndy Fiddaman         "[+0?Success.]"
872*b30d1939SAndy Fiddaman         "[+>0?An error occurred.]"
873*b30d1939SAndy Fiddaman "}"
874*b30d1939SAndy Fiddaman "[+SEE ALSO?\bopen\b(1),\btmpfile\b(1),\bdup\b(1),\bclose\b(1),\bstat\b(1),\bstat\b(2)]"
875*b30d1939SAndy Fiddaman ;
876*b30d1939SAndy Fiddaman 
877*b30d1939SAndy Fiddaman 
b_rewind(int argc,char * argv[],Shbltin_t * context)878*b30d1939SAndy Fiddaman extern int b_rewind(int argc, char *argv[], Shbltin_t *context)
879*b30d1939SAndy Fiddaman {
880*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
881*b30d1939SAndy Fiddaman 	int fd = -1;
882*b30d1939SAndy Fiddaman 	register int n;
883*b30d1939SAndy Fiddaman 	while (n = optget(argv, sh_optrewind)) switch (n)
884*b30d1939SAndy Fiddaman 	{
885*b30d1939SAndy Fiddaman 	    case ':':
886*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, 2, "%s", opt_info.arg);
887*b30d1939SAndy Fiddaman 		break;
888*b30d1939SAndy Fiddaman 	    case '?':
889*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
890*b30d1939SAndy Fiddaman 		break;
891*b30d1939SAndy Fiddaman 	}
892*b30d1939SAndy Fiddaman 	argc -= opt_info.index;
893*b30d1939SAndy Fiddaman 	argv += opt_info.index;
894*b30d1939SAndy Fiddaman 	if(argc!=1)
895*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
896*b30d1939SAndy Fiddaman 
897*b30d1939SAndy Fiddaman 	errno = 0;
898*b30d1939SAndy Fiddaman 	fd = strtol(argv[0], (char **)NULL, 0);
899*b30d1939SAndy Fiddaman 	if (errno != 0 || fd < 0)
900*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "%s: invalid fd", argv[0]);
901*b30d1939SAndy Fiddaman 
902*b30d1939SAndy Fiddaman 	if (sh_seek(fd, 0, SEEK_SET) == (off_t)-1)
903*b30d1939SAndy Fiddaman 		errormsg(SH_DICT, ERROR_system(1), "seek error");
904*b30d1939SAndy Fiddaman 
905*b30d1939SAndy Fiddaman 	return(0);
906*b30d1939SAndy Fiddaman }
907