On Mon, Oct 05, 2015 at 10:07:21AM -0700, Philip Guenther wrote: > On Mon, Oct 5, 2015 at 6:54 AM, Kim Zeitler <kim.zeit...@konzept-is.de> wrote: > > I am trying to transfer a new firmware to a switch using cu(1) with XMODEM > > using a USB-to-RS232 adapter and running on -current. > > > > Connection works fine, but for the XMODEM resulting in 'Resource temporarily > > unavailable' > > > > $cu -d -l /dev/ttyU0 > > ... > > ~X > > Local file? /tmp/fw.swi > > cu: /tmp/fw.swi: Resource temporarily unavailable > > Tthe -d option makes cu open the tty with O_NONBLOCK so that it won't > block for carrier; perhaps it should be clearing the flag afterwards? > Hmm, no, it uses libevent, so maybe it should be *always* turning it > on xmodem_{read,write}() updated to use libevent too, or xmodem_send() > updated to explicitly mark it blocking during the transfer.
How about this? (Not tested as I don't have any serial cables around at the moment :-/) Index: command.c =================================================================== RCS file: /cvs/src/usr.bin/cu/command.c,v retrieving revision 1.14 diff -u -p -r1.14 command.c --- command.c 5 Oct 2015 17:53:56 -0000 1.14 +++ command.c 5 Oct 2015 17:56:14 -0000 @@ -51,6 +51,7 @@ pipe_command(void) return; restore_termios(); + set_blocking(line_fd, 1); switch (pid = fork()) { case -1: @@ -81,6 +82,7 @@ pipe_command(void) break; } + set_blocking(line_fd, 0); set_termios(); } @@ -102,6 +104,7 @@ connect_command(void) return; restore_termios(); + set_blocking(line_fd, 1); switch (pid = fork()) { case -1: @@ -129,6 +132,7 @@ connect_command(void) break; } + set_blocking(line_fd, 0); set_termios(); } Index: cu.c =================================================================== RCS file: /cvs/src/usr.bin/cu/cu.c,v retrieving revision 1.22 diff -u -p -r1.22 cu.c --- cu.c 18 May 2015 09:35:05 -0000 1.22 +++ cu.c 5 Oct 2015 17:56:14 -0000 @@ -186,6 +186,7 @@ main(int argc, char **argv) NULL); bufferevent_enable(output_ev, EV_WRITE); + set_blocking(line_fd, 0); line_ev = bufferevent_new(line_fd, line_read, NULL, line_error, NULL); bufferevent_enable(line_ev, EV_READ|EV_WRITE); @@ -209,6 +210,21 @@ signal_event(int fd, short events, void } void +set_blocking(int fd, int state) +{ + int mode; + + if ((mode = fcntl(fd, F_GETFL)) == -1) + cu_err(1, "fcntl"); + if (!state) + mode |= O_NONBLOCK; + else + mode &= ~O_NONBLOCK; + if (fcntl(fd, F_SETFL, mode) == -1) + cu_err(1, "fcntl"); +} + +void set_termios(void) { struct termios tio; @@ -342,7 +358,7 @@ try_remote(const char *host, const char if (entry != NULL && cgetset(entry) != 0) cu_errx(1, "cgetset failed"); - error = cgetent(&cp, (char**)paths, (char*)host); + error = cgetent(&cp, (char **)paths, (char *)host); if (error < 0) { switch (error) { case -1: Index: cu.h =================================================================== RCS file: /cvs/src/usr.bin/cu/cu.h,v retrieving revision 1.6 diff -u -p -r1.6 cu.h --- cu.h 10 Jul 2012 12:47:23 -0000 1.6 +++ cu.h 5 Oct 2015 17:56:14 -0000 @@ -27,6 +27,7 @@ extern FILE *record_file; extern struct termios saved_tio; extern int line_fd; extern struct bufferevent *line_ev; +void set_blocking(int, int); int set_line(int); void set_termios(void); void restore_termios(void); Index: xmodem.c =================================================================== RCS file: /cvs/src/usr.bin/cu/xmodem.c,v retrieving revision 1.7 diff -u -p -r1.7 xmodem.c --- xmodem.c 21 Sep 2014 05:29:47 -0000 1.7 +++ xmodem.c 5 Oct 2015 17:56:14 -0000 @@ -137,8 +137,9 @@ xmodem_send(const char *file) if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio) != 0) cu_err(1, "tcsetattr"); } - + set_blocking(line_fd, 1); tcflush(line_fd, TCIFLUSH); + if (xmodem_read(&c) != 0) goto fail; if (c == XMODEM_C) @@ -214,6 +215,7 @@ fail: cu_warn("%s", file); out: + set_blocking(line_fd, 0); set_termios(); sigaction(SIGINT, &oact, NULL);