From 0cdc7b50b0e7758a1660c94be664a810504a88f4 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 17 Sep 2009 10:08:44 +0000 Subject: [PATCH] Packetize the command stream for more robustness Deal with NULL data pointers Rewrite gldump to use mmap to avoid hassle with large packets Fix some style issues --- Makefile | 2 +- genwrap.py | 16 +++++------ source/gldecoder.c | 54 +++++++++++++++++++++++++++---------- source/gldecoder.h | 2 +- source/gldump.c | 57 +++++++++++++++++++++++---------------- source/glwrap.c | 67 ++++++++++++++++++++++++++-------------------- 6 files changed, 120 insertions(+), 78 deletions(-) diff --git a/Makefile b/Makefile index e6f6d11..93fe681 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # $Id$ -CFLAGS=-Igensrc -ggdb +CFLAGS = -Igensrc -ggdb all: glwrap.so gldump diff --git a/genwrap.py b/genwrap.py index 35e3439..7f87c7f 100755 --- a/genwrap.py +++ b/genwrap.py @@ -254,17 +254,17 @@ out.write("} GlDecoder;\n") out = open(os.path.join(outdir, "gldecoder.funcs"), "w") for f in funcs: - out.write("static unsigned decode_%s(GlDecoder *dec, const char *data, unsigned len)\n{\n"%(f[0])) + out.write("static unsigned decode_%s(GlDecoder *dec, const char *data)\n{\n"%(f[0])) out.write("\tunsigned pos = 0;\n") if f[1]!="void": out.write("\t%s ret;\n"%f[1]) for p in f[2]: out.write("\t%s arg_%s;\n"%(p[1], p[0])) if f[1]!="void": - out.write("\tpos += read_%s(&ret, data+pos, len);\n"%iomap[f[1]]) + out.write("\tpos += read_%s(&ret, data+pos);\n"%iomap[f[1]]) for p in f[2]: (t, c) = getread(f, p) - out.write("\tpos += read_%s(%s&arg_%s, data+pos, len-pos);\n"%(t, c, p[0])) + out.write("\tpos += read_%s(%s&arg_%s, data+pos);\n"%(t, c, p[0])) out.write("\tif(dec->%s)\n"%f[0]) out.write("\t\tdec->%s(dec->user_data"%f[0]) if f[1]!="void": @@ -275,20 +275,16 @@ for f in funcs: out.write("\treturn pos;\n") out.write("}\n\n") -out.write("""unsigned gldecoder_decode(GlDecoder *dec, const char *data, unsigned len) +out.write("""static int decode_func(GlDecoder *dec, short func, const char *data) { - unsigned pos = 0; - short func; - - pos += read_short(&func, data, len); switch(func) { """) for f in funcs: - out.write("\t\tcase FUNC_%s: pos += decode_%s(dec, data+pos, len); break;\n"%(f[0].upper(), f[0])) + out.write("\t\tcase FUNC_%s: return decode_%s(dec, data);\n"%(f[0].upper(), f[0])) out.write(""" } - return pos; + return -1; } """) out.close() diff --git a/source/gldecoder.c b/source/gldecoder.c index 93a5258..85d089d 100644 --- a/source/gldecoder.c +++ b/source/gldecoder.c @@ -10,6 +10,10 @@ Distributed under the GPL #include "functions.h" #include "gldecoder.h" +static unsigned read_short(short *, const char *); +static unsigned read_int(int *, const char *); +static int decode_func(GlDecoder *, short, const char *); + GlDecoder *gldecoder_new(void *user_data, void (*destroy)(void *)) { GlDecoder *dec; @@ -29,72 +33,94 @@ void gldecoder_delete(GlDecoder *dec) free(dec); } -unsigned read_char(char *v, const char *data, unsigned len) +int gldecoder_decode(GlDecoder *dec, const char *data, unsigned len) +{ + unsigned pos = 0; + int pktlen; + short func; + int ret; + + if(len #include -#include +#include +#include +#include +#include #include "glprint.h" int main(int argc, char **argv) { - FILE *in; + int fd; + struct stat st; GlDecoder *dec; - char *buf; - unsigned size; - unsigned start; - unsigned end; + char *addr; + char *end; + char *ptr; - in = fopen(argv[1], "r"); + if(argc<2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + fd = open(argv[1], O_RDONLY); + if(fd==-1) + { + perror("open"); + return 1; + } + fstat(fd, &st); + addr = (char *)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + end = addr+st.st_size; + ptr = addr; dec = glprint_new(NULL, 0); - size = 16384; - buf = (char *)malloc(size); - start = 0; - end = 0; - while(1) + while(ptrsize/2) + int ret; + ret = gldecoder_decode(dec, ptr, end-ptr); + if(ret<0) { - memmove(buf, buf+start, end-start); - end -= start; - start = 0; - } - if(endiov_base) { - cur_vec->iov_len=write_pos-(char *)cur_vec->iov_base; + cur_vec->iov_len = write_pos-(char *)cur_vec->iov_base; + length += cur_vec->iov_len; ++cur_vec; - cur_vec->iov_base=write_pos; + cur_vec->iov_base = write_pos; } } @@ -48,12 +50,12 @@ static inline void write_bytes(const char *ptr, unsigned size) { unsigned i; for(i=0; iiov_base=(void *)data; - cur_vec->iov_len=size; - ++cur_vec; - cur_vec->iov_base=write_pos; + if(data) + { + write_int(size); + next_vec(); + cur_vec->iov_base = (void *)data; + cur_vec->iov_len = size; + length += size; + ++cur_vec; + cur_vec->iov_base = write_pos; + } + else + write_int(0); } static inline void write_string(const unsigned char *s) { write_data(s, strlen(s)); - /*int len=strlen(s); - write_int(len); - write_bytes(s, len);*/ } static inline void begin_packet(int func) { if(!buffer) - buffer=(char *)malloc(1024); + buffer = (char *)malloc(1024); if(!iovecs) - iovecs=(struct iovec *)malloc(16*sizeof(struct iovec)); - write_pos=buffer; - cur_vec=iovecs; - cur_vec->iov_base=write_pos; + iovecs = (struct iovec *)malloc(16*sizeof(struct iovec)); + write_pos = buffer; + cur_vec = iovecs; + cur_vec->iov_base = write_pos; + length = 0; + write_int(0); write_short(func); } static inline void send_packet() { - static int fd=-1; + static int fd = -1; if(fd<0) { - const char *var=getenv("GLWRAP_FD"); + const char *var = getenv("GLWRAP_FD"); if(var) - fd=strtol(var, NULL, 0); + fd = strtol(var, NULL, 0); else - fd=2; + fd = 2; } next_vec(); + write_pos = buffer; + write_int(length); writev(fd, iovecs, cur_vec-iovecs); } -- 2.45.2