Subject: Cygwin RCS Build Instructions (or sometimes ash does not like a.out)
From: Jason Tishler <[email-masked]>
To: Cygwin <[email-masked]>
Cc: Steve Kelem <[email-masked]>, John Green <[email-masked]>, Andre Oliveira da Costa <[email-masked]>, "Sagar R. Shah" <[email-masked]>
Date: Thu, 12 Oct 2000 10:27:45 -0400

I believe that I finally got to the bottom of why there are problems
building RCS on Cygwin.  It boils down to an idiosyncrasy of ash which
can be demonstrating by the following:

    $ cd /tmp
    $ cp /usr/bin/id.exe a.out
    $ sh -c ./a.out
    ./a.out: not found

Hence, ash will not execute programs when their full path is specified
and they don't end in ".exe".

The above behavior was causing RCS's src/conf.sh to fail because it
builds a.out files and attempts to run them via sh (i.e., ash) as
"./a.out".  Hence, conf.sh would get confused and finally abort.

My guess is that Andre did not experience the above because his /bin/sh
was really bash and not ash.

The following is my Cygwin RCS build procedure:

1. tar -xzvf rcs-5.7.tar.gz

2. cd rcs-5.7

3. patch -p1 <rcs-5.7-cygwin-1.patch

4. patch -p1 <rcs-5.7-cygwin-2.patch

5. configure

6. make

7. make install

8. make installcheck

Notes:

1. See attachments for the above patches.

2. rcs-5.7-cygwin-1.patch is identical to the one that Andre Oliveira
da Costa posted in:

   http://sources.redhat.com/ml/cygwin/2000-08/msg00618.html.

3. There are alternatives to using rcs-5.7-cygwin-2.patch:

   a. (temporarily) replace ash with bash (i.e., cp /bin/bash /bin/sh)
   b. fiddle with "mount -x" so that "sh -c ./a.out" works as expected

4. make installcheck did not report any errors.  But, unfortunately the
way that it was written required me to run it after make install and
not before as one would expect.

Jason

-- 
Jason Tishler
Director, Software Engineering       Phone: +1 (732) 264-8770 x235
Dot Hill Systems Corporation         Fax:   +1 (732) 264-8798
82 Bethany Road, Suite 7             Email: [email-masked]
Hazlet, NJ 07730 USA                 WWW:   http://www.dothill.com

#  patches rcs-5.7 to work with cygwin b19/20/20.1
#  doesn't break the configure script for other systems
#  To apply: cd rcs-5.7 ; patch -p 1 -i rcs-5.7-cygwinb20.patchb

diff -rc rcs-5.7/src/conf.sh rcs-5.7-good/src/conf.sh
*** rcs-5.7/src/conf.sh	Mon Nov 15 07:17:49 1999
--- rcs-5.7-good/src/conf.sh	Mon Nov 15 08:49:40 1999
***************
*** 311,325 ****
  # We must do has_readlink next, because it might generate
  # #include directives that affect later definitions.
  
! $ech >&3 "$0: configuring has_readlink, readlink_isreg_errno $dots"
  cat >a.c <<EOF
  #include "$A_H"
  static char b[7];
  int
! main() {
  	if (readlink("a.sym2",b,7) == 6  &&  strcmp(b,"a.sym1") == 0  &&
  		readlink("a.c",b,7) == -1  &&  errno != ENOENT
  	) {
  		if (errno == EINVAL)
  			printf("EINVAL\n");
  		else
--- 311,338 ----
  # We must do has_readlink next, because it might generate
  # #include directives that affect later definitions.
  
! $ech >&3 "$0: configuring has_readlink, readlink_isreg_errno, bad_readlink_enoent $dots"
  cat >a.c <<EOF
  #include "$A_H"
  static char b[7];
  int
! main(argc, argv) int argc; char **argv; {
  	if (readlink("a.sym2",b,7) == 6  &&  strcmp(b,"a.sym1") == 0  &&
  		readlink("a.c",b,7) == -1  &&  errno != ENOENT
  	) {
+ 		/*
+ 		* test for readlink returning same errno for
+ 		* regular files and non-existent files
+ 		*/
+ 		if (1 < argc) {
+ 			int e=errno;
+ 			readlink("a.sym3",b,7);
+ 			if( errno==e )
+ 				printf( "1\n" );
+ 			else
+ 				printf( "0\n" );
+ 			exitmain(ferror(stdout) || fclose(stdout)!=0);
+ 		}
  		if (errno == EINVAL)
  			printf("EINVAL\n");
  		else
***************
*** 335,343 ****
  then h=1
  else h=0
  fi
! echo >&3 $h, $readlink_isreg_errno
  cat <<EOF
  #define has_readlink $h /* Does readlink() work?  */
  #define readlink_isreg_errno $readlink_isreg_errno /* errno after readlink on regular file */
  
  #if has_readlink && !defined(MAXSYMLINKS)
--- 348,361 ----
  then h=1
  else h=0
  fi
! case $h in
! 1) bh=`$aout t`;;
! *) bh=0;;
! esac
! echo >&3 $h, $readlink_isreg_errno, $bh
  cat <<EOF
  #define has_readlink $h /* Does readlink() work?  */
+ #define bad_readlink_enoent $bh /* Does readlink() return ENOENT correctly?  */
  #define readlink_isreg_errno $readlink_isreg_errno /* errno after readlink on regular file */
  
  #if has_readlink && !defined(MAXSYMLINKS)
***************
*** 1053,1059 ****
  		# when someone unexpectedly truncates a file
  		# while RCS has it mmapped.
  		rm -f a.e && cp a.c a.e &&
! 		mmap_signal=`$aout a.e <a.e` || exit
  	esac
  esac
  echo >&3 $has_map_fd, $has_mmap, $has_madvise, $mmap_signal
--- 1071,1077 ----
  		# when someone unexpectedly truncates a file
  		# while RCS has it mmapped.
  		rm -f a.e && cp a.c a.e &&
! 		mmap_signal=`$aout a.e <a.e` || mmap_signal=
  	esac
  esac
  echo >&3 $has_map_fd, $has_mmap, $has_madvise, $mmap_signal
***************
*** 1103,1108 ****
--- 1121,1151 ----
  echo "#define bad_a_rename $a /* Does rename(A,B) fail if A is unwritable?  */"
  echo "#define bad_b_rename $b /* Does rename(A,B) fail if B is unwritable?  */"
  echo "#define bad_NFS_rename 0 /* Can rename(A,B) falsely report success?  */"
+ 
+ $ech >&3 "$0: configuring bad_nw_utime $dots"
+ cat >a.c <<EOF
+ #include "$A_H"
+ int main() {
+ 	static struct utimbuf amtime; /* static so unused fields are zero */
+ 	static time_t t;
+ 	time(&t);
+ 	amtime.actime = t;
+ 	amtime.modtime = t;
+ 	exitmain(utime("a.a",&amtime) != 0); }
+ EOF
+ if $CL a.c $L >&2
+ then
+ 	rm -f a.a &&
+ 	echo a >a.a && chmod -w a.a || exit
+ 	if $aout
+ 	then a=0
+ 	else a=1
+ 	fi
+ 	rm -f a.a || exit
+ else a=0
+ fi
+ echo >&3 $a
+ echo "#define bad_nw_utime $a /* Does utime() work on unwriteable files?  */"
  
  $ech >&3 "$0: configuring void, VOID $dots"
  cat >a.c <<EOF
diff -rc rcs-5.7/src/rcsedit.c rcs-5.7-good/src/rcsedit.c
*** rcs-5.7/src/rcsedit.c	Mon Nov 15 07:17:49 1999
--- rcs-5.7-good/src/rcsedit.c	Mon Nov 15 07:51:40 1999
***************
*** 1279,1285 ****
  	bufautoend(&bigbuf);
  	errno = e;
  	switch (e) {
! 	    case readlink_isreg_errno: return 1;
  	    case ENOENT: return 0;
  	    default: return -1;
  	}
--- 1279,1300 ----
  	bufautoend(&bigbuf);
  	errno = e;
  	switch (e) {
! 	    case readlink_isreg_errno:
! #			if bad_readlink_enoent
! 			/*
! 			* Cygwin32 betas 19 & 20 report EINVAL if the
! 			* file doesn't exist, instead of ENOENT.
! 			* Make sure the file really does exist.
! 			*/
! 			{
! 		 		struct stat st;
!  				if ( stat(L->string, &st) == 0 )
! 					/* File exists, but no symlink */
! 					return 1;
! 			}
! #			else
! 				return 1;
! #			endif
  	    case ENOENT: return 0;
  	    default: return -1;
  	}
***************
*** 1595,1601 ****
  	    }
  #	endif
  
! #	if bad_a_rename
  		/*
  		* There's a short window of inconsistency
  		* during which the lock file is writable.
--- 1610,1617 ----
  	    }
  #	endif
  
! 	if ( bad_a_rename || (bad_nw_utime && mtime!=-1) )
! 	{
  		/*
  		* There's a short window of inconsistency
  		* during which the lock file is writable.
***************
*** 1603,1609 ****
  		mode_while_renaming = mode|S_IWUSR;
  		if (mode != mode_while_renaming)
  		    set_mode = 1;
! #	endif
  
  #	if has_fchmod
  	    if (0<set_mode  &&  fchmod(fileno(*fromp),mode_while_renaming) == 0)
--- 1619,1625 ----
  		mode_while_renaming = mode|S_IWUSR;
  		if (mode != mode_while_renaming)
  		    set_mode = 1;
! 	}
  
  #	if has_fchmod
  	    if (0<set_mode  &&  fchmod(fileno(*fromp),mode_while_renaming) == 0)
***************
*** 1616,1621 ****
--- 1632,1647 ----
  
  	if (setmtime(from, mtime) != 0)
  		return -1;
+ 
+ 	/*
+ 	* if rename unwriteable works but utime unwriteable doesn't, we can
+ 	* change the mode back now.  Otherwise wait until after rename.
+ 	*/
+ 	if ( !bad_a_rename && (bad_nw_utime && mtime!=-1) )
+ 	{
+ 	    if (0 < set_mode  &&  chmod(from, mode) != 0)
+ 		return -1;
+ 	}
  
  #	if !has_rename || bad_b_rename
  		/*
diff -rc rcs-5.7/src/rcslex.c rcs-5.7-good/src/rcslex.c
*** rcs-5.7/src/rcslex.c	Mon Nov 15 07:17:49 1999
--- rcs-5.7-good/src/rcslex.c	Fri Nov 12 11:56:47 1999
***************
*** 1113,1119 ****
  /* Open NAME for reading, yield its descriptor, and set *STATUS.  */
  {
  	int fd = fdSafer(open(name, O_RDONLY
! #		if OPEN_O_BINARY
  			|  (strchr(type,'b') ? OPEN_O_BINARY : 0)
  #		endif
  	));
--- 1113,1119 ----
  /* Open NAME for reading, yield its descriptor, and set *STATUS.  */
  {
  	int fd = fdSafer(open(name, O_RDONLY
! #		if OPEN_O_BINARY && !(large_memory && maps_memory)
  			|  (strchr(type,'b') ? OPEN_O_BINARY : 0)
  #		endif
  	));
diff -upr rcs-5.7.orig/src/Makefile.in rcs-5.7/src/Makefile.in
--- rcs-5.7.orig/src/Makefile.in	Fri Jun 16 02:19:24 1995
+++ rcs-5.7/src/Makefile.in	Thu Oct 12 09:38:02 2000
@@ -128,7 +128,7 @@ RCSTEST = \
 	ALL_CFLAGS='$(ALL_CFLAGS)' CC='$(CC)' DIFF='$(DIFF)' \
 	LDFLAGS='$(LDFLAGS)' LIBS='$(LIBS)' \
 	PATH=$(bindir):$$PATH \
-	sh $(srcdir)/rcstest
+	bash $(srcdir)/rcstest
 installcheck ::
 	$(RCSTEST)
 installdebug ::
diff -upr rcs-5.7.orig/src/conf.sh rcs-5.7/src/conf.sh
--- rcs-5.7.orig/src/conf.sh	Fri Jun 16 02:19:24 1995
+++ rcs-5.7/src/conf.sh	Thu Oct 12 09:33:41 2000
@@ -47,7 +47,7 @@ Id='$Id: conf.sh,v 5.25 1995/06/16 06:19
 # : ${LDFLAGS=} ${LIBS=} tickles old shell bug
 
 C="$CC $ALL_CFLAGS"
-CL="$CC $ALL_CFLAGS $LDFLAGS -o a.out"
+CL="$CC $ALL_CFLAGS $LDFLAGS -o a.exe"
 L=$LIBS
 
 cat <<EOF

--
Want to unsubscribe from this list?
Send a message to [email-masked]