void NCCALogger::setLogFile(const std::string &_fname) { // close the file m_impl->m_output.flush(); m_impl->m_output.close(); m_impl->m_file.close(); m_impl->m_logfileName=_fname; m_impl->m_file.open(m_impl->m_logfileName.c_str() ); if(!m_impl->m_file.is_open()) { std::cerr<<"error opening log file for writing\n"; exit(EXIT_FAILURE); } Tee tee( std::cout, m_impl->m_file ); m_impl->m_output.open(tee); m_impl->m_output.set_auto_close(true); if( !m_impl->m_output.is_open()) { std::cerr<<"problem opening log stream tee\n"; exit(EXIT_FAILURE); } }
NCCALogger::Impl::Impl(const std::string &_fname): m_logFileAndConsole(false), m_logFile(true), m_logConsole(false), m_timeStamp(true), m_lineNumber(true), m_disableColours(false), m_lineNumberCount(0), m_pad(4), m_colour(RESET), m_logfileName(_fname) { m_file.open(m_logfileName.c_str() ); if(!m_file.is_open()) { std::cerr<<"error opening log file for writing\n"; exit(EXIT_FAILURE); } Tee tee( std::cout, m_file ); m_output.open(tee); m_output.set_auto_close(true); if( !m_output.is_open()) { std::cerr<<"problem opening log stream tee\n"; exit(EXIT_FAILURE); } m_timeString="%I:%M%p"; }
int main(int argc, char *argv[]) { if(argc != 2) { printf("Usage: %s <file>\n", basename(argv[0])); exit(EXIT_FAILURE); } int filefd = open(argv[1], O_CREAT | O_WRONLY | O_TRUNC, 0666); if(filefd == -1) ERR_EXIT("open"); int pipefd_stdout[2]; int ret = pipe(pipefd_stdout); if(ret == -1) ERR_EXIT("pipe"); int pipefd_file[2]; ret = pipe(pipefd_file); if(ret == -1) ERR_EXIT("pipe"); if(splice(STDIN_FILENO, NULL, pipefd_stdout[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE) == -1) ERR_EXIT("splice"); if(tee(pipefd_stdout[0], pipefd_file[1], 32768, SPLICE_F_NONBLOCK) == -1) ERR_EXIT("tee"); if(splice(pipefd_file[0], NULL, filefd, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE) == -1) ERR_EXIT("splice"); if(splice(pipefd_stdout[0], NULL, STDOUT_FILENO, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE) == -1) ERR_EXIT("splice"); close(filefd); close(pipefd_stdout[0]); close(pipefd_stdout[1]); close(pipefd_file[0]); close(pipefd_file[1]); exit(EXIT_SUCCESS); }
void PlanEntryModelManager::DeleteTimeEntry(unsigned __int64 id) { EnterCriticalSection(&critical_section); MSXML2::IXMLDOMNode *pNode = 0; StringBuffer conv(32); StringBuffer sb(_T("//timeentry[@entryid=\"")); sb.append(ModelUtils::toHexString(id, conv)); sb.append(_T("\"]")); BSTR xpath = SysAllocString(sb); HRESULT hr = m_pXMLDoc->selectSingleNode(xpath, &pNode); SysFreeString(xpath); if(hr == S_OK && pNode) { MSXML2::IXMLDOMNode *pOld = 0; hr = m_pRoot->removeChild(pNode, &pOld); if(hr == S_OK) { pOld->Release(); TimeEntryEvent tee(TimeEntryEvent::TIME_ENTRY_DELETE, id); NotifyChanged(tee); } pNode->Release(); } LeaveCriticalSection(&critical_section); }
int main(void) { int fd_in = 3; int fd_out = 4; return tee(fd_in, fd_out, ~0, 0); }
TimeEntry * PlanEntryModelManager::CreateTimeEntry( unsigned __int64 taskID, unsigned __int64 start, unsigned __int64 stop, TCHAR *pTaskname) { MSXML2::IXMLDOMNode *pNode = CreateEntryNode(); TimeEntry *pEntry = new(pNode) PlanEntryModel(pNode, start, stop, taskID, m_pDataManager->GetUsername(), pTaskname); pNode->Release(); if(pEntry) { TimeEntryEvent tee(TimeEntryEvent::TIME_ENTRY_ADD, pEntry->GetID(), pEntry); NotifyChanged(tee); } return pEntry; }
int main(int argc, char *argv[]) { int fd; int len; int slen; struct stat sb; if (argc < 2) { fprintf(stderr, "%s: outfile\n", argv[0]); exit(EXIT_FAILURE); } if ((fstat(STDIN_FILENO, &sb) < 0) || !S_ISFIFO(sb.st_mode)) { perror("fstat"); fprintf(stderr, "stdin must be a pipe\n"); exit(EXIT_FAILURE); } if ((fstat(STDOUT_FILENO, &sb) < 0) || !S_ISFIFO(sb.st_mode)) { perror("fstat"); fprintf(stderr, "stdout must be a pipe\n"); exit(EXIT_FAILURE); } if ((fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { perror("open"); exit(EXIT_FAILURE); } do { // tee stdin to stdout if ((len = tee(STDIN_FILENO, STDOUT_FILENO, 1024, 0)) < 0) { perror("tee"); exit(EXIT_FAILURE); } else { if (len == 0) break; // consume stdin by splicing it to a file while (len > 0) { if ((slen = splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE)) < 0) { perror("splice"); break; } len -= slen; } } } while (1); close(fd); return 0; }
/* * Class: jFUSE_lowlevel_Splice * Method: tee * Signature: (Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;JI)J */ JNIEXPORT jlong JNICALL Java_jFUSE_lowlevel_Splice_tee (JNIEnv *env, jclass jSpliceClass, jobject jinputFD, jobject joutputFD, jlong length, jint flags) { /* Not linux so throw UnSupportException */ #if __LINUX__ == 0 (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/UnsupportedOperationException"), "Tee is not supported on this platform"); return 0; #else /* Declarations */ int inputFD = -1; int outputFD = -1; ssize_t amtTransferred; /* Gets the input fds */ inputFD = _getFDFromFileDescriptor(env, jinputFD); outputFD = _getFDFromFileDescriptor(env, joutputFD); if((*env)->ExceptionCheck(env)) { return -1; } /* Connect the to pipes * (the read end of the first one to the write end of the second) */ amtTransferred = tee(inputFD, outputFD, length, (int)flags); if(amtTransferred < 0) { (*env)->ThrowNew(env, (*env)->FindClass(env, "java/io/IOException"), strerror(errno)); return -1; } /* Return the result */ return amtTransferred; #endif }
/** * Copies max(n bytes, remaining bytes) from file descriptor in * to file descriptor out without moving the file pointer, returning * the number of bytes copied */ static inline int teen(int n, int in, int out) { int bytesread = 0, bytesleft = n; while (bytesleft) { int len = tee(in, out, n, SPLICE_F_NONBLOCK); if (len == 0) { return bytesread; } else if (len == -1) { if (errno == EAGAIN) { continue; } else { perror("tee"); return -1; } } else { bytesread += len; bytesleft -= len; } } return bytesread; }
int main( int argc, char* argv[] ) { if ( argc != 2 ) { printf( "usage: %s <file>\n", argv[0] ); return 1; } int filefd = open( argv[1], O_CREAT | O_WRONLY | O_TRUNC, 0666 ); assert( filefd > 0 ); int pipefd_stdout[2]; int ret = pipe( pipefd_stdout ); assert( ret != -1 ); int pipefd_file[2]; ret = pipe( pipefd_file ); assert( ret != -1 ); //close( STDIN_FILENO ); //dup2( pipefd_stdout[1], STDIN_FILENO ); //write( pipefd_stdout[1], "abc\n", 4 ); // 将标准输入move到管道a ret = splice( STDIN_FILENO, NULL, pipefd_stdout[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE ); assert( ret != -1 ); // 从管道a中读取内容写入另一个管道b ret = tee( pipefd_stdout[0], pipefd_file[1], 32768, SPLICE_F_NONBLOCK ); assert( ret != -1 ); // 从管道b中读取写入到文件 ret = splice( pipefd_file[0], NULL, filefd, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE ); assert( ret != -1 ); // 从管道b中读取写入到标准输出 ret = splice( pipefd_stdout[0], NULL, STDOUT_FILENO, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE ); assert( ret != -1 ); close( filefd ); close( pipefd_stdout[0] ); close( pipefd_stdout[1] ); close( pipefd_file[0] ); close( pipefd_file[1] ); return 0; }
void serve_cache_headers(struct cache_req_t *req) { int ret = tee(req->file->cache_headers->pipe[0], req->buf->pipe[1], req->file->cache_headers->filled, SPLICE_F_NONBLOCK); if (ret < 0) { perror("cannot tee into the request buffer!!\n"); mk_bug(1); } if (ret < req->file->header_len) { PLUGIN_TRACE("teed %d data instead of headers len %ld\n", ret, req->file->header_len); mk_bug(ret < req->file->header_len); } req->buf->filled += ret; // HACK: make headers seem like file contents req->bytes_offset -= req->file->header_len; req->bytes_to_send += req->file->header_len; }
static void tee_verify(const struct test_case_t *tc) { TEST(tee(*(tc->fdin), *(tc->fdout), TEE_TEST_LEN, 0)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "tee() returned %ld, " "expected -1, errno:%d", TEST_RETURN, tc->exp_errno); return; } TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == tc->exp_errno) { tst_resm(TPASS | TTERRNO, "tee() failed as expected"); } else { tst_resm(TFAIL | TTERRNO, "tee() failed unexpectedly; expected: %d - %s", tc->exp_errno, strerror(tc->exp_errno)); } }
int main(int argc, char *argv[]) { if(argc != 2) { printf("Usage:%s <file>\n", argv[0]); return -1; } int filefd; CHECK(filefd = open(argv[1], O_CREAT|O_WRONLY|O_TRUNC, 0666)); int pipefd_stdout[2]; int pipefd_file[2]; CHECK(pipe(pipefd_stdout)); CHECK(pipe(pipefd_file)); CHECK(splice(STDIN_FILENO, NULL, pipefd_stdout[1], NULL, 32768, SPLICE_F_MOVE|SPLICE_F_MORE)); CHECK(tee(pipefd_stdout[0], pipefd_file[1], 32768, SPLICE_F_NONBLOCK)); CHECK(splice(pipefd_stdout[0], NULL, STDOUT_FILENO, NULL, 32768, SPLICE_F_MOVE|SPLICE_F_MORE)); CHECK(splice(pipefd_file[0], NULL, filefd, NULL, 32768, SPLICE_F_MOVE|SPLICE_F_MORE)); close(filefd); close(pipefd_stdout[0]); close(pipefd_stdout[1]); close(pipefd_file[0]); close(pipefd_file[1]); }
static int tee_test(void) { char buffer[SPLICE_TEST_BLOCK_SIZE]; char teebuffer[SPLICE_TEST_BLOCK_SIZE]; int pipe1[2]; int pipe2[2]; int ret; int i, len; int fd_in, fd_out; for (i = 0; i < SPLICE_TEST_BLOCK_SIZE; i++) { buffer[i] = i & 0xff; } fd_in = open(testfile1, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd_in < 0) { perror("open: "); return -1; } len = write(fd_in, buffer, SPLICE_TEST_BLOCK_SIZE); if (len < SPLICE_TEST_BLOCK_SIZE) { perror("write: "); close(fd_in); return -1; } close(fd_in); fd_in = open(testfile1, O_RDONLY); if (fd_in < 0) { perror("open: "); return -1; } ret = pipe(pipe1); if (ret < 0) { perror("pipe: "); close(fd_in); return -1; } ret = pipe(pipe2); if (ret < 0) { perror("pipe: "); close(pipe1[0]); close(pipe1[1]); close(fd_in); return -1; } fd_out = open(testfile2, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd_out < 0) { close(fd_in); close(pipe1[0]); close(pipe1[1]); close(pipe2[0]); close(pipe2[1]); perror("open: "); return -1; } ret = splice(fd_in, NULL, pipe1[1], NULL, SPLICE_TEST_BLOCK_SIZE, 0); if (ret < 0) { ret = -errno; close(fd_in); close(fd_out); close(pipe1[0]); close(pipe1[1]); close(pipe2[0]); close(pipe2[1]); return ret; } ret = tee(pipe1[0], pipe2[1], SPLICE_TEST_BLOCK_SIZE, SPLICE_F_NONBLOCK); if (ret < 0) { ret = -errno; close(fd_in); close(fd_out); close(pipe1[0]); close(pipe1[1]); close(pipe2[0]); close(pipe2[1]); return ret; } ret = splice(pipe2[0], NULL, fd_out, NULL, SPLICE_TEST_BLOCK_SIZE, 0); if (ret < 0) { ret = -errno; close(fd_in); close(fd_out); close(pipe1[0]); close(pipe1[1]); close(pipe2[0]); close(pipe2[1]); return ret; } close(fd_in); close(fd_out); close(pipe1[0]); close(pipe1[1]); close(pipe2[0]); close(pipe2[1]); fd_out = open(testfile2, O_RDONLY); if (fd_out < 0) { perror("open: "); return -1; } read(fd_out, teebuffer, SPLICE_TEST_BLOCK_SIZE); for (i = 0; i < SPLICE_TEST_BLOCK_SIZE; i++) { if (buffer[i] != teebuffer[i]) break; } if (i < SPLICE_TEST_BLOCK_SIZE) { return -1; } return 0; }
static bool send_stream(char const *program, struct notify_info *notify, struct memory_block_data const *payload, struct signature_algorithm *sigalg, struct decompression_algorithm *decompalg) { struct decompressor decomp = { .pid = -1 }; size_t len; pid_t pid = -1; int pfds[2] = { -1, -1 }; int status; notification_send(notify, "s", 1); if (pipe(pfds) < 0) { perror("pipe(<pfds>)"); goto err; } pid = fork(); if (pid < 0) { perror("fork()"); goto err; } if (pid == 0) { char size_str[sizeof(size_t)*3 + 2]; char type_str[sizeof(unsigned int)*3 + 2]; if (!signature_setenv(sigalg)) { fprintf(stderr, "failed to export signature details\n"); _exit(1); } close(pfds[1]); if (dup2(pfds[0], 0) < 0) { perror("dup2()"); _exit(1); } if (pfds[0] != 0) close(pfds[0]); sprintf(size_str, "%zu", payload->len); sprintf(type_str, "%u", payload->type); execlp(program, program, "stream", type_str, size_str, NULL); perror("execlp()"); _exit(1); } close(pfds[0]); pfds[0] = -1; if (!decompressor_run(&decomp, decompalg, payload->mem.stream->fd, payload->mem.len)) { fprintf(stderr, "failed to start decompressor\n"); goto err; } for (len = 0; len < payload->len && !payload->mem.stream->is_eos;) { ssize_t l; /* \todo: implement decompressor */ l = tee(decomp.fd_out, pfds[1], payload->len - len, SPLICE_F_MORE); if (l == 0) payload->mem.stream->is_eos = true; else if (l < 0 && errno == EINTR) { continue; } else if (l < 0) { perror("tee()"); break; } notification_handle_read(notify, l); if (!signature_pipein(sigalg, decomp.fd_out, l)) break; len += l; } close(pfds[1]); pfds[1] = -1; if (!decompressor_wait(&decomp)) goto err; if (len != payload->len) { fprintf(stderr, "failed to read all payload data (%zu < %zu)\n", len, payload->len); goto err; } notification_send(notify, "w", 1); if (waitpid(pid, &status, 0) < 0) { perror("waitpid()"); goto err; } pid = -1; if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { fprintf(stderr, "program failed with %d\n", status); goto err; } notification_send(notify, "e\0", 2); return true; err: if (pfds[0] != -1) close(pfds[0]); if (pfds[1] != -1) close(pfds[0]); if (pid != -1) { kill(pid, SIGTERM); waitpid(pid, NULL, 0); } decompressor_wait(&decomp); notification_send(notify, "e\1", 2); return false; } static bool verify_signature(struct memory_block_signature const *signature, struct signature_algorithm *sigalg) { be32_t tmp; size_t len; unsigned char sig[MAX_SIGNATURE_SIZE]; if (!stream_data_read(signature->mem.stream, &tmp, sizeof tmp, false)) { fprintf(stderr, "failed to read signature length\n"); return false; } len = be32toh(tmp); if (len > sizeof sig) { fprintf(stderr, "signature too large (%zu)\n", len); return false; } if (!stream_data_read(signature->mem.stream, &sig, len, false)) { fprintf(stderr, "failed to read signature\n"); return false; } if (!signature_verify(sigalg, sig, len)) { fprintf(stderr, "failed to verify signature\n"); return false; } return true; }
// TODO: Assuming headers are only filled once void fill_cache_headers(struct cache_file_t *file, struct client_session *cs, struct session_request *sr) { int ret = 0; if (pthread_mutex_trylock(&file->cache_headers->write_mutex) == 0) { if (!file->cache_headers->filled) { // HACK: change server request values to prevent monkey to // not add "connection: close" in any case as it messes up things // when served every request with same cached headers. int old_conn = sr->headers.connection, old_keepalive = sr->keep_alive, old_close = sr->close_now, old_conlen = sr->connection.len; sr->headers.connection= 0; sr->keep_alive = MK_TRUE; sr->close_now = MK_FALSE; if (sr->connection.len == 0) sr->connection.len = 1; mk_api->header_send(file->cache_headers->pipe[1], cs, sr); if (ioctl(file->cache_headers->pipe[0], FIONREAD, &file->header_len) != 0) { perror("cannot find size of pipe buf!"); mk_bug(1); } // restoring modified server request values sr->headers.connection = old_conn; sr->keep_alive = old_keepalive; sr->close_now = old_close; sr->connection.len = old_conlen; file->cache_headers->filled = file->header_len; // fill in the empty header pipe space with some initial file // data to send them in a single tee syscall, only in case // there is enough room which would be true for small files // which fit inside a pipe int leftover = file->cache_headers->cap - file->cache_headers->filled; struct pipe_buf_t *first_buf = mk_list_entry_first(&file->cache, struct pipe_buf_t, _head); if (leftover > first_buf->filled) { if (first_buf->filled) { ret = tee(first_buf->pipe[0], file->cache_headers->pipe[1], first_buf->filled, SPLICE_F_NONBLOCK); mk_bug(ret <= 0); file->cache_headers->filled += ret; } } else { // file too big to compltely fit in the header pipe // along with the rest of the headers } mk_bug(file->cache_headers->filled == 0); } pthread_mutex_unlock(&file->cache_headers->write_mutex); }