...

Source file src/github.com/containerd/fifo/raw.go

Documentation: github.com/containerd/fifo

     1  //go:build !windows
     2  
     3  /*
     4     Copyright The containerd Authors.
     5  
     6     Licensed under the Apache License, Version 2.0 (the "License");
     7     you may not use this file except in compliance with the License.
     8     You may obtain a copy of the License at
     9  
    10         http://www.apache.org/licenses/LICENSE-2.0
    11  
    12     Unless required by applicable law or agreed to in writing, software
    13     distributed under the License is distributed on an "AS IS" BASIS,
    14     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15     See the License for the specific language governing permissions and
    16     limitations under the License.
    17  */
    18  
    19  package fifo
    20  
    21  import (
    22  	"syscall"
    23  )
    24  
    25  // SyscallConn provides raw access to the fifo's underlying filedescrptor.
    26  // See syscall.Conn for guarantees provided by this interface.
    27  func (f *fifo) SyscallConn() (syscall.RawConn, error) {
    28  	// deterministic check for closed
    29  	select {
    30  	case <-f.closed:
    31  		return nil, ErrClosed
    32  	default:
    33  	}
    34  
    35  	select {
    36  	case <-f.closed:
    37  		return nil, ErrClosed
    38  	case <-f.opened:
    39  		return f.file.SyscallConn()
    40  	default:
    41  	}
    42  
    43  	// Not opened and not closed, this means open is non-blocking AND it's not open yet
    44  	// Use rawConn to deal with non-blocking open.
    45  	rc := &rawConn{f: f, ready: make(chan struct{})}
    46  	go func() {
    47  		select {
    48  		case <-f.closed:
    49  			return
    50  		case <-f.opened:
    51  			rc.raw, rc.err = f.file.SyscallConn()
    52  			close(rc.ready)
    53  		}
    54  	}()
    55  
    56  	return rc, nil
    57  }
    58  
    59  type rawConn struct {
    60  	f     *fifo
    61  	ready chan struct{}
    62  	raw   syscall.RawConn
    63  	err   error
    64  }
    65  
    66  func (r *rawConn) Control(f func(fd uintptr)) error {
    67  	select {
    68  	case <-r.f.closed:
    69  		return ErrCtrlClosed
    70  	case <-r.ready:
    71  	}
    72  
    73  	if r.err != nil {
    74  		return r.err
    75  	}
    76  
    77  	return r.raw.Control(f)
    78  }
    79  
    80  func (r *rawConn) Read(f func(fd uintptr) (done bool)) error {
    81  	if r.f.flag&syscall.O_WRONLY > 0 {
    82  		return ErrRdFrmWRONLY
    83  	}
    84  
    85  	select {
    86  	case <-r.f.closed:
    87  		return ErrReadClosed
    88  	case <-r.ready:
    89  	}
    90  
    91  	if r.err != nil {
    92  		return r.err
    93  	}
    94  
    95  	return r.raw.Read(f)
    96  }
    97  
    98  func (r *rawConn) Write(f func(fd uintptr) (done bool)) error {
    99  	if r.f.flag&(syscall.O_WRONLY|syscall.O_RDWR) == 0 {
   100  		return ErrWrToRDONLY
   101  	}
   102  
   103  	select {
   104  	case <-r.f.closed:
   105  		return ErrWriteClosed
   106  	case <-r.ready:
   107  	}
   108  
   109  	if r.err != nil {
   110  		return r.err
   111  	}
   112  
   113  	return r.raw.Write(f)
   114  }
   115  

View as plain text