[rfc] xioctl()

Tito farmatito at tiscali.it
Sun Jun 24 15:20:00 UTC 2007


On Sunday 24 June 2007 16:25:20 walter harms wrote:
> 
> Tito wrote:
> > On Sunday 24 June 2007 14:59:42 walter harms wrote:
> >> perhaps this can be fixed using a macro like:
> >>
> >>
> >> #define xioctl(fd,req,...)   bb_ioctl(#req,fd,req,__VA_ARGS__)
> >>
> >> static int bb_ioctl(const char *estr, int fd, int request, void *argp, ...)
> >> ...
> >>
> >> xioctl(get_console_fd(), VT_DISALLOCATE, (void *)num);
> >> will now call a modified
> >> bb_ioctl("VT_DISALLOCATE",get_console_fd(), VT_DISALLOCATE, (void *)num);
> >>
> >> the define eats no space and the new bb_ioctl will allow passing a free errormsg.
> >>
> >>
> >> beware: I did no real testing an that ...
> >>
> >>
> >> re,
> >>  wh
> > 
> > Hi,
> > you can fix it the same way also without a macro by adding one more arg to 
> > the function (eventually set to NULL to trigger the default behaviour):
> > 
> > xioctl(int fd, int request, void *argp, char * emsg)
> > 
> 
> 
> This is a fix that changes the semantic of the call. IMHO the xcalls should emulate to original.
> therefore i used bb_ioclt() as the one with the additional argument.
> 
> 
> > but the initial idea was to supply a default error message "ioctl" and switch to
> > an optional error message with printf formatting capabilities only if needed
> > without increasing the number of args needed by default by the function like:
> > 
> > xioctl(int fd, int request, void *argp,...)
> > 
> > so that we could do:
> > 
> > xioctl(fd, request, argp)
> > or
> > xioctl(fd, request, argp, "this ioctl failed %s %s", a, b)
> > 
> > but i found no way to test fot the presence or absence
> > of args in the va_list......as the behaviour seems to be
> > undefined if i understand the man page correctly. 
> > 
> > Ciao,
> > Tito
> > 
> > 
> > 
>
Hi,
new implementation of xioctl that follows all the hints of the mailing list.
Comments, critics and hints are welcome...

Ciao,
Tito

/* in libbb.h*/
#define xioctl_request_name_and_die(fd,request,argp)  xioctl_msg_and_die(fd,request,argp,#request)
void xioctl_msg_and_die(int fd, int request, void *argp, const char *fmt,...);
void xioctl(int fd, int request, void *argp);

/* in xfuncs.c */
void xioctl_msg_and_die(int fd, int request, void *argp, const char *fmt,...)
{
	va_list p;

	if (ioctl(fd, request, argp) < 0) {
		if (fmt) {
			va_start(p, fmt);
			bb_vperror_msg(fmt, p);
			/* va_end(p);*/
		} else {
			bb_perror_msg("ioctl %#x failed", request);
		}
		xfunc_die();
	}
}

void xioctl(int fd, int request, void *argp)
{
	xioctl_msg_and_die(fd, request, argp, NULL);
}

/* example in deallocvt.c */

int deallocvt_main(int argc, char **argv)
{
	/* num = 0 deallocate all unused consoles */
	int num = 0;

	switch (argc) {
	case 2:
		num = xatoul_range(argv[1], 1, 63);
		/* Fallthrough */
	case 1:
		break;
	default:
		bb_show_usage();
	}

	/*if (-1 == ioctl(get_console_fd(), VT_DISALLOCATE, num)) {
		bb_perror_msg_and_die("VT_DISALLOCATE");
	}*/
	xioctl(get_console_fd(), VT_DISALLOCATE, (void *)num);

	or 

	xioctl_request_name_and_die(get_console_fd(), VT_DISALLOCATE, (void *)num);

	or

	xioctl_msg_and_die(get_console_fd(), VT_DISALLOCATE, (void *)num, "this ioctl failed");
	return EXIT_SUCCESS;
}

output will be:

./busybox deallocvt 63
deallocvt: ioctl 0x5608 failed: Device or resource busy

./busybox deallocvt 63
deallocvt: VT_DISALLOCATE: Device or resource busy

./busybox deallocvt 63
deallocvt: this ioctl failed: Device or resource busy







More information about the busybox mailing list