def Run(self, cmd_val): # type: (cmd_value__Argv) -> int attrs, arg_r = flag_spec.ParseCmdVal('read', cmd_val) arg = arg_types.read(attrs.attrs) names = arg_r.Rest() fd = self.stdin.fileno() if arg.t >= 0.0: if arg.t != 0.0: e_die("read -t isn't implemented (except t=0)") else: return 0 if pyos.InputAvailable(fd) else 1 bits = 0 if self.stdin.isatty(): bits |= pyos.TERM_ICANON if arg.s: # silent bits |= pyos.TERM_ECHO if arg.p is not None: # only if tty mylib.Stderr().write(arg.p) if bits == 0: status = self._Read(arg, names) else: term = pyos.TermState(fd, ~bits) try: status = self._Read(arg, names) finally: term.Restore() return status
def Run(self, cmd_val): # type: (cmd_value__Argv) -> int attrs, arg_r = flag_spec.ParseCmdVal('read', cmd_val) arg = arg_types.read(attrs.attrs) names = arg_r.Rest() if arg.n >= 0: # read a certain number of bytes (-1 means unset) if len(names): name = names[0] else: name = 'REPLY' # default variable name status = 0 stdin_fd = self.stdin.fileno() if self.stdin.isatty(): # set stdin to read in unbuffered mode s = passwd.ReadBytesFromTerminal(stdin_fd, arg.n) else: chunks = [] # type: List[str] n = arg.n while n > 0: chunk = posix.read(stdin_fd, n) # read at up to N chars if len(chunk) == 0: break chunks.append(chunk) n -= len(chunk) s = ''.join(chunks) # DIdn't read all the bytes we wanted if len(s) != n: status = 1 state.SetStringDynamic(self.mem, name, s) # NOTE: Even if we don't get n bytes back, there is no error? return status if len(names) == 0: names.append('REPLY') # leftover words assigned to the last name if arg.a is not None: max_results = 0 # no max else: max_results = len(names) if arg.d is not None: if len(arg.d): delim_char = arg.d[0] else: delim_char = '\0' # -d '' delimits by NUL else: delim_char = '\n' # read a line # We have to read more than one line if there is a line continuation (and # it's not -r). parts = [] # type: List[mylib.BufWriter] join_next = False status = 0 while True: line, eof = ReadLineFromStdin(delim_char) if eof: # status 1 to terminate loop. (This is true even though we set # variables). status = 1 #log('LINE %r', line) if len(line) == 0: break spans = self.splitter.SplitForRead(line, not arg.r) done, join_next = _AppendParts(line, spans, max_results, join_next, parts) #log('PARTS %s continued %s', parts, continued) if done: break entries = [buf.getvalue() for buf in parts] num_parts = len(entries) if arg.a is not None: state.SetArrayDynamic(self.mem, arg.a, entries) else: for i in xrange(max_results): if i < num_parts: s = entries[i] else: s = '' # if there are too many variables #log('read: %s = %s', names[i], s) state.SetStringDynamic(self.mem, names[i], s) return status
def Run(self, cmd_val): # type: (cmd_value__Argv) -> int attrs, arg_r = flag_spec.ParseCmdVal('read', cmd_val) arg = arg_types.read(attrs.attrs) names = arg_r.Rest() # Don't respect any of the other options here? This is buffered I/O. if arg.line: # read --line var_name, var_spid = arg_r.Peek2() if var_name is None: var_name = '_line' else: if var_name.startswith(':'): # optional : sigil var_name = var_name[1:] arg_r.Next() next_arg, next_spid = arg_r.Peek2() if next_arg is not None: raise error.Usage('got extra argument', span_id=next_spid) return self._Line(arg, var_name) if arg.q: e_usage('--qsn can only be used with --line') if arg.all: # read --all var_name, var_spid = arg_r.Peek2() if var_name is None: var_name = '_all' else: if var_name.startswith(':'): # optional : sigil var_name = var_name[1:] arg_r.Next() next_arg, next_spid = arg_r.Peek2() if next_arg is not None: raise error.Usage('got extra argument', span_id=next_spid) return self._All(var_name) if arg.q: e_usage('--qsn not implemented yet') fd = self.stdin.fileno() if arg.t >= 0.0: if arg.t != 0.0: e_die("read -t isn't implemented (except t=0)") else: return 0 if pyos.InputAvailable(fd) else 1 bits = 0 if self.stdin.isatty(): bits |= pyos.TERM_ICANON if arg.s: # silent bits |= pyos.TERM_ECHO if arg.p is not None: # only if tty mylib.Stderr().write(arg.p) if bits == 0: status = self._Read(arg, names) else: term = pyos.TermState(fd, ~bits) try: status = self._Read(arg, names) finally: term.Restore() return status