func OpenFileReader(name string, intr rh.Intr) (r *FileReader, err error) {
	r = &FileReader{
		cmd: exec.Command(helper.LookupExecutable(), "-sysread", path.Clean(name)),
	}
	// the helper process communicates control messages back to us on stderr
	stderr, err := r.cmd.StderrPipe()
	if err != nil {
		panic(err) // system error
	}
	r.stdin, err = r.cmd.StdinPipe()
	if err != nil {
		panic(err) // system error
	}
	// stdout is the reading channel
	r.ir, r.cmd.Stdout = interruptible.BufferPipe(bufferCap)
	//
	if err = r.cmd.Start(); err != nil {
		panic(err) // system errors are reported as panics to distinguish them
	}
	waitopen := make(chan error, 1)
	go func() {
		// read open-file result from stderr
		scanner := bufio.NewScanner(stderr)
		for scanner.Scan() {
			switch scanner.Text() {
			case "ok":
				waitopen <- nil
			case "not exist":
				waitopen <- rh.ErrNotExist
			case "permission":
				waitopen <- rh.ErrPerm
			default:
				waitopen <- fmt.Errorf("helper says: %s", scanner.Text())
			}
			break
		}
		r.cmd.Wait()
	}()
	select {
	case <-intr:
		r.cmd.Process.Kill()
		return nil, rh.ErrIntr
	case err := <-waitopen:
		if err != nil {
			r.cmd.Process.Kill()
			return nil, err
		}
		// Kill helper process on garbage collection
		runtime.SetFinalizer(r, 
			func(r2 *FileReader) { 
				r2.Close()
			},
		)
		return r, nil
	}
}
// OpenFileReader tries to open the named file for reading, potentially blocking for a while.
OpenFileReader tries to open the named file for reading, potentially blocking for a while.
// OpenFileReader tries to open the named file for reading potentially blocking for a while .
func OpenFileReader(name string, intr rh.Intr) (r *FileReader, err error) {
	r = &FileReader{
		cmd: exec.Command(helper.LookupExecutable(), "-sysread", path.Clean(name)),
	}
	stderr, err := r.cmd.StderrPipe()
	if err != nil {
		panic(err) 
	}
	r.stdin, err = r.cmd.StdinPipe()
	if err != nil {
		panic(err) 
	}
	r.ir, r.cmd.Stdout = interruptible.BufferPipe(bufferCap)
	if err = r.cmd.Start(); err != nil {
		panic(err) s are reported as panics to distinguish them
	}
	waitopen := make(chan error, 1)
	go func() {
		 read open-file result from stderr
		scanner := bufio.NewScanner(stderr)
		for scanner.Scan() {
			switch scanner.Text() {
			case "ok":
				waitopen <- nil
			case "not exist":
				waitopen <- rh.ErrNotExist
			case "permission":
				waitopen <- rh.ErrPerm
			default:
				waitopen <- fmt.Errorf("helper says: %s", scanner.Text())
			}
			break
		}
		r.cmd.Wait()
	}()
	select {
	case <-intr:
		r.cmd.Process.Kill()
		return nil, rh.ErrIntr
	case err := <-waitopen:
		if err != nil {
			r.cmd.Process.Kill()
			return nil, err
		}
		 Kill helper process on garbage collection
		runtime.SetFinalizer(r, 
			func(r2 *FileReader) { 
				r2.Close()
			},
		)
		return r, nil
	}
}
func OpenFileReader ( name string , intr rh . Intr ) ( r * FileReader , err error ) { r = & FileReader { cmd : exec . Command ( helper . LookupExecutable ( ) , " " , path . Clean ( name ) ) , } stderr , err := r . cmd . StderrPipe ( ) if err != nil { panic ( err ) } r . stdin , err = r . cmd . StdinPipe ( ) if err != nil { panic ( err ) } r . ir , r . cmd . Stdout = interruptible . BufferPipe ( bufferCap ) if err = r . cmd . Start ( ) ; err != nil { panic ( err ) } waitopen := make ( chan error , 1 ) go func ( ) { scanner := bufio . NewScanner ( stderr ) for scanner . Scan ( ) { switch scanner . Text ( ) { case " " : waitopen <- nil case " " : waitopen <- rh . ErrNotExist case " " : waitopen <- rh . ErrPerm default : waitopen <- fmt . Errorf ( " " , scanner . Text ( ) ) } break } r . cmd . Wait ( ) } ( ) select { case <- intr : r . cmd . Process . Kill ( ) return nil , rh . ErrIntr case err := <- waitopen : if err != nil { r . cmd . Process . Kill ( ) return nil , err } runtime . SetFinalizer ( r , func ( r2 * FileReader ) { r2 . Close ( ) } , ) return r , nil } }
OpenFileReader tries to open the named file for reading, potentially blocking for a while.
OpenFileReader tries to open the named file for reading potentially blocking for a while .
// the helper process communicates control messages back to us on stderr // system error // system error // stdout is the reading channel // // system errors are reported as panics to distinguish them // read open-file result from stderr // Kill helper process on garbage collection