rust/chg/src/attachio.rs
author Yuya Nishihara <yuya@tcha.org>
Fri, 10 Apr 2020 23:08:57 +0900
changeset 44749 cb5822e6e545
parent 44738 1be605526c34
child 44756 27fe8cc1338f
permissions -rw-r--r--
rust-chg: have attach_io() simply take reference of AsRawFd object We no longer have to deal with the restriction of the Future type. Before, these file objects couldn't be references and that's the only reason why we had to make stderr an Option<T>. This fixes future type deduction issue of stderr = None, where rustc would complain that T of Option<T> couldn't be deduced. Differential Revision: https://phab.mercurial-scm.org/D8443
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     1
// Copyright 2018 Yuya Nishihara <yuya@tcha.org>
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     2
//
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     3
// This software may be used and distributed according to the terms of the
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     4
// GNU General Public License version 2 or any later version.
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     5
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     6
//! Functions to send client-side fds over the command server channel.
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     7
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     8
use std::io;
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     9
use std::os::unix::io::AsRawFd;
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    10
use tokio_hglib::codec::ChannelMessage;
44738
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    11
use tokio_hglib::{Connection, Protocol};
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    12
44689
6bef9d43cc55 rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents: 44688
diff changeset
    13
use crate::message;
6bef9d43cc55 rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents: 44688
diff changeset
    14
use crate::procutil;
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    15
44738
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    16
/// Sends client-side fds over the command server channel.
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    17
///
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    18
/// This works as follows:
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    19
/// 1. Client sends "attachio" request.
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    20
/// 2. Server sends back 1-byte input request.
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
/// 3. Client sends fds with 1-byte dummy payload in response.
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    22
/// 4. Server returns the number of the fds received.
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    23
///
44749
cb5822e6e545 rust-chg: have attach_io() simply take reference of AsRawFd object
Yuya Nishihara <yuya@tcha.org>
parents: 44738
diff changeset
    24
/// The client-side fds may be dropped once duplicated to the server.
44738
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    25
pub async fn attach_io(
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    26
    proto: &mut Protocol<impl Connection + AsRawFd>,
44749
cb5822e6e545 rust-chg: have attach_io() simply take reference of AsRawFd object
Yuya Nishihara <yuya@tcha.org>
parents: 44738
diff changeset
    27
    stdin: &impl AsRawFd,
cb5822e6e545 rust-chg: have attach_io() simply take reference of AsRawFd object
Yuya Nishihara <yuya@tcha.org>
parents: 44738
diff changeset
    28
    stdout: &impl AsRawFd,
cb5822e6e545 rust-chg: have attach_io() simply take reference of AsRawFd object
Yuya Nishihara <yuya@tcha.org>
parents: 44738
diff changeset
    29
    stderr: &impl AsRawFd,
44738
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    30
) -> io::Result<()> {
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    31
    // TODO: unindent
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    32
    {
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    33
        proto.send_command("attachio").await?;
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    34
        loop {
44738
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    35
            match proto.fetch_response().await? {
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    36
                ChannelMessage::Data(b'r', data) => {
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    37
                    let fd_cnt = message::parse_result_code(data)?;
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    38
                    if fd_cnt == 3 {
44738
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    39
                        return Ok(());
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    40
                    } else {
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    41
                        return Err(io::Error::new(
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    42
                            io::ErrorKind::InvalidData,
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    43
                            "unexpected attachio result",
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    44
                        ));
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    45
                    }
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    46
                }
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    47
                ChannelMessage::Data(..) => {
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    48
                    // just ignore data sent to uninteresting (optional) channel
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    49
                }
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    50
                ChannelMessage::InputRequest(1) => {
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    51
                    // this may fail with EWOULDBLOCK in theory, but the
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    52
                    // payload is quite small, and the send buffer should
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    53
                    // be empty so the operation will complete immediately
44738
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    54
                    let sock_fd = proto.as_raw_fd();
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    55
                    let ifd = stdin.as_raw_fd();
1be605526c34 rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
    56
                    let ofd = stdout.as_raw_fd();
44749
cb5822e6e545 rust-chg: have attach_io() simply take reference of AsRawFd object
Yuya Nishihara <yuya@tcha.org>
parents: 44738
diff changeset
    57
                    let efd = stderr.as_raw_fd();
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    58
                    procutil::send_raw_fds(sock_fd, &[ifd, ofd, efd])?;
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    59
                }
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    60
                ChannelMessage::InputRequest(..)
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    61
                | ChannelMessage::LineRequest(..)
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    62
                | ChannelMessage::SystemRequest(..) => {
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    63
                    return Err(io::Error::new(
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    64
                        io::ErrorKind::InvalidData,
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    65
                        "unsupported request while attaching io",
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39972
diff changeset
    66
                    ));
39972
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    67
                }
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    68
            }
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    69
        }
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    70
    }
7a0ffdd4af78 rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    71
}