Date: Sun, 21 Apr 1996 21:53:51 -0400 From: dj (DJ Delorie) Message-Id: <199604220153.VAA28554@delorie.com> To: djgpp-workers Subject: [d79042 AT r350 DOT ee DOT ntu DOT edu DOT tw: FIND41B: BUG REPORT AND PATCHES] Date: Mon, 22 Apr 96 06:03:52 CST From: d79042 AT r350 DOT ee DOT ntu DOT edu DOT tw (CHIN-YUAN KUO) To: dj AT delorie DOT com Subject: FIND41B: BUG REPORT AND PATCHES Dear Sir, FIND.EXE in FIND41B.ZIP (GNU findutils v4.1 for DJGPP v2.0) is very powerful and useful. Thank you for porting it to MS-DOS. By the way, DJGPP is an excellent DOS compiler. Thank you very much. I find 2 bugs in find.exe. These bugs are shown with the following example. =============================================================================== command 1 ==> | E:\Z>dir c:\test | | Volume in drive C is DRIVE_C | Volume Serial Number is 025F-1505 | Directory of C:\TEST | | . 04-20-96 16:41 . | .. 04-20-96 16:41 .. | TMP 04-20-96 16:41 TMP | FIRST DAT 20 04-20-96 16:45 FIRST.DAT | SECOND DAT 50 04-20-96 16:46 SECOND.DAT | 2 file(s) 70 bytes | 3 dir(s) 37,617,664 bytes free | | E:\Z> command 2 ==> | E:\Z>dir c:\test\tmp | | Volume in drive C is DRIVE_C | Volume Serial Number is 025F-1505 | Directory of C:\TEST\TMP | | . 04-20-96 16:41 . | .. 04-20-96 16:41 .. | THIRD DAT 120 04-20-96 16:47 THIRD.DAT | 1 file(s) 120 bytes | 2 dir(s) 37,617,664 bytes free | | E:\Z> command 3 ==> | E:\Z>find c:/test -type f -exec cmp -s {} c:/test/first.dat ; -print | c:/test/tmp/third.dat | c:/test/second.dat | | E:\Z> command 4 ==> | E:\Z>cd c:\test\tmp | command 5 ==> | E:\Z>find c:.. -type f -exec wc {} ; | 22 22 120 c:../tmp/third.dat | D:\BIN32/wc.exe: c:../first.dat: No such file or directory (ENOENT) | D:\BIN32/wc.exe: c:../second.dat: No such file or directory (ENOENT) | | E:\Z> =============================================================================== Command 1 and 2 reveal a portion of file hierarchy in my drive C. Command 3 is trivial. However, its output is NOT "c:/test/first.dat". (This bug can be easily removed.) We change drive C's working directory with command 4. The output of command 5 is wrong because c:../first.dat and c:../second.dat do exist. (It is harder to remove the second bug than the first one.) I use my patches to try to remove these two bugs. My patches are appended in this e-mail. (To apply the patches, please decompress find41s.zip first.) Best regards, Chin-yuan Kuo d79042 AT r350 DOT ee DOT ntu DOT edu DOT tw -------------------------CUT HERE-------------------------- *** ./gnu/findu41/configur.bat Sun Nov 5 23:00:24 1995 --- ./gnu/findu41/configur.bat.new Tue Apr 2 17:36:16 1996 *************** *** 1,5 **** @echo off ! cp config.dj config.h sed -f configdj.sed lib/Makefile.in > lib\makefile ! sed -f configdj.sed find/Makefile.in > find\makefile --- 1,5 ---- @echo off ! copy config.dj config.h sed -f configdj.sed lib/Makefile.in > lib\makefile ! sed -f configok.sed find/Makefile.in > find\makefile *** ./gnu/findu41/makeall.bat Sun Nov 5 22:59:22 1995 --- ./gnu/findu41/makeall.bat.new Sat Mar 30 18:56:40 1996 *************** *** 2,6 **** cd lib make ! cd ../find make --- 2,6 ---- cd lib make ! cd ..\find make *** ./gnu/findu41/configdj.sed Sun Nov 5 23:04:16 1995 --- ./gnu/findu41/configdj.sed.new Mon Apr 1 18:08:22 1996 *************** *** 5,11 **** s/@YACC@/bison -y/g s/@DEFS@/-DHAVE_CONFIG_H/g s/@CPPFLAGS@//g ! s/@CFLAGS@/-O2/g s/@LDFLAGS@/-s/g s/@RANLIB@/ranlib/g s/@ALLOCA@//g --- 5,11 ---- s/@YACC@/bison -y/g s/@DEFS@/-DHAVE_CONFIG_H/g s/@CPPFLAGS@//g ! s/@CFLAGS@/-O3 -m486 -Wall/g s/@LDFLAGS@/-s/g s/@RANLIB@/ranlib/g s/@ALLOCA@//g *** ./gnu/findu41/lib/listfile.c Sun Nov 5 22:47:16 1995 --- ./gnu/findu41/lib/listfile.c.new Mon Apr 1 18:11:32 1996 *************** *** 153,159 **** } timebuf[16] = 0; ! fprintf (stream, "%6lu ", statp->st_ino); fprintf (stream, "%4u ", convert_blocks (ST_NBLOCKS (statp), kilobytes)); --- 153,159 ---- } timebuf[16] = 0; ! fprintf (stream, "%6lu ", (unsigned long) statp->st_ino); fprintf (stream, "%4u ", convert_blocks (ST_NBLOCKS (statp), kilobytes)); *************** *** 172,178 **** fprintf (stream, " "); #endif else ! fprintf (stream, "%8lu ", statp->st_size); fprintf (stream, "%s ", timebuf + 4); --- 172,178 ---- fprintf (stream, " "); #endif else ! fprintf (stream, "%8lu ", (unsigned long) statp->st_size); fprintf (stream, "%s ", timebuf + 4); *** ./gnu/findu41/find/pred.c Sun Nov 5 22:55:50 1995 --- ./gnu/findu41/find/pred.c.new Sat Apr 20 15:55:15 1996 *************** *** 15,20 **** --- 15,24 ---- along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #ifdef CH_WD + #include "ch_wd.h" + #endif + #include #include #include *************** *** 1335,1341 **** fflush (stderr); #ifdef __MSDOS__ ! return spawnvp(P_WAIT, execp->vec[0], execp->vec); #else /* Make sure to listen for the kids. */ if (first_time) --- 1339,1355 ---- fflush (stderr); #ifdef __MSDOS__ ! #ifdef CH_WD ! { ! int val; ! SaveTempWD(); ! val = !spawnvp(P_WAIT, execp->vec[0], execp->vec); ! RestoreTempWD(); ! return val; ! } ! #else ! return !spawnvp(P_WAIT, execp->vec[0], execp->vec); ! #endif #else /* Make sure to listen for the kids. */ if (first_time) *************** *** 1412,1418 **** if (kind == '@') { ! sprintf (buf, "%ld", when); return (buf); } else --- 1426,1432 ---- if (kind == '@') { ! sprintf (buf, "%ld", (long) when); return (buf); } else *** ./gnu/findu41/find/find.c Wed Oct 12 21:21:10 1994 --- ./gnu/findu41/find/find.c.new Mon Apr 1 18:30:00 1996 *************** *** 22,27 **** --- 22,31 ---- The idea for -print0 and xargs -0 came from Dan Bernstein . */ + #ifdef CH_WD + #include "ch_wd.h" + #endif + #include #include #include *************** *** 247,252 **** --- 251,259 ---- error (1, errno, "cannot open current directory"); #endif + #ifdef CH_WD + WorkingDirectory(); + #endif /* If no paths are given, default to ".". */ for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++) process_top_path (argv[i]); *************** *** 273,278 **** --- 280,289 ---- cache the second time. */ if ((*xstat) (pathname, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode)) { + #ifdef CH_WD + AdjustmentIsNeeded(); + ArgWorkingDirectory(pathname); + #endif if (chdir (pathname) < 0) { error (0, errno, "%s", pathname); *************** *** 287,295 **** --- 298,316 ---- if (fchdir (starting_desc)) error (1, errno, "cannot return to starting directory"); #endif + #ifdef CH_WD + RestoreArgWD(); + #endif } else + #ifdef CH_WD + { + DoNotAdjust(); + #endif process_path (pathname, pathname, false, "."); + #ifdef CH_WD + } + #endif } /* Info on each directory in the current tree branch, to avoid *** /dev/null Sat Apr 20 22:34:04 1996 --- ./gnu/findu41/configok.sed Tue Apr 2 17:35:50 1996 *************** *** 0 **** --- 1,17 ---- + s/@srcdir@/./g + s/@top_srcdir@/../g + s/@CC@/gcc/g + s/@LEX@/flex/g + s/@YACC@/bison -y/g + s/@DEFS@/-DHAVE_CONFIG_H/g + s/@CPPFLAGS@//g + s/@CFLAGS@/-DCH_WD -O3 -m486 -Wall/g + s/@LDFLAGS@/-s/g + s/@RANLIB@/ranlib/g + s/@ALLOCA@//g + s/@LIBOBJS@//g + s/@LIBS@//g + s/^find_OBJECTS =.*$/& ch_wd.o/ + s/^find_SOURCES =.*$/& ch_wd.c/ + $a\ + echo find.o pred.o ch_wd.o: ch_wd.h *** /dev/null Sat Apr 20 22:34:04 1996 --- ./gnu/findu41/find/ch_wd.h Mon Apr 1 15:51:52 1996 *************** *** 0 **** --- 1,7 ---- + void WorkingDirectory(void); + void ArgWorkingDirectory(const char *pathname); + void AdjustmentIsNeeded(void); + void DoNotAdjust(void); + void SaveTempWD(void); + void RestoreTempWD(void); + void RestoreArgWD(void); *** /dev/null Sat Apr 20 22:34:04 1996 --- ./gnu/findu41/find/ch_wd.c Mon Apr 1 18:56:36 1996 *************** *** 0 **** --- 1,104 ---- + #include + #include + #include + #include + #include + #include "ch_wd.h" + + static char w_dir[PATH_MAX]; + static char w_drive[] = {'X', ':', '\0'}; + static char arg_dir[PATH_MAX]; + static char arg_drive[] = {'X', ':', '\0'}; + static char saved_dir[PATH_MAX]; + static int Adjust; + + #define IsAdjustmentNecessary (Adjust != 0) + + void WorkingDirectory() + { + if (NULL == getcwd(w_dir, sizeof(w_dir))) { + perror("Working directory not found"); + exit(1); + } + w_drive[0] = tolower(w_dir[0]); + } + + void ArgWorkingDirectory(const char *pathname) + { + if (':' == pathname[1] && isalpha(pathname[0])) { + arg_drive[0] = tolower(pathname[0]); + if (arg_drive[0] == w_drive[0]) { + strcpy(arg_dir, w_dir); + } else { + if (0 != chdir(arg_drive)) { + perror(pathname); + exit(1); + } + if (NULL == getcwd(arg_dir, sizeof(arg_dir))) { + perror("Working directory not found"); + exit(1); + } + if (0 != chdir(w_drive)) { + perror(w_drive); + exit(1); + } + } + } else { + arg_drive[0] = w_drive[0]; + strcpy(arg_dir, w_dir); + } + } + + void AdjustmentIsNeeded() + { + Adjust = 1; + } + + void DoNotAdjust() + { + Adjust = 0; + } + + void SaveTempWD() + { + if (IsAdjustmentNecessary) { + if (0 != chdir(arg_drive)) { + perror(arg_dir); + exit(1); + } + if (NULL == getcwd(saved_dir, sizeof(saved_dir))) { + perror("Working directory not found"); + exit(1); + } + if (0 != chdir(arg_dir)) { + perror(arg_dir); + exit(1); + } + if (0 != chdir(w_dir)) { + perror(w_dir); + exit(1); + } + } + } + + void RestoreTempWD() + { + if (IsAdjustmentNecessary) { + if (0 != chdir(saved_dir)) { + perror(saved_dir); + exit(1); + } + } + } + + void RestoreArgWD() + { + if (0 != chdir(arg_dir)) { + perror(arg_dir); + exit(1); + } + if (0 != chdir(w_dir)) { + perror(w_dir); + exit(1); + } + } -------------------------CUT HERE--------------------------