static void sigio_handler (int sig) { int saved_errno = errno; static timeval ztv = { 0, 0 }; sigio_received = 1; flock (shmfd, LOCK_UN); while (fdwait (rwfd, selread, &ztv) > 0) { /* Note that rwfd is a unix domain socket, not a pipe. Since unix * domain sockets are not specified by POSIX, writes of less than * PIPE_BUF bytes could conceivably not be atomic on some systems, * and a true select for writing might not even guarantee PIPE_BUF * bytes of buffer space. * * We thereforedo a "fullread" here. We know the client is trying * to write sizeof (msg) bytes to us, so we don't need to worry * about blocking. */ aiomsg_t msg; ssize_t n = fullread (rwfd, &msg, sizeof (msg)); if (n != sizeof (msg)) { if (n < 0) fatal ("read: %m\n"); exit (0); } srv->getmsg (msg); } errno = saved_errno; }
static bool read_stdin(void *buffer, size_t nbytes) { ssize_t nread = fullread(fileno(stdin), buffer, nbytes); if(nread != (ssize_t)nbytes) { logmsg("exiting..."); return FALSE; } return TRUE; }
// Copy ordinary file static FXbool copyfile (const FXString & oldfile, const FXString & newfile, thread_elem * te) { unsigned char buffer[4096]; struct stat status; long nread, nwritten; int src, dst; FXbool ok = FALSE; if ((src = open (oldfile.text (), O_RDONLY)) >= 0) { if (::stat (oldfile.text (), &status) == 0) { te->act_file_name = oldfile.text (); te->act_file_size = 1; te->file_size = status.st_size; if ((dst = open (newfile.text (), O_WRONLY | O_CREAT | O_TRUNC, status.st_mode)) >= 0) { while (1) { nread = fullread (src, buffer, sizeof (buffer)); if (nread < 0) goto err; if (nread == 0) break; if (te->cancel == true) { fxmessage ("CANCEL CANCEL CANCEL CANCEL !!!\n\n\n\n\n"); close (dst); close (src); return FALSE; } te->act_file_size += nread; te->act_total_size += nread; nwritten = fullwrite (dst, buffer, nread); if (nwritten < 0) goto err; } ok = TRUE; err:close (dst); } } close (src); } return ok; }
void streamtools_object::test<25>() { std::string str = "First Line.\nSecond Line\n"; std::istringstream is(str); char buf[255] = {0}; fullread(is, buf, 255); ensure_memory_matches("fullread: read with newlines", (void*) buf, str.size()-1, (void*) str.c_str(), str.size()-1); is.clear(); is.str(str = "First Line.\nSecond Line\n"); memset(buf, 0, 255); char expected_string[] = "First Line.\nSecond"; int len = sizeof(expected_string)-1; fullread(is, buf, len); ensure_memory_matches("fullread: read with newlines", (void*) buf, len, (void*) &expected_string, len); }
static bool read_fd (int fd, fd_set *set, aiomsg_t *msg) { bool ret = false; if (FD_ISSET (fd, set)) { size_t msz = sizeof (*msg); size_t n = fullread (fd, msg, msz); if (n == msz) { ret = true; } else if (n < 0) { warn ("error in reading from fd=%d: %m\n", fd); } else if (n == 0) { exit (0); } } return ret; }
bool LLSDBinaryParser::parseString( std::istream& istr, std::string& value) const { // *FIX: This is memory inefficient. U32 value_nbo = 0; read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ S32 size = (S32)ntohl(value_nbo); if(mCheckLimits && (size > mMaxBytesLeft)) return false; std::vector<char> buf; if(size) { buf.resize(size); account(fullread(istr, &buf[0], size)); value.assign(buf.begin(), buf.end()); } return true; }
enum kcgi_err kworker_auth_parent(int fd, struct khttpauth *auth) { enum kcgi_err ke; if (fullread(fd, &auth->type, sizeof(enum kauth), 0, &ke) < 0) return(ke); switch (auth->type) { case (KAUTH_DIGEST): if (fullread(fd, &auth->authorised, sizeof(int), 0, &ke) < 0) return(ke); if ( ! auth->authorised) break; if (fullread(fd, &auth->d.digest.alg, sizeof(enum khttpalg), 0, &ke) < 0) return(ke); if (fullread(fd, &auth->d.digest.qop, sizeof(enum khttpqop), 0, &ke) < 0) return(ke); if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.user))) return(ke); if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.uri))) return(ke); if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.realm))) return(ke); if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.nonce))) return(ke); if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.cnonce))) return(ke); if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.response))) return(ke); if (fullread(fd, &auth->d.digest.count, sizeof(size_t), 0, &ke) < 0) return(ke); if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.opaque))) return(ke); break; case (KAUTH_BASIC): if (fullread(fd, &auth->authorised, sizeof(int), 0, &ke) < 0) return(ke); if ( ! auth->authorised) break; if (KCGI_OK != (ke = fullreadword(fd, &auth->d.basic.response))) return(ke); break; default: break; } return(KCGI_OK); }
int deserialize_string_raw( std::istream& istr, std::string& value, S32 max_bytes) { int count = 0; const S32 BUF_LEN = 20; char buf[BUF_LEN]; /* Flawfinder: ignore */ istr.get(buf, BUF_LEN - 1, ')'); count += istr.gcount(); char c = istr.get(); c = istr.get(); count += 2; if(((c == '"') || (c == '\'')) && (buf[0] == '(')) { // We probably have a valid raw string. determine // the size, and read it. // *FIX: This is memory inefficient. S32 len = strtol(buf + 1, NULL, 0); if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE; std::vector<char> buf; if(len) { buf.resize(len); count += fullread(istr, (char *)&buf[0], len); value.assign(buf.begin(), buf.end()); } c = istr.get(); ++count; if(!((c == '"') || (c == '\''))) { return LLSDParser::PARSE_FAILURE; } } else { return LLSDParser::PARSE_FAILURE; } return count; }
// virtual S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const { /** * Undefined: '!'<br> * Boolean: 't' for true 'f' for false<br> * Integer: 'i' + 4 bytes network byte order<br> * Real: 'r' + 8 bytes IEEE double<br> * UUID: 'u' + 16 byte unsigned integer<br> * String: 's' + 4 byte integer size + string<br> * strings also secretly support the notation format * Date: 'd' + 8 byte IEEE double for seconds since epoch<br> * URI: 'l' + 4 byte integer size + string uri<br> * Binary: 'b' + 4 byte integer size + binary data<br> * Array: '[' + 4 byte integer size + all values + ']'<br> * Map: '{' + 4 byte integer size every(key + value) + '}'<br> * map keys are serialized as s + 4 byte integer size + string or in the * notation format. */ char c; c = get(istr); if(!istr.good()) { return 0; } S32 parse_count = 1; switch(c) { case '{': { S32 child_count = parseMap(istr, data); if((child_count == PARSE_FAILURE) || data.isUndefined()) { parse_count = PARSE_FAILURE; } else { parse_count += child_count; } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary map." << llendl; parse_count = PARSE_FAILURE; } break; } case '[': { S32 child_count = parseArray(istr, data); if((child_count == PARSE_FAILURE) || data.isUndefined()) { parse_count = PARSE_FAILURE; } else { parse_count += child_count; } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary array." << llendl; parse_count = PARSE_FAILURE; } break; } case '!': data.clear(); break; case '0': data = false; break; case '1': data = true; break; case 'i': { U32 value_nbo = 0; read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ data = (S32)ntohl(value_nbo); if(istr.fail()) { llinfos << "STREAM FAILURE reading binary integer." << llendl; } break; } case 'r': { F64 real_nbo = 0.0; read(istr, (char*)&real_nbo, sizeof(F64)); /*Flawfinder: ignore*/ data = ll_ntohd(real_nbo); if(istr.fail()) { llinfos << "STREAM FAILURE reading binary real." << llendl; } break; } case 'u': { LLUUID id; read(istr, (char*)(&id.mData), UUID_BYTES); /*Flawfinder: ignore*/ data = id; if(istr.fail()) { llinfos << "STREAM FAILURE reading binary uuid." << llendl; } break; } case '\'': case '"': { std::string value; int cnt = deserialize_string_delim(istr, value, c); if(PARSE_FAILURE == cnt) { parse_count = PARSE_FAILURE; } else { data = value; account(cnt); } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary (notation-style) string." << llendl; parse_count = PARSE_FAILURE; } break; } case 's': { std::string value; if(parseString(istr, value)) { data = value; } else { parse_count = PARSE_FAILURE; } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary string." << llendl; parse_count = PARSE_FAILURE; } break; } case 'l': { std::string value; if(parseString(istr, value)) { data = LLURI(value); } else { parse_count = PARSE_FAILURE; } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary link." << llendl; parse_count = PARSE_FAILURE; } break; } case 'd': { F64 real = 0.0; read(istr, (char*)&real, sizeof(F64)); /*Flawfinder: ignore*/ data = LLDate(real); if(istr.fail()) { llinfos << "STREAM FAILURE reading binary date." << llendl; parse_count = PARSE_FAILURE; } break; } case 'b': { // We probably have a valid raw binary stream. determine // the size, and read it. U32 size_nbo = 0; read(istr, (char*)&size_nbo, sizeof(U32)); /*Flawfinder: ignore*/ S32 size = (S32)ntohl(size_nbo); if(mCheckLimits && (size > mMaxBytesLeft)) { parse_count = PARSE_FAILURE; } else { std::vector<U8> value; if(size > 0) { value.resize(size); account(fullread(istr, (char*)&value[0], size)); } data = value; } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary." << llendl; parse_count = PARSE_FAILURE; } break; } default: parse_count = PARSE_FAILURE; llinfos << "Unrecognized character while parsing: int(" << (int)c << ")" << llendl; break; } if(PARSE_FAILURE == parse_count) { data.clear(); } return parse_count; }
bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const { // binary: b##"ff3120ab1" // or: b(len)"..." // I want to manually control those values here to make sure the // parser doesn't break when someone changes a constant somewhere // else. const U32 BINARY_BUFFER_SIZE = 256; const U32 STREAM_GET_COUNT = 255; // need to read the base out. char buf[BINARY_BUFFER_SIZE]; /* Flawfinder: ignore */ get(istr, buf, STREAM_GET_COUNT, '"'); char c = get(istr); if(c != '"') return false; if(0 == strncmp("b(", buf, 2)) { // We probably have a valid raw binary stream. determine // the size, and read it. S32 len = strtol(buf + 2, NULL, 0); if(mCheckLimits && (len > mMaxBytesLeft)) return false; std::vector<U8> value; if(len) { value.resize(len); account(fullread(istr, (char *)&value[0], len)); } c = get(istr); // strip off the trailing double-quote data = value; } else if(0 == strncmp("b64", buf, 3)) { // *FIX: A bit inefficient, but works for now. To make the // format better, I would need to add a hint into the // serialization format that indicated how long it was. std::stringstream coded_stream; get(istr, *(coded_stream.rdbuf()), '\"'); c = get(istr); std::string encoded(coded_stream.str()); S32 len = apr_base64_decode_len(encoded.c_str()); std::vector<U8> value; if(len) { value.resize(len); len = apr_base64_decode_binary(&value[0], encoded.c_str()); value.resize(len); } data = value; } else if(0 == strncmp("b16", buf, 3)) { // yay, base 16. We pop the next character which is either a // double quote or base 16 data. If it's a double quote, we're // done parsing. If it's not, put the data back, and read the // stream until the next double quote. char* read; /*Flawfinder: ignore*/ U8 byte; U8 byte_buffer[BINARY_BUFFER_SIZE]; U8* write; std::vector<U8> value; c = get(istr); while(c != '"') { putback(istr, c); read = buf; write = byte_buffer; get(istr, buf, STREAM_GET_COUNT, '"'); c = get(istr); while(*read != '\0') /*Flawfinder: ignore*/ { byte = hex_as_nybble(*read++); byte = byte << 4; byte |= hex_as_nybble(*read++); *write++ = byte; } // copy the data out of the byte buffer value.insert(value.end(), byte_buffer, write); } data = value; } else { return false; } return true; }
/* * Read a single kpair from the child. * This returns 0 if there are no more pairs to read and -1 if any * errors occur (the parent should also exit with server failure). * Otherwise, it returns 1 and the pair is zeroed and filled in. */ static int input(enum input *type, struct kpair *kp, int fd, enum kcgi_err *ke, int eofok) { size_t sz; int rc; ptrdiff_t diff; memset(kp, 0, sizeof(struct kpair)); /* This will return EOF for the last one. */ rc = fullread(fd, type, sizeof(enum input), 1, ke); if (0 == rc) { if (eofok) return(0); XWARNX("unexpected eof from child"); *ke = KCGI_FORM; return(-1); } else if (rc < 0) return(-1); if (*type == IN__MAX) return(0); if (*type > IN__MAX) { XWARNX("unknown input type %d", *type); *ke = KCGI_FORM; return(-1); } /* TODO: check additive overflow. */ if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0) return(-1); if (NULL == (kp->key = XCALLOC(sz + 1, 1))) { *ke = KCGI_ENOMEM; return(-1); } if (fullread(fd, kp->key, sz, 0, ke) < 0) return(-1); /* TODO: check additive overflow. */ if (fullread(fd, &kp->valsz, sizeof(size_t), 0, ke) < 0) return(-1); if (NULL == (kp->val = XCALLOC(kp->valsz + 1, 1))) { *ke = KCGI_ENOMEM; return(-1); } if (fullread(fd, kp->val, kp->valsz, 0, ke) < 0) return(-1); if (fullread(fd, &kp->state, sizeof(enum kpairstate), 0, ke) < 0) return(-1); if (fullread(fd, &kp->type, sizeof(enum kpairtype), 0, ke) < 0) return(-1); if (fullread(fd, &kp->keypos, sizeof(size_t), 0, ke) < 0) return(-1); if (KPAIR_VALID == kp->state) switch (kp->type) { case (KPAIR_DOUBLE): if (fullread(fd, &kp->parsed.d, sizeof(double), 0, ke) < 0) return(-1); break; case (KPAIR_INTEGER): if (fullread(fd, &kp->parsed.i, sizeof(int64_t), 0, ke) < 0) return(-1); break; case (KPAIR_STRING): if (fullread(fd, &diff, sizeof(ptrdiff_t), 0, ke) < 0) return(-1); if (diff > (ssize_t)kp->valsz) { *ke = KCGI_FORM; return(-1); } kp->parsed.s = kp->val + diff; break; default: break; } /* TODO: check additive overflow. */ if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0) return(-1); if (NULL == (kp->file = XCALLOC(sz + 1, 1))) { *ke = KCGI_ENOMEM; return(-1); } if (fullread(fd, kp->file, sz, 0, ke) < 0) return(-1); /* TODO: check additive overflow. */ if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0) return(-1); if (NULL == (kp->ctype = XCALLOC(sz + 1, 1))) { *ke = KCGI_ENOMEM; return(-1); } if (fullread(fd, kp->ctype, sz, 0, ke) < 0) return(-1); if (fullread(fd, &kp->ctypepos, sizeof(size_t), 0, ke) < 0) return(-1); /* TODO: check additive overflow. */ if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0) return(-1); if (NULL == (kp->xcode = XCALLOC(sz + 1, 1))) { *ke = KCGI_ENOMEM; return(-1); } if (fullread(fd, kp->xcode, sz, 0, ke) < 0) return(-1); return(1); }
/* * This is the parent kcgi process. * It spins on input from the child until all fields have been received. * These fields are sent from the child's output() function. * Each input field consists of the data and its validation state. * We build up the kpair arrays here with this data, then assign the * kpairs into named buckets. */ enum kcgi_err kworker_parent(int fd, struct kreq *r, int eofok) { struct kpair kp; struct kpair *kpp; enum krequ requ; enum input type; int rc; enum kcgi_err ke; size_t i, dgsz; /* Pointers freed at "out" label. */ memset(&kp, 0, sizeof(struct kpair)); /* * First read all of our parsed parameters. * Each parsed parameter is handled a little differently. * This list will end with META__MAX. */ if (fullread(fd, &r->reqsz, sizeof(size_t), 0, &ke) < 0) { XWARNX("failed to read request header size"); goto out; } r->reqs = XCALLOC(r->reqsz, sizeof(struct khead)); if (NULL == r->reqs) { ke = KCGI_ENOMEM; goto out; } for (i = 0; i < r->reqsz; i++) { if (fullread(fd, &requ, sizeof(enum krequ), 0, &ke) < 0) { XWARNX("failed to read request identifier"); goto out; } if (KCGI_OK != (ke = fullreadword(fd, &r->reqs[i].key))) { XWARNX("failed to read request key"); goto out; } if (KCGI_OK != (ke = fullreadword(fd, &r->reqs[i].val))) { XWARNX("failed to read request value"); goto out; } if (requ != KREQU__MAX) r->reqmap[requ] = &r->reqs[i]; } if (fullread(fd, &r->method, sizeof(enum kmethod), 0, &ke) < 0) { XWARNX("failed to read request method"); goto out; } else if (fullread(fd, &r->auth, sizeof(enum kauth), 0, &ke) < 0) { XWARNX("failed to read authorisation type"); goto out; } else if (KCGI_OK != (ke = kworker_auth_parent(fd, &r->rawauth))) { XWARNX("failed to read raw authorisation"); goto out; } else if (fullread(fd, &r->scheme, sizeof(enum kscheme), 0, &ke) < 0) { XWARNX("failed to read scheme"); goto out; } else if (KCGI_OK != (ke = fullreadword(fd, &r->remote))) { XWARNX("failed to read remote"); goto out; } else if (KCGI_OK != (ke = fullreadword(fd, &r->fullpath))) { XWARNX("failed to read fullpath"); goto out; } else if (KCGI_OK != (ke = fullreadword(fd, &r->suffix))) { XWARNX("failed to read suffix"); goto out; } else if (KCGI_OK != (ke = fullreadword(fd, &r->pagename))) { XWARNX("failed to read page part"); goto out; } else if (KCGI_OK != (ke = fullreadword(fd, &r->path))) { XWARNX("failed to read path part"); goto out; } else if (KCGI_OK != (ke = fullreadword(fd, &r->pname))) { XWARNX("failed to read script name"); goto out; } else if (KCGI_OK != (ke = fullreadword(fd, &r->host))) { XWARNX("failed to read host name"); goto out; } else if (fullread(fd, &r->port, sizeof(uint16_t), 0, &ke) < 0) { XWARNX("failed to read port"); goto out; } else if (fullread(fd, &dgsz, sizeof(size_t), 0, &ke) < 0) { XWARNX("failed to read digest length"); goto out; } else if (MD5_DIGEST_LENGTH == dgsz) { /* This is a binary value. */ if (NULL == (r->rawauth.digest = XMALLOC(dgsz))) goto out; if (fullread(fd, r->rawauth.digest, dgsz, 0, &ke) < 0) { XWARNX("failed to read digest"); goto out; } } while ((rc = input(&type, &kp, fd, &ke, eofok)) > 0) { assert(type < IN__MAX); /* * We have a parsed field from the child process. * Begin by expanding the number of parsed fields * depending on whether we have a cookie or form input. * Then copy the new data. */ kpp = IN_COOKIE == type ? kpair_expand(&r->cookies, &r->cookiesz) : kpair_expand(&r->fields, &r->fieldsz); if (NULL == kpp) { rc = -1; ke = KCGI_ENOMEM; break; } *kpp = kp; } if (rc < 0) goto out; /* * Now that the field and cookie arrays are fixed and not going * to be reallocated any more, we run through both arrays and * assign the named fields into buckets. */ for (i = 0; i < r->fieldsz; i++) { kpp = &r->fields[i]; if (kpp->keypos == r->keysz) continue; if (KPAIR_INVALID != kpp->state) { kpp->next = r->fieldmap[kpp->keypos]; r->fieldmap[kpp->keypos] = kpp; } else { kpp->next = r->fieldnmap[kpp->keypos]; r->fieldnmap[kpp->keypos] = kpp; } } for (i = 0; i < r->cookiesz; i++) { kpp = &r->cookies[i]; if (kpp->keypos == r->keysz) continue; if (KPAIR_INVALID != kpp->state) { kpp->next = r->cookiemap[kpp->keypos]; r->cookiemap[kpp->keypos] = kpp; } else { kpp->next = r->cookienmap[kpp->keypos]; r->cookienmap[kpp->keypos] = kpp; } } ke = KCGI_OK; /* * Usually, "kp" would be zeroed after its memory is copied into * one of the form-input arrays. * However, in the case of error, these may still have * allocations, so free them now. */ out: free(kp.key); free(kp.val); free(kp.file); free(kp.ctype); free(kp.xcode); return(ke); }
static void* daemon_main(void *param) { struct daemon_thread *dt; struct dazuko_request request; char reqdesc[64]; long long ptr_num; struct xp_daemon_id xp_id; dt = (struct daemon_thread *)param; while (1) { if (fullread(dt->fd, &request, sizeof(request)) != 0) break; request.buffer = NULL; request.reply_buffer = NULL; if (request.buffer_size > 0) { request.buffer = (char *)malloc(request.buffer_size); if (request.buffer == NULL) break; if (fullread(dt->fd, request.buffer, request.buffer_size) != 0) break; } if (request.reply_buffer_size > 0) { request.reply_buffer = (char *)malloc(request.reply_buffer_size); if (request.reply_buffer == NULL) break; if (fullread(dt->fd, request.reply_buffer, request.reply_buffer_size) != 0) break; } /* we now have the full request from the daemon */ xp_id.id = dt->fd; memset(reqdesc, 0, sizeof(reqdesc)); snprintf(reqdesc, sizeof(reqdesc), "%p", &request); ptr_num = strtoll(reqdesc, NULL, 16); snprintf(reqdesc, sizeof(reqdesc), "\nRA=%lld", (long long)ptr_num); if (dazuko_handle_user_request(reqdesc, &xp_id) != 0) break; /* we now have the request response */ if (fullwrite(dt->fd, &request, sizeof(request)) != 0) break; if (request.buffer_size > 0) { if (fullwrite(dt->fd, request.buffer, request.buffer_size) != 0) break; } if (request.reply_buffer_size > 0) { if (fullwrite(dt->fd, request.reply_buffer, request.reply_buffer_size) != 0) break; } if (request.buffer != NULL) free(request.buffer); if (request.reply_buffer != NULL) free(request.reply_buffer); } close(dt->fd); return NULL; }