void fmt_tofrom_array(unsigned long (*func)(char*,const char*,unsigned long), array* dest,array* src) { unsigned long needed; char* x; if (array_failed(dest) || array_failed(src)) { array_fail(dest); return; } needed=func(0,array_start(src),array_bytes(src)); if (array_allocate(dest,1,array_bytes(dest)+needed-1)) { x=((char*)array_start(dest))+array_bytes(dest)-needed; func(x,array_start(src),array_bytes(src)); } else array_fail(dest); }
void fmt_tofrom_array(size_t (*func)(char*,const char*,size_t), array* dest,array* src) { size_t needed; char* x; if (array_failed(dest) || array_failed(src)) { array_fail(dest); return; } needed=func(0,array_start(src),array_bytes(src)); if (array_bytes(dest)+needed>needed && array_allocate(dest,1,array_bytes(dest)+needed-1)) { x=((char*)array_start(dest))+array_bytes(dest)-needed; func(x,array_start(src),array_bytes(src)); } else array_fail(dest); }
size_t scan_tofrom_array(size_t (*func)(const char*,char*,size_t*), array* src,array* dest) { size_t scanned; size_t needed; char* x; array_cat0(src); if (array_failed(src) || array_failed(dest)) return 0; needed=array_bytes(src); x=((char*)array_start(dest))+array_bytes(dest); if (!array_allocate(dest,1,array_bytes(dest)+needed-1)) return 0; needed=func(array_start(src),x,&scanned); array_truncate(src,1,array_bytes(src)-1); return needed; }
static void test_failed() { PREPARE_ARRAY(x, p, int, sizeof(int), 10); PREPARE_ARRAY(y, q, int, sizeof(int), 10); array_fail(&x); array_cat(&x, &y); struct array z = y; assert(array_failed(&x)); assert(!array_failed(&y)); assert(y.p == z.p); assert(y.a == z.a); assert(y.len == z.len); }
static ssize_t handle_read( const int64 clientsocket ) { struct http_data* h = io_getcookie( clientsocket ); ssize_t l; if( ( l = io_tryread( clientsocket, static_inbuf, sizeof static_inbuf ) ) <= 0 ) { handle_dead( clientsocket ); return 0; } /* If we get the whole request in one packet, handle it without copying */ if( !array_start( &h->request ) ) { if( memchr( static_inbuf, '\n', l ) ) return http_handle_request( clientsocket, static_inbuf, l ); h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; array_catb( &h->request, static_inbuf, l ); return 0; } h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; array_catb( &h->request, static_inbuf, l ); if( array_failed( &h->request ) ) return http_issue_error( clientsocket, CODE_HTTPERROR_500 ); if( ( array_bytes( &h->request ) > 8192 ) && !accesslist_isblessed( (char*)&h->ip, OT_PERMISSION_MAY_SYNC ) ) return http_issue_error( clientsocket, CODE_HTTPERROR_500 ); if( memchr( array_start( &h->request ), '\n', array_bytes( &h->request ) ) ) return http_handle_request( clientsocket, array_start( &h->request ), array_bytes( &h->request ) ); return 0; }
/* Reset the array, fill it with the path arguments, and a null terminator. */ static int array_path(array_t *sa, char *path1, char *path2) { array_reset(sa); array_append(sa, path1, strlen(path1)); array_append(sa, "/", 1); array_append(sa, path2, strlen(path2)); array_append_null(sa); return array_failed(sa); }
void array_resize(array_t *array, size_t num) { if (array_failed(array)) return; if (array_size(array) < num) _array_pad(array, num - array_size(array)); array->size = num; }
static void test_right_failed() { PREPARE_ARRAY(x, p, int, sizeof(int), 10); PREPARE_ARRAY(y, q, int, sizeof(int), 10); array_fail(&y); array_cat(&x, &y); assert(array_failed(&x)); }
int sv_stat_save(char *path, sv_stat_t *svst) { int fd; array_t new_path = ARRAY_INIT(1); int r; char status[SUPERVISE_STATUS_SIZE]; uint32_t tmp; /* Pack the svstat data into the status byte array. */ taia_pack(status, &svst->timestamp); tmp = svst->pid; ((uint32_t *)status)[3] = htobe32(tmp); status[16] = svst->paused; status[17] = svst->mode; /* Construct the path for the .new file into the array which *MUST* be freed * before returning. */ array_append(&new_path, path, strlen(path)); array_append(&new_path, SUPERVISE_STATUS_NEW_EXT, strlen(SUPERVISE_STATUS_NEW_EXT)); array_append_null(&new_path); if (array_failed(&new_path)) { array_reset(&new_path); errno = ENOMEM; return -1; } /* Open the tmp file, write the status byte array to it, verify the entire * array was written, and finally rename it to status. */ fd = open_trunc(array_start(&new_path)); if (fd == -1) { array_reset(&new_path); return ESVOPENSTATNEW; } r = write(fd, status, SUPERVISE_STATUS_SIZE); if ((r == -1) || (r != SUPERVISE_STATUS_SIZE)) { close(fd); array_reset(&new_path); return ESVWRITESTATNEW; } close(fd); if (rename(array_start(&new_path), path) == -1) { array_reset(&new_path); return ESVWRITESTAT; } array_reset(&new_path); return 0; }
void *array_get(array_t *array, size_t pos) { if ((array_failed(array)) || (array_size(array) <= pos)) return 0; return array->data + (array->esize * pos); }