// ================================================================ int main(int argc, char** argv) { int ok = 1; if (argc == 1) { ok = ok && do_stream("-"); } else { for (int argi = 1; argi < argc; argi++) { ok = do_stream(argv[argi]); } } return ok ? 0 : 1; }
int redirectorStreamHandler1(int status, FdEventHandlerPtr event, StreamRequestPtr srequest) { RedirectRequestPtr request = (RedirectRequestPtr)srequest->data; if(status) { if(status >= 0) status = -EPIPE; do_log_error(L_ERROR, -status, "Write to redirector failed"); goto fail; } if(!streamRequestDone(srequest)) return 0; do_stream(IO_READ, redirector_read_fd, 0, redirector_buffer, REDIRECTOR_BUFFER_SIZE, redirectorStreamHandler2, request); return 1; fail: request->handler(status < 0 ? status : -EPIPE, request->url, NULL, NULL, request->data); redirectorDestroyRequest(request); redirectorKill(); return 1; }
static void bufRead(int fd, CircularBufferPtr buf, int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr), void *data) { int tail; if(buf->tail == 0) tail = CHUNK_SIZE - 1; else tail = buf->tail - 1; if(buf->head == 0) do_stream_buf(IO_READ | IO_NOTNOW, fd, 0, &buf->buf, tail, handler, data); else if(buf->tail > buf->head) do_stream(IO_READ | IO_NOTNOW, fd, buf->head, buf->buf, tail, handler, data); else do_stream_2(IO_READ | IO_NOTNOW, fd, buf->head, buf->buf, CHUNK_SIZE, buf->buf, tail, handler, data); }
static void bufWrite(int fd, CircularBufferPtr buf, int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr), void *data) { if(buf->head > buf->tail) do_stream(IO_WRITE, fd, buf->tail, buf->buf, buf->head, handler, data); else do_stream_2(IO_WRITE, fd, buf->tail, buf->buf, CHUNK_SIZE, buf->buf, buf->head, handler, data); }
int httpSpecialDoSide(HTTPRequestPtr requestor) { HTTPConnectionPtr client = requestor->connection; if(client->reqlen - client->reqbegin >= client->bodylen) { AtomPtr data; data = internAtomN(client->reqbuf + client->reqbegin, client->reqlen - client->reqbegin); client->reqbegin = 0; client->reqlen = 0; if(data == NULL) { do_log(L_ERROR, "Couldn't allocate data.\n"); httpClientError(requestor, 500, internAtom("Couldn't allocate data")); return 1; } httpSpecialDoSideFinish(data, requestor); return 1; } if(client->reqlen - client->reqbegin >= CHUNK_SIZE) { httpClientError(requestor, 500, internAtom("POST too large")); return 1; } if(client->reqbegin > 0 && client->reqlen > client->reqbegin) { memmove(client->reqbuf, client->reqbuf + client->reqbegin, client->reqlen - client->reqbegin); } client->reqlen -= client->reqbegin; client->reqbegin = 0; do_stream(IO_READ | IO_NOTNOW, client->fd, client->reqlen, client->reqbuf, CHUNK_SIZE, httpSpecialClientSideHandler, client); return 1; }
int specialRequestHandler(int status, FdEventHandlerPtr event, StreamRequestPtr srequest) { SpecialRequestPtr request = srequest->data; int rc; int killed = 0; (void)event; if (status < 0) { kill(request->pid, SIGTERM); killed = 1; request->object->flags &= ~OBJECT_INPROGRESS; abortObject(request->object, 502, internAtomError(-status, "Couldn't read from client")); goto done; } if (srequest->offset > 0) { rc = objectAddData(request->object, request->buf, request->offset, srequest->offset); if (rc < 0) { kill(request->pid, SIGTERM); killed = 1; request->object->flags &= ~OBJECT_INPROGRESS; abortObject(request->object, 503, internAtom ("Couldn't add data to connection")); goto done; } request->offset += srequest->offset; } if (status) { request->object->flags &= ~OBJECT_INPROGRESS; request->object->length = request->object->size; goto done; } if (request->object->refcount <= 1) { kill(request->pid, SIGTERM); killed = 1; request->object->flags &= ~OBJECT_INPROGRESS; abortObject(request->object, 500, internAtom("Aborted")); goto done; } notifyObject(request->object); do_stream(IO_READ | IO_NOTNOW, request->fd, 0, request->buf, CHUNK_SIZE, specialRequestHandler, request); return 1; done: close(request->fd); dispose_chunk(request->buf); releaseNotifyObject(request->object); do { rc = waitpid(request->pid, &status, 0); } while (rc < 0 && errno == EINTR); if (rc < 0) { do_log(L_ERROR, "Wait for %d: %d\n", (int)request->pid, errno); } else { int normal = (WIFEXITED(status) && WEXITSTATUS(status) == 0) || (killed && WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM); char *reason = WIFEXITED(status) ? "with status" : WIFSIGNALED(status) ? "on signal" : "with unknown status"; int value = WIFEXITED(status) ? WEXITSTATUS(status) : WIFSIGNALED(status) ? WTERMSIG(status) : status; do_log(normal ? D_CHILD : L_ERROR, "Child %d exited %s %d.\n", (int)request->pid, reason, value); } free(request); return 1; }
static void fillSpecialObject(ObjectPtr object, void (*fn) (FILE *, char *), void *closure) { int rc; int filedes[2]; pid_t pid; sigset_t ss, old_mask; if (object->flags & OBJECT_INPROGRESS) return; rc = pipe(filedes); if (rc < 0) { do_log_error(L_ERROR, errno, "Couldn't create pipe"); abortObject(object, 503, internAtomError(errno, "Couldn't create pipe")); return; } fflush(stdout); fflush(stderr); flushLog(); interestingSignals(&ss); do { rc = sigprocmask(SIG_BLOCK, &ss, &old_mask); } while (rc < 0 && errno == EINTR); if (rc < 0) { do_log_error(L_ERROR, errno, "Sigprocmask failed"); abortObject(object, 503, internAtomError(errno, "Sigprocmask failed")); close(filedes[0]); close(filedes[1]); return; } pid = fork(); if (pid < 0) { do_log_error(L_ERROR, errno, "Couldn't fork"); abortObject(object, 503, internAtomError(errno, "Couldn't fork")); close(filedes[0]); close(filedes[1]); do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while (rc < 0 && errno == EINTR); if (rc < 0) { do_log_error(L_ERROR, errno, "Couldn't restore signal mask"); s_serverExit(); } return; } if (pid > 0) { SpecialRequestPtr request; close(filedes[1]); do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while (rc < 0 && errno == EINTR); if (rc < 0) { do_log_error(L_ERROR, errno, "Couldn't restore signal mask"); s_serverExit(); return; } request = malloc(sizeof(SpecialRequestRec)); if (request == NULL) { kill(pid, SIGTERM); close(filedes[0]); abortObject(object, 503, internAtom("Couldn't allocate request\n")); notifyObject(object); } else { request->buf = get_chunk(); if (request->buf == NULL) { kill(pid, SIGTERM); close(filedes[0]); free(request); abortObject(object, 503, internAtom ("Couldn't allocate request\n")); notifyObject(object); } } object->flags |= OBJECT_INPROGRESS; retainObject(object); request->object = object; request->fd = filedes[0]; request->pid = pid; request->offset = 0; do_stream(IO_READ, filedes[0], 0, request->buf, CHUNK_SIZE, specialRequestHandler, request); } else { close(filedes[0]); uninitEvents(); do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while (rc < 0 && errno == EINTR); if (rc < 0) exit(1); if (filedes[1] != 1) dup2(filedes[1], 1); (*fn) (stdout, closure); exit(0); } }
std::ostream& recorder::stream() { return do_stream(); }
int main(int argc, char *argv[]) { char c; int ret = 1; const struct sysdef *s; const struct targetdef *t; uint8_t tn, listmsrs = 0, listknown = 0, input = 0; uint32_t addr = 0; const char *streamfn = NULL, *difffn = NULL; struct msr msrval = MSR2(-1, -1); while ((c = getopt(argc, argv, "hqvrklc:m:t:a:i:s:d:")) != -1) switch (c) { case 'h': syntax(argv); return 0; case 'q': quiet = 1; break; case 'v': ++verbose; break; case 'r': reserved = 1; break; case 'k': listknown = 1; break; case 'l': listmsrs = 1; break; case 'c': cpu = atoi(optarg); break; case 'm': for (s = allsystems; !SYSTEM_ISEOT(*s); s++) if (!strcmp(s->name, optarg)) { sys = s; break; } break; case 't': for (t = alltargets; !TARGET_ISEOT(*t); t++) if (!strcmp(t->name, optarg)) { add_target(t); break; } break; case 'i': input = 1; addr = msraddrbyname(optarg); optarg = strchr(optarg, '='); if (NULL == optarg) { fprintf(stderr, "missing value in -i argument!\n"); break; } if (!str2msr(++optarg, &msrval, NULL)) fprintf(stderr, "invalid value in -i argument!\n"); break; case 's': streamfn = optarg; break; case 'd': difffn = optarg; break; default: break; } printf_quiet("msrtool %s\n", VERSION); pacc = pci_alloc(); if (NULL == pacc) { fprintf(stderr, "Could not initialize PCI library! pci_alloc() failed.\n"); return 1; } pci_init(pacc); pci_scan_bus(pacc); if (!sys && !input && !listknown) for (sys = allsystems; !SYSTEM_ISEOT(*sys); sys++) { printf_verbose("Probing for system %s: %s\n", sys->name, sys->prettyname); if (!sys->probe(sys)) continue; printf_quiet("Detected system %s: %s\n", sys->name, sys->prettyname); break; } if (targets) for (tn = 0; tn < targets_found; tn++) printf_quiet("Forced target %s: %s\n", targets[tn]->name, targets[tn]->prettyname); else for (t = alltargets; !TARGET_ISEOT(*t); t++) { printf_verbose("Probing for target %s: %s\n", t->name, t->prettyname); if (!t->probe(t)) continue; printf_quiet("Detected target %s: %s\n", t->name, t->prettyname); add_target(t); } printf_quiet("\n"); fflush(stdout); if (listknown) { printf("Known systems:\n"); for (s = allsystems; s->name; s++) printf("%s: %s\n", s->name, s->prettyname); printf("\nKnown targets:\n"); for (t = alltargets; t->name; t++) { if (listmsrs && alltargets != t) printf("\n"); printf("%s: %s\n", t->name, t->prettyname); if (listmsrs) dumpmsrdefs(t); } printf("\n"); return 0; } if (!targets_found || !targets) { fprintf(stderr, "Unable to detect a known target; can not decode any MSRs! (Use -t to force)\n"); fprintf(stderr, "Please send a report or patch to [email protected]. Thanks for your help!\n"); fprintf(stderr, "\n"); return 1; } if (input) { decodemsr(cpu, addr, msrval); return 0; } if (listmsrs) { if (streamfn) return do_stream(streamfn, 1); for (tn = 0; tn < targets_found; tn++) { if (tn) printf("\n"); dumpmsrdefs(targets[tn]); } printf("\n"); return 0; } if (streamfn) return do_stream(streamfn, 0); if (difffn) { ret = do_diff(difffn); goto done; } if (optind == argc) { syntax(argv); printf("\nNo mode or address(es) specified!\n"); goto done; } if (!found_system()) return 1; if (!sys->open(cpu, SYS_RDONLY)) return 1; for (; optind < argc; optind++) { addr = msraddrbyname(argv[optind]); if (!sys->rdmsr(cpu, addr, &msrval)) break; decodemsr(cpu, addr, msrval); } ret = 0; done: sys->close(cpu); return ret; }
static void fillSpecialObject(ObjectPtr object, void (*fn)(FILE*, char*), void* closure) { int rc; int filedes[2]; pid_t pid; sigset_t ss, old_mask; if(object->flags & OBJECT_INPROGRESS) return; rc = pipe(filedes); if(rc < 0) { do_log_error(L_ERROR, errno, "Couldn't create pipe"); abortObject(object, 503, internAtomError(errno, "Couldn't create pipe")); return; } fflush(stdout); fflush(stderr); flushLog(); /* Block signals that we handle specially until the child can disable the handlers. */ interestingSignals(&ss); /* I'm a little confused. POSIX doesn't allow EINTR here, but I think that both Linux and SVR4 do. */ do { rc = sigprocmask(SIG_BLOCK, &ss, &old_mask); } while (rc < 0 && errno == EINTR); if(rc < 0) { do_log_error(L_ERROR, errno, "Sigprocmask failed"); abortObject(object, 503, internAtomError(errno, "Sigprocmask failed")); close(filedes[0]); close(filedes[1]); return; } pid = fork(); if(pid < 0) { do_log_error(L_ERROR, errno, "Couldn't fork"); abortObject(object, 503, internAtomError(errno, "Couldn't fork")); close(filedes[0]); close(filedes[1]); do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while (rc < 0 && errno == EINTR); if(rc < 0) { do_log_error(L_ERROR, errno, "Couldn't restore signal mask"); polipoExit(); } return; } if(pid > 0) { SpecialRequestPtr request; close(filedes[1]); do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while (rc < 0 && errno == EINTR); if(rc < 0) { do_log_error(L_ERROR, errno, "Couldn't restore signal mask"); polipoExit(); return; } request = malloc(sizeof(SpecialRequestRec)); if(request == NULL) { kill(pid, SIGTERM); close(filedes[0]); abortObject(object, 503, internAtom("Couldn't allocate request\n")); notifyObject(object); return; } else { request->buf = get_chunk(); if(request->buf == NULL) { kill(pid, SIGTERM); close(filedes[0]); free(request); abortObject(object, 503, internAtom("Couldn't allocate request\n")); notifyObject(object); return; } } object->flags |= OBJECT_INPROGRESS; retainObject(object); request->object = object; request->fd = filedes[0]; request->pid = pid; request->offset = 0; /* Under any sensible scheduler, the child will run before the parent. So no need for IO_NOTNOW. */ do_stream(IO_READ, filedes[0], 0, request->buf, CHUNK_SIZE, specialRequestHandler, request); } else { /* child */ close(filedes[0]); uninitEvents(); do { rc = sigprocmask(SIG_SETMASK, &old_mask, NULL); } while (rc < 0 && errno == EINTR); if(rc < 0) exit(1); if(filedes[1] != 1) dup2(filedes[1], 1); (*fn)(stdout, closure); exit(0); } }