#include "std.h" #include "../lpc_incl.h" #include "async.h" #include "../function.h" #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "../config.h" #include "../interpret.h" #include "../file.h" #if defined(F_ASYNC_READ) || defined(F_ASYNC_WRITE) static struct request *reqs = NULL; void add_req(struct request *req){ req->next = reqs; reqs = req; } int add_read(const char *fname, function_to_call_t *fun){ aiob *aio = MALLOC(sizeof(aiob)); memset(aio, 0, sizeof(aiob)); printf("fname: %s\n", fname); int fd = open(fname, O_RDONLY); aio->aio_fildes = fd; aio->aio_buf = MALLOC(READ_FILE_MAX_SIZE); aio->aio_nbytes = READ_FILE_MAX_SIZE; struct request *req = MALLOC(sizeof(struct request)); req->aio = aio; req->fun = fun; req->type = aread; add_req(req); return aio_read(aio); } int add_write(const char *fname, char *buf, int size, char append, function_to_call_t *fun){ aiob *aio = MALLOC(sizeof(aiob)); memset(aio, 0, sizeof(aiob)); int fd = open(fname, append?O_CREAT|O_WRONLY|O_APPEND:O_CREAT|O_WRONLY, S_IRWXU|S_IRWXG); aio->aio_fildes = fd; aio->aio_buf = buf; aio->aio_nbytes = size; struct request *req = MALLOC(sizeof(struct request)); req->aio = aio; req->fun = fun; req->type = awrite; add_req(req); return aio_write(aio); } void handle_read(struct request *req, int val){ aiob *aio = req->aio; close(aio->aio_fildes); if(val){ push_number(val); call_efun_callback(req->fun, 1); free_funp(req->fun->f.fp); return; } val = aio_return(aio); if(val < 0){ push_number(val); call_efun_callback(req->fun, 1); free_funp(req->fun->f.fp); return; } char *file = MALLOC(val+1); memcpy(file, (char *)(aio->aio_buf), val); file[val]=0; push_malloced_string(file); call_efun_callback(req->fun, 1); free_funp(req->fun->f.fp); } void handle_write(struct request *req, int val){ aiob *aio = req->aio; close(aio->aio_fildes); if(val){ push_number(val); call_efun_callback(req->fun, 1); free_funp(req->fun->f.fp); return; } val = aio_return(aio); if(val < 0){ push_number(val); call_efun_callback(req->fun, 1); free_funp(req->fun->f.fp); return; } push_undefined(); call_efun_callback(req->fun, 1); free_funp(req->fun->f.fp); } void check_reqs() { struct request **check = &reqs; while (*check) { int val = aio_error((*check)->aio); if (val != EINPROGRESS) { switch ((*check)->type) { case aread: handle_read(*check, val); break; case awrite: handle_write(*check, val); break; default: fatal("unknown async type\n"); } struct request *tmp = *check; *check = (*check)->next; fflush(0); FREE((char *)(tmp->aio->aio_buf)); FREE(tmp->aio); FREE(tmp->fun); FREE(tmp); } else { struct request *tmp = *check; if(tmp->next){ fflush(0); check = &((*check)->next); } else check = 0; } } } #ifdef F_ASYNC_READ void f_async_read(){ function_to_call_t *cb = MALLOC(sizeof(function_to_call_t)); memset(cb, 0, sizeof(function_to_call_t)); process_efun_callback(1, cb, F_ASYNC_READ); cb->f.fp->hdr.ref++; add_read(check_valid_path((sp-1)->u.string, current_object, "read_file", 0), cb); pop_2_elems(); } #endif #ifdef F_ASYNC_WRITE void f_async_write(){ char *buf = MALLOC(strlen((sp-1)->u.string)); strcpy(buf, (sp-1)->u.string); function_to_call_t *cb = MALLOC(sizeof(function_to_call_t)); memset(cb, 0, sizeof(function_to_call_t)); process_efun_callback(2, cb, F_ASYNC_WRITE); cb->f.fp->hdr.ref++; add_write(check_valid_path((sp-2)->u.string, current_object, "write_file", 1), buf, strlen(buf), 0, cb); pop_3_elems(); } #endif #endif