bitkeeper revision 1.1403 (4284c2edzLTGTr4gHmGzYsZMuetTRQ)

Switch to using unix-domain interface on xend instead
of http via libcurl.
Sundry other merges and fixes.
Signed-off-by: Mike Wray <mike.wray@hp.com>
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2005-05-13 15:08:29 +00:00
1 parent 21eaf26c10
commit 007d7b6e1e
18 files changed
+1703 -1158

No files matched your search

+2
View File
@@ -754,6 +754,8 @@
41a216cav5JJbtDQnusfuMa_1x_Xpw tools/libxutil/debug.h
40e9808eyjiahG5uF6AMelNVujBzCg tools/libxutil/enum.c
40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/libxutil/enum.h
4284c2ecWyadIhHF1u_QSgWqIXkaLA tools/libxutil/fd_stream.c
4284c2ecEOOcF6fZUf_NsZzYAoNo-w tools/libxutil/fd_stream.h
40e03332p5Dc_owJQRuN72ymJZddFQ tools/libxutil/file_stream.c
40e03332jWfB2viAhLSkq1WK0r_iDQ tools/libxutil/file_stream.h
40e03332rUjNMGg11n2rN6V4DCrvOg tools/libxutil/gzip_stream.c
+184
View File
@@ -0,0 +1,184 @@
/*
* Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** @file
* An IOStream implementation using fds.
*/
#ifndef __KERNEL__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "allocate.h"
#include "fd_stream.h"
#define MODULE_NAME "fd_stream"
#define DEBUG 1
//#undef DEBUG
#include "debug.h"
static int fd_read(IOStream *s, void *buf, size_t n);
static int fd_write(IOStream *s, const void *buf, size_t n);
static int fd_error(IOStream *s);
static int fd_close(IOStream *s);
static void fd_free(IOStream *s);
static int fd_flush(IOStream *s);
/** Methods used by a fd IOStream. */
static const IOMethods fd_methods = {
read: fd_read,
write: fd_write,
error: fd_error,
close: fd_close,
free: fd_free,
flush: fd_flush,
};
/** Get the fd data.
*
* @param io fd stream
* @return data
*/
static inline FDData * fd_data(IOStream *io){
return (FDData *)io->data;
}
/** Test if a stream is a fd stream.
*
* @param io stream
* @return 0 if a fd stream, -EINVAL if not
*/
int fd_stream_check(IOStream *io){
return (io && io->methods == &fd_methods ? 0 : -EINVAL);
}
/** Get the data for a fd stream.
*
* @param io stream
* @param data return value for the data
* @return 0 if a fd stream, -EINVAL if not
*/
int fd_stream_data(IOStream *io, FDData **data){
int err = fd_stream_check(io);
if(err){
*data = NULL;
} else {
*data = fd_data(io);
}
return err;
}
/** Write to the underlying fd.
*
* @param stream input
* @param buf where to put input
* @param n number of bytes to write
* @return number of bytes written
*/
static int fd_write(IOStream *s, const void *buf, size_t n){
FDData *data = fd_data(s);
int k;
k = write(data->fd, buf, n);
return k;
}
/** Read from the underlying stream;
*
* @param stream input
* @param buf where to put input
* @param n number of bytes to read
* @return number of bytes read
*/
static int fd_read(IOStream *s, void *buf, size_t n){
FDData *data = fd_data(s);
int k;
k = read(data->fd, buf, n);
//printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k);
return k;
}
/** Flush the fd (no-op).
*
* @param s fd stream
* @return 0 on success, error code otherwise
*/
static int fd_flush(IOStream *s){
return 0;
}
/** Check if a fd stream has an error (no-op).
*
* @param s fd stream
* @return 1 if has an error, 0 otherwise
*/
static int fd_error(IOStream *s){
return 0;
}
/** Close a fd stream.
*
* @param s fd stream to close
* @return result of the close
*/
static int fd_close(IOStream *s){
FDData *data = fd_data(s);
return close(data->fd);
}
/** Free a fd stream.
*
* @param s fd stream
*/
static void fd_free(IOStream *s){
FDData *data = fd_data(s);
deallocate(data);
}
/** Create an IOStream for a fd.
*
* @param fd fd to wtap
* @return new IOStream using fd for i/o
*/
IOStream *fd_stream_new(int fd){
int err = -ENOMEM;
IOStream *io = NULL;
FDData *data = NULL;
io = ALLOCATE(IOStream);
if(!io) goto exit;
io->methods = &fd_methods;
data = ALLOCATE(FDData);
if(!data) goto exit;
io->data = data;
data->fd = fd;
err = 0;
exit:
if(err){
if(io){
if(data) deallocate(data);
deallocate(io);
io = NULL;
}
}
return io;
}
#endif
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XMC_FD_STREAM_H_
#define _XMC_FD_STREAM_H_
#ifndef __KERNEL__
#include "iostream.h"
/** Data associated with a fd stream. */
typedef struct FDData {
/** The socket file descriptor. */
int fd;
} FDData;
extern IOStream *fd_stream_new(int fd);
extern int fd_stream_data(IOStream *io, FDData **data);
extern int fd_stream_check(IOStream *io);
#endif
#endif /* !_XMC_FD_STREAM_H_ */
+1 -1
View File
@@ -34,7 +34,7 @@
#define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 })
/** Class of separator characters. */
#define sep_class "{}()<>[]@!;"
#define sep_class "{}()<>[]!;\"'"
#define comment_class "#"
+365 -115
View File
@@ -28,6 +28,19 @@
#include <errno.h>
#endif
#ifdef __KERNEL__
#include <linux/random.h>
int rand(void){
int v;
get_random_bytes(&v, sizeof(v));
return v;
}
#else
#include <stdlib.h>
#endif
#undef free
/** @file
@@ -42,41 +55,51 @@
static int atom_print(IOStream *io, Sxpr obj, unsigned flags);
static int atom_equal(Sxpr x, Sxpr y);
static void atom_free(Sxpr obj);
static Sxpr atom_copy(Sxpr obj);
static int string_print(IOStream *io, Sxpr obj, unsigned flags);
static int string_equal(Sxpr x, Sxpr y);
static void string_free(Sxpr obj);
static Sxpr string_copy(Sxpr obj);
static int cons_print(IOStream *io, Sxpr obj, unsigned flags);
static int cons_equal(Sxpr x, Sxpr y);
static void cons_free(Sxpr obj);
static Sxpr cons_copy(Sxpr obj);
static int null_print(IOStream *io, Sxpr obj, unsigned flags);
static int none_print(IOStream *io, Sxpr obj, unsigned flags);
static int int_print(IOStream *io, Sxpr obj, unsigned flags);
static int bool_print(IOStream *io, Sxpr obj, unsigned flags);
static int err_print(IOStream *io, Sxpr obj, unsigned flags);
static int nomem_print(IOStream *io, Sxpr obj, unsigned flags);
/** Type definitions. */
static SxprType types[1024] = {
[T_NONE] { type: T_NONE, name: "none", print: none_print },
[T_NULL] { type: T_NULL, name: "null", print: null_print },
[T_UINT] { type: T_UINT, name: "int", print: int_print, },
[T_BOOL] { type: T_BOOL, name: "bool", print: bool_print, },
[T_ATOM] { type: T_ATOM, name: "atom", print: atom_print,
pointer: TRUE,
free: atom_free,
equal: atom_equal,
},
[T_STRING] { type: T_STRING, name: "string", print: string_print,
pointer: TRUE,
free: string_free,
equal: string_equal,
},
[T_CONS] { type: T_CONS, name: "cons", print: cons_print,
pointer: TRUE,
free: cons_free,
equal: cons_equal,
},
[T_NONE] { .type= T_NONE, .name= "none", .print= none_print },
[T_NULL] { .type= T_NULL, .name= "null", .print= null_print },
[T_UINT] { .type= T_UINT, .name= "int", .print= int_print, },
[T_BOOL] { .type= T_BOOL, .name= "bool", .print= bool_print, },
[T_ERR] { .type= T_ERR, .name= "err", .print= err_print, },
[T_NOMEM] { .type= T_ERR, .name= "nomem", .print= nomem_print, },
[T_ATOM] { .type= T_ATOM, .name= "atom", .print= atom_print,
.pointer= TRUE,
.free= atom_free,
.equal= atom_equal,
.copy= atom_copy,
},
[T_STRING] { .type= T_STRING, .name= "string", .print= string_print,
.pointer= TRUE,
.free= string_free,
.equal= string_equal,
.copy= string_copy,
},
[T_CONS] { .type= T_CONS, .name= "cons", .print= cons_print,
.pointer= TRUE,
.free= cons_free,
.equal= cons_equal,
.copy= cons_copy,
},
};
/** Number of entries in the types array. */
@@ -157,12 +180,29 @@ int objprint(IOStream *io, Sxpr x, unsigned flags){
int k = 0;
if(!io) return k;
if(flags & PRINT_TYPE){
k += IOStream_print(io, "%s:", def->name);
k += IOStream_print(io, "%s:", def->name);
}
if(def->pointer && (flags & PRINT_ADDR)){
k += IOStream_print(io, "<%p>", get_ptr(x));
}
k += print_fn(io, x, flags);
return k;
}
Sxpr objcopy(Sxpr x){
SxprType *def = get_sxpr_type(get_type(x));
ObjCopyFn *copy_fn = (def ? def->copy : NULL);
Sxpr v;
if(copy_fn){
v = copy_fn(x);
} else if(def->pointer){
v = ONOMEM;
} else {
v = x;
}
return v;
}
/** General sxpr free function.
* Frees an sxpr using the free function for its type.
* Free functions must recursively free any subsxprs.
@@ -176,11 +216,11 @@ void objfree(Sxpr x){
SxprType *def = get_sxpr_type(get_type(x));
if(def){
if(def->free){
def->free(x);
} else if (def->pointer){
hfree(x);
}
if(def->free){
def->free(x);
} else if (def->pointer){
hfree(x);
}
}
}
@@ -284,9 +324,9 @@ Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
*/
int cons_subset(Sxpr s, Sxpr t){
for( ; CONSP(t); t = CDR(t)){
if(!CONSP(cons_member(s, CAR(t)))){
return 0;
}
if(!CONSP(cons_member(s, CAR(t)))){
return 0;
}
}
return 1;
}
@@ -365,18 +405,27 @@ Sxpr setf(Sxpr k, Sxpr v, Sxpr l){
#endif /* USE_GC */
/** Create a new atom with the given name.
* Makes an integer sxpr if the name can be parsed as an int.
*
* @param name the name
* @return new atom
*/
Sxpr atom_new(char *name){
Sxpr n, obj = ONOMEM;
long v;
n = string_new(name);
if(NOMEMP(n)) goto exit;
obj = HALLOC(ObjAtom, T_ATOM);
if(NOMEMP(obj)) goto exit;
OBJ_ATOM(obj)->name = n;
if(convert_atol(name, &v) == 0){
obj = OINT(v);
} else {
n = string_new(name);
if(NOMEMP(n)) goto exit;
obj = HALLOC(ObjAtom, T_ATOM);
if(NOMEMP(obj)){
string_free(n);
goto exit;
}
OBJ_ATOM(obj)->name = n;
}
exit:
return obj;
}
@@ -392,6 +441,20 @@ void atom_free(Sxpr obj){
hfree(obj);
}
/** Copy an atom.
*
* @param obj to copy
*/
Sxpr atom_copy(Sxpr obj){
Sxpr v;
if(OBJ_ATOM(obj)->interned){
v = obj;
} else {
v = atom_new(atom_name(obj));
}
return v;
}
/** Print an atom. Prints the atom name.
*
* @param io stream to print to
@@ -400,8 +463,7 @@ void atom_free(Sxpr obj){
* @return number of bytes printed
*/
int atom_print(IOStream *io, Sxpr obj, unsigned flags){
//return string_print(io, OBJ_ATOM(obj)->name, (flags | PRINT_RAW));
return string_print(io, OBJ_ATOM(obj)->name, flags);
return objprint(io, OBJ_ATOM(obj)->name, flags);
}
/** Atom equality.
@@ -430,13 +492,17 @@ char * atom_name(Sxpr obj){
return string_string(OBJ_ATOM(obj)->name);
}
int atom_length(Sxpr obj){
return string_length(OBJ_ATOM(obj)->name);
}
/** Get the C string from a string sxpr.
*
* @param obj string sxpr
* @return string
*/
char * string_string(Sxpr obj){
return OBJ_STRING(obj);
return OBJ_STRING(obj)->data;
}
/** Get the length of a string.
@@ -445,7 +511,7 @@ char * string_string(Sxpr obj){
* @return length
*/
int string_length(Sxpr obj){
return strlen(OBJ_STRING(obj));
return OBJ_STRING(obj)->len;
}
/** Create a new string. The input string is copied,
@@ -456,12 +522,28 @@ int string_length(Sxpr obj){
*/
Sxpr string_new(char *s){
int n = (s ? strlen(s) : 0);
return string_new_n(s, n);
}
/** Create a new string. The input string is copied,
* and need not be null-terminated.
*
* @param s characters to put in the string (may be null)
* @param n string length
* @return new sxpr
*/
Sxpr string_new_n(char *s, int n){
Sxpr obj;
obj = halloc(n+1, T_STRING);
obj = halloc(sizeof(ObjString) + n + 1, T_STRING);
if(!NOMEMP(obj)){
char *str = OBJ_STRING(obj);
strncpy(str, s, n);
str[n] = '\0';
char *str = OBJ_STRING(obj)->data;
OBJ_STRING(obj)->len = n;
if(s){
memcpy(str, s, n);
str[n] = '\0';
} else {
memset(str, 0, n + 1);
}
}
return obj;
}
@@ -474,70 +556,180 @@ void string_free(Sxpr obj){
hfree(obj);
}
/** Copy a string.
*
* @param obj to copy
*/
Sxpr string_copy(Sxpr obj){
return string_new_n(string_string(obj), string_length(obj));
}
/** Determine if a string needs escapes when printed
* using the given flags.
*
* @param str string to check
* @param n string length
* @param flags print flags
* @return 1 if needs escapes, 0 otherwise
*/
int needs_escapes(char *str, unsigned flags){
int needs_escapes(char *str, int n, unsigned flags){
char *c;
int i;
int val = 0;
if(str){
for(c=str; *c; c++){
if(in_alpha_class(*c)) continue;
if(in_decimal_digit_class(*c)) continue;
if(in_class(*c, "/._+:@~-")) continue;
val = 1;
break;
}
for(i=0, c=str; i<n; i++, c++){
if(in_alpha_class(*c)) continue;
if(in_decimal_digit_class(*c)) continue;
if(in_class(*c, "/._+:@~-")) continue;
val = 1;
break;
}
}
//printf("\n> val=%d str=|%s|\n", val, str);
return val;
}
char randchar(void){
int r;
char c;
for( ; ; ){
r = rand();
c = (r >> 16) & 0xff;
if('a' <= c && c <= 'z') break;
}
return c;
}
int string_contains(char *s, int s_n, char *k, int k_n){
int i, n = s_n - k_n;
for(i=0; i < n; i++){
if(!memcmp(s+i, k, k_n)) return 1;
}
return 0;
}
int string_delim(char *s, int s_n, char *d, int d_n){
int i;
if(d_n < 4) return -1;
memset(d, 0, d_n+1);
for(i=0; i<3; i++){
d[i] = randchar();
}
for( ; i < d_n; i++){
if(!string_contains(s, s_n, d, i)){
return i;
}
d[i] = randchar();
}
return -1;
}
/** Print the bytes in a string as-is.
*
* @param io stream
* @param str string
* @param n length
* @return bytes written or error code
*/
int _string_print_raw(IOStream *io, char *str, int n){
int k = 0;
k = IOStream_write(io, str, n);
return k;
}
/** Print a string in counted data format.
*
* @param io stream
* @param str string
* @param n length
* @return bytes written or error code
*/
int _string_print_counted(IOStream *io, char *str, int n){
int k = 0;
k += IOStream_print(io, "%c%c%d%c",
c_data_open, c_data_count, n, c_data_count);
k += IOStream_write(io, str, n);
return k;
}
/** Print a string in quoted data format.
*
* @param io stream
* @param str string
* @param n length
* @return bytes written or error code
*/
int _string_print_quoted(IOStream *io, char *str, int n){
int k = 0;
char d[10];
int d_n;
d_n = string_delim(str, n, d, sizeof(d) - 1);
k += IOStream_print(io, "%c%c%s%c",
c_data_open, c_data_quote, d, c_data_quote);
k += IOStream_write(io, str, n);
k += IOStream_print(io, "%c%s%c", c_data_quote, d, c_data_quote);
return k;
}
/** Print a string as a quoted string.
*
* @param io stream
* @param str string
* @param n length
* @return bytes written or error code
*/
int _string_print_string(IOStream *io, char *str, int n){
int k = 0;
k += IOStream_print(io, "\"");
if(str){
char *s, *t;
for(s = str, t = str + n; s < t; s++){
if(*s < ' ' || *s >= 127 ){
switch(*s){
case '\a': k += IOStream_print(io, "\\a"); break;
case '\b': k += IOStream_print(io, "\\b"); break;
case '\f': k += IOStream_print(io, "\\f"); break;
case '\n': k += IOStream_print(io, "\\n"); break;
case '\r': k += IOStream_print(io, "\\r"); break;
case '\t': k += IOStream_print(io, "\\t"); break;
case '\v': k += IOStream_print(io, "\\v"); break;
default:
// Octal escape;
k += IOStream_print(io, "\\%o", *s);
break;
}
} else if(*s == c_double_quote ||
*s == c_single_quote ||
*s == c_escape){
k += IOStream_print(io, "\\%c", *s);
} else {
k+= IOStream_print(io, "%c", *s);
}
}
}
k += IOStream_print(io, "\"");
return k;
}
/** Print a string to a stream, with escapes if necessary.
*
* @param io stream to print to
* @param str string
* @param n string length
* @param flags print flags
* @return number of bytes written
*/
int _string_print(IOStream *io, char *str, unsigned flags){
int _string_print(IOStream *io, char *str, int n, unsigned flags){
int k = 0;
if((flags & PRINT_RAW) || !needs_escapes(str, flags)){
k += IOStream_print(io, str);
if((flags & PRINT_COUNTED)){
k = _string_print_counted(io, str, n);
} else if((flags & PRINT_RAW) || !needs_escapes(str, n, flags)){
k = _string_print_raw(io, str, n);
} else if(n > 50){
k = _string_print_quoted(io, str, n);
} else {
k += IOStream_print(io, "\"");
if(str){
char *s;
for(s = str; *s; s++){
if(*s < ' ' || *s >= 127 ){
switch(*s){
case '\a': k += IOStream_print(io, "\\a"); break;
case '\b': k += IOStream_print(io, "\\b"); break;
case '\f': k += IOStream_print(io, "\\f"); break;
case '\n': k += IOStream_print(io, "\\n"); break;
case '\r': k += IOStream_print(io, "\\r"); break;
case '\t': k += IOStream_print(io, "\\t"); break;
case '\v': k += IOStream_print(io, "\\v"); break;
default:
// Octal escape;
k += IOStream_print(io, "\\%o", *s);
break;
}
} else if(*s == c_double_quote ||
*s == c_single_quote ||
*s == c_escape){
k += IOStream_print(io, "\\%c", *s);
} else {
k+= IOStream_print(io, "%c", *s);
}
}
}
k += IOStream_print(io, "\"");
k = _string_print_string(io, str, n);
}
return k;
}
@@ -550,7 +742,14 @@ int _string_print(IOStream *io, char *str, unsigned flags){
* @return number of bytes written
*/
int string_print(IOStream *io, Sxpr obj, unsigned flags){
return _string_print(io, OBJ_STRING(obj), flags);
return _string_print(io,
OBJ_STRING(obj)->data,
OBJ_STRING(obj)->len,
flags);
}
int string_eq(char *s, int s_n, char *t, int t_n){
return (s_n == t_n) && (memcmp(s, t, s_n) == 0);
}
/** Compare an sxpr with a string for equality.
@@ -563,9 +762,13 @@ int string_equal(Sxpr x, Sxpr y){
int ok = 0;
ok = eq(x,y);
if(ok) goto exit;
ok = has_type(y, T_STRING) && !strcmp(OBJ_STRING(x), OBJ_STRING(y));
ok = has_type(y, T_STRING) &&
string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
OBJ_STRING(y)->data, OBJ_STRING(y)->len);
if(ok) goto exit;
ok = has_type(y, T_ATOM) && !strcmp(OBJ_STRING(x), atom_name(y));
ok = has_type(y, T_ATOM) &&
string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
atom_name(y), atom_length(y));
exit:
return ok;
}
@@ -613,15 +816,38 @@ int cons_push(Sxpr *list, Sxpr elt){
void cons_free(Sxpr obj){
Sxpr next;
for(; CONSP(obj); obj = next){
next = CDR(obj);
objfree(CAR(obj));
hfree(obj);
next = CDR(obj);
objfree(CAR(obj));
hfree(obj);
}
if(!NULLP(obj)){
objfree(obj);
objfree(obj);
}
}
/** Copy a cons. Recursively copies the car and cdr.
*
* @param obj to copy
*/
Sxpr cons_copy(Sxpr obj){
Sxpr v = ONULL;
Sxpr l = ONULL, x = ONONE;
for(l = obj; CONSP(l); l = CDR(l)){
x = objcopy(CAR(l));
if(NOMEMP(x)) goto exit;
x = cons_new(x, v);
if(NOMEMP(x)) goto exit;
v = x;
}
v = nrev(v);
exit:
if(NOMEMP(x)){
objfree(v);
v = ONOMEM;
}
return v;
}
/** Free a cons and its cdr cells, but not the car sxprs.
* Does nothing if called on something that is not a cons.
*
@@ -630,8 +856,8 @@ void cons_free(Sxpr obj){
void cons_free_cells(Sxpr obj){
Sxpr next;
for(; CONSP(obj); obj = next){
next = CDR(obj);
hfree(obj);
next = CDR(obj);
hfree(obj);
}
}
@@ -698,26 +924,26 @@ int cons_length(Sxpr obj){
*/
Sxpr nrev(Sxpr l){
if(CONSP(l)){
// Iterate down the cells in the list making the cdr of
// each cell point to the previous cell. The last cell
// is the head of the reversed list.
Sxpr prev = ONULL;
Sxpr cell = l;
Sxpr next;
// Iterate down the cells in the list making the cdr of
// each cell point to the previous cell. The last cell
// is the head of the reversed list.
Sxpr prev = ONULL;
Sxpr cell = l;
Sxpr next;
while(1){
next = CDR(cell);
CDR(cell) = prev;
if(!CONSP(next)) break;
prev = cell;
cell = next;
}
l = cell;
while(1){
next = CDR(cell);
CDR(cell) = prev;
if(!CONSP(next)) break;
prev = cell;
cell = next;
}
l = cell;
}
return l;
}
/** Print the null sxpr.
/** Print the null sxpr.
*
* @param io stream to print to
* @param obj to print
@@ -761,6 +987,30 @@ static int bool_print(IOStream *io, Sxpr obj, unsigned flags){
return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false));
}
/** Print an error.
*
* @param io stream to print to
* @param obj to print
* @param flags print flags
* @return number of bytes written
*/
static int err_print(IOStream *io, Sxpr obj, unsigned flags){
int err = OBJ_INT(obj);
if(err < 0) err = -err;
return IOStream_print(io, "[error:%d:%s]", err, strerror(err));
}
/** Print the 'nomem' sxpr.
*
* @param io stream to print to
* @param obj to print
* @param flags print flags
* @return number of bytes written
*/
static int nomem_print(IOStream *io, Sxpr obj, unsigned flags){
return IOStream_print(io, "[ENOMEM]");
}
int sxprp(Sxpr obj, Sxpr name){
return CONSP(obj) && objequal(CAR(obj), name);
}
@@ -781,8 +1031,8 @@ Sxpr sxpr_name(Sxpr obj){
}
int sxpr_is(Sxpr obj, char *s){
if(ATOMP(obj)) return !strcmp(atom_name(obj), s);
if(STRINGP(obj)) return !strcmp(string_string(obj), s);
if(ATOMP(obj)) return string_eq(atom_name(obj), atom_length(obj), s, strlen(s));
if(STRINGP(obj)) return string_eq(string_string(obj), string_length(obj), s, strlen(s));
return 0;
}
@@ -915,11 +1165,11 @@ static int sym_equal_fn(void *x, void *y){
*/
static void sym_free_fn(HashTable *table, HTEntry *entry){
if(entry){
objfree(((ObjAtom*)entry->value)->name);
HTEntry_free(entry);
objfree(((ObjAtom*)entry->value)->name);
HTEntry_free(entry);
}
}
/** Initialize the symbol table.
*
* @return 0 on sucess, error code otherwise
@@ -929,7 +1179,7 @@ static int init_symbols(void){
if(symbols){
symbols->key_hash_fn = sym_hash_fn;
symbols->key_equal_fn = sym_equal_fn;
symbols->entry_free_fn = sym_free_fn;
symbols->entry_free_fn = sym_free_fn;
return 0;
}
return -1;
@@ -950,8 +1200,8 @@ void cleanup_symbols(void){
Sxpr get_symbol(char *sym){
HTEntry *entry;
if(!symbols){
if(init_symbols()) return ONOMEM;
return ONULL;
if(init_symbols()) return ONOMEM;
return ONULL;
}
entry = HashTable_get_entry(symbols, sym);
if(entry){
@@ -969,10 +1219,10 @@ Sxpr get_symbol(char *sym){
Sxpr intern(char *sym){
Sxpr symbol = get_symbol(sym);
if(NULLP(symbol)){
if(!symbols) return ONOMEM;
if(!symbols) return ONOMEM;
symbol = atom_new(sym);
if(!NOMEMP(symbol)){
OBJ_ATOM(symbol)->interned = TRUE;
OBJ_ATOM(symbol)->interned = TRUE;
HashTable_add(symbols, atom_name(symbol), get_ptr(symbol));
}
}
+176 -160
View File
@@ -52,142 +52,13 @@ typedef struct Sxpr {
/** Sxpr type. */
TypeCode type;
union {
/** Sxpr value. */
/** Sxpr value. */
unsigned long ul;
/** Pointer. */
/** Pointer. */
void *ptr;
} v;
} Sxpr;
/** Sxpr type to indicate out of memory. */
#define T_NOMEM ((TypeCode)-1)
/** The 'unspecified' sxpr. */
#define T_NONE ((TypeCode)0)
/** The empty list. */
#define T_NULL ((TypeCode)1)
/** Unsigned integer. */
#define T_UINT ((TypeCode)2)
/** A string. */
#define T_STRING ((TypeCode)3)
/** An atom. */
#define T_ATOM ((TypeCode)4)
/** A boolean. */
#define T_BOOL ((TypeCode)5)
/** A cons (pair or list). */
#define T_CONS ((TypeCode)10)
/** An error. */
#define T_ERR ((TypeCode)40)
/** An atom. */
typedef struct ObjAtom {
Sxpr name;
Hashcode hashcode;
int interned;
} ObjAtom;
/** A cons (pair). */
typedef struct ObjCons {
Sxpr car;
Sxpr cdr;
} ObjCons;
/** A vector. */
typedef struct ObjVector {
int n;
Sxpr data[0];
} ObjVector;
/** Flags for sxpr printing. */
enum PrintFlags {
PRINT_RAW = 0x001,
PRINT_TYPE = 0x002,
PRINT_PRETTY = 0x004,
PRINT_NUM = 0x008,
};
/** An integer sxpr.
*
* @param ty type
* @param val integer value
*/
#define OBJI(ty, val) (Sxpr){ type: (ty), v: { ul: (val) }}
/** A pointer sxpr.
* If the pointer is non-null, returns an sxpr containing it.
* If the pointer is null, returns ONOMEM.
*
* @param ty type
* @param val pointer
*/
#define OBJP(ty, val) ((val) ? (Sxpr){ type: (ty), v: { ptr: (val) }} : ONOMEM)
/** Make an integer sxpr containing a pointer.
*
* @param val pointer
*/
#define PTR(val) OBJP(T_UINT, (void*)(val))
/** Make an integer sxpr.
* @param x value
*/
#define OINT(x) OBJI(T_UINT, x)
/** Make an error sxpr.
*
* @param x value
*/
#define OERR(x) OBJI(T_ERR, x)
/** Out of memory constant. */
#define ONOMEM OBJI(T_NOMEM, 0)
/** The `unspecified' constant. */
#define ONONE OBJI(T_NONE, 0)
/** Empty list constant. */
#define ONULL OBJI(T_NULL, 0)
/** False constant. */
#define OFALSE OBJI(T_BOOL, 0)
/** True constant. */
#define OTRUE OBJI(T_BOOL, 1)
/* Recognizers for the various sxpr types. */
#define ATOMP(obj) has_type(obj, T_ATOM)
#define BOOLP(obj) has_type(obj, T_BOOL)
#define CONSP(obj) has_type(obj, T_CONS)
#define ERRP(obj) has_type(obj, T_ERR)
#define INTP(obj) has_type(obj, T_UINT)
#define NOMEMP(obj) has_type(obj, T_NOMEM)
#define NONEP(obj) has_type(obj, T_NONE)
#define NULLP(obj) has_type(obj, T_NULL)
#define STRINGP(obj) has_type(obj, T_STRING)
#define TRUEP(obj) get_ul(obj)
/** Convert an sxpr to an unsigned integer. */
#define OBJ_UINT(x) get_ul(x)
/** Convert an sxpr to an integer. */
#define OBJ_INT(x) (int)get_ul(x)
/* Conversions of sxprs to their values.
* No checking is done.
*/
#define OBJ_STRING(x) ((char*)get_ptr(x))
#define OBJ_CONS(x) ((ObjCons*)get_ptr(x))
#define OBJ_ATOM(x) ((ObjAtom*)get_ptr(x))
#define OBJ_SET(x) ((ObjSet*)get_ptr(x))
#define CAR(x) (OBJ_CONS(x)->car)
#define CDR(x) (OBJ_CONS(x)->cdr)
#define CAAR(x) (CAR(CAR(x)))
#define CADR(x) (CAR(CDR(x)))
#define CDAR(x) (CDR(CAR(x)))
#define CDDR(x) (CDR(CDR(x)))
/** Get the integer value from an sxpr.
*
* @param obj sxpr
@@ -208,22 +79,22 @@ static inline void * get_ptr(Sxpr obj){
/** Create an sxpr containing a pointer.
*
* @param type typecode
* @param ty typecode
* @param val pointer
* @return sxpr
*/
static inline Sxpr obj_ptr(TypeCode type, void *val){
return (Sxpr){ type: type, v: { ptr: val } };
static inline Sxpr obj_ptr(TypeCode ty, void *val){
return (Sxpr){ .type= ty, .v= { .ptr= val } };
}
/** Create an sxpr containing an integer.
*
* @param type typecode
* @param ty typecode
* @param val integer
* @return sxpr
*/
static inline Sxpr obj_ul(TypeCode type, unsigned long val){
return (Sxpr){ type: type, v: { ul: val } };
static inline Sxpr obj_ul(TypeCode ty, unsigned long val){
return (Sxpr){ .type= ty, .v= { .ul= val } };
}
/** Get the type of an sxpr.
@@ -255,6 +126,160 @@ static inline int eq(Sxpr x, Sxpr y){
return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y)));
}
/** The 'unspecified' sxpr. */
#define T_NONE ((TypeCode)0)
/** The empty list. */
#define T_NULL ((TypeCode)1)
/** Unsigned integer. */
#define T_UINT ((TypeCode)2)
/** A string. */
#define T_STRING ((TypeCode)3)
/** An atom. */
#define T_ATOM ((TypeCode)4)
/** A boolean. */
#define T_BOOL ((TypeCode)5)
/** A cons (pair or list). */
#define T_CONS ((TypeCode)10)
/** An error. */
#define T_ERR ((TypeCode)40)
/** Sxpr type to indicate out of memory. */
#define T_NOMEM ((TypeCode)41)
typedef struct ObjString {
int len;
char data[];
} ObjString;
/** An atom. */
typedef struct ObjAtom {
Sxpr name;
Hashcode hashcode;
int interned;
} ObjAtom;
/** A cons (pair). */
typedef struct ObjCons {
Sxpr car;
Sxpr cdr;
} ObjCons;
/** Flags for sxpr printing. */
enum PrintFlags {
PRINT_RAW = 0x001,
PRINT_TYPE = 0x002,
PRINT_PRETTY = 0x004,
PRINT_COUNTED = 0x008,
PRINT_ADDR = 0x010,
};
extern int _string_print(IOStream *io, char *str, int n, unsigned flags);
extern int _string_print_raw(IOStream *io, char *str, int n);
extern int _string_print_counted(IOStream *io, char *str, int n);
extern int _string_print_quoted(IOStream *io, char *str, int n);
extern int _string_print_string(IOStream *io, char *str, int n);
/** An integer sxpr.
*
* @param ty type
* @param val integer value
*/
#define OBJI(ty, val) obj_ul(ty, val)
/** Make an integer sxpr.
* @param x value
*/
#define OINT(x) OBJI(T_UINT, x)
/** Make an error sxpr.
*
* @param x value
*/
#define OERR(x) OBJI(T_ERR, x)
/** Out of memory constant. */
#define ONOMEM OBJI(T_NOMEM, 0)
/** The `unspecified' constant. */
#define ONONE OBJI(T_NONE, 0)
/** Empty list constant. */
#define ONULL OBJI(T_NULL, 0)
/** False constant. */
#define OFALSE OBJI(T_BOOL, 0)
/** True constant. */
#define OTRUE OBJI(T_BOOL, 1)
/** A pointer sxpr.
* If the pointer is non-null, returns an sxpr containing it.
* If the pointer is null, returns ONOMEM.
*
* @param ty type
* @param val pointer
*/
static inline Sxpr OBJP(int ty, void *val){
return (val ? obj_ptr(ty, val) : ONOMEM);
}
/** Make an integer sxpr containing a pointer.
*
* @param val pointer
*/
#define PTR(val) OBJP(T_UINT, (void*)(val))
/** Allocate some memory and return an sxpr containing it.
* Returns ONOMEM if allocation failed.
*
* @param n number of bytes to allocate
* @param ty typecode
* @return sxpr
*/
#define halloc(_n, _ty) OBJP(_ty, allocate(_n))
/** Allocate an sxpr containing a pointer to the given type.
*
* @param _ctype type (uses sizeof to determine how many bytes to allocate)
* @param _tycode typecode
* @return sxpr, ONOMEM if allocation failed
*/
#define HALLOC(_ctype, _tycode) halloc(sizeof(_ctype), _tycode)
/* Recognizers for the various sxpr types. */
#define ATOMP(obj) has_type(obj, T_ATOM)
#define BOOLP(obj) has_type(obj, T_BOOL)
#define CONSP(obj) has_type(obj, T_CONS)
#define ERRP(obj) has_type(obj, T_ERR)
#define INTP(obj) has_type(obj, T_UINT)
#define NOMEMP(obj) has_type(obj, T_NOMEM)
#define NONEP(obj) has_type(obj, T_NONE)
#define NULLP(obj) has_type(obj, T_NULL)
#define STRINGP(obj) has_type(obj, T_STRING)
#define TRUEP(obj) get_ul(obj)
/** Convert an sxpr to an unsigned integer. */
#define OBJ_UINT(x) get_ul(x)
/** Convert an sxpr to an integer. */
#define OBJ_INT(x) (int)get_ul(x)
/* Conversions of sxprs to their values.
* No checking is done.
*/
#define OBJ_STRING(x) ((ObjString*)get_ptr(x))
#define OBJ_CONS(x) ((ObjCons*)get_ptr(x))
#define OBJ_ATOM(x) ((ObjAtom*)get_ptr(x))
#define OBJ_SET(x) ((ObjSet*)get_ptr(x))
#define CAR(x) (OBJ_CONS(x)->car)
#define CDR(x) (OBJ_CONS(x)->cdr)
#define CAAR(x) (CAR(CAR(x)))
#define CADR(x) (CAR(CDR(x)))
#define CDAR(x) (CDR(CAR(x)))
#define CDDR(x) (CDR(CDR(x)))
/** Checked version of CAR
*
* @param x sxpr
@@ -273,28 +298,10 @@ static inline Sxpr cdr(Sxpr x){
return (CONSP(x) ? CDR(x) : ONULL);
}
/** Allocate some memory and return an sxpr containing it.
* Returns ONOMEM if allocation failed.
*
* @param n number of bytes to allocate
* @param ty typecode
* @return sxpr
*/
static inline Sxpr halloc(size_t n, TypeCode ty){
return OBJP(ty, allocate(n));
}
/** Allocate an sxpr containing a pointer to the given type.
*
* @param ty type (uses sizeof to determine how many bytes to allocate)
* @param code typecode
* @return sxpr, ONOMEM if allocation failed
*/
#define HALLOC(ty, code) halloc(sizeof(ty), code)
typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags);
typedef int ObjEqualFn(Sxpr obj, Sxpr other);
typedef void ObjFreeFn(Sxpr obj);
typedef Sxpr ObjCopyFn(Sxpr obj);
/** An sxpr type definition. */
typedef struct SxprType {
@@ -304,6 +311,7 @@ typedef struct SxprType {
ObjPrintFn *print;
ObjEqualFn *equal;
ObjFreeFn *free;
ObjCopyFn *copy;
} SxprType;
@@ -321,6 +329,7 @@ static inline void hfree(Sxpr x){
extern int objprint(IOStream *io, Sxpr x, unsigned flags);
extern int objequal(Sxpr x, Sxpr y);
extern void objfree(Sxpr x);
extern Sxpr objcopy(Sxpr x);
extern void cons_free_cells(Sxpr obj);
extern Sxpr intern(char *s);
@@ -341,8 +350,10 @@ extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
extern Sxpr atom_new(char *name);
extern char * atom_name(Sxpr obj);
extern int atom_length(Sxpr obj);
extern Sxpr string_new(char *s);
extern Sxpr string_new_n(char *s, int n);
extern char * string_string(Sxpr obj);
extern int string_length(Sxpr obj);
@@ -405,15 +416,20 @@ static inline Sxpr mkbool(int b){
#define k_true "true"
#define k_false "false"
#define c_var '$'
#define c_escape '\\'
#define c_single_quote '\''
#define c_double_quote '"'
#define c_string_open c_double_quote
#define c_string_close c_double_quote
#define c_data_open '['
#define c_data_close ']'
#define c_binary '*'
#define c_data_open '<'
#define c_data_quote '<'
#define c_data_count '*'
//#define c_data_open '['
//#define c_data_close ']'
//#define c_binary '*'
#define c_var '$'
#define c_eval '!'
#define c_concat_open '{'
#define c_concat_close '}'
File diff suppressed because it is too large. Load diff
+43 -23
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
* Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
@@ -25,10 +25,13 @@
* Sxpr parsing definitions.
*/
/** Size of a parser input buffer.
* Tokens read must fit into this size (including trailing null).
/** Initial size of a parser input buffer.
*/
#define PARSER_BUF_SIZE 4096
#define PARSER_BUF_SIZE 512
/** Input buffer size increment (when it's full).
*/
#define PARSER_BUF_INCREMENT 512
struct Parser;
typedef int ParserStateFn(struct Parser *, char c);
@@ -43,13 +46,14 @@ typedef struct ParserState {
char *name;
} ParserState;
/** Structure representing an input source for the parser.
* Can read from any IOStream implementation.
*/
typedef struct Parser {
/** Initial state function. */
ParserStateFn *begin;
/** Parse value. */
Sxpr val;
/** Error reporting stream (null for no reports). */
IOStream *error_out;
/** End-of-file flag, */
int eof;
/** Error flag. Non-zero if there has been a read error. */
int err;
@@ -57,13 +61,11 @@ typedef struct Parser {
int line_no;
/** Column number of input (reset on new line). */
int char_no;
/** Lookahead character. */
char c;
/** Buffer for reading tokens. */
char buf[PARSER_BUF_SIZE];
/** Size of token buffer. */
int buf_n;
int buf_i;
char *buf;
char *buf_end;
char *tok;
char *tok_end;
/** Line the last token started on. */
int tok_begin_line;
/** Character number the last token started on. */
@@ -95,7 +97,7 @@ typedef enum {
* @param in parser
* @param flags flags mask
*/
inline static void parser_flags_raise(Parser *in, int flags){
inline static void Parser_flags_raise(Parser *in, int flags){
in->flags |= flags;
}
@@ -104,7 +106,7 @@ inline static void parser_flags_raise(Parser *in, int flags){
* @param in parser
* @param flags flags mask
*/
inline static void parser_flags_lower(Parser *in, int flags){
inline static void Parser_flags_lower(Parser *in, int flags){
in->flags &= ~flags;
}
@@ -112,7 +114,7 @@ inline static void parser_flags_lower(Parser *in, int flags){
*
* @param in parser
*/
inline static void parser_flags_clear(Parser *in){
inline static void Parser_flags_clear(Parser *in){
in->flags = 0;
}
@@ -121,14 +123,32 @@ extern Parser * Parser_new(void);
extern int Parser_input(Parser *p, char *buf, int buf_n);
extern int Parser_input_eof(Parser *p);
extern int Parser_input_char(Parser *p, char c);
extern void set_error_stream(Parser *z, IOStream *error_out);
extern void Parser_set_error_stream(Parser *z, IOStream *error_out);
extern int parse_error_message(Parser *in, char *buf, int n);
extern int has_error(Parser *in);
extern int at_eof(Parser *in);
extern int Parser_error_message(Parser *in, char *buf, int n);
extern int Parser_has_error(Parser *in);
extern int Parser_at_eof(Parser *in);
int Parser_ready(Parser *p);
Sxpr Parser_get_val(Parser *p);
Sxpr Parser_get_all(Parser *p);
extern int Parser_ready(Parser *p);
extern Sxpr Parser_get_val(Parser *p);
extern Sxpr Parser_get_all(Parser *p);
/* Internal parser api. */
void Parser_pop(Parser *p);
int Parser_push(Parser *p, ParserStateFn *fn, char *name);
int Parser_return(Parser *p);
int Parser_at_eof(Parser *p);
int Parser_error(Parser *in);
int Parser_set_value(Parser *p, Sxpr val);
int Parser_intern(Parser *p);
int Parser_string(Parser *p);
int Parser_data(Parser *p);
int Parser_uint(Parser *p);
char *peek_token(Parser *p);
char *copy_token(Parser *p);
void new_token(Parser *p);
int save_char(Parser *p, char c);
int token_len(Parser *p);
#endif /* ! _XUTIL_SXPR_PARSER_H_ */
+55
View File
@@ -49,6 +49,27 @@ inline static const char * convert_set_base(const char *s, int *base){
return s;
}
/** Set the sign to use for converting a string to a number.
* Value is 1 for positive, -1 for negative.
*
* @param s input string
* @param sign where to put the sign
* @return rest of s to parse as a number
*/
inline static const char * convert_set_sign(const char *s, int *sign){
*sign = 1;
if(s){
if(*s == '+'){
*sign = 1;
s++;
} else if (*s == '-'){
*sign = -1;
s++;
}
}
return s;
}
/** Get the numerical value of a digit in the given base.
*
* @param c digit character
@@ -103,6 +124,40 @@ int convert_atoul(const char *str, unsigned long *val){
return err;
}
/** Convert a string to a long by parsing it as a number.
* Will accept hex or decimal in usual C syntax.
*
* @param str input string
* @param val where to put the result
* @return 0 if converted OK, negative otherwise
*/
int convert_atol(const char *str, long *val){
int err = 0;
unsigned long v = 0;
int base, sign = 1;
const char *s = str;
if(!s) {
err = -EINVAL;
goto exit;
}
s = convert_set_sign(s, &sign);
s = convert_set_base(s, &base);
for( ; !err && *s; s++){
int digit = convert_get_digit(*s, base);
if(digit<0){
err = -EINVAL;
goto exit;
}
v *= base;
v += digit;
}
if(sign < 0) v = -v;
exit:
*val = (err ? 0 : v);
return err;
}
/** Combine a directory path with a relative path to produce
* a new path.
*
+1
View File
@@ -86,6 +86,7 @@ static inline size_t strnlen(const char *s, size_t n){
/*============================================================================*/
extern int convert_atoul(const char *s, unsigned long *v);
extern int convert_atol(const char *s, long *v);
extern int path_concat(char *s, char *t, char **val);
#endif /* !_XUTIL_SYS_STRING_H_ */
+1 -5
View File
@@ -60,7 +60,6 @@ class Daemon:
if not pm: continue
xm = xendre.match(pm.group('cmd'))
if not xm: continue
#print 'pid=', pm.group('pid'), 'cmd=', pm.group('cmd')
pids.append(int(pm.group('pid')))
return pids
@@ -313,7 +312,7 @@ class Daemon:
os.setuid(pwd.getpwnam(XEND_USER)[2])
return 0
except KeyError, error:
print "Error: no such user '%s'" % XEND_USER
print >>sys.stderr, "Error: no such user '%s'" % XEND_USER
return 1
def stop(self):
@@ -328,7 +327,6 @@ class Daemon:
self.listenChannels()
servers = SrvServer.create()
self.daemonize()
print 'running serverthread...'
servers.start()
except Exception, ex:
print >>sys.stderr, 'Exception starting xend:', ex
@@ -342,14 +340,12 @@ class Daemon:
def listenChannels(self):
def virqReceived(virq):
print 'virqReceived>', virq
eserver.inject('xend.virq', virq)
self.channelF.setVirqHandler(virqReceived)
self.channelF.start()
def exit(self, rc=0):
#reactor.disconnectAll()
if self.channelF:
self.channelF.stop()
# Calling sys.exit() raises a SystemExit exception, which only
+30 -16
View File
@@ -3,17 +3,13 @@ import StringIO
from xen.web import reactor, protocol
from xen.lowlevel import xu
from xen.xend import sxp
from xen.xend import PrettyPrint
from xen.xend import EventServer
eserver = EventServer.instance()
from xen.xend import EventServer; eserver = EventServer.instance()
from xen.xend.XendError import XendError
from xen.xend import XendRoot; xroot = XendRoot.instance()
DEBUG = 1
DEBUG = 0
class EventProtocol(protocol.Protocol):
"""Asynchronous handler for a connected event socket.
@@ -30,7 +26,7 @@ class EventProtocol(protocol.Protocol):
self.pretty = 0
# For debugging subscribe to everything and make output pretty.
self.subscribe(['*'])
#self.subscribe(['*'])
self.pretty = 1
def dataReceived(self, data):
@@ -45,10 +41,7 @@ class EventProtocol(protocol.Protocol):
except SystemExit:
raise
except:
if DEBUG:
raise
else:
self.send_error()
self.send_error()
def loseConnection(self):
if self.transport:
@@ -73,7 +66,11 @@ class EventProtocol(protocol.Protocol):
return 0
def send_result(self, res):
return self.send_reply(['ok', res])
if res is None:
resp = ['ok']
else:
resp = ['ok', res]
return self.send_reply(resp)
def send_error(self):
(extype, exval) = sys.exc_info()[:2]
@@ -129,7 +126,6 @@ class EventProtocol(protocol.Protocol):
def op_pretty(self, name, req):
self.pretty = 1
return ['ok']
def op_console_disconnect(self, name, req):
id = sxp.child_value(req, 'id')
@@ -137,7 +133,6 @@ class EventProtocol(protocol.Protocol):
raise XendError('Missing console id')
id = int(id)
self.daemon.console_disconnect(id)
return ['ok']
def op_info(self, name, req):
val = ['info']
@@ -151,13 +146,11 @@ class EventProtocol(protocol.Protocol):
# (sys.subscribe event*)
# Subscribe to the events:
self.subscribe(v[1:])
return ['ok']
def op_sys_inject(self, name, v):
# (sys.inject event)
event = v[1]
eserver.inject(sxp.name(event), event)
return ['ok']
def op_trace(self, name, v):
mode = (v[1] == 'on')
@@ -181,6 +174,27 @@ class EventProtocol(protocol.Protocol):
import controller
controller.DEBUG = (mode == 'on')
def op_domain_ls(self, name, v):
xd = xroot.get_component("xen.xend.XendDomain")
return xd.domain_ls()
def op_domain_configure(self, name, v):
domid = sxp.child_value(v, "dom")
config = sxp.child_value(v, "config")
if domid is None:
raise XendError("missing domain id")
if config is None:
raise XendError("missing domain config")
xd = xroot.get_component("xen.xend.XendDomain")
xd.domain_configure(domid, config)
def op_domain_unpause(self, name, v):
domid = sxp.child_value(v, "dom")
if domid is None:
raise XendError("missing domain id")
xd = xroot.get_component("xen.xend.XendDomain")
xd.domain_unpause(domid)
class EventFactory(protocol.ServerFactory):
"""Asynchronous handler for the event server socket.
"""
+2 -1
View File
@@ -6,6 +6,7 @@ UTIL_LIB = libutil.a
UTIL_LIB_SRC =
UTIL_LIB_SRC += allocate.c
UTIL_LIB_SRC += enum.c
UTIL_LIB_SRC += fd_stream.c
UTIL_LIB_SRC += file_stream.c
UTIL_LIB_SRC += gzip_stream.c
UTIL_LIB_SRC += hash_table.c
@@ -19,7 +20,7 @@ UTIL_LIB_SRC += sxpr_parser.c
UTIL_LIB_SRC += sys_net.c
UTIL_LIB_SRC += sys_string.c
#UTIL_LIB_SRC += util.c
UTIL_LIB_SRC += xdr.c
#UTIL_LIB_SRC += xdr.c
#----------------------------------------------------------------------------
# Xfrd.
+1 -14
View File
@@ -26,18 +26,11 @@ UTIL_LIB_OBJ = $(UTIL_LIB_SRC:.c=.o)
XFRD_PROG_OBJ = $(XFRD_PROG_SRC:.c=.o)
XFRD_PROG_OBJ += $(UTIL_LIB)
# Flag controlling whether to use stubs.
# Define to use stubs, undefine to use the real Xen functions.
#CPPFLAGS += -D _XEN_XFR_STUB_
ifeq ($(SXPR_DEBUG),1)
CPPFLAGS += -D _XEN_XFR_STUB_ -D SXPR_PARSER_MAIN
endif
CC := gcc
CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing
CFLAGS += $(INCLUDES)
# Make gcc generate dependencies.
CFLAGS += -Wp,-MD,.$(@F).d
PROG_DEP = .*.d
@@ -55,12 +48,6 @@ XFRD_LIBS += -L $(XEN_LIBXUTIL) -lxutil
# zlib library.
XFRD_LIBS += -lz
CURL_FLAGS = $(shell curl-config --cflags)
CURL_LIBS = $(shell curl-config --libs)
CFLAGS += $(CURL_FLAGS)
# libcurl libraries.
XFRD_LIBS += $(CURL_LIBS)
#$(warning XFRD_LIBS = $(XFRD_LIBS))
all: build
+1 -1
View File
@@ -171,7 +171,7 @@ int Conn_sxpr(Conn *conn, Sxpr *sxpr){
dprintf(">\n");
if(!conn->parser){
conn->parser = Parser_new();
set_error_stream(conn->parser, iostdout);
Parser_set_error_stream(conn->parser, iostdout);
}
while(!err && c >= 0 && !Parser_ready(conn->parser)){
c = IOStream_getc(conn->in);
+2 -3
View File
@@ -475,7 +475,6 @@ static int lzi_close(IOStream *io){
*/
static void lzi_free(IOStream *s){
LZIState *state = lzi_state(s);
IOStream_free(state->io);
LZIState_free(state);
s->data = NULL;
}
@@ -525,8 +524,8 @@ IOStream *lzi_stream_fdopen(int fd, const char *mode){
err = 0;
exit:
if(err){
IOStream_free(io);
IOStream_free(zio);
IOStream_close(io);
IOStream_close(zio);
zio = NULL;
}
return zio;
+171 -232
View File
@@ -1,17 +1,18 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef _XEN_XFR_STUB_
typedef unsigned long u32;
#else
#include "xc.h"
#include "xc_io.h"
#endif
#include "sxpr.h"
#include "sxpr_parser.h"
#include "file_stream.h"
#include "fd_stream.h"
#include "xen_domain.h"
#include "marshal.h"
#include "xdr.h"
#include "xfrd.h"
#define MODULE_NAME "XFRD"
@@ -33,7 +34,6 @@ int domain_configure(void *data, u32 dom, char *vmconfig, int vmconfig_n){
return xen_domain_configure(dom, vmconfig, vmconfig_n);
}
#ifndef _XEN_XFR_STUB_
static int xc_handle = 0;
int xcinit(void){
@@ -50,7 +50,6 @@ void xcfini(void){
xc_handle = 0;
}
}
#endif
/** Write domain state.
*
@@ -62,31 +61,6 @@ int xen_domain_snd(Conn *xend, IOStream *io,
char *vmconfig, int vmconfig_n,
int live, int resource){
int err = 0;
#ifdef _XEN_XFR_STUB_
char buf[1024];
int n, k, d, buf_n;
dprintf("> dom=%d\n", dom);
err = marshal_uint32(io, dom);
if(err) goto exit;
err = marshal_string(io, vmconfig, vmconfig_n);
if(err) goto exit;
n = 32 * 1024 * 1024;
n = 32 * 1024;
buf_n = sizeof(buf);
err = marshal_uint32(io, n);
for(k = 0; k < n; k += d){
d = n - k;
if(d > buf_n) d = buf_n;
err = marshal_bytes(io, buf, d);
if(err) goto exit;
dprintf("> k=%d n=%d\n", k, n);
}
dom = 99;
err = domain_suspend(xend, dom);
IOStream_close(io);
exit:
#else
XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
ioctxt->domain = dom;
ioctxt->io = io;
@@ -101,7 +75,6 @@ int xen_domain_snd(Conn *xend, IOStream *io,
}
ioctxt->resource = resource;
err = xc_linux_save(xcinit(), ioctxt);
#endif
dprintf("< err=%d\n", err);
return err;
}
@@ -114,25 +87,6 @@ int xen_domain_rcv(IOStream *io,
char **vmconfig, int *vmconfig_n,
int *configured){
int err = 0;
#ifdef _XEN_XFR_STUB_
char buf[1024];
int n, k, d, buf_n;
dprintf(">\n");
err = unmarshal_uint32(io, dom);
if(err) goto exit;
err = unmarshal_new_string(io, vmconfig, vmconfig_n);
if(err) goto exit;
err = unmarshal_uint32(io, &n);
buf_n = sizeof(buf);
for(k = 0; k < n; k += d){
d = n - k;
if(d > buf_n) d = buf_n;
err = unmarshal_bytes(io, buf, d);
if(err) goto exit;
dprintf("> k=%d n=%d\n", k, n);
}
exit:
#else
XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
dprintf(">\n");
ioctxt->io = io;
@@ -147,137 +101,182 @@ int xen_domain_rcv(IOStream *io,
*vmconfig = ioctxt->vmconfig;
*vmconfig_n = ioctxt->vmconfig_n;
*configured = (ioctxt->flags & XCFLAGS_CONFIGURE);
#endif
dprintf("< err=%d\n", err);
return err;
}
#include <curl/curl.h>
#include "http.h"
typedef struct xend {
int fd;
IOStream *io;
Parser *parser;
int seeneof;
} Xend;
/** Flag indicating whether we need to initialize libcurl.
*/
static int do_curl_global_init = 1;
/** Get a curl handle, initializing libcurl if needed.
*
* @return curl handle
*/
static CURL *curlinit(void){
if(do_curl_global_init){
do_curl_global_init = 0;
// Stop libcurl using the proxy. There's a curl option to
// set the proxy - but no option to defeat it.
unsetenv("http_proxy");
curl_global_init(CURL_GLOBAL_ALL);
}
return curl_easy_init();
char *xend_server_addr(void){
char * val = getenv("XEND_EVENT_ADDR");
return (val ? val : "/var/lib/xend/event-socket");
}
/** Curl debug function.
/** Open a unix-domain socket to the xend server.
*/
int curldebug(CURL *curl, curl_infotype ty, char *buf, int buf_n, void *data){
// printf("%*s\n", buf_n, buf); /* Does not compile correctly on non 32bit platforms */
fwrite(data, buf_n, 1, stdout);
printf("\n");
return 0;
}
/** Setup a curl handle with a url.
* Creates the url by formatting 'fmt' and the remaining arguments.
*
* @param pcurl return parameter for the curl handle
* @param url url buffer
* @param url_n size of url
* @param fmt url format string, followed by parameters
* @return 0 on success, error code otherwise
*/
static int curlsetup(CURL **pcurl, struct curl_slist **pheaders, char *url, int url_n, char *fmt, ...){
int xend_open_fd(void){
struct sockaddr_un addr_un = { .sun_family = AF_UNIX };
struct sockaddr *addr = (struct sockaddr*)&addr_un;
int addr_n = sizeof(addr_un);
int err = 0;
va_list args;
CURL *curl = NULL;
struct curl_slist *headers = NULL;
int n = 0;
curl = curlinit();
if(!curl){
eprintf("> Could not init libcurl\n");
err = -ENOMEM;
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(fd < 0){
err = -errno;
perror("socket");
goto exit;
}
url_n -= 1;
va_start(args, fmt);
n = vsnprintf(url, url_n, fmt, args);
va_end(args);
if(n <= 0 || n >= url_n){
err = -ENOMEM;
eprintf("> Out of memory in url\n");
strcpy(addr_un.sun_path, xend_server_addr());
if(connect(fd, addr, addr_n) < 0){
err = -errno;
perror("connect");
goto exit;
}
dprintf("> url=%s\n", url);
#if DEBUG
// Verbose.
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
// Call the debug function on data received.
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curldebug);
#else
// No progress meter.
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
// Completely quiet.
curl_easy_setopt(curl, CURLOPT_MUTE, 1);
#endif
// Set the URL.
curl_easy_setopt(curl, CURLOPT_URL, url);
headers = curl_slist_append(headers, "Expect:");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
exit:
if(err && (fd >= 0)){
close(fd);
}
exit:
if(err && curl){
curl_easy_cleanup(curl);
curl = NULL;
}
*pcurl = curl;
if (pheaders)
*pheaders = headers;
return err;
return (err ? err : fd);
}
static void curlcleanup(CURL **pcurl, struct curl_slist **pheaders){
if (*pcurl)
curl_easy_cleanup(*pcurl);
if (*pheaders)
curl_slist_free_all(*pheaders);
*pcurl = NULL;
*pheaders = NULL;
}
/** Make the http request stored in the curl handle and get
* the result code from the curl code and the http return code.
/** Close a connection to the server.
*
* @param curl curl handle
* @return 0 for success, error code otherwise
*/
int curlresult(CURL *curl){
int err = 0;
CURLcode curlcode = 0;
long httpcode = 0;
* @param xend connection
*/
void xend_close(Xend *xend){
if(!xend) return;
close(xend->fd);
Parser_free(xend->parser);
}
curlcode = curl_easy_perform(curl);
if(curlcode){
eprintf("> curlcode=%d\n", curlcode);
err = -EINVAL;
/** Open a connection to the server.
*
* @param xend result parameter for the connection
* @return 0 on success, negative error code otherwise
*/
int xend_open(Xend **xend){
int err = 0;
Xend *val = ALLOCATE(Xend);
val->fd = xend_open_fd();
if(val->fd < 0){
err = val->fd;
goto exit;
}
curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode);
if(httpcode != HTTP_OK){
eprintf("> httpcode=%d\n", (int)httpcode);
err = -EINVAL;
goto exit;
val->io = fd_stream_new(val->fd);
val->parser = Parser_new();
exit:
if(err) xend_close(val);
*xend = (err ? NULL : val);
return err;
}
/** Read a response from a server connection.
*/
int xend_read_resp(Xend *xend, Sxpr *resp){
int err = 0;
Sxpr val = ONONE;
char buf[1024];
int buf_n = sizeof(buf), n;
for( ; ; ){
if(Parser_ready(xend->parser)){
val = Parser_get_val(xend->parser);
goto exit;
}
if(xend->seeneof){
err = -EIO;
goto exit;
}
memset(buf, 0, buf_n);
n = IOStream_read(xend->io, buf, 100);
if(n <= 0){
xend->seeneof = 1;
err = Parser_input_eof(xend->parser);
} else {
err = Parser_input(xend->parser, buf, n);
}
}
exit:
*resp = (err < 0 ? ONONE : val);
return err;
}
/** Read a response from a server connection and decode the value.
*
* @param xend server connection
* @param resp result parameter for the response value
* @return 0 on success, negative error code otherwise
*/
int xend_read(Xend *xend, Sxpr *resp){
int err = 0;
Sxpr val = ONONE;
dprintf(">\n");
for( ; ; ){
err = xend_read_resp(xend, &val);
if(err < 0) goto exit;
if(sxpr_is(sxpr_name(val), "event")){
// We don't care about events, try again.
err = 0;
continue;
} else if(sxpr_is(sxpr_name(val), "err")){
eprintf("> "); objprint(iostderr, val, 0); fprintf(stderr, "\n");
err = -EINVAL;
break;
} else {
err = 0;
val = sxpr_child0(val, ONULL);
break;
}
}
#ifdef DEBUG
dprintf("> OK ");
objprint(iostdout, val, 0);
printf("\n");
#endif
exit:
if(resp){
*resp = (err < 0 ? ONONE : val);
}
dprintf("> err=%d\n", err);
return err;
}
/** Send a request to the server and return the result value in resp.
*
* @param xend server connection
* @param resp result parameter for the response value
* @param format request format followed by args to print
* @return 0 on success, negative error code otherwise
*/
int xend_call(Xend *xend, Sxpr *resp, char *format, ...){
va_list args;
int err;
dprintf("> ");
va_start(args, format);
#ifdef DEBUG
vprintf(format, args); printf("\n");
#endif
err = IOStream_vprint(xend->io, format, args);
va_end(args);
if(err < 0) goto exit;
IOStream_flush(xend->io);
err = xend_read(xend, resp);
exit:
dprintf("> err=%d\n", err);
return (err < 0 ? err : 0);
}
/** Get xend to list domains.
* We use this to force xend to refresh its domain list.
*
@@ -285,18 +284,12 @@ int curlresult(CURL *curl){
*/
int xen_domain_ls(void){
int err = 0;
CURL *curl = NULL;
struct curl_slist *headers = NULL;
char url[128] = {};
int url_n = sizeof(url);
dprintf(">\n");
err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain", XEND_PORT);
Xend *xend = NULL;
err = xend_open(&xend);
if(err) goto exit;
err = curlresult(curl);
err = xend_call(xend, NULL, "(domain.ls)");
exit:
curlcleanup(&curl, &headers);
dprintf("< err=%d\n", err);
xend_close(xend);
return err;
}
@@ -309,49 +302,18 @@ int xen_domain_ls(void){
*/
int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){
int err = 0;
CURL *curl = NULL;
struct curl_slist *headers = NULL;
char url[128] = {};
int url_n = sizeof(url);
struct curl_httppost *form = NULL, *last = NULL;
CURLFORMcode formcode = 0;
Xend *xend = NULL;
dprintf("> dom=%u\n", dom);
// List domains so that xend will update its domain list and notice the new domain.
xen_domain_ls();
err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom);
// Now configure it.
err = xend_open(&xend);
if(err) goto exit;
// Config field - set from vmconfig.
formcode = curl_formadd(&form, &last,
CURLFORM_COPYNAME, "config",
CURLFORM_BUFFER, "config",
CURLFORM_BUFFERPTR, vmconfig,
CURLFORM_BUFFERLENGTH, vmconfig_n,
CURLFORM_CONTENTTYPE, "application/octet-stream",
CURLFORM_END);
if(formcode){
eprintf("> Error adding config field.\n");
goto exit;
}
// Op field.
formcode = curl_formadd(&form, &last,
CURLFORM_COPYNAME, "op",
CURLFORM_COPYCONTENTS, "configure",
CURLFORM_END);
if(formcode){
eprintf("> Error adding op field.\n");
err = -EINVAL;
goto exit;
}
// POST the form.
curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
err = curlresult(curl);
err = xend_call(xend, NULL, "(domain.configure (dom %d) (config %*s))",
dom, vmconfig_n, vmconfig);
exit:
curlcleanup(&curl, &headers);
if(form) curl_formfree(form);
dprintf("< err=%d\n", err);
xend_close(xend);
return err;
}
@@ -362,34 +324,11 @@ int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){
*/
int xen_domain_unpause(uint32_t dom){
int err = 0;
CURL *curl = NULL;
struct curl_slist *headers = NULL;
char url[128] = {};
int url_n = sizeof(url);
struct curl_httppost *form = NULL, *last = NULL;
CURLFORMcode formcode = 0;
dprintf("> dom=%u\n", dom);
err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom);
Xend *xend = NULL;
err = xend_open(&xend);
if(err) goto exit;
// Op field.
formcode = curl_formadd(&form, &last,
CURLFORM_COPYNAME, "op",
CURLFORM_COPYCONTENTS, "unpause",
CURLFORM_END);
if(formcode){
eprintf("> Error adding op field.\n");
err = -EINVAL;
goto exit;
}
// POST the form.
curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
err = curlresult(curl);
err = xend_call(xend, NULL, "(domain.unpause (dom %d))", dom);
exit:
curlcleanup(&curl, &headers);
if(form) curl_formfree(form);
dprintf("< err=%d\n", err);
xend_close(xend);
return err;
}
+1 -7
View File
@@ -188,7 +188,6 @@ enum {
XFR_MAX
};
#ifndef SXPR_PARSER_MAIN
/** Short options. Options followed by ':' take an argument. */
static char *short_opts = (char[]){
OPT_PORT, ':',
@@ -213,7 +212,6 @@ static Args _args = {};
/** Xfrd arguments. */
static Args *args = &_args;
#endif
/** Initialize an array element for a constant to its string name. */
#define VALDEF(val) { val, #val }
@@ -782,7 +780,6 @@ int xfr_save(Args *args, XfrState *state, Conn *xend, char *file){
exit:
if(io){
IOStream_close(io);
IOStream_free(io);
}
if(err){
unlink(file);
@@ -798,7 +795,7 @@ int xfr_save(Args *args, XfrState *state, Conn *xend, char *file){
int xfr_restore(Args *args, XfrState *state, Conn *xend, char *file){
int err = 0;
IOStream *io = NULL;
int configured=0;
int configured = 0;
dprintf("> file=%s\n", file);
io = gzip_stream_fopen(file, "rb");
@@ -820,7 +817,6 @@ int xfr_restore(Args *args, XfrState *state, Conn *xend, char *file){
exit:
if(io){
IOStream_close(io);
IOStream_free(io);
}
if(err){
xfr_error(xend, err);
@@ -1215,7 +1211,6 @@ int xfrd_main(Args *args){
return err;
}
#ifndef SXPR_PARSER_MAIN
/** Parse command-line arguments and call the xfrd main program.
*
* @param arg argument count
@@ -1271,4 +1266,3 @@ int main(int argc, char *argv[]){
}
return (err ? 1 : 0);
}
#endif
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.