Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!husc6!think!ames!ucbcad!ucbvax!decvax!decwrl!pyramid!prls!mips!dce
From: dce@mips.UUCP (David Elliott)
Newsgroups: comp.bugs.4bsd
Subject: 4.3BSD rcp doesn't handle FIFO files nicely
Message-ID: <520@quacky.UUCP>
Date: Wed, 15-Jul-87 18:47:10 EDT
Article-I.D.: quacky.520
Posted: Wed Jul 15 18:47:10 1987
Date-Received: Sat, 18-Jul-87 03:54:20 EDT
Distribution: world
Organization: MIPS Computer Systems, Sunnyvale, CA
Lines: 91

Index:	bin/rcp.c 4.3BSD

Description:
	Before you go yelling at me about FIFO files not being in
	4.3, this came about as a result of porting the 4.3 rcp
	to our System V.3-based system that has BSD TCP/IP.

	Rcp checks source file types by doing an open() followed by
	an fstat(). Since FIFO files block on open if there is no
	process on the other side, the rcp just hangs forever.

Repeat-By:
	Get on a system with FIFO files and rcp (which, according
	to an AT&T marketing person I met a couple of years ago,
	is any Unix system, though we know better) and try

		rcp fifo-file machine:

Fix:
	The easiest fix is to just not allow rcp of FIFO files, even
	though it's really a hard call to make. We decided that it's
	better to force someone to work around the restriction than
	to have a naive user get stung by a hung "rcp * machine:".

	I did this by changing rcp to do a stat() followed by an open()
	instead of the open()-fstat() sequence.

	The following can be used to patch rcp.c:


*** rcp.c.old
--- rcp.c
***************
*** 367,378 ****
  
  	for (x = 0; x < argc; x++) {
  		name = argv[x];
! 		if ((f = open(name, 0)) < 0) {
  			error("rcp: %s: %s\n", name, sys_errlist[errno]);
  			continue;
  		}
- 		if (fstat(f, &stb) < 0)
- 			goto notreg;
  		switch (stb.st_mode&S_IFMT) {
  
  		case S_IFREG:
--- 367,376 ----
  
  	for (x = 0; x < argc; x++) {
  		name = argv[x];
! 		if (stat(name, &stb) < 0) {
  			error("rcp: %s: %s\n", name, sys_errlist[errno]);
  			continue;
  		}
  		switch (stb.st_mode&S_IFMT) {
  
  		case S_IFREG:
***************
*** 380,386 ****
  
  		case S_IFDIR:
  			if (iamrecursive) {
- 				(void) close(f);
  				rsource(name, &stb);
  				continue;
  			}
--- 378,383 ----
***************
*** 387,394 ****
  			/* fall into ... */
  		default:
  notreg:
- 			(void) close(f);
  			error("rcp: %s: not a plain file\n", name);
  			continue;
  		}
  		last = rindex(name, '/');
--- 384,394 ----
  			/* fall into ... */
  		default:
  notreg:
  			error("rcp: %s: not a plain file\n", name);
+ 			continue;
+ 		}
+ 		if ((f = open(name, 0)) < 0) {
+ 			error("rcp: %s: %s\n", name, sys_errlist[errno]);
  			continue;
  		}
  		last = rindex(name, '/');
-- 
David Elliott		{decvax,ucbvax,ihnp4}!decwrl!mips!dce