Esempio n. 1
0
dev_t rsrcdbmgr_devno_attach(const char *name, int minor_guess, int flags) {
    iov_t					iovout[3], iovin[1];
    rsrc_cmd_t				request;
    rsrc_minor_request_t	data;

    if (name && strchr(name, '/')) {
        errno = EINVAL;
        return((dev_t)-1);
    }
    if (!name)
        name = " ";

    request.i.type = RSRCDBMGR_RSRC_CMD;
    request.i.subtype = RSRCDBMGR_REQ_ATTACH | RSRCDBMGR_MINOR_NUM;
    request.i.pid = 0;
    request.i.count = 1;
    request.i.nbytes = sizeof(data) + strlen(name) +1;

    data.major = 0;
    data.minor = minor_guess;
    data.flags = flags;
    data.name = NULL;

    SETIOV(&iovout[0], &request, sizeof(request));
    SETIOV(&iovout[1], &data, sizeof(data));
    SETIOV(&iovout[2], name, strlen(name) +1);
    SETIOV(&iovin[0], &data, sizeof(data));

    if (MsgSendv(RSRCDBMGR_COID, iovout, 3, iovin, 1) == -1) {
        return((dev_t)-1);
    }

    return(makedev(0, data.major, data.minor));
}
Esempio n. 2
0
ssize_t write(int fd, const void *buff, size_t nbytes) {
	io_write_t					msg;
	iov_t						iov[2];

	msg.i.type = _IO_WRITE;
	msg.i.combine_len = sizeof msg.i;
	msg.i.xtype = _IO_XTYPE_NONE;
	msg.i.nbytes = nbytes;
	msg.i.zero = 0;
	SETIOV(iov + 0, &msg.i, sizeof msg.i);
	SETIOV(iov + 1, buff, nbytes);
	return MsgSendv(fd, iov, 2, 0, 0);
}
Esempio n. 3
0
ssize_t _writexv(int fd, iov_t *iov, int nparts, unsigned xtype, void *xdata, size_t xdatalen, size_t nbytes) {
	io_write_t				msg;

	if(nparts < 1 || (int)xdatalen < 0) {
		errno = EINVAL;
		return -1;
	}
	msg.i.type = _IO_WRITE;
	msg.i.combine_len = sizeof msg.i;
	msg.i.xtype = xtype;
	msg.i.zero = 0;
	SETIOV(iov + 0, &msg.i, sizeof msg.i);
	if((msg.i.nbytes = nbytes) == 0) {
		int						i;

		for(i = 1; i < nparts; i++) {
			msg.i.nbytes += GETIOVLEN(&iov[i]);
		}
	}
	/* If the parts is negative, then the iov points to -nparts bytes of data */
	return MsgSendv(fd, iov, nparts, xdata, -xdatalen);
}
Esempio n. 4
0
int ioctl(int fd, int cmd, ...) {
    va_list vl;
	void *data;
	struct termios	ltermios;
#ifdef NOT_USED
	struct termios	*ptermios;
	struct termio	ltermio;
#endif
	struct termio	*ptermio;
	int				match, tempint;

	//Pull out the command and the data
	va_start(vl, cmd);
	data = va_arg(vl, void *);
	va_end(vl);

	/* 
     These calls have significantly different inputs or outputs
     that we have to manipulate (or re-direct entirely)
	*/
	switch ((unsigned)cmd) {	
	/**** These calls map to fcntl's ****/

	//Set/Clear FD_CLOEXEC state
	case FIOCLEX:	
		return(fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC));
	case FIONCLEX:
		return(fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC));

	//These are undoced uses for fcntl
	case SIOCGPGRP:
	case FIOGETOWN:
		if ( (tempint = fcntl (fd, F_GETOWN)) != -1)
			*(int *)data = tempint;
		return(tempint);
	case SIOCSPGRP:
	case FIOSETOWN:
		return(fcntl(fd, F_SETOWN, *(int *)data));

	//Set the non-blocking state for reads on and off
	case FIONBIO:
		if (*(int *)data)
			return(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK));
		else
			return(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK));

	//Set the async state on and off
	case FIOASYNC:
		if (*(int *)data)
			return(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC));
		else
			return(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_ASYNC));

	//Set/Clear exclusive mode
	case TIOCEXCL: {
		struct flock lflock;
		memset(&lflock, 0, sizeof(lflock));
		lflock.l_type = F_WRLCK;			//Fails if file opened read only?
		lflock.l_whence = SEEK_SET;
		lflock.l_start = 0;
		lflock.l_len = 0;
		lflock.l_pid = getpid();
		return(__fcntl2ioctl(fcntl(fd, F_SETLK, &lflock)));
	}
	case TIOCNXCL: {
		struct flock lflock;
		memset(&lflock, 0, sizeof(lflock));
		lflock.l_type = F_UNLCK;
		lflock.l_whence = SEEK_SET;
		lflock.l_start = 0;
		lflock.l_len = 0;
		lflock.l_pid = getpid();
		(void)fcntl(fd, F_GETLK, &lflock);
		return(__fcntl2ioctl(fcntl(fd, F_SETLK, &lflock)));
	}

	//Make the terminal the controlling terminal for the process
	case TIOCSCTTY:
		return(tcsetsid(fd, getpid()));
	//Dis-associate this terminal as the controlling terminal
	case TIOCNOTTY:
		return(tcsetsid(-1, getpid()));

	/**** These calls translate from one type to another using tc[s|g]etattr ****/

	//Terminal properties w/ termio
	case TCGETA: {
		ptermio = (struct termio *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		termios2termio(&ltermios, ptermio);
		return(EOK);
	}
	case TCSETA: {
		ptermio = (struct termio *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);		
		termio2termios(ptermio, &ltermios);
		return(tcsetattr(fd, TCSANOW, &ltermios));
	}
	case TCSETAW: {
		ptermio = (struct termio *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);		
		termio2termios(ptermio, &ltermios);
		return(tcsetattr(fd, TCSADRAIN, &ltermios));
	}
	case TCSETAF: {
		ptermio = (struct termio *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);		
		termio2termios(ptermio, &ltermios);
		return(tcsetattr(fd, TCSAFLUSH, &ltermios));
	}

	//Set terminal state in an sgttyb structure (incomplete)
	case TIOCGETP: {
		struct sgttyb *psgttyb = (struct sgttyb *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		termios2sgttyb(&ltermios, psgttyb);
		return(EOK);
	}	
	case TIOCSETP: {
		struct sgttyb *psgttyb = (struct sgttyb *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		sgttyb2termios(psgttyb, &ltermios);
		return(tcsetattr(fd, TCSAFLUSH, &ltermios));
	}
	case TIOCSETN: {
		struct sgttyb *psgttyb = (struct sgttyb *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		sgttyb2termios(psgttyb, &ltermios);
		return(tcsetattr(fd, TCSANOW, &ltermios));
	}

	//Terminal state in tchars structure
	case TIOCGETC: {
		struct tchars *ptchars = (struct tchars *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		termios2tchars(&ltermios, ptchars);
		return(EOK);
	}
	case TIOCSETC: {
		struct tchars *ptchars = (struct tchars *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		tchars2termios(ptchars, &ltermios);
		return(tcsetattr(fd, TCSANOW, &ltermios));
	}
	
	//Terminal state in an ltchars structure
	case TIOCGLTC: {
		struct ltchars *pltchars = (struct ltchars *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		termios2ltchars(&ltermios, pltchars);
		return(EOK);
	}
	case TIOCSLTC: {
		struct ltchars *pltchars = (struct ltchars *)data;
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		ltchars2termios(pltchars, &ltermios);
		return(tcsetattr(fd, TCSANOW, &ltermios));
	}

	//Set/Get the local flags structure
	case TIOCLGET: {
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		*((int *)data) = (int)ltermios.c_lflag;
		return(EOK);
	}
	case TIOCLSET: {
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		ltermios.c_lflag &= ~0xffff;
		ltermios.c_lflag |= *((int*)data);
		return(tcsetattr(fd, TCSANOW, &ltermios));
	}

	//Clear the break flag (implement TIOCSBRK?)
	case TIOCCBRK: {
		if (tcgetattr(fd, &ltermios) == -1)
			return(-1);
		ltermios.c_iflag &= ~(BRKINT);
		ltermios.c_iflag |= IGNBRK;
		return(tcsetattr(fd, TCSANOW, &ltermios));
	}

	//Set the HUPCL flag 
	case TIOCHPCL: {
		if (tcgetattr(fd, &ltermios) != -1) {
			ltermios.c_cflag |= HUPCL;
			return(tcsetattr(fd, TCSANOW, &ltermios));
		}
	}

	/**** These calls map to devctl's, but need serious data munging ****/

	//Inject a character into the stream
	case TIOCSTI: {	
		return(tcinject(fd, (char*)data, sizeof(char)));
	}

	//Send a break for a period of time
	case TCSBRK: {
		int *duration = (int *) data;				//Duration is measured in ms 
		return(tcsendbreak(fd, *duration));
		//tempint = (((*duration) ? *duration : 300) << 16) | _SERCTL_BRK_CHG | _SERCTL_BRK;
		//return(devctl(fd, DCMD_CHR_SERCTL, &tempint, sizeof(tempint), &ret));
	}

	/**** Modem control operations (via devctl) ****/
	//Clear the state of the modem by ~AND'ing in the int argument
	case TIOCMBIC: {
		int tmpmodem;
		if (_devctl(fd, DCMD_CHR_LINESTATUS, &tmpmodem, sizeof(tmpmodem), _DEVCTL_FLAG_NOTTY) == -1) 
			return(-1);
		tmpmodem &= ~(*((int*)data));
		tempint = 0;
		modem2serctl(&tmpmodem, &tempint);
		return(_devctl(fd, DCMD_CHR_SERCTL, &tempint, sizeof(tempint), _DEVCTL_FLAG_NOTTY)); 
	}
	//Set the state of the modem by OR'ing in the int argument
	case TIOCMBIS: {
		int tmpmodem;
		if (_devctl(fd, DCMD_CHR_LINESTATUS, &tmpmodem, sizeof(tmpmodem), _DEVCTL_FLAG_NOTTY) == -1) 
			return(-1);
		tmpmodem |= *((int*)data);		
		tempint = 0;
		modem2serctl(&tmpmodem, &tempint);
		return(_devctl(fd, DCMD_CHR_SERCTL, &tempint, sizeof(tempint), _DEVCTL_FLAG_NOTTY)); 
	}

	//Set the state of the modem lines
	case TIOCMSET: {
		tempint = 0;
		modem2serctl((int*)data, &tempint);
		return(_devctl(fd, DCMD_CHR_SERCTL, &tempint, sizeof(tempint), _DEVCTL_FLAG_NOTTY)); 
	}

	//Set/Clear DTR lines
	case TIOCCDTR: {
		int status; 
		if (_devctl(fd, DCMD_CHR_LINESTATUS, &status, sizeof(status), _DEVCTL_FLAG_NOTTY) == -1)
			return(-1);
		if (status & _LINESTATUS_SER_DTR) {
			status =  _SERCTL_DTR_CHG;
			return(_devctl(fd, DCMD_CHR_SERCTL, &status, sizeof(status), _DEVCTL_FLAG_NOTTY));
		}
		return(EOK);
	}
	case TIOCSDTR: {
		int status; 
		if (_devctl(fd, DCMD_CHR_LINESTATUS, &status, sizeof(status), _DEVCTL_FLAG_NOTTY) == -1)
			return(-1);
		if (!(status & _LINESTATUS_SER_DTR)) {
			status =  _SERCTL_DTR | _SERCTL_DTR_CHG;
			return(_devctl(fd, DCMD_CHR_SERCTL, &status, sizeof(status), _DEVCTL_FLAG_NOTTY));
		}
		return(EOK);
	}
	default:
		break;
	}

/*
 * The following block can go away when 6.4 is released
 * and <sys/sockio.h> from the networking project is
 * generally available.
 */
#ifndef NOSIOCGIFCONF
/* Define these as in the latest <sys/sockio.h> */
#define NOSIOCGIFCONF _IOWR('i', 36, struct ifconf)
#undef SIOCGIFCONF
#define SIOCGIFCONF   _IOWR('i', 38, struct ifconf)
#endif
	/* 
	 Generic handling for all but SIOCGIFCONF networking IOCTL's
	*/
	if ((unsigned)cmd == SIOCGIFCONF || (unsigned)cmd == NOSIOCGIFCONF) {
		io_devctl_t		msg;
		iov_t			wiov[2], riov[3];
		struct ifconf *ifconfp = (struct ifconf *)data;

		msg.i.type = _IO_DEVCTL;
		msg.i.combine_len = sizeof(msg.i);
		msg.i.dcmd = cmd;
		msg.i.zero = 0;
		msg.i.nbytes = ifconfp->ifc_len;

		SETIOV (wiov + 0, &msg, sizeof (msg.i));
		SETIOV (wiov + 1, data, IOCPARM_LEN((unsigned)cmd));
		SETIOV (riov + 0, &msg, sizeof (msg.o));
		SETIOV (riov + 1, ifconfp, sizeof (ifconfp->ifc_len));
		SETIOV (riov + 2, ifconfp->ifc_buf, ifconfp->ifc_len);
		return MsgSendv(fd, wiov, 2, riov, 3);
	}

	/* 
	 These calls require their command types to be translated
	*/
	switch ((unsigned)cmd) {
	case TCGETS:								//Not on NetBSD 
		SETNEWNUM(cmd, TIOCGETA);  match = 1;
		break;

	case TCSETS:								//Not on NetBSD
		SETNEWNUM(cmd, TIOCSETA);  match = 1; 
		break;

	case TCSETSW:								//Not on NetBSD
		SETNEWNUM(cmd, TIOCSETAW);  match = 1;
		break;

	case TCSETSF:								//Not on NetBSD
		SETNEWNUM(cmd, TIOCSETAF);  match = 1;
		break;

	case TIOCSETPGRP:							//Not on Sun
		SETNEWNUM(cmd, TIOCSPGRP);  match = 1;
		break;

	case TIOCGETPGRP:							//Not on Sun
		SETNEWNUM(cmd, TIOCGPGRP);  match = 1; 
		break;

	case TIOCSTOP: 
	case TIOCSTART:							
		//These functions pass in void but we need to pass an int so ...
		data = &tempint;
		tempint = (cmd == TIOCSTOP) ? TCOOFF : TIOCSTART;
		cmd = _IOW(_DCMD_CHR,TCXONC,int);		//Create new command  
	case TCXONC:								//Not on NetBSD
		//Assume incoming data already looks like:
		//data = 0= suspend output = TCOOFF, 1= restart output = TCOON
		//       2= suspend input = TCIOFF,  3= restart input = TCION
		SETNEWNUM(cmd, TCXONC);  match = 1;
		break;

	case TIOCFLUSH: 
		//Need to re-map 0 -> 2, FREAD -> 0, FWRITE -> 1
		switch (*((int*)data)) {
			case 0:      *((int*)data) = TCIOFLUSH; break;
			case FREAD:  *((int*)data) = TCIFLUSH; break;
			case FWRITE: *((int*)data) = TCOFLUSH; break;
			default: break;
		}
		/* Fall Through */
	case TCFLSH:								//Not on NetBSD 
		//Assume input data looks like:
		//data = 0 = flush in, 1 = flush output, 2 = flush both
		SETNEWNUM(cmd, TIOCFLUSH); match = 1;
		break;

	default:
		break;
	}

	//If you got this far then out you go as a generic devctl
	return(_devctl(fd, cmd, data, IOCPARM_LEN((unsigned)cmd), _DEVCTL_FLAG_NOTTY));
	/*
	 Returns different things for different commands:
	 - GETPRGRP returns pid_t 
	 - FIOREAD returns number of chars in input queue
	 - TIOCOUTQ returns number of chars in output queue
	 - 0 for all other cases
	*/
}
Esempio n. 5
0
void
service_message(struct _Ph_msg_forward *msg, input_region_data_t *regdat)
{
        input_module_t			*module;
        iov_t 				smx[3], rmx[1];
        io_devctl_t			devhdr;

        struct {
                struct _Ph_msg_forward	fwd;
                int			result;
        } reply;

        SETIOV(rmx, &reply, sizeof(reply));
        
        memset(&reply, '\0', sizeof(reply));

        devhdr.i.type            = _IO_DEVCTL;
        devhdr.i.combine_len 	 = 0;
        devhdr.i.dcmd            = _Ph_REPLY;
        devhdr.i.zero            = 0;
        SETIOV(&smx[0], &devhdr.i, sizeof(devhdr.i));

        reply.fwd.hdr.type = _Ph_REPLY;
        reply.fwd.pid = msg->pid;
        reply.fwd.len = sizeof(reply.result);
        reply.result = EOK;

        SETIOV(&smx[1], &reply, sizeof(reply));

        switch(msg->hdr.subtype) {

        case _INTERACTTYPE & 0xffff: {
                
                struct _interact_device *interact = 
                        (struct _interact_device *)((char *)msg + 
                                                    sizeof(struct _Ph_msg_forward));

                module = interact->handle;
                switch(module->type & DEVI_CLASS_MASK) {
                        
                case DEVI_CLASS_REL:
                case DEVI_CLASS_ABS:
                        interact->type = _INTERACT_TYPE_POINTER;
                        break;

                case DEVI_CLASS_KBD:
                        interact->type = _INTERACT_TYPE_KEY;
                        break;

                default:
                        break;
                }

                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*interact);
                SETIOV(&smx[2], interact, sizeof(*interact));
                break;

        }

        case _POINTERGETINFO & 0xffff: {

                unsigned long	         flags;

                struct _pointer_info	*ctrl =
                        (struct _pointer_info *)((char *)msg +
                                                 sizeof(struct _Ph_msg_forward));

                struct devctl_coord_range	range;

                module = ctrl->type.handle;
                if(!module) {
                        break;
                }

                memset(ctrl, '\0', sizeof(*ctrl));
                ctrl->type.type = _INTERACT_TYPE_POINTER;
                
                if(module->devctrl) {
                        (module->devctrl)(module, DEVCTL_GETPTRBTNS, 
                                         &ctrl->buttons);
                        (module->devctrl)(module, DEVCTL_GETDEVFLAGS, &flags);
                }
    
                ctrl->flags = 0U;
                
                if(flags & ABSOLUTE) {
                        ctrl->flags |= _POINTER_FLAG_TOUCH;
                        if(flags & ABS_PRESS_DATA) {
                                ctrl->flags |= _POINTER_FLAG_PRESSURE;
                        }
                } else {
                        ctrl->flags |= _POINTER_FLAG_MOUSE;
                }
                
                if(ctrl->buttons) {
                        ctrl->flags |= _POINTER_FLAG_BUTTON;
                }
    
                if(module->devctrl) {

                        if((module->devctrl)(module, DEVCTL_GETPTRCOORD, 
                                            &ctrl->num_coord) != -1) {

                                if(flags & ABSOLUTE) {

                                        for(range.which = 0; range.which < 
                                            ctrl->num_coord; range.which++) {
                                                (module->devctrl)(module, 
                                                                 DEVCTL_GETCOORDRNG, &range);
                                                ctrl->range[range.which].min = range.min;
                                                ctrl->range[range.which].max = range.max;
                                        }
                                }
                        } else {
                                ctrl->num_coord = 0;
                        }
                } else {
                        ctrl->num_coord = 0;
                }
                
                if(module->devctrl) {
                        if((module->devctrl)(module, DEVCTL_GETPTRPRESS, 
                                            &ctrl->num_pressure) != -1) {
                                
                                for(range.which = 0; range.which < 
                                    ctrl->num_pressure; range.which++) {

                                        (module->devctrl)(module, DEVCTL_GETPRESSRNG, &range);
                                        ctrl->range[range.which+
                                                    ctrl->num_coord].min = 
                                                            range.min;
                                        ctrl->range[range.which+
                                                    ctrl->num_coord].max = 
                                                            range.max;
                                }
                        } else {
                                ctrl->num_pressure = 0;
                        }
                } else {
                        ctrl->num_pressure = 0;
                }
                
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*ctrl);
                SETIOV(&smx[2], ctrl, sizeof(*ctrl));
                break;
        }
                
        case _POINTERGETCTRL & 0xffff: {
                
                struct _pointer_ctrl *ctrl =
                        (struct _pointer_ctrl *)((char *)msg + 
                                                 sizeof(struct _Ph_msg_forward));

                if (verbosity)
                        printf("POINTERGETCTRL\n");

                module = ctrl->type.handle;
                if(!module) {
                        reply.result = ESRCH;
                        goto reply;
                }
                
                memset(ctrl, '\0', sizeof(*ctrl));
                if(module->devctrl) {
                        struct devctl_rel_accel	accel;
		        struct devctl_wheel_accel wheel_accel;
                        if(module) {
                                unsigned swap = 0, wheel = 0;

                                if((module->devctrl)(module, DEVCTL_GETACCEL, 
                                                     &accel) == -1) {
                                        reply.result = ENOTSUP;
                                }

			        if((module->devctrl)(module, DEVCTL_GETWHEEL_ACCEL, 
                                                     &wheel_accel) == -1) {
                                        reply.result = ENOTSUP;
                                }

                                if((module->devctrl)(module, DEVCTL_GETSWAP, 
                                                     &swap) == -1) {
                                        reply.result = ENOTSUP;
                                }
                                if((module->devctrl)(module, DEVCTL_GETWHEEL, 
                                                     &wheel) == -1) {
                                        reply.result = ENOTSUP;
                                }

                                ctrl->flags = (swap << _POINTER_FLAG_SWAP_POS)
							                  | (wheel & 3) << 20;
                                ctrl->gain = accel.gain;
                                ctrl->threshold = accel.threshold;
                        } else {
                                reply.result = ESRCH;
                        }
                }

        reply:
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*ctrl);
                SETIOV(&smx[2], ctrl, sizeof(*ctrl));
                break;
        }

        case _POINTERSETCTRL & 0xffff: {

                struct _pointer_ctrl *ctrl =
                        (struct _pointer_ctrl *)((char *)msg + 
                                                 sizeof(struct _Ph_msg_forward));

                module = ctrl->type.handle;
                if(!module) {
                        break;
                }
                
                if(module->devctrl) {
                        struct devctl_rel_accel		accel;
                        unsigned			swap, wheel;
                        
                        accel.gain = ctrl->gain;
                        accel.threshold = ctrl->threshold;
                        swap = (ctrl->flags & _POINTER_FLAG_SWAP_MASK) >> 
                                _POINTER_FLAG_SWAP_POS;
				        wheel = (ctrl->flags & 0x00300000) >> 20;
                        
                        if(module) {
                                if((module->devctrl)(module, DEVCTL_SETACCEL, 
                                                     &accel) == -1) {
                                        reply.result = ENOTSUP;
                                }
                                if((module->devctrl)(module, DEVCTL_SETSWAP, 
                                                     &swap) == -1) {
                                        reply.result = ENOTSUP;
                                }
				if((module->devctrl)(module, DEVCTL_SETWHEEL,
				  		     &wheel) == -1)
			                reply.result = ENOTSUP;
                        } else {
                                reply.result = ESRCH;
                        }
                }
                
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*ctrl);
                SETIOV(&smx[2], ctrl, sizeof(*ctrl));
                break;
        }
                
        case _POINTERSETMATRIX & 0xffff: {
                
                struct _pointer_transform *transform =
                        (struct _pointer_transform *)((char *)msg + 
                                                      sizeof(struct _Ph_msg_forward));

                module = transform->type.handle;
                if(!module) {
                        break;
                }
                
                switch(module->type & DEVI_CLASS_MASK) {
                        
                case DEVI_CLASS_ABS: {
                        
                        struct devctl_disparea_res	new_res;

                        new_res.xl = transform->xy_coord.xoffset.number;
                        new_res.yl = transform->xy_coord.yoffset.number;
                        new_res.xh = transform->xy_coord.xscale.number;
                        new_res.yh = transform->xy_coord.yscale.number;
                        
                        if(module && module->devctrl) {
                                (module->devctrl)(module, DEVCTL_RESCHG, 
                                                  &new_res);
                        }
                }
                        
                default:
                        reply.result = EINVAL;
                        break;
                }
                
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*transform);
                SETIOV(&smx[2], transform, sizeof(*transform));
                break;
        }
                
        case _KEYBOARDGETCTRL & 0xffff: {
                
                struct _keyboard_ctrl *kbctrl =
                        (struct _keyboard_ctrl *)((char *)msg + 
                                                  sizeof(struct _Ph_msg_forward));
                
                module = (kbctrl) ? kbctrl->type.handle : NULL;
                if(!module) {
                        break;
                }

                switch(module->type & DEVI_CLASS_MASK) {
                        
                case DEVI_CLASS_KBD: {
                        
                        struct devctl_getkbd	info;
                        
                        (module->devctrl)(module, DEVCTL_GETKBD, &info);
                        kbctrl->rate = info.rate;
                        kbctrl->delay = info.delay;
                        break;
                }
                        
                default:
                        
                        reply.result = EINVAL;
                        break;
                }
                
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*kbctrl);
                SETIOV(&smx[2], kbctrl, sizeof(*kbctrl));
                break;
        }
                
        case _KEYBOARDSETCTRL & 0xffff: {
                
                struct _keyboard_ctrl *kbctrl =
                        (struct _keyboard_ctrl *)((char *)msg + 
                                                  sizeof(struct _Ph_msg_forward));
                
                module = kbctrl->type.handle;
                if(!module) {
                        break;
                }
                
                switch(module->type & DEVI_CLASS_MASK) {
                        
                case DEVI_CLASS_KBD: {
                        
                        if(module->devctrl) {
                                struct devctl_setkbd devctl;
                                
                                if(verbosity) {
                                        printf("%s: setting kb ctrl parms [rate %d, delay %d]\n", 
                                               module->name, kbctrl->rate, kbctrl->delay);
                                }							
                                devctl.delay = kbctrl->delay;
                                devctl.rate = kbctrl->rate;
                                if((module->devctrl)(module, DEVCTL_SETKBD, 
                                                    &devctl) == -1) {
                                        reply.result = ENOTSUP;
                                }
                        }
                        
                        break;
                }
                        
                default:
                        
                        reply.result = EINVAL;
                        break;
                }
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*kbctrl);
                SETIOV(&smx[2], kbctrl, sizeof(*kbctrl));
                break;
        }
                
        case _KEYBOARDGETKEYMAPPATH & 0xffff: {
                
                struct _keyboard_ctrl *keymap =
                        (struct _keyboard_ctrl *)((char *)msg + 
                                                  sizeof(struct _Ph_msg_forward));

		if (verbosity)
                        printf("devctl: KEYBOARDGETKEYMAPPATH\n");

                module = keymap->type.handle;
                if(!module || !keymap) {
                        break;
                }

                switch(module->type & DEVI_CLASS_MASK) {
	
                case DEVI_CLASS_KBD: {
                        
                        char          *kmf = keymap->mapfile;
                        
                        if(kmf) {
                                if((module->devctrl)(module, DEVCTL_GETKEYF, 
                                                     kmf) == -1) {
                                        reply.result = ENOTSUP;
                                }
                        }

                        break;
                }
                        
                default:
                        
                        reply.result = EINVAL;
                        break;
                }
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*keymap);
                SETIOV(&smx[2], keymap, sizeof(*keymap));
                break;
        }
                
        case _KEYBOARDSETKEYMAPPATH & 0xffff: {
                
                struct _keyboard_ctrl *keymap =
                        (struct _keyboard_ctrl *)((char *)msg + 
                                                  sizeof(struct _Ph_msg_forward));

		if (verbosity)
                        printf("devctl: KEYBOARDSETKEYMAPPATH\n");

                module = keymap->type.handle;
                if(!module) {
                        break;
                }
                
                switch(module->type & DEVI_CLASS_MASK) {
                        
                case DEVI_CLASS_KBD: {
                        
                        char          *kmf = keymap->mapfile;
                        
                        if((module->devctrl)(module, DEVCTL_SETKEYF, kmf) 
                           == -1) {
                                reply.result=ENOTSUP;
                        }
                        break;
                }
                        
                default:
                        
                        reply.result = EINVAL;
                        break;
                }

                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*keymap);
                SETIOV(&smx[2], keymap, sizeof(*keymap));
                break;
        }
                
                
        case _FEEDBACKGETLEDMASK & 0xffff: {
                
                struct _feedback_led *led =
                        (struct _feedback_led *)((char *)msg + 
                                                 sizeof(struct _Ph_msg_forward));

                module = led->type.handle;
                if(!module) break;
                
                switch(module->type & DEVI_CLASS_MASK) {
                        
                case DEVI_CLASS_KBD: {
                        
                        if(led) {
                                (module->devctrl)(module, DEVCTL_GETLEDMASK, 
                                                  led);
                        }
                        break;
                }
                default:
                        reply.result = EINVAL;
                        break;
                }
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*led);
                SETIOV(&smx[2], led, sizeof(*led));
                break;
        }
                
        case _FEEDBACKGETLED & 0xffff: {
                struct _feedback_led *led =
                        (struct _feedback_led *)((char *)msg + 
                                                 sizeof(struct _Ph_msg_forward));

                module = led->type.handle;
                if(!module) {
                        break;
                }
                
                switch(module->type & DEVI_CLASS_MASK) {
                        
                case DEVI_CLASS_KBD: {
                        
		if(led) {
		        struct devctl_led led2;
		        (module->devctrl)(module, DEVCTL_GETLED, &led2);
		        led->value = led2.value;
		        led->mask = led2.mask;
		}

                        break;
                }
                        
                default:
                        
                        reply.result = EINVAL;
                        break;
                }
                
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*led);
                SETIOV(&smx[2], led, sizeof(*led));
                break;
        }
                
        case _FEEDBACKSETLED & 0xffff: {
                
                struct _feedback_led *led =
                        (struct _feedback_led *)((char *)msg + 
                                                 sizeof(struct _Ph_msg_forward));
                
                module = led->type.handle;
                if(!module) {
                        break;
                }
    
                switch(module->type & DEVI_CLASS_MASK) {

                case DEVI_CLASS_KBD: {

                        reply.result=(module->devctrl)(module, DEVCTL_SETLED, 
                                                       led);
                        break;
                }
                        
                default:
                        reply.result = EINVAL;
                        break;
                }
                
                reply.fwd.hdr.subtype = msg->hdr.subtype;
                reply.fwd.len += sizeof(*led);
                SETIOV(&smx[2], led, sizeof(*led));
                break;
        }
                
        default:
                reply.result = EINVAL;
                break;
        }

        devhdr.i.nbytes          = sizeof(reply) + reply.fwd.len;

        if (MsgSendv(IpCurrentFd, smx, 3, rmx, 1) < 0)
                perror("MsgSendv");
        
}
Esempio n. 6
0
int _vfcntl(int fd, int cmd, va_list ap) {
	union {
		io_dup_t						dup;
		io_space_t						space;
		io_lock_t						lock;
	}								msg;
	iov_t							iov[4];
	int								arg;
	pid_t	pid;

	switch(cmd) {
	case F_DUPFD: {
		struct _server_info				info;
		int								fd2;
		if(fd == -1 || (fd & _NTO_SIDE_CHANNEL) || ConnectServerInfo(0, fd, &info) != fd) {
			errno = EBADF;
			return -1;
		}
		if((fd2 = va_arg(ap, int)) < 0 || (fd2 & _NTO_SIDE_CHANNEL)) {
			errno = EINVAL;
			return -1;
		}		
		if((fd2 = ConnectAttach(info.nd, info.pid, info.chid, fd2, _NTO_COF_CLOEXEC)) == -1) {
			return -1;
		}
		msg.dup.i.type = _IO_DUP;
		msg.dup.i.combine_len = sizeof msg.dup;
		msg.dup.i.info.nd = netmgr_remote_nd(info.nd, ND_LOCAL_NODE);
		msg.dup.i.info.pid = getpid();
		msg.dup.i.info.chid = info.chid;
		msg.dup.i.info.scoid = info.scoid;
		msg.dup.i.info.coid = fd;
		if(MsgSendnc(fd2, &msg.dup.i, sizeof msg.dup.i, 0, 0) == -1) {
			ConnectDetach_r(fd2);
			return -1;
		}
		ConnectFlags_r(0, fd2, FD_CLOEXEC, 0);
		return fd2;
	}

	case F_GETFD:
		return ConnectFlags(0, fd, 0, 0);

	case F_SETFD:
		return ConnectFlags(0, fd, ~0, va_arg(ap, int));
		
	case F_GETFL:
		if(_devctl(fd, DCMD_ALL_GETFLAGS, &arg, sizeof arg, 0) == -1) {
			return -1;
		}
		return arg;

	case F_SETFL:
		arg = va_arg(ap, int);
		return _devctl(fd, DCMD_ALL_SETFLAGS, &arg, sizeof arg, _DEVCTL_FLAG_NORETVAL);

	case F_GETOWN:
		if(_devctl(fd, DCMD_ALL_GETOWN, &pid, sizeof pid, 0) == -1) {
			return -1;
		}
		return pid;
		
	case F_SETOWN:
		pid = va_arg(ap, pid_t);
		return _devctl(fd, DCMD_ALL_SETOWN, &pid, sizeof pid, _DEVCTL_FLAG_NORETVAL);
		
	case F_ALLOCSP64:
	case F_FREESP64: {
		flock64_t				*area = va_arg(ap, flock64_t *);

		msg.space.i.start = area->l_start;
		msg.space.i.len = area->l_len;
		msg.space.i.whence = area->l_whence;
		goto common;
	}
	case F_ALLOCSP:
		cmd = F_ALLOCSP64;	/* Always pass the 64 bit values */
		goto stuff;
	case F_FREESP:
		cmd = F_FREESP64;	/* Always pass the 64 bit values */
stuff: {
		flock_t					*area = va_arg(ap, flock_t *);

		msg.space.i.start = area->l_start;
		msg.space.i.len = area->l_len;
		msg.space.i.whence = area->l_whence;
	}
common:
		msg.space.i.type = _IO_SPACE;
		msg.space.i.combine_len = sizeof msg.space.i;
		msg.space.i.subtype = cmd;
		return MsgSend(fd, &msg.space.i, sizeof msg.space.i, 0, 0);

	case F_GETLK:
	case F_SETLK:
	case F_SETLKW:
	case F_GETLK64:
	case F_SETLK64:
	case F_SETLKW64:
		msg.lock.i.type = _IO_LOCK;
		msg.lock.i.combine_len = sizeof msg.lock.i;
		msg.lock.i.subtype = cmd;
		SETIOV(iov + 0, &msg.lock.i, sizeof msg.lock.i);
		SETIOV(iov + 1, va_arg(ap, flock_t *), sizeof(flock_t));
		iov[3] = iov[1];
		SETIOV(iov + 2, &msg.lock.o, sizeof msg.lock.o);
		return MsgSendv(fd, iov + 0, 2, iov + 2, (cmd == F_GETLK || cmd == F_GETLK64) ? 2 : 1);
		
	default:
		break;
	}

	errno = EINVAL;
	return -1;
}
Esempio n. 7
0
static int _aio_handler(struct _aio_context *ctp)
{
	struct aiocb *curr;
	io_lseek_t	 lmsg;
	union {
		io_read_t   rmsg;
		io_write_t  wmsg;
	} msg;
	iov_t iov[3];
	int niov;

	if (!ctp)
	  return -1;
	
	while ((curr = ctp->curr_list) != NULL) 
	{
		/* see if we need to change sched_param */
		if (ctp->policy != curr->_aio_policy || memcmp(&ctp->param, &curr->_aio_param, sizeof(ctp->param)))
		{
			curr->_aio_error = pthread_setschedparam(ctp->tid, curr->_aio_policy, (struct sched_param *)&curr->_aio_param);
			if (curr->_aio_error != EOK) {
				curr->_aio_result = (unsigned)-1;
				_aio_wakeup(curr);
				continue;
			}
			ctp->policy = curr->_aio_policy;
			memcpy(&ctp->param, &curr->_aio_param, sizeof ctp->param);
		}
		niov = 0;
		switch (curr->_aio_iotype) {
		  case _AIO_OPCODE_READ:
		  case _AIO_OPCODE_WRITE:
			/* creat a lseek + read/write combined message */
			lmsg.i.type = _IO_LSEEK;
			lmsg.i.combine_len = sizeof(lmsg) | _IO_COMBINE_FLAG;
			lmsg.i.offset = curr->aio_offset;
			lmsg.i.whence = SEEK_SET;
			lmsg.i.zero = 0;
			SETIOV(iov + niov, &lmsg, sizeof(lmsg));
			niov++;
			
			if (curr->_aio_iotype == _AIO_OPCODE_READ) {
				msg.rmsg.i.type = _IO_READ;
				msg.rmsg.i.combine_len = sizeof(msg.rmsg);
				msg.rmsg.i.nbytes = curr->aio_nbytes;
				msg.rmsg.i.xtype = _IO_XTYPE_NONE;
				msg.rmsg.i.zero = 0;
				SETIOV(iov + niov, &msg, sizeof(msg.rmsg));
				niov++;
				curr->_aio_result = MsgSendvs(curr->aio_fildes, iov, niov,
											  (void *)curr->aio_buf, curr->aio_nbytes);
			} else {
				msg.wmsg.i.type = _IO_WRITE;
				msg.wmsg.i.combine_len = sizeof(msg.wmsg);
				msg.wmsg.i.xtype = _IO_XTYPE_NONE;
				msg.wmsg.i.nbytes = curr->aio_nbytes;
				msg.wmsg.i.zero = 0;
				SETIOV(iov + niov, &msg, sizeof(msg.wmsg));
				SETIOV(iov + niov + 1, curr->aio_buf, curr->aio_nbytes);
				niov += 2;
				curr->_aio_result = MsgSendv(curr->aio_fildes, iov, niov, 0, 0);
			}
			break;
		  case _AIO_OPCODE_SYNC:
			curr->_aio_result = fsync(curr->aio_fildes);
			break;
		  case _AIO_OPCODE_DSYNC:
			curr->_aio_result = fdatasync(curr->aio_fildes);
			break;
		  default:
			break;
		}
		
		_mutex_lock(&_aio_cb->cb_mutex);
		ctp->curr_list = curr->_aio_next;
		curr->_aio_next = NULL;
		_mutex_unlock(&_aio_cb->cb_mutex);
		
		if (curr->_aio_result == -1U) {
			curr->_aio_error = errno;
		} else {
			curr->_aio_error = EOK;
		}

		_aio_wakeup(curr);
	}
	return 0;
}