kopia lustrzana https://github.com/FreeSpacenav/spacenavd
- fixed bug in AF_UNIX protocol request handling (both versions):
spacenavd would enter an infinite loop if at the time when a client disconnected, errno happened to be EINTR. - allow axis mappings to be -1, to unmap a device axis.pull/68/head
rodzic
01e59bed7a
commit
6aaf85f598
|
@ -5,8 +5,10 @@ dep = $(obj:.o=.d)
|
|||
bin = spacenavd
|
||||
ctl = spnavd_ctl
|
||||
|
||||
warn = -pedantic -Wall
|
||||
|
||||
CC ?= gcc
|
||||
CFLAGS = -pedantic -Wall $(dbg) $(opt) -fno-strict-aliasing -fcommon \
|
||||
CFLAGS = $(warn) $(dbg) $(opt) -fno-strict-aliasing -fcommon \
|
||||
-I$(srcdir)/src -I/usr/local/include -MMD $(add_cflags)
|
||||
LDFLAGS = -L/usr/local/lib $(xlib) $(add_ldflags)
|
||||
|
||||
|
|
45
src/proto.h
45
src/proto.h
|
@ -109,4 +109,49 @@ enum {
|
|||
DEV_SMMOD /* SpaceMouse Module */
|
||||
};
|
||||
|
||||
|
||||
#ifdef DEF_PROTO_REQ_NAMES
|
||||
static const char *reqnames_1000[] = {
|
||||
"SET_NAME",
|
||||
"SET_SENS",
|
||||
"GET_SENS",
|
||||
"SET_EVMASK",
|
||||
"GET_EVMASK",
|
||||
};
|
||||
static const char *reqnames_2000[] = {
|
||||
"DEV_NAME",
|
||||
"DEV_PATH",
|
||||
"DEV_NAXES",
|
||||
"DEV_NBUTTONS",
|
||||
"DEV_USBID",
|
||||
"DEV_TYPE",
|
||||
};
|
||||
static const char *reqnames_3000[] = {
|
||||
"SCFG_SENS",
|
||||
"GCFG_SENS",
|
||||
"SCFG_SENS_AXIS",
|
||||
"GCFG_SENS_AXIS",
|
||||
"SCFG_DEADZONE",
|
||||
"GCFG_DEADZONE",
|
||||
"SCFG_INVERT",
|
||||
"GCFG_INVERT",
|
||||
"SCFG_AXISMAP",
|
||||
"GCFG_AXISMAP",
|
||||
"SCFG_BNMAP",
|
||||
"GCFG_BNMAP",
|
||||
"SCFG_BNACTION",
|
||||
"GCFG_BNACTION",
|
||||
"SCFG_KBMAP",
|
||||
"GCFG_KBMAP",
|
||||
"SCFG_SWAPYZ",
|
||||
"GCFG_SWAPYZ",
|
||||
"SCFG_LED",
|
||||
"GCFG_LED",
|
||||
"SCFG_GRAB",
|
||||
"GCFG_GRAB",
|
||||
"SCFG_SERDEV",
|
||||
"GCFG_SERDEV",
|
||||
};
|
||||
#endif /* DEF_PROTO_REQ_NAMES */
|
||||
|
||||
#endif /* PROTO_H_ */
|
||||
|
|
|
@ -27,7 +27,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
#define DEF_PROTO_REQ_NAMES
|
||||
#include "proto.h"
|
||||
#undef DEF_PROTO_REQ_NAMES
|
||||
#include "proto_unix.h"
|
||||
#include "spnavd.h"
|
||||
#ifdef USE_X11
|
||||
|
@ -39,7 +41,7 @@ static int lsock = -1;
|
|||
|
||||
|
||||
static int handle_request(struct client *c, struct reqresp *req);
|
||||
|
||||
static const char *reqstr(int req);
|
||||
|
||||
int init_unix(void)
|
||||
{
|
||||
|
@ -191,7 +193,7 @@ int handle_uevents(fd_set *rset)
|
|||
/* handle client requests */
|
||||
switch(c->proto) {
|
||||
case 0:
|
||||
while((rdbytes = read(s, &msg, sizeof msg)) <= 0 && errno == EINTR);
|
||||
while((rdbytes = read(s, &msg, sizeof msg)) < 0 && errno == EINTR);
|
||||
if(rdbytes <= 0) { /* something went wrong... disconnect client */
|
||||
close(get_client_socket(c));
|
||||
remove_client(c);
|
||||
|
@ -228,7 +230,7 @@ int handle_uevents(fd_set *rset)
|
|||
|
||||
case 1:
|
||||
/* protocol v1: accumulate request bytes, and process */
|
||||
while((rdbytes = read(s, c->reqbuf + c->reqbytes, sizeof *req - c->reqbytes)) <= 0 && errno == EINTR);
|
||||
while((rdbytes = read(s, c->reqbuf + c->reqbytes, sizeof *req - c->reqbytes)) < 0 && errno == EINTR);
|
||||
if(rdbytes <= 0) {
|
||||
close(s);
|
||||
remove_client(c);
|
||||
|
@ -274,6 +276,11 @@ static int handle_request(struct client *c, struct reqresp *req)
|
|||
struct device *dev;
|
||||
const char *str = 0;
|
||||
|
||||
/*
|
||||
logmsg(LOG_DEBUG, "request %s - %x %x %x %x %x %x\n", reqstr(req->type), req->data[0],
|
||||
req->data[1], req->data[2], req->data[3], req->data[4], req->data[5], req->data[6]);
|
||||
*/
|
||||
|
||||
switch(req->type & 0xffff) {
|
||||
case REQ_SET_NAME:
|
||||
memcpy(c->name, req->data, sizeof req->data);
|
||||
|
@ -438,7 +445,7 @@ static int handle_request(struct client *c, struct reqresp *req)
|
|||
break;
|
||||
|
||||
case REQ_SCFG_AXISMAP:
|
||||
if(!AXIS_VALID(req->data[0]) || req->data[1] < 0 || req->data[1] >= 6) {
|
||||
if(!AXIS_VALID(req->data[0]) || req->data[1] < -1 || req->data[1] >= 6) {
|
||||
logmsg(LOG_WARNING, "client attempted to set invalid axis mapping: %d -> %d\n",
|
||||
req->data[0], req->data[1]);
|
||||
sendresp(c, req, -1);
|
||||
|
@ -598,9 +605,39 @@ static int handle_request(struct client *c, struct reqresp *req)
|
|||
break;
|
||||
|
||||
default:
|
||||
logmsg(LOG_WARNING, "invalid client request: %04xh\n", (unsigned int)req->type);
|
||||
logmsg(LOG_WARNING, "invalid client request: %s\n", reqstr(req->type));
|
||||
sendresp(c, req, -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *reqstr(int req)
|
||||
{
|
||||
static char buf[8];
|
||||
|
||||
req &= 0xffff;
|
||||
|
||||
if(req >= 0x1000 && req < 0x1000 + sizeof reqnames_1000 / sizeof *reqnames_1000) {
|
||||
return reqnames_1000[req - 0x1000];
|
||||
}
|
||||
if(req >= 0x2000 && req < 0x2000 + sizeof reqnames_2000 / sizeof *reqnames_2000) {
|
||||
return reqnames_2000[req - 0x2000];
|
||||
}
|
||||
if(req >= 0x3000 && req < 0x3000 + sizeof reqnames_3000 / sizeof *reqnames_3000) {
|
||||
return reqnames_3000[req - 0x3000];
|
||||
}
|
||||
switch(req) {
|
||||
case REQ_CFG_SAVE:
|
||||
return "CFG_SAVE";
|
||||
case REQ_CFG_RESTORE:
|
||||
return "CFG_RESTORE";
|
||||
case REQ_CFG_RESET:
|
||||
return "CFG_RESET";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(buf, "0x%04x", req);
|
||||
return buf;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue