delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/07/28/13:33:29

Message-Id: <200007281731.UAA10498@mailgw1.netvision.net.il>
Date: Fri, 28 Jul 2000 20:30:22 +0200
To: Bruce Korb <bkorb AT sco DOT COM>
X-Mailer: Emacs 20.6 (via feedmail 8.2.emacs20_6 I) and Blat ver 1.8.5b
From: "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
CC: djgpp-workers AT delorie DOT com
In-reply-to: <397DCC3F.32D9BB7C@sco.com> (message from Bruce Korb on Tue, 25
Jul 2000 10:19:59 -0700)
Subject: Re: DJGPP patch for fixincludes
References: <397DCC3F DOT 32D9BB7C AT sco DOT com>
Reply-To: djgpp-workers AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

> Date: Tue, 25 Jul 2000 10:19:59 -0700
> From: Bruce Korb <bkorb AT sco DOT COM>
> 
> Good luck and feel free to write  :-).

Okay, I have a first working version of fixincl and applyfix programs.
The patches are attached below; they should be applied *after* the
patches posted by Bruce here a few days ago.  (If someone wants diffs
agains the current CVS, I can do that, too.)

These patches don't include any changes to fixinc/Makefile.in.  Since
the programs built for Unix and DOS are now different, I didn't make
any changes in Makefile.in; instead, I simply threw together a
Makefile by editing Makefile.in manually.  Bruce, please let me know
if you would like me to do something about Makefile.in.

I tested the programs by running the fixinc.sh script on the DJGPP
include directory.  The utility of this testing is limited, since
inclhack.def doesn't have any DJGPP-specific fixes.  But some of the
tests catch all platforms, and they did get run and allowed to test
both internal and external fix methods.  The result was that none of
the DJGPP headers were changed in any way (one more sign that the
programs DTRT ;-)

(I did see some of the headers being ``fixed''--due to bugs--while
working on this.  So it seems that when the program decides it needs
to edit a header, it does that correctly.)

Nevertheless, I think it might be a good idea to come up with
DJGPP-specific fixes and actually run them.  Does someone have ideas
for such fixes?  DJ?

Well, enough talking; let the code talk now ;-)


2000-07-28  Eli Zaretskii  <eliz AT is DOT elta DOT co DOT il>

	* fixinc/fixfixes.c (main) [__MSDOS__]: Avoid overwriting the
	output file with the temporary one by appending ".X" to generate
	the temporary fuile's name.  If the output file already has an
	extension, replace it with ".X".

	* fixinc/fixincl.c (fix_with_system) [__MSDOS__]: Use $ORIGDIR,
	not $DESTDIR, to find applyfix.  Use sprintf instead of snprintf;
	reallocate the command buffer while copying the command-line
	argument.  Redirect the output directly to the temporary file,
	instead of going through another temporary file.
	(process): Close the temporary file before unlinking it.
	(machine_matches) [__MSDOS__]: If the machine doesn't match, set
	the FD_SKIP_TEST flag.  Pay attention to the FD_MACH_IFNOT flag.
	(run_compiles): Pass p_fixd argument to machine_matches, as it
	expects.

	* fixinc/fixincl.sh: Export ORIGDIR.  If $DJDIR is set in the
	environment, assume there are no symlinks in the include
	directory.  When cleaning up the DONE files, look for them
	case-insensitively.  Don't try to remove symlinks if they aren't
	there.

	* fixinc/fixlib.c (make_raw_shell_str): Accept new argument smax;
	all callers changed.  Declare pz "const char *", to avoid compiler
	warnings.

	* fixinc/fixlib.h (ENV_TABLE): Get ORIGDIR from the environment.
	Change prototype of make_raw_shell_str.

2000-07-27  Eli Zaretskii  <eliz AT is DOT elta DOT co DOT il>

	* fixinc/fixincl.c [__MSDOS__]: Don't include "server.h".
	(initialize) [__MSDOS__]: Use tempnam.
	(initialize): Don't use SIGPIPE if it is not defined.

	* fixinc/fixfixes.c (main) [__MSDOS__]: freopen for stdout should
	return stdout.


--- fixinc/fixlib.c~0	Thu Jul 27 20:53:42 2000
+++ fixinc/fixlib.c	Fri Jul 28 13:37:16 2000
@@ -247,20 +247,24 @@
 #endif
 
 
-#ifdef __DOS__
+#ifdef __MSDOS__
 
 char*
-make_raw_shell_str( pz_d, pz_s )
+make_raw_shell_str( pz_d, pz_s, smax )
   char*       pz_d;
   tCC*        pz_s;
+  size_t      smax;
 {
   tSCC zQ[] = "'\\''";
   size_t     dtaSize;
+  char*      pz_d_start = pz_d;
+
+  smax--; /* adjust for trailing NUL */
 
   dtaSize = strlen( pz_s ) + 3;
 
   {
-    char* pz = pz_s - 1;
+    const char* pz = pz_s - 1;
 
     for (;;) {
       pz = strchr( pz+1, '\'' );
@@ -269,15 +273,21 @@
       dtaSize += sizeof( zQ )-1;
     }
   }
+  if (dtaSize > smax)
+    return (char*)NULL;
 
   *(pz_d++) = '\'';
 
   for (;;) {
+    if (pz_d - pz_d_start >= smax)
+      return (char*)NULL;
     switch (*(pz_d++) = *(pz_s++)) {
     case NUL:
       goto loopDone;
 
     case '\'':
+      if (pz_d - pz_d_start >= smax - sizeof( zQ )-1)
+	return (char*)NULL;
       strcpy( pz_d-1, zQ );
       pz_d += sizeof( zQ )-2;
     }
--- fixinc/fixlib.h~0	Thu Jul 27 21:54:12 2000
+++ fixinc/fixlib.h	Fri Jul 28 13:45:20 2000
@@ -100,6 +100,9 @@
   _ENV_( pz_machine,   BOOL_TRUE, "TARGET_MACHINE",  \
          "output from config.guess" )                \
                                                      \
+  _ENV_( pz_orig_dir,  BOOL_TRUE, "ORIGDIR",         \
+         "directory of fixincl and applyfix" )       \
+                                                     \
   _ENV_( pz_src_dir,   BOOL_TRUE, "SRCDIR",          \
          "directory of original files" )             \
                                                      \
@@ -204,8 +207,8 @@
 void apply_fix _P_(( tFixDesc* p_fixd, tCC* filname ));
 apply_fix_p_t run_test _P_((tCC* t_name, tCC* f_name, tCC* text ));
 
-#ifdef __DOS__
-char* make_raw_shell_str _P_(( char* pz_d, tCC* pz_s ));
+#ifdef __MSDOS__
+char* make_raw_shell_str _P_(( char* pz_d, tCC* pz_s, size_t smax ));
 #endif
 
 #ifdef MN_NAME_PAT
--- fixinc/fixfixes.c~1	Thu Jul 27 20:53:42 2000
+++ fixinc/fixfixes.c	Fri Jul 28 19:05:18 2000
@@ -60,7 +60,7 @@
 #include "fixlib.h"
 #define    GTYPE_SE_CT 1
 
-#ifdef __DOS__
+#ifdef __MSDOS__
 #include "fixincl.x"
 #endif
 
@@ -730,7 +730,7 @@
   (*pfe->fix_proc)( filname, buf, p_fixd );
 }
 
-#ifdef __DOS__
+#ifdef __MSDOS__
 tSCC z_usage[] =
 "USAGE: applyfix <fix-name> <file-to-fix> <file-source> <file-destination>\n";
 tSCC z_reopen[] =
@@ -743,6 +743,8 @@
 {
   tFixDesc* pFix;
   char* pz_tmptmp;
+  char* pz_tmp_base;
+  char* pz_tmp_dot;
 
   if (argc != 5)
     {
@@ -771,8 +773,19 @@
     }
 
   pz_tmptmp = (char*)xmalloc( strlen( argv[4] ) + 5 );
-  sprintf( pz_tmptmp, "%sX", argv[4] );
-  if (freopen( pz_tmptmp, "w", stdout ) != stdin)
+  strcpy( pz_tmptmp, argv[4] );
+
+  /* Don't lose because "12345678" and "12345678X" map to the same
+     file under DOS restricted 8+3 file namespace.  Note that DOS
+     doesn't allow more than one dot in the trunk of a file name.  */
+  pz_tmp_base = basename( pz_tmptmp );
+  pz_tmp_dot = strchr( pz_tmp_base, '.' );
+  if (pathconf( pz_tmptmp, _PC_NAME_MAX ) <= 12	/* is this DOS or Windows9X? */
+      && pz_tmp_dot != (char*)NULL)
+    strcpy( pz_tmp_dot+1, "X" ); /* nuke the original extension */
+  else
+    strcat( pz_tmptmp, ".X" );
+  if (freopen( pz_tmptmp, "w", stdout ) != stdout)
     {
       fprintf( stderr, z_reopen, errno, strerror( errno ), pz_tmptmp, "out" );
       return EXIT_FAILURE;
--- fixinc/fixincl.c~1	Thu Jul 27 20:59:30 2000
+++ fixinc/fixincl.c	Fri Jul 28 19:26:08 2000
@@ -30,7 +30,7 @@
 #endif
 
 #include <signal.h>
-#ifndef __DOS__
+#ifndef __MSDOS__
 #include "server.h"
 #endif
 
@@ -182,7 +182,7 @@
   }
 #endif /* DO_STATS */
 
-# ifdef __DOS__
+# ifdef __MSDOS__
   unlink( pz_temp_file );
 # endif
   return EXIT_SUCCESS;
@@ -202,7 +202,7 @@
   */
   run_compiles ();
   sprintf (zBuf, zFmt, program_id);
-#ifndef __DOS__
+#ifndef __MSDOS__
   puts (zBuf + 5);
   exit (strcmp (run_shell (zBuf), program_id));
 #else
@@ -298,22 +298,19 @@
       */
   run_compiles ();
 
-# ifdef __DOS__
-  {
-    tSCC z_tmp_fname_fmt[] = "%s/fxinc%03X.tp";
-    char* pz = getenv( "TMP" );
-    if (pz == NULL)
-      pz = "/tmp";
-    pz_temp_file = (char*)xmalloc (sizeof(z_tmp_fname_fmt) + strlen (pz));
-    sprintf (pz_temp_file, z_tmp_fname_fmt, pz, getpid() & 0x0FFF);
-  }
+# ifdef __MSDOS__
+  /* NULL as the first argument to `tempnam' causes it to DTRT
+     wrt the temporary directory where the file will be created.  */
+  pz_temp_file = tempnam( NULL, "fxinc" );
 # endif
 
   signal (SIGQUIT, SIG_IGN);
 #ifdef SIGIOT
   signal (SIGIOT,  SIG_IGN);
 #endif
+#ifdef SIGPIPE
   signal (SIGPIPE, SIG_IGN);
+#endif
   signal (SIGALRM, SIG_IGN);
   signal (SIGTERM, SIG_IGN);
 }
@@ -374,7 +371,7 @@
 machine_matches( p_fixd )
   tFixDesc *p_fixd;
         {
-# ifndef __DOS__
+# ifndef __MSDOS__
           tSCC case_fmt[] = "case %s in\n";     /*  9 bytes, plus string */
           tSCC esac_fmt[] =
                " )\n    echo %s ;;\n* ) echo %s ;;\nesac";/*  4 bytes */
@@ -436,26 +433,25 @@
             if (skip)
               {
                 p_fixd->fd_flags |= FD_SKIP_TEST;
-        return BOOL_FALSE;
-      }
-  }
+		return BOOL_FALSE;
+	      }
+	  }
 
   return BOOL_TRUE;
-# else /* is __DOS__ */
+# else /* is __MSDOS__ */
   const char **papz_machs = p_fixd->papz_machs;
+  int invert = (p_fixd->fd_flags & FD_MACH_IFNOT) != 0;
   for (;;)
     {
       const char* pz_mach = *(papz_machs++);
 
       if (pz_mach == (const char*) NULL)
         break;
-      if (strstr (pz_mach, "dos") != NULL)
-        {
-          p_fixd->fd_flags |= FD_SKIP_TEST;
-          return BOOL_TRUE;
-              }
-           }
+      if (strstr (pz_mach, "dos") != NULL && !invert)
+	return BOOL_TRUE;
+    }
 
+  p_fixd->fd_flags |= FD_SKIP_TEST;
   return BOOL_FALSE;
 # endif
 }
@@ -476,7 +472,7 @@
       fprintf (stderr, "fixincl ERROR:  cannot allocate %d bytes for regex\n",
                REGEX_COUNT * sizeof (regex_t));
       exit (EXIT_FAILURE);
-        }
+    }
 
   /*  Make sure compile_re does not stumble across invalid data */
 
@@ -503,7 +499,7 @@
 
       if (  (pz_machine != NULL)
          && (p_fixd->papz_machs != (const char**) NULL)
-         && ! machine_matches () )
+         && ! machine_matches (p_fixd) )
         continue;
 
       /* FOR every test for the fixup, ...  */
@@ -611,7 +607,7 @@
           the name of the file that we might want to fix
   Result: APPLY_FIX or SKIP_FIX, depending on the result of the
           shell script we run.  */
-#ifndef __DOS__
+#ifndef __MSDOS__
 int
 test_test (p_test, pz_test_file)
      tTestDesc *p_test;
@@ -767,7 +763,7 @@
       /*  Skip forward to the included file name */
       while (ISSPACE (*pz_incl_quot))
         pz_incl_quot++;
-      /* ISSPACE() may evaluate is argument more than once!  */
+      /* ISSPACE() may evaluate its argument more than once!  */
       while (++pz_incl_quot, ISSPACE (*pz_incl_quot))
         ;
       pz_incl_quot += sizeof ("include") - 1;
@@ -806,7 +802,7 @@
 
     Somebody wrote a *_fix subroutine that we must call.
     */
-#ifndef __DOS__
+#ifndef __MSDOS__
 int
 internal_fix (read_fd, p_fixd)
   int read_fd;
@@ -872,10 +868,10 @@
   apply_fix (p_fixd, pz_curr_file);
   exit (0);
 }
-#endif
+#endif /* !__MSDOS__ */
 
 
-#ifdef __DOS__
+#ifdef __MSDOS__
 static void
 fix_with_system (p_fixd, pz_fix_file, pz_file_source, pz_temp_file)
   tFixDesc* p_fixd;
@@ -889,10 +885,10 @@
 
   if (p_fixd->fd_flags & FD_SUBROUTINE)
     {
-      tSCC z_applyfix_prog = "fixinc/applyfix";
+      tSCC z_applyfix_prog[] = "/fixinc/applyfix";
 
       argsize = 32
-              + strlen( pz_dest_dir )
+              + strlen( pz_orig_dir )
               + sizeof( z_applyfix_prog )
               + strlen( pz_fix_file )
               + strlen( pz_file_source )
@@ -900,26 +896,34 @@
 
       pz_cmd = (char*)xmalloc( argsize );
 
-      strcpy( pz_cmd, pz_dest_dir );
-      pz_scan = strrchr( pz_cmd, '/' );
-      strcpy( pz_scan+1, z_applyfix_prog );
-      pz_scan += sizeof( z_applyfix_prog );
+      strcpy( pz_cmd, pz_orig_dir );
+      pz_scan = pz_cmd + strlen( pz_orig_dir );
+      strcpy( pz_scan, z_applyfix_prog );
+      pz_scan += sizeof( z_applyfix_prog ) - 1;
       *(pz_scan++) = ' ';
 
       /*
        *  Now add the fix number and file names that may be needed
        */
-      snprintf (pz_scan, argsize - (pz_scan - pz_cmd),
-                "%d %s %s %s", fixDescList - p_fixd,
-                pz_fix_file, pz_file_source, pz_temp_file);
+      sprintf (pz_scan, "%ld %s %s %s", p_fixd - fixDescList,
+	       pz_fix_file, pz_file_source, pz_temp_file);
     }
   else /* NOT an "internal" fix: */
     {
-      tSCC   z_cmd_fmt[] = " %s > %sX\nrm -f %s\nmv -f %sX %s";
+      size_t parg_size;
+      /* Don't use the "src > dstX; rm -f dst; mv -f dstX dst" trick:
+	 dst is a temporary file anyway, so we know there's no other
+	 file by that name; and DOS's system(3) doesn't mind to
+	 clobber existing file in redirection.  Besides, with DOS 8+3
+	 limited file namespace, we can easily lose if dst already has
+	 an extension that is 3 or more characters long.  */
+      tSCC   z_cmd_fmt[] = " %s > %s";
       tCC**  ppArgs = p_fixd->patch_args;
 
-      argsize = sizeof( z_cmd_fmt ) + 4 * strlen( pz_temp_file )
+      argsize = sizeof( z_cmd_fmt ) + strlen( pz_temp_file )
               + strlen( pz_file_source );
+      parg_size = argsize;
+      
 
       /*
        *  Compute the size of the command line.  Add lotsa extra space
@@ -936,7 +940,12 @@
           argsize += 24 + strlen( p_arg );
         }
 
+      /* Estimated buffer size we will need.  */
       pz_scan = pz_cmd = (char*)xmalloc( argsize );
+      /* How much of it do we allot to the program name and its
+         arguments.  */
+      parg_size = argsize - parg_size;
+
       ppArgs = p_fixd->patch_args;
 
       /*
@@ -959,19 +968,31 @@
       for (;;)
         {
           tCC*   pArg = *(ppArgs++);
+	  char*  pz_scan_save;
           if (pArg == NULL)
             break;
           *(pz_scan++) = ' ';
-          pz_scan = make_raw_shell_str( pz_scan, pArg );
+          pz_scan = make_raw_shell_str( pz_scan_save = pz_scan, pArg,
+					parg_size - (pz_scan - pz_cmd) );
+	  /*
+	   *  Make sure we don't overflow the buffer due to sloppy
+	   *  size estimation.
+	   */
+	  while (pz_scan == (char*)NULL)
+	    {
+	      size_t already_filled = pz_scan_save - pz_cmd;
+	      pz_cmd = (char*)xrealloc( pz_cmd, argsize += 100 );
+	      pz_scan_save = pz_scan = pz_cmd + already_filled;
+	      parg_size += 100;
+	      pz_scan = make_raw_shell_str( pz_scan, pArg,
+					    parg_size - (pz_scan - pz_cmd) );
+	    }
         }
 
       /*
-       *  add the file machinations.  Make sure we don't overflow
-       *  the buffer due to sloppy size estimation.
+       *  add the file machinations.
        */
-      snprintf( pz_scan, argsize - (pz_scan - pz_cmd), z_cmd_fmt,
-                pz_file_source,
-                pz_temp_file, pz_temp_file, pz_temp_file );
+      sprintf( pz_scan, z_cmd_fmt, pz_file_source, pz_temp_file );
     }
   system( pz_cmd );
   free( (void*)pz_cmd );
@@ -984,7 +1005,7 @@
     its stdin and returns the new fd this process will use
     for stdout.  */
 
-#else /* is *NOT* __DOS__ */
+#else /* is *NOT* __MSDOS__ */
 int
 start_fixer (read_fd, p_fixd, pz_fix_file)
   int read_fd;
@@ -1073,7 +1094,7 @@
   int test_ct;
   tTestDesc *p_test;
 
-# ifdef __DOS__
+# ifdef __MSDOS__
   /*
    *  There is only one fix that uses a shell script as of this writing.
    *  I hope to nuke it anyway, it does not apply to DOS and it would
@@ -1280,9 +1301,9 @@
   tFixDesc *p_fixd = fixDescList;
   int todo_ct = FIX_COUNT;
   int read_fd = -1;
-# ifndef __DOS__
+# ifndef __MSDOS__
   int num_children = 0;
-# else /* is __DOS__ */
+# else /* is __MSDOS__ */
   char* pz_file_source = pz_curr_file;
 # endif
 
@@ -1305,7 +1326,7 @@
   if (VLEVEL( VERB_PROGRESS ) && have_tty)
     fprintf (stderr, "%6d %-50s   \r", data_map_size, pz_curr_file );
 
-# ifndef __DOS__
+# ifndef __MSDOS__
   process_chain_head = NOPROCESS;
 
   /* For every fix in our fix list, ...  */
@@ -1366,7 +1387,7 @@
       } while (--num_children > 0);
     }
 
-# else /* is __DOS__ */
+# else /* is __MSDOS__ */
 
   for (; todo_ct > 0; p_fixd++, todo_ct--)
     {
@@ -1389,6 +1410,9 @@
 
   read_fd = open( pz_temp_file, O_RDONLY );
   test_for_changes( read_fd );
+  /* Unlinking a file while it is still open is a Bad Idea on
+     DOS/Windows.  */
+  close( read_fd );
   unlink( pz_temp_file );
 
 # endif
--- fixinc/README.~0	Wed May 24 19:12:56 2000
+++ fixinc/README	Thu Jul 27 20:44:54 2000
@@ -67,7 +67,7 @@
     It is nice if:
 
     3.  The expression is as simple as possible to both
-        process and uderstand by people.  :-)
+        process and understand by people.  :-)
 
         Please take advantage of the fact AutoGen will glue
         together string fragments.  It helps.  Also take note
--- fixinc/fixincl.s~0	Fri Jul 28 00:09:02 2000
+++ fixinc/fixincl.sh	Fri Jul 28 19:52:04 2000
@@ -112,7 +112,9 @@
 then echo Fixing headers into ${LIB} for ${target_canonical} target ; fi
 
 # Determine whether this system has symbolic links.
-if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
+if test -n "$DJDIR"; then
+  LINKS=false
+elif ln -s X $LIB/ShouldNotExist 2>/dev/null; then
   rm -f $LIB/ShouldNotExist
   LINKS=true
 elif ln -s X /tmp/ShouldNotExist 2>/dev/null; then
@@ -423,7 +425,9 @@
 if test $VERBOSE -gt 2
 then echo 'Cleaning up DONE files.' ; fi
 cd $LIB
-find . -name DONE -exec rm -f '{}' ';'
+# Look for files case-insensitively, for the benefit of
+# DOS/Windows filesystems.
+find . -name '[Dd][Oo][Nn][Ee]' -exec rm -f '{}' ';'
 
 if test $VERBOSE -gt 1
 then echo 'Cleaning up unneeded directories:' ; fi
@@ -436,20 +440,25 @@
   fi
 done 2> /dev/null
 
-test $VERBOSE -gt 2 && echo "Removing unused symlinks"
+# On systems which don't support symlinks, `find' may barf
+# if called with "-type l" predicate.  So only use that if
+# we know we should look for symlinks.
+if $LINKS; then
+  test $VERBOSE -gt 2 && echo "Removing unused symlinks"
 
-all_dirs=`find . -type l -print`
-for file in $all_dirs
-do
-  if ls -lLd $file > /dev/null
-  then :
-  else rm -f $file
-       test $VERBOSE -gt 3 && echo "  removed $file"
-       rmdir `dirname $file` > /dev/null && \
-         test $VERBOSE -gt 3 && \
-         echo "  removed `dirname $file`"
-  fi
-done 2> /dev/null
+  all_dirs=`find . -type l -print`
+  for file in $all_dirs
+  do
+    if ls -lLd $file > /dev/null
+    then :
+    else rm -f $file
+         test $VERBOSE -gt 3 && echo "  removed $file"
+         rmdir `dirname $file` > /dev/null && \
+           test $VERBOSE -gt 3 && \
+           echo "  removed `dirname $file`"
+    fi
+  done 2> /dev/null
+fi
 
 if test $VERBOSE -gt 0
 then echo fixincludes is done ; fi

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019