当前位置: 首页>>代码示例>>C++>>正文


C++ io_chain_t类代码示例

本文整理汇总了C++中io_chain_t的典型用法代码示例。如果您正苦于以下问题:C++ io_chain_t类的具体用法?C++ io_chain_t怎么用?C++ io_chain_t使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了io_chain_t类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: read_try

/**
   Read from descriptors until they are empty.

   \param j the job to test
*/
static void read_try(job_t *j)
{
    io_buffer_t *buff = NULL;

    /*
      Find the last buffer, which is the one we want to read from
    */
    const io_chain_t chain = j->all_io_redirections();
    for (size_t idx = 0; idx < chain.size(); idx++)
    {
        io_data_t *d = chain.at(idx).get();
        if (d->io_mode == IO_BUFFER)
        {
            buff = static_cast<io_buffer_t *>(d);
        }
    }

    if (buff)
    {
        debug(3, L"proc::read_try('%ls')\n", j->command_wcstr());
        while (1)
        {
            char b[BUFFER_SIZE];
            long l;

            l=read_blocked(buff->pipe_fd[0],
                           b, BUFFER_SIZE);
            if (l==0)
            {
                break;
            }
            else if (l<0)
            {
                if (errno != EAGAIN)
                {
                    debug(1,
                          _(L"An error occured while reading output from code block"));
                    wperror(L"read_try");
                }
                break;
            }
            else
            {
                buff->out_buffer_append(b, l);
            }
        }
    }
}
开发者ID:ByScripts,项目名称:fish-shell,代码行数:53,代码来源:proc.cpp

示例2: move_fd_to_unused

int move_fd_to_unused(int fd, const io_chain_t &io_chain, bool cloexec) {
    if (fd < 0 || io_chain.get_io_for_fd(fd).get() == NULL) {
        return fd;
    }

    // We have fd >= 0, and it's a conflict. dup it and recurse. Note that we recurse before
    // anything is closed; this forces the kernel to give us a new one (or report fd exhaustion).
    int new_fd = fd;
    int tmp_fd;
    do {
        tmp_fd = dup(fd);
    } while (tmp_fd < 0 && errno == EINTR);

    assert(tmp_fd != fd);
    if (tmp_fd < 0) {
        // Likely fd exhaustion.
        new_fd = -1;
    } else {
        // Ok, we have a new candidate fd. Recurse. If we get a valid fd, either it's the same as
        // what we gave it, or it's a new fd and what we gave it has been closed. If we get a
        // negative value, the fd also has been closed.
        if (cloexec) set_cloexec(tmp_fd);
        new_fd = move_fd_to_unused(tmp_fd, io_chain);
    }

    // We're either returning a new fd or an error. In both cases, we promise to close the old one.
    assert(new_fd != fd);
    int saved_errno = errno;
    exec_close(fd);
    errno = saved_errno;
    return new_fd;
}
开发者ID:fish-shell,项目名称:fish-shell,代码行数:32,代码来源:io.cpp

示例3: io_print

void io_print(const io_chain_t &chain)
{
    if (chain.empty())
    {
        fprintf(stderr, "Empty chain %p\n", &chain);
        return;
    }

    fprintf(stderr, "Chain %p (%ld items):\n", &chain, (long)chain.size());
    for (size_t i=0; i < chain.size(); i++)
    {
        const shared_ptr<const io_data_t> &io = chain.at(i);
        fprintf(stderr, "\t%lu: fd:%d, ", (unsigned long)i, io->fd);
        io->print();
    }
}
开发者ID:NewXX,项目名称:fish-shell,代码行数:16,代码来源:io.cpp

示例4: free_redirected_fds_from_pipes

/** Make sure the fd used by each redirection is not used by a pipe. Note that while this does not modify the vector, it does modify the IO redirections within (gulp) */
static void free_redirected_fds_from_pipes(const io_chain_t &io_chain)
{
    size_t max = io_chain.size();
    for (size_t i = 0; i < max; i++)
    {
        int fd_to_free = io_chain.at(i)->fd;

        /* We only have to worry about fds beyond the three standard ones */
        if (fd_to_free <= 2)
            continue;

        /* Make sure the fd is not used by a pipe */
        for (size_t j = 0; j < max; j++)
        {
            /* We're only interested in pipes */
            io_data_t *io = io_chain.at(j).get();
            if (io->io_mode != IO_PIPE && io->io_mode != IO_BUFFER)
                continue;

            CAST_INIT(io_pipe_t *, possible_conflict, io);
            /* If the pipe is a conflict, dup it to some other value */
            for (int k=0; k<2; k++)
            {
                /* If it's not a conflict, we don't care */
                if (possible_conflict->pipe_fd[k] != fd_to_free)
                    continue;

                /* Repeat until we have a replacement fd */
                int replacement_fd = -1;
                while (replacement_fd < 0)
                {
                    replacement_fd = dup(fd_to_free);
                    if (replacement_fd == -1 && errno != EINTR)
                    {
                        debug_safe_int(1, FD_ERROR, fd_to_free);
                        safe_perror("dup");
                        FATAL_EXIT();
                    }
                }
                possible_conflict->pipe_fd[k] = replacement_fd;
            }
        }
    }
}
开发者ID:ByScripts,项目名称:fish-shell,代码行数:45,代码来源:postfork.cpp

示例5: select_try

/**
   Check if there are buffers associated with the job, and select on
   them for a while if available.

   \param j the job to test

   \return 1 if buffers were available, zero otherwise
*/
static int select_try(job_t *j)
{
    fd_set fds;
    int maxfd=-1;

    FD_ZERO(&fds);

    const io_chain_t chain = j->all_io_redirections();
    for (size_t idx = 0; idx < chain.size(); idx++)
    {
        const io_data_t *io = chain.at(idx).get();
        if (io->io_mode == IO_BUFFER)
        {
            CAST_INIT(const io_pipe_t *, io_pipe, io);
            int fd = io_pipe->pipe_fd[0];
//			fwprintf( stderr, L"fd %d on job %ls\n", fd, j->command );
            FD_SET(fd, &fds);
            maxfd = maxi(maxfd, fd);
            debug(3, L"select_try on %d\n", fd);
        }
    }

    if (maxfd >= 0)
    {
        int retval;
        struct timeval tv;

        tv.tv_sec=0;
        tv.tv_usec=10000;

        retval =select(maxfd+1, &fds, 0, 0, &tv);
        if (retval == 0) {
            debug(3, L"select_try hit timeout\n");
        }
        return retval > 0;
    }

    return -1;
}
开发者ID:Qilewuqiong,项目名称:fish-shell,代码行数:47,代码来源:proc.cpp

示例6: io_print

// This isn't used so the lint tools were complaining about its presence. I'm keeping it in the
// source because it could be useful for debugging.
void io_print(const io_chain_t &chain)
{
    if (chain.empty())
    {
        std::fwprintf(stderr, L"Empty chain %p\n", &chain);
        return;
    }

    std::fwprintf(stderr, L"Chain %p (%ld items):\n", &chain, (long)chain.size());
    for (size_t i=0; i < chain.size(); i++)
    {
        const shared_ptr<io_data_t> &io = chain.at(i);
        if (io.get() == NULL)
        {
            std::fwprintf(stderr, L"\t(null)\n");
        }
        else
        {
            std::fwprintf(stderr, L"\t%lu: fd:%d, ", (unsigned long)i, io->fd);
            io->print();
        }
    }
}
开发者ID:fish-shell,项目名称:fish-shell,代码行数:25,代码来源:io.cpp

示例7: io_chain_destroy

void io_chain_destroy(io_chain_t &chain)
{
    chain.destroy();
}
开发者ID:JanKanis,项目名称:fish-shell,代码行数:4,代码来源:io.cpp

示例8: io_duplicate_prepend

void io_duplicate_prepend(const io_chain_t &src, io_chain_t &dst)
{
    return dst.duplicate_prepend(src);
}
开发者ID:JanKanis,项目名称:fish-shell,代码行数:4,代码来源:io.cpp

示例9: io_duplicate

io_chain_t io_duplicate(const io_chain_t &chain)
{
    return chain.duplicate();
}
开发者ID:JanKanis,项目名称:fish-shell,代码行数:4,代码来源:io.cpp

示例10: io_remove

void io_remove(io_chain_t &list, const io_data_t *element)
{
    list.remove(element);
}
开发者ID:JanKanis,项目名称:fish-shell,代码行数:4,代码来源:io.cpp

示例11: exec_job

void exec_job(parser_t &parser, shared_ptr<job_t> j) {
    assert(j && "null job_t passed to exec_job!");

    // Set to true if something goes wrong while exec:ing the job, in which case the cleanup code
    // will kick in.
    bool exec_error = false;

    // If fish was invoked with -n or --no-execute, then no_exec will be set and we do nothing.
    if (no_exec) {
        return;
    }

    // Unfortunately `exec_job()` is called recursively when functions are encountered, with a new
    // job id (and therefore pgrp) each time, but always from the main thread. This breaks terminal
    // control since new pgrps take terminal control away from commands upstream in a different pgrp.
    // We try to work around this with a heuristic to determine whether to reuse the same pgrp as the
    // last-spawned pgrp if part of an existing job pipeline (keeping in mind that new jobs are
    // recursively started for both foreground and background jobs, and that a function can expand
    // to more than one external command, one (or more?) of which may want to read from upstream or
    // write to downstream of a pipe.
    // By keeping track of (select) "jobs in flight" we can try to marshall newly-created external
    // processes into existing pgrps. Fixes #3952.
    // This is a HACK and the correct solution would be to pass the active job through the pipeline
    // to the newly established parser context so that the funtion as parsed and evaluated can be
    // directly associated with this job and not a new one, BUT sometimes functions NEED to start a
    // new job. This HACK seeks a compromise by letting functions trigger the unilateral creation of
    // a new job, but reusing the "parent" job's existing pgrp in case of terminal control.
    static std::stack<decltype(j)> active_jobs;
    // There's an assumption that there's a one-to-one mapping between jobs under job control and
    // pgrps. When we share a parent job's pgrp, we risk reaping its processes before it is fully
    // constructed, causing later setpgrp(2) calls to fails (#5219). While the parent job is still
    // under construction, child jobs have job_flag_t::WAIT_BY_PROCESS set to prevent early repaing.
    // We store them here until the parent job is constructed, at which point it unsets this flag.
    static std::stack<decltype(j)> child_jobs;

    auto parent_job = active_jobs.empty() ? nullptr : active_jobs.top();
    bool job_pushed = false;
    if (j->get_flag(job_flag_t::TERMINAL) && j->get_flag(job_flag_t::JOB_CONTROL)) {
        // This will be popped before this job leaves exec_job
        active_jobs.push(j);
        job_pushed = true;
    }

    if (parent_job && j->processes.front()->type == EXTERNAL) {
        if (parent_job->pgid != INVALID_PID) {
            j->pgid = parent_job->pgid;
            j->set_flag(job_flag_t::JOB_CONTROL, true);
            j->set_flag(job_flag_t::NESTED, true);
            j->set_flag(job_flag_t::WAIT_BY_PROCESS, true);
            child_jobs.push(j);
        }
    }

    // Verify that all IO_BUFFERs are output. We used to support a (single, hacked-in) magical input
    // IO_BUFFER used by fish_pager, but now the claim is that there are no more clients and it is
    // removed. This assertion double-checks that.
    size_t stdout_read_limit = 0;
    const io_chain_t all_ios = j->all_io_redirections();
    for (size_t idx = 0; idx < all_ios.size(); idx++) {
        const shared_ptr<io_data_t> &io = all_ios.at(idx);

        if ((io->io_mode == IO_BUFFER)) {
            io_buffer_t *io_buffer = static_cast<io_buffer_t *>(io.get());
            assert(!io_buffer->is_input);
            stdout_read_limit = io_buffer->buffer().limit();
        }
    }

    if (j->processes.front()->type == INTERNAL_EXEC) {
        internal_exec(j.get(), std::move(all_ios));
        DIE("this should be unreachable");
    }

    // We may have block IOs that conflict with fd redirections. For example, we may have a command
    // with a redireciton like <&3; we may also have chosen 3 as the fd for our pipe. Ensure we have
    // no conflicts.
    for (const auto io : all_ios) {
        if (io->io_mode == IO_BUFFER) {
            auto *io_buffer = static_cast<io_buffer_t *>(io.get());
            if (!io_buffer->avoid_conflicts_with_io_chain(all_ios)) {
                // We could not avoid conflicts, probably due to fd exhaustion. Mark an error.
                exec_error = true;
                job_mark_process_as_failed(j.get(), j->processes.front().get());
                break;
            }
        }
    }

    // This loop loops over every process_t in the job, starting it as appropriate. This turns out
    // to be rather complex, since a process_t can be one of many rather different things.
    //
    // The loop also has to handle pipelining between the jobs.
    //
    // We can have up to three pipes "in flight" at a time:
    //
    // 1. The pipe the current process should read from (courtesy of the previous process)
    // 2. The pipe that the current process should write to
    // 3. The pipe that the next process should read from (courtesy of us)
    //
    autoclose_fd_t pipe_next_read;
//.........这里部分代码省略.........
开发者ID:moverest,项目名称:fish-shell,代码行数:101,代码来源:exec.cpp

示例12: setup_child_process

/**
   Set up a childs io redirections. Should only be called by
   setup_child_process(). Does the following: First it closes any open
   file descriptors not related to the child by calling
   close_unused_internal_pipes() and closing the universal variable
   server file descriptor. It then goes on to perform all the
   redirections described by \c io.

   \param io the list of IO redirections for the child

   \return 0 on sucess, -1 on failiure
*/
static int handle_child_io(const io_chain_t &io_chain)
{
    for (size_t idx = 0; idx < io_chain.size(); idx++)
    {
        const io_data_t *io = io_chain.at(idx).get();
        int tmp;

        if (io->io_mode == IO_FD && io->fd == static_cast<const io_fd_t*>(io)->old_fd)
        {
            continue;
        }

        switch (io->io_mode)
        {
            case IO_CLOSE:
            {
                if (log_redirections) fprintf(stderr, "%d: close %d\n", getpid(), io->fd);
                if (close(io->fd))
                {
                    debug_safe_int(0, "Failed to close file descriptor %s", io->fd);
                    safe_perror("close");
                }
                break;
            }

            case IO_FILE:
            {
                // Here we definitely do not want to set CLO_EXEC because our child needs access
                CAST_INIT(const io_file_t *, io_file, io);
                if ((tmp=open(io_file->filename_cstr,
                              io_file->flags, OPEN_MASK))==-1)
                {
                    if ((io_file->flags & O_EXCL) &&
                            (errno ==EEXIST))
                    {
                        debug_safe(1, NOCLOB_ERROR, io_file->filename_cstr);
                    }
                    else
                    {
                        debug_safe(1, FILE_ERROR, io_file->filename_cstr);
                        safe_perror("open");
                    }

                    return -1;
                }
                else if (tmp != io->fd)
                {
                    /*
                      This call will sometimes fail, but that is ok,
                      this is just a precausion.
                    */
                    close(io->fd);

                    if (dup2(tmp, io->fd) == -1)
                    {
                        debug_safe_int(1,  FD_ERROR, io->fd);
                        safe_perror("dup2");
                        return -1;
                    }
                    exec_close(tmp);
                }
                break;
            }

            case IO_FD:
            {
                int old_fd = static_cast<const io_fd_t *>(io)->old_fd;
                if (log_redirections) fprintf(stderr, "%d: fd dup %d to %d\n", getpid(), old_fd, io->fd);

                /*
                  This call will sometimes fail, but that is ok,
                  this is just a precausion.
                */
                close(io->fd);


                if (dup2(old_fd, io->fd) == -1)
                {
                    debug_safe_int(1, FD_ERROR, io->fd);
                    safe_perror("dup2");
                    return -1;
                }
                break;
            }

            case IO_BUFFER:
            case IO_PIPE:
            {
//.........这里部分代码省略.........
开发者ID:FUNK88,项目名称:fish-shell,代码行数:101,代码来源:postfork.cpp

示例13: io_transmogrify

/// Make a copy of the specified io redirection chain, but change file redirection into fd
/// redirection. This makes the redirection chain suitable for use as block-level io, since the file
/// won't be repeatedly reopened for every command in the block, which would reset the cursor
/// position.
///
/// \return true on success, false on failure. Returns the output chain and opened_fds by reference.
static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t *out_chain,
                            std::vector<int> *out_opened_fds) {
    ASSERT_IS_MAIN_THREAD();
    assert(out_chain != NULL && out_opened_fds != NULL);
    assert(out_chain->empty());

    // Just to be clear what we do for an empty chain.
    if (in_chain.empty()) {
        return true;
    }

    bool success = true;

    // Make our chain of redirections.
    io_chain_t result_chain;

    // In the event we can't finish transmorgrifying, we'll have to close all the files we opened.
    std::vector<int> opened_fds;

    for (size_t idx = 0; idx < in_chain.size(); idx++) {
        const shared_ptr<io_data_t> &in = in_chain.at(idx);
        shared_ptr<io_data_t> out;  // gets allocated via new

        switch (in->io_mode) {
            case IO_PIPE:
            case IO_FD:
            case IO_BUFFER:
            case IO_CLOSE: {
                // These redirections don't need transmogrification. They can be passed through.
                out = in;
                break;
            }
            case IO_FILE: {
                // Transmogrify file redirections.
                int fd;
                io_file_t *in_file = static_cast<io_file_t *>(in.get());
                if ((fd = open(in_file->filename_cstr, in_file->flags, OPEN_MASK)) == -1) {
                    debug(1, FILE_ERROR, in_file->filename_cstr);

                    wperror(L"open");
                    success = false;
                    break;
                }

                opened_fds.push_back(fd);
                out.reset(new io_fd_t(in->fd, fd, false));
                break;
            }
        }

        if (out.get() != NULL) result_chain.push_back(out);

        // Don't go any further if we failed.
        if (!success) {
            break;
        }
    }

    // Now either return success, or clean up.
    if (success) {
        *out_chain = std::move(result_chain);
        *out_opened_fds = std::move(opened_fds);
    } else {
        result_chain.clear();
        io_cleanup_fds(opened_fds);
    }
    return success;
}
开发者ID:moverest,项目名称:fish-shell,代码行数:74,代码来源:exec.cpp

示例14: io_remove

void io_remove(io_chain_t &list, const shared_ptr<const io_data_t> &element)
{
    list.remove(element);
}
开发者ID:NewXX,项目名称:fish-shell,代码行数:4,代码来源:io.cpp

示例15: append

void io_chain_t::append(const io_chain_t &chain)
{
    this->insert(this->end(), chain.begin(), chain.end());
}
开发者ID:Aulos,项目名称:fish-shell,代码行数:4,代码来源:io.cpp


注:本文中的io_chain_t类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。