/* Used by bufread and bufgetdata to prepare the buffer and retrieve the * actual amount of data available for reading. This function explicitly * does not check the validity of the input handle. It does do range checks * on size and returns a valid (and explicit) amount of data for reading */ static struct memory_handle *prep_bufdata(int handle_id, size_t *size, bool guardbuf_limit) { struct memory_handle *h = find_handle(handle_id); if (!h) return NULL; size_t avail = ringbuf_sub(h->widx, h->ridx); if (avail == 0 && h->filerem == 0) { /* File is finished reading */ *size = 0; return h; } if (*size == 0 || *size > avail + h->filerem) *size = avail + h->filerem; if (guardbuf_limit && h->type == TYPE_PACKET_AUDIO && *size > GUARD_BUFSIZE) { logf("data request > guardbuf"); /* If more than the size of the guardbuf is requested and this is a * bufgetdata, limit to guard_bufsize over the end of the buffer */ *size = MIN(*size, buffer_len - h->ridx + GUARD_BUFSIZE); /* this ensures *size <= buffer_len - h->ridx + GUARD_BUFSIZE */ } if (h->filerem > 0 && avail < *size) { /* Data isn't ready. Request buffering */ buf_request_buffer_handle(handle_id); /* Wait for the data to be ready */ do { sleep(1); /* it is not safe for a non-buffering thread to sleep while * holding a handle */ h = find_handle(handle_id); if (!h) return NULL; avail = ringbuf_sub(h->widx, h->ridx); } while (h->filerem > 0 && avail < *size); } *size = MIN(*size,avail); return h; }
ssize_t bufgettail(int handle_id, size_t size, void **data) { size_t tidx; const struct memory_handle *h; h = find_handle(handle_id); if (!h) return ERR_HANDLE_NOT_FOUND; if (h->filerem) return ERR_HANDLE_NOT_DONE; /* We don't support tail requests of > guardbuf_size, for simplicity */ if (size > GUARD_BUFSIZE) return ERR_INVALID_VALUE; tidx = ringbuf_sub(h->widx, size); if (tidx + size > buffer_len) { size_t copy_n = tidx + size - buffer_len; memcpy(guard_buffer, (const unsigned char *)buffer, copy_n); } *data = &buffer[tidx]; return size; }
static awk_value_t * do_pg_putcopyend(int nargs, awk_value_t *result) { PGconn *conn; awk_value_t emsg; int res; if (do_lint && (nargs > 2)) lintwarn(ext_id, _("pg_putcopyend: called with too many arguments")); if (!(conn = find_handle(conns, 0))) { set_ERRNO(_("pg_putcopyend called with unknown connection handle")); RET_NUM(-1); } if (nargs > 1) { if (!get_argument(1, AWK_STRING, &emsg)) { set_ERRNO(_("pg_putcopyend optional 2nd argument should be a string")); RET_NUM(-1); } } else emsg.str_value.str = NULL; res = PQputCopyEnd(conn, emsg.str_value.str); if (res < 0) /* connection is probably bad */ set_ERRNO(PQerrorMessage(conn)); RET_NUM(res); }
uLong oz_knl_handle_release (OZ_Handle handle, OZ_Procmode procmode) { Handleent *he; Long refc; OZ_Handletbl *handletbl; uLong sts; void *object; handletbl = OZ_SYS_PDATA_FROM_KNL (OZ_PROCMODE_KNL) -> handletbl; OZ_KNL_CHKOBJTYPE (handletbl, OZ_OBJTYPE_HANDLETBL); object = NULL; // assume entry is in use by someone LOCKTABLE_EX (handletbl); // get exclusive access to table so we can call free_handle sts = find_handle (handletbl, handle, procmode, &he); // find entry to be released if (sts == OZ_SUCCESS) { refc = atomic_inc_long (&(he -> refcount), -1); // if found, clear the assigned bit (refcount<00>) if (refc == 0) { // check for all references gone object = free_handle (handletbl, handle & handletbl -> curmask); // if so, free the entry off and get object pointer } } UNLOCKTABLE_EX (handletbl); // unlock table if (object != NULL) { OBJINCREFC (OZ_KNL_GETOBJTYPE (object), object, -1); // if we actually freed the entry, release object pointer } return (sts); }
void nb_qfileinfo(int fnum) { int i; i = find_handle(fnum); cli_qfileinfo_basic(c, ftable[i].fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL); }
static awk_value_t * do_pg_fname(int nargs, awk_value_t *result) { PGresult *res; awk_value_t colarg; int col; if (do_lint && (nargs > 2)) lintwarn(ext_id, _("pg_fname: called with too many arguments")); if (!(res = find_handle(results, 0))) { set_ERRNO(_("pg_fname called with unknown result handle")); RET_NULSTR; } if (!get_argument(1, AWK_NUMBER, &colarg)) { set_ERRNO(_("pg_fname: 2nd argument must be a number")); RET_NULSTR; } col = colarg.num_value; if ((col < 0) || (col >= PQnfields(res))) { set_ERRNO(_("pg_fname: 2nd argument col_number is out of range")); RET_NULSTR; } { char *fname = PQfname(res, col); return make_string_malloc(fname, strlen(fname), result); } }
void do_note(COMMAND_ARGS) { User *u; Note *n; Strp *sp,**np; char header[MSGLEN]; /* * no-args is handled in on_msg() */ if (!(u = find_handle(rest))) { to_user(from,TEXT_UNKNOWNUSER,rest); return; } to_user(from,"Enter your note for %s, end with \".\" on a line by itself", u->name); set_mallocdoer(do_note); n = Calloc(sizeof(Note) + StrlenX(from,to,u->name,NULL)); n->start = now; n->next = notelist; notelist = n; n->to = stringcat(n->from,from) + 1; n->user = stringcat(n->to,to) + 1; stringcpy(n->user,rest); /* * add a note header */ sprintf(header,"\001%s %s",from,time2str(now)); append_strp(&u->note,header); }
ssize_t buf_handle_offset(int handle_id) { const struct memory_handle *h = find_handle(handle_id); if (!h) return ERR_HANDLE_NOT_FOUND; return h->offset; }
static awk_value_t * do_pg_putcopydata(int nargs, awk_value_t *result) { PGconn *conn; awk_value_t buffer; int res; if (do_lint && (nargs > 2)) lintwarn(ext_id, _("pg_putcopydata: called with too many arguments")); if (!(conn = find_handle(conns, 0))) { set_ERRNO(_("pg_putcopydata called with unknown connection handle")); RET_NUM(-1); } if (!get_argument(1, AWK_STRING, &buffer)) { set_ERRNO(_("pg_putcopydata 2nd argument should be a string")); RET_NUM(-1); } res = PQputCopyData(conn, buffer.str_value.str, buffer.str_value.len); if (res < 0) /* connection is probably bad */ set_ERRNO(PQerrorMessage(conn)); RET_NUM(res); }
void nb_flush(int fnum) { int i; i = find_handle(fnum); cli_flush(NULL, c, i); }
static awk_value_t * do_pg_sendquery(int nargs, awk_value_t *result) { PGconn *conn; awk_value_t command; int res; if (do_lint && (nargs > 2)) lintwarn(ext_id, _("pg_sendquery: called with too many arguments")); if (!(conn = find_handle(conns, 0))) { set_ERRNO(_("pg_sendquery called with unknown connection handle")); RET_NUM(0); } if (!get_argument(1, AWK_STRING, &command)) { set_ERRNO(_("pg_sendquery 2nd argument should be a string")); RET_NUM(0); } res = PQsendQuery(conn, command.str_value.str); if (!res) /* connection is probably bad */ set_ERRNO(PQerrorMessage(conn)); RET_NUM(res); }
static awk_value_t * do_pg_sendprepare(int nargs, awk_value_t *result) { PGconn *conn; awk_value_t command; char *stmtName; int res; if (do_lint && (nargs > 2)) lintwarn(ext_id, _("pg_sendprepare: called with too many arguments")); if (!(conn = find_handle(conns, 0))) { set_ERRNO(_("pg_sendprepare called with unknown connection handle")); RET_NULSTR; } if (!get_argument(1, AWK_STRING, &command)) { set_ERRNO(_("pg_sendprepare 2nd argument should be a string")); RET_NULSTR; } res = PQsendPrepare(conn, (stmtName = prep_name()), command.str_value.str, 0, NULL); if (!res) { /* connection is probably bad */ set_ERRNO(PQerrorMessage(conn)); RET_NULSTR; } return make_string_malloc(stmtName, strlen(stmtName), result); }
uLong oz_knl_handle_takeout (OZ_Handle handle, OZ_Procmode procmode, OZ_Secaccmsk secaccmsk, OZ_Objtype objtype, void **object_r, OZ_Secaccmsk *secaccmsk_r) { Handleent *he; Long tablelock; OZ_Handletbl *handletbl; uLong sts; handletbl = OZ_SYS_PDATA_FROM_KNL (OZ_PROCMODE_KNL) -> handletbl; OZ_KNL_CHKOBJTYPE (handletbl, OZ_OBJTYPE_HANDLETBL); LOCKTABLE_SH (handletbl); // lock for shared access sts = find_handle (handletbl, handle, procmode, &he); /* find the handle in question */ if ((sts == OZ_SUCCESS) /* make sure object type matches */ && (objtype != OZ_OBJTYPE_UNKNOWN) && (he -> objtype != objtype)) sts = OZ_BADHANDOBJTYPE; if ((sts == OZ_SUCCESS) && (secaccmsk & ~(he -> secaccmsk))) { /* ok, check its security attributes */ sts = OZ_SECACCDENIED; } if ((sts == OZ_SUCCESS) && (object_r != NULL)) { *object_r = he -> object; /* ok, return object pointer */ atomic_inc_long (&(he -> refcount), 2); /* inc entry ref count, leave bit <00> alone */ if (secaccmsk_r != NULL) *secaccmsk_r = he -> secaccmsk; /* maybe return security access mask */ } UNLOCKTABLE_SH (handletbl); // release shared lock return (sts); }
/* Seek to a nonbuffered part of a handle by rebuffering the data. */ static void rebuffer_handle(int handle_id, size_t newpos) { struct memory_handle *h = find_handle(handle_id); if (!h) return; /* When seeking foward off of the buffer, if it is a short seek don't rebuffer the whole track, just read enough to satisfy */ if (newpos > h->offset && newpos - h->offset < BUFFERING_DEFAULT_FILECHUNK) { LOGFQUEUE("buffering >| Q_BUFFER_HANDLE %d", handle_id); queue_send(&buffering_queue, Q_BUFFER_HANDLE, handle_id); h->ridx = h->data + newpos; return; } h->offset = newpos; /* Reset the handle to its new offset */ LOGFQUEUE("buffering >| Q_RESET_HANDLE %d", handle_id); queue_send(&buffering_queue, Q_RESET_HANDLE, handle_id); uintptr_t next = ringbuf_offset(h->next); if (ringbuf_sub(next, h->data) < h->filesize - newpos) { /* There isn't enough space to rebuffer all of the track from its new offset, so we ask the user to free some */ DEBUGF("%s(): space is needed\n", __func__); send_event(BUFFER_EVENT_REBUFFER, &handle_id); } /* Now we ask for a rebuffer */ LOGFQUEUE("buffering >| Q_BUFFER_HANDLE %d", handle_id); queue_send(&buffering_queue, Q_BUFFER_HANDLE, handle_id); }
static void update_data_counters(void) { struct memory_handle *m = find_handle(base_handle_id); bool is_useful = m==NULL; size_t buffered = 0; size_t wasted = 0; size_t remaining = 0; size_t useful = 0; mutex_lock(&llist_mutex); m = first_handle; while (m) { buffered += m->available; wasted += ringbuf_sub(m->ridx, m->data); remaining += m->filerem; if (m->id == base_handle_id) is_useful = true; if (is_useful) useful += ringbuf_sub(m->widx, m->ridx); m = m->next; } mutex_unlock(&llist_mutex); data_counters.buffered = buffered; data_counters.wasted = wasted; data_counters.remaining = remaining; data_counters.useful = useful; }
static awk_value_t * do_pg_fieldsbyname(int nargs, awk_value_t *result) { PGresult *res; awk_value_t array; int nf; int col; if (do_lint && (nargs > 2)) lintwarn(ext_id, _("pg_fieldsbyname: called with too many arguments")); if (!(res = find_handle(results, 0))) { set_ERRNO(_("pg_fieldsbyname called with unknown result handle")); RET_NUM(-1); } if (!get_argument(1, AWK_ARRAY, &array)) { set_ERRNO(_("pg_fieldsbyname 2nd argument must be an array")); RET_NUM(-1); } clear_array(array.array_cookie); nf = PQnfields(res); for (col = 0; col < nf; col++) { char *fname; awk_value_t idx, val; fname = PQfname(res, col); set_array_element(array.array_cookie, make_string_malloc(fname, strlen(fname), &idx), make_number(col, &val)); } RET_NUM(nf); }
static awk_value_t * do_pg_exec(int nargs, awk_value_t *result) { PGconn *conn; awk_value_t command; PGresult *res; if (do_lint && (nargs > 2)) lintwarn(ext_id, _("pg_exec: called with too many arguments")); if (!(conn = find_handle(conns, 0))) { set_ERRNO(_("pg_exec called with unknown connection handle")); RET_NULSTR; } if (!get_argument(1, AWK_STRING, &command)) { set_ERRNO(_("pg_exec 2nd argument should be a string")); RET_NULSTR; } res = PQexec(conn, command.str_value.str); if (!res) { /* I presume the connection is probably bad, since no result returned */ set_error(conn, PQresultStatus(NULL), result); set_ERRNO(PQerrorMessage(conn)); return result; } return process_result(conn, res, result); }
/* Get a handle offset from a pointer */ ssize_t buf_get_offset(int handle_id, void *ptr) { const struct memory_handle *h = find_handle(handle_id); if (!h) return ERR_HANDLE_NOT_FOUND; return (size_t)ptr - (size_t)&buffer[h->ridx]; }
LONG WINAPI dllRegCloseKey(HKEY key) { if(key==HKEY_LOCAL_MACHINE) return 0; if(key==HKEY_CURRENT_USER) return 0; remove_handle(find_handle((int)key)); return 1; }
/* Advance the reading index in a handle (relatively to its current position). Return 0 for success and < 0 for failure */ int bufadvance(int handle_id, off_t offset) { const struct memory_handle *h = find_handle(handle_id); if (!h) return ERR_HANDLE_NOT_FOUND; size_t newpos = h->offset + ringbuf_sub(h->ridx, h->data) + offset; return bufseek(handle_id, newpos); }
void nb_close(int handle) { int i; i = find_handle(handle); if (!NT_STATUS_IS_OK(cli_close(c, ftable[i].fd))) { printf("(%d) close failed on handle %d\n", line_count, handle); exit(1); } ftable[i].handle = 0; }
static awk_value_t * do_pg_getrowbyname(int nargs, awk_value_t *result) { PGresult *res; awk_value_t array; awk_value_t rowarg; int row; int nf; int found; int col; if (do_lint && (nargs > 3)) lintwarn(ext_id, _("pg_getrowbyname: called with too many arguments")); if (!(res = find_handle(results, 0))) { set_ERRNO(_("pg_getrowbyname called with unknown result handle")); RET_NUM(-1); } if (!get_argument(1, AWK_NUMBER, &rowarg)) { set_ERRNO(_("pg_getrowbyname: 2nd argument must be a row number")); RET_NUM(-1); } row = rowarg.num_value; if ((row < 0) || (row >= PQntuples(res))) { set_ERRNO(_("pg_getrowbyname: 2nd argument row_number is out of range")); RET_NUM(-1); } if (!get_argument(2, AWK_ARRAY, &array)) { set_ERRNO(_("pg_getrowbyname 3rd argument must be an array")); RET_NUM(-1); } clear_array(array.array_cookie); found = 0; nf = PQnfields(res); for (col = 0; col < nf; col++) { if (!PQgetisnull(res, row, col)) { char *fname; char *val; awk_value_t idx, value; fname = PQfname(res, col); val = PQgetvalue(res, row, col); set_array_element(array.array_cookie, make_string_malloc(fname, strlen(fname), &idx), make_string_malloc(val, strlen(val), &value)); found++; } } RET_NUM(found); }
static int get_data_handle(char *filename,void *dec) { int i; i = find_handle(filename,dec); if (i == -1) { i = end_ptr++; def_handle(i,filename,dec,SR_DIALOGS); } return i; }
void nb_readx(int handle, int offset, int size, int ret_size) { int i, ret; i = find_handle(handle); if ((ret=cli_read(c, ftable[i].fd, buf, offset, size)) != ret_size) { printf("(%d) ERROR: read failed on handle %d ofs=%d size=%d res=%d fd %d errno %d (%s)\n", line_count, handle, offset, size, ret, ftable[i].fd, errno, strerror(errno)); exit(1); } children[nbio_id].bytes_in += ret_size; }
void nb_writex(int handle, int offset, int size, int ret_size) { int i; if (buf[0] == 0) memset(buf, 1, sizeof(buf)); i = find_handle(handle); if (cli_write(c, ftable[i].fd, 0, buf, offset, size) != ret_size) { printf("(%d) ERROR: write failed on handle %d, fd %d \ errno %d (%s)\n", line_count, handle, ftable[i].fd, errno, strerror(errno)); exit(1); }
static awk_value_t * do_pg_getcopydata(int nargs, awk_value_t *result) { PGconn *conn; char *buffer; int rc; if (do_lint && (nargs > 1)) lintwarn(ext_id, _("pg_getcopydata: called with too many arguments")); if (!(conn = find_handle(conns, 0))) { set_ERRNO(_("pg_getcopydata called with unknown connection handle")); RET_NULSTR; } buffer = NULL; switch (rc = PQgetCopyData(conn, &buffer, FALSE)) { /* case 0 can only happen if async is TRUE */ case -1: /* copy done */ make_null_string(result); unset_ERRNO(); break; case -2: /* error */ make_null_string(result); { const char *emsg = PQerrorMessage(conn); if (emsg) set_ERRNO(PQerrorMessage(conn)); else set_ERRNO(_("PQgetCopyData failed, but no error message is available")); } break; default: /* rc should be positive and equal # of bytes in row */ if (rc > 0) { make_string_malloc(buffer, rc, result); unset_ERRNO(); } else { /* this should not happen */ char buf[512]; make_null_string(result); snprintf(buf, sizeof(buf), _("PQgetCopyData returned invalid value %d: %s"), rc, PQerrorMessage(conn)); set_ERRNO(buf); } } if (buffer) PQfreemem(buffer); return result; }
static awk_value_t * do_pg_nfields(int nargs, awk_value_t *result) { PGresult *res; if (do_lint && (nargs > 1)) lintwarn(ext_id, _("pg_nfields: called with too many arguments")); if (!(res = find_handle(results, 0))) { set_ERRNO(_("pg_nfields called with unknown result handle")); RET_NUM(-1); } RET_NUM(PQnfields(res)); }
static bool close_handle(int handle_id) { struct memory_handle *h = find_handle(handle_id); /* If the handle is not found, it is closed */ if (!h) return true; if (h->fd >= 0) { close(h->fd); h->fd = -1; } /* rm_handle returns true unless the handle somehow persists after exit */ return rm_handle(h); }
uLong oz_knl_handle_setthread (OZ_Handle handle, OZ_Procmode procmode, OZ_Thread *thread) { Handleent *he; OZ_Handletbl *handletbl; uLong sts; void *object; handletbl = OZ_SYS_PDATA_FROM_KNL (OZ_PROCMODE_KNL) -> handletbl; OZ_KNL_CHKOBJTYPE (handletbl, OZ_OBJTYPE_HANDLETBL); LOCKTABLE_SH (handletbl); sts = find_handle (handletbl, handle, procmode, &he); if (sts == OZ_SUCCESS) he -> thread = thread; UNLOCKTABLE_SH (handletbl); return (sts); }
uLong oz_knl_handle_setsecaccmsk (OZ_Handle handle, OZ_Procmode procmode, OZ_Secaccmsk secaccmsk) { Handleent *he; OZ_Handletbl *handletbl; uLong sts; handletbl = OZ_SYS_PDATA_FROM_KNL (OZ_PROCMODE_KNL) -> handletbl; OZ_KNL_CHKOBJTYPE (handletbl, OZ_OBJTYPE_HANDLETBL); LOCKTABLE_SH (handletbl); /* lock the handle table */ sts = find_handle (handletbl, handle, procmode, &he); /* find the handle in question */ if (sts == OZ_SUCCESS) he -> secaccmsk = secaccmsk; /* if success, set mask */ UNLOCKTABLE_SH (handletbl); /* unlock the handle table */ return (sts); }