From: Paul Smith Date: Wed, 5 Apr 2000 16:02:55 +0000 (+0000) Subject: * Some final cleanups, and release 3.79. X-Git-Tag: 3.79^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f9c91ec34d9427c35bceec9b025a0bb20c9ec17f;p=platform%2Fupstream%2Fmake.git * Some final cleanups, and release 3.79. --- diff --git a/ChangeLog b/ChangeLog index b6e13f9..657b170 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2000-04-04 Paul D. Smith + + * Version 3.79 released. + + * make.texinfo: Update documentation with new features for 3.79. + + * function.c (func_wordlist): Don't re-order arguments to + wordlist. + 2000-04-03 Paul D. Smith * remake.c (f_mtime): Archive member timestamps are stored as diff --git a/NEWS b/NEWS index 0079ffe..8a29d5c 100644 --- a/NEWS +++ b/NEWS @@ -39,8 +39,8 @@ Version 3.79 * The --debug option has changed: it now allows optional flags controlling the amount and type of debugging output. By default only a minimal amount information is generated, displaying the names of - "normal" targets (not makefiles) were deemed out of date and in need - of being rebuilt. + "normal" targets (not makefiles) that were deemed out of date and in + need of being rebuilt. Note that the -d option behaves as before: it takes no arguments and all debugging information is generated. @@ -48,6 +48,10 @@ Version 3.79 * The `-p' (print database) output now includes filename and linenumber information for variable definitions, to help debugging. +* The wordlist function no longer reverses its arguments if the "start" + value is greater than the "end" value. If that's true, nothing is + returned. + * Hartmut Becker provided many updates for the VMS port of GNU make. See the readme.vms file for more details. diff --git a/configure.in b/configure.in index 01fafb6..7d2c68a 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ AC_REVISION([$Id$]) AC_PREREQ(2.13)dnl dnl Minimum Autoconf version required. AC_INIT(vpath.c)dnl dnl A distinctive file to look for in srcdir. -AM_INIT_AUTOMAKE(make, 3.78.92) +AM_INIT_AUTOMAKE(make, 3.79) AM_CONFIG_HEADER(config.h) dnl Regular configure stuff diff --git a/function.c b/function.c index 60a02ed..dd638ae 100644 --- a/function.c +++ b/function.c @@ -37,7 +37,7 @@ struct function_table_entry unsigned char minimum_args; unsigned char maximum_args; char expand_args; - char *(*func_ptr) PARAMS((char *output, char **argv, const char*funcname)); + char *(*func_ptr) PARAMS ((char *output, char **argv, const char *fname)); }; @@ -231,7 +231,7 @@ lookup_function (table, s) const struct function_table_entry *table; const char *s; { - int len = strlen(s); + int len = strlen (s); for (; table->name != NULL; ++table) if (table->len <= len @@ -386,7 +386,7 @@ func_patsubst (o, argv, funcname) static char * -func_join(o, argv, funcname) +func_join (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -429,7 +429,7 @@ func_join(o, argv, funcname) static char * -func_origin(o, argv, funcname) +func_origin (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -483,7 +483,7 @@ func_origin(o, argv, funcname) static char * -func_notdir_suffix(o, argv, funcname) +func_notdir_suffix (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -518,7 +518,7 @@ func_notdir_suffix(o, argv, funcname) } #if defined(WINDOWS32) || defined(__MSDOS__) /* Handle the case of "d:foo/bar". */ - else if (streq(funcname, "notdir") && p2[0] && p2[1] == ':') + else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':') { p = p2 + 2; o = variable_buffer_output (o, p, len - (p - p2)); @@ -544,7 +544,7 @@ func_notdir_suffix(o, argv, funcname) static char * -func_basename_dir(o, argv, funcname) +func_basename_dir (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -603,7 +603,7 @@ func_basename_dir(o, argv, funcname) } static char * -func_addsuffix_addprefix(o, argv, funcname) +func_addsuffix_addprefix (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -636,7 +636,7 @@ func_addsuffix_addprefix(o, argv, funcname) } static char * -func_subst(o, argv, funcname) +func_subst (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -649,7 +649,7 @@ func_subst(o, argv, funcname) static char * -func_firstword(o, argv, funcname) +func_firstword (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -666,7 +666,7 @@ func_firstword(o, argv, funcname) static char * -func_words(o, argv, funcname) +func_words (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -724,7 +724,7 @@ check_numeric (s, message) static char * -func_word(o, argv, funcname) +func_word (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -758,45 +758,42 @@ func_wordlist (o, argv, funcname) char **argv; const char *funcname; { - int i=0; - int j=0; + int start, count; - /* Check the first argument. */ + /* Check the arguments. */ check_numeric (argv[0], _("non-numeric first argument to `wordlist' function")); - i =atoi(argv[0]); check_numeric (argv[1], _("non-numeric second argument to `wordlist' function")); - j = atoi(argv[1]); - + start = atoi (argv[0]); + count = atoi (argv[1]) - start + 1; - { - char *p; - char *end_p = argv[2]; + if (count > 0) + { + char *p; + char *end_p = argv[2]; - int start = (i < j) ? i : j; - int count = j -i ; - if (count < 0) - count = - count; - count ++; + /* Find the beginning of the "start"th word. */ + while (((p = find_next_token (&end_p, 0)) != 0) && --start) + ; + if (p) + { + /* Find the end of the "count"th word from start. */ + while (--count && (find_next_token (&end_p, 0) != 0)) + ; + /* Return the stuff in the middle. */ + o = variable_buffer_output (o, p, end_p - p); + } + } - while (((p = find_next_token (&end_p, 0)) != 0) && --start) - {} - if (p) - { - while (--count && (find_next_token (&end_p, 0) != 0)) - {} - o = variable_buffer_output (o, p, end_p - p); - } - } return o; } static char* -func_findstring(o, argv, funcname) +func_findstring (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -888,7 +885,7 @@ func_filter_filterout (o, argv, funcname) /* Chop ARGV[1] up into words and then run each pattern through. */ while ((p = find_next_token (&word_iterator, &len)) != 0) { - struct a_word *w = (struct a_word *)alloca(sizeof(struct a_word)); + struct a_word *w = (struct a_word *)alloca (sizeof (struct a_word)); if (wordhead == 0) wordhead = w; else @@ -944,7 +941,7 @@ func_filter_filterout (o, argv, funcname) static char * -func_strip(o, argv, funcname) +func_strip (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -992,18 +989,18 @@ func_error (o, argv, funcname) another special case where function arguments aren't broken up, just create a format string that puts them back together. */ for (len=0, argvp=argv; *argvp != 0; ++argvp) - len += strlen(*argvp) + 2; + len += strlen (*argvp) + 2; p = msg = alloca (len + 1); for (argvp=argv; argvp[1] != 0; ++argvp) { - strcpy(p, *argvp); - p += strlen(*argvp); + strcpy (p, *argvp); + p += strlen (*argvp); *(p++) = ','; *(p++) = ' '; } - strcpy(p, *argvp); + strcpy (p, *argvp); if (*funcname == 'e') fatal (reading_file, "%s", msg); @@ -1128,7 +1125,7 @@ func_if (o, argv, funcname) } static char * -func_wildcard(o, argv, funcname) +func_wildcard (o, argv, funcname) char *o; char **argv; const char *funcname; @@ -1197,11 +1194,11 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp) HANDLE hProcess; - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.nLength = sizeof (SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; - if (DuplicateHandle(GetCurrentProcess(), + if (DuplicateHandle (GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &hIn, @@ -1371,7 +1368,7 @@ func_shell (o, argv, funcname) /* For error messages. */ if (reading_file != 0) { - error_prefix = (char *) alloca (strlen(reading_file->filenm)+11+4); + error_prefix = (char *) alloca (strlen (reading_file->filenm)+11+4); sprintf (error_prefix, "%s:%lu: ", reading_file->filenm, reading_file->lineno); } @@ -1470,8 +1467,8 @@ func_shell (o, argv, funcname) if (batch_filename) { DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"), batch_filename)); - remove(batch_filename); - free(batch_filename); + remove (batch_filename); + free (batch_filename); } shell_function_pid = 0; @@ -1623,7 +1620,7 @@ func_not (char* o, char **argv, char *funcname) #endif -#define STRING_SIZE_TUPLE(_s) (_s), (sizeof(_s)-1) +#define STRING_SIZE_TUPLE(_s) (_s), (sizeof (_s)-1) /* Lookup table for builtin functions. @@ -1637,7 +1634,7 @@ func_not (char* o, char **argv, char *funcname) EXPAND_ARGS means that all arguments should be expanded before invocation. Functions that do namespace tricks (foreach) don't automatically expand. */ -static char *func_call PARAMS((char *o, char **argv, const char *funcname)); +static char *func_call PARAMS ((char *o, char **argv, const char *funcname)); static struct function_table_entry function_table[] = @@ -1751,7 +1748,7 @@ handle_function (op, stringp) *stringp = end; /* Get some memory to store the arg pointers. */ - argvp = argv = (char **) alloca (sizeof(char *) * (nargs + 2)); + argvp = argv = (char **) alloca (sizeof (char *) * (nargs + 2)); /* Chop the string into arguments, then a nul. As soon as we hit MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the @@ -1833,7 +1830,7 @@ func_call (o, argv, funcname) while (*fname != '\0' && isspace ((unsigned char)*fname)) ++fname; - cp = fname + strlen(fname) - 1; + cp = fname + strlen (fname) - 1; while (cp > fname && isspace ((unsigned char)*cp)) --cp; cp[1] = '\0'; @@ -1886,5 +1883,5 @@ func_call (o, argv, funcname) pop_variable_scope (); - return o + strlen(o); + return o + strlen (o); } diff --git a/make.texinfo b/make.texinfo index 175493a..6b16027 100644 --- a/make.texinfo +++ b/make.texinfo @@ -8,10 +8,10 @@ @c FSF publishers: format makebook.texi instead of using this file directly. @set RCSID $Id$ -@set EDITION 0.54 -@set VERSION 3.78.1 -@set UPDATED 09 September 1999 -@set UPDATE-MONTH September 1999 +@set EDITION 0.55 +@set VERSION 3.79 +@set UPDATED 04 April 2000 +@set UPDATE-MONTH April 2000 @comment The ISBN number might need to change on next publication. @set ISBN 1-882114-80-9 @c CHANGE THIS BEFORE PRINTING AGAIN! --psmith 16jul98 @@ -37,7 +37,7 @@ and issues the commands to recompile them. This is Edition @value{EDITION}, last updated @value{UPDATED}, of @cite{The GNU Make Manual}, for @code{make}, Version @value{VERSION}. -Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 +Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99, 2000 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of @@ -73,7 +73,7 @@ by the Free Software Foundation. @author Richard M. Stallman and Roland McGrath @page @vskip 0pt plus 1filll -Copyright @copyright{} 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98 +Copyright @copyright{} 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99, 2000 Free Software Foundation, Inc. @sp 2 Published by the Free Software Foundation @* @@ -134,7 +134,7 @@ This manual describes @code{make} and contains the following chapters:@refill * Missing:: What GNU @code{make} lacks from other @code{make}s. * Makefile Conventions:: Conventions for makefiles in GNU programs. * Quick Reference:: A quick reference for experienced users. -* Make Errors:: A list of common errors generated by @code{make}. +* Error Messages:: A list of common errors generated by @code{make}. * Complex Makefile:: A real example of a straightforward, but nontrivial, makefile. * Concept Index:: Index of Concepts @@ -2479,7 +2479,7 @@ Sub-@code{make}}. If @code{.NOTPARALLEL} is mentioned as a target, then this invocation of @code{make} will be run serially, even if the @samp{-j} option is given. Any recursively invoked @code{make} command will still be run in -parallel if its makefile doesn't contain this target. Any prerequisites +parallel (unless its makefile contains this target). Any prerequisites on this target are ignored. @end table @@ -5854,8 +5854,7 @@ ending with word @var{e} (inclusive). The legitimate values of @var{s} and @var{e} start from 1. If @var{s} is bigger than the number of words in @var{text}, the value is empty. If @var{e} is bigger than the number of words in @var{text}, words up to the end of @var{text} are returned. -If @var{s} is greater than @var{e}, @code{make} swaps them for you. For -example, +If @var{s} is greater than @var{e}, nothing is returned. For example, @example $(wordlist 2, 3, foo bar baz) @@ -6060,6 +6059,12 @@ If @var{variable} is the name of a builtin function, the builtin function is always invoked (even if a @code{make} variable by that name also exists). +The @code{call} function expands the @var{param} arguments before +assigning them to temporary variables. This means that @var{variable} +values containing references to builtin functions that have special +expansion rules, like @code{foreach} or @code{if}, may not work as you +expect. + Some examples may make this clearer. This macro simply reverses its arguments: @@ -6067,12 +6072,11 @@ This macro simply reverses its arguments: @smallexample reverse = $(2) $(1) -foo = a b -bar = $(call reverse,$(foo)) +foo = $(call reverse,a,b) @end smallexample @noindent -Here @var{bar} will contain @samp{b a}. +Here @var{foo} will contain @samp{b a}. This one is slightly more interesting: it defines a macro to search for the first instance of a program in @code{PATH}: @@ -6803,8 +6807,6 @@ This is typically used with recursive invocations of @code{make} @item -d @cindex @code{-d} -@itemx --debug -@cindex @code{--debug} @c Extra blank line here makes the table look better. Print debugging information in addition to normal processing. The @@ -6812,7 +6814,46 @@ debugging information says which files are being considered for remaking, which file-times are being compared and with what results, which files actually need to be remade, which implicit rules are considered and which are applied---everything interesting about how -@code{make} decides what to do. +@code{make} decides what to do. The @code{-d} option is equivalent to +@samp{--debug=a} (see below). + +@item --debug[=@var{options}] +@cindex @code{--debug} +@c Extra blank line here makes the table look better. + +Print debugging information in addition to normal processing. Various +levels and types of output can be chosen. With no arguments, print the +``basic'' level of debugging. Possible arguments are below; only the +first character is considered, and values must be comma- or +space-separated. + +@table @code +@item a@var{ll} +All types of debugging output is enabled. This is equivalent to using +@samp{-d}. + +@item b@var{asic} +Basic debugging prints each target that was found to be out-of-date, and +whether the build was successful or not. + +@item v@var{erbose} +A level above @samp{basic}; includes messages about which makefiles were +parsed, prerequisites that did not need to be rebuilt, etc. This option +also enables @samp{basic} messages. + +@item i@var{mplicit} +Prints messages describing the implicit rule searches for each target. +This option also enables @samp{basic} messages. + +@item j@var{obs} +Prints messages giving details on the invocation of specific subcommands. + +@item m@var{akefile} +By default, the above messages are not enabled while trying to remake +the makefiles. This option enables messages while rebuilding makefiles, +too. Note that the @samp{all} option does enable this option. This +option also enables @samp{basic} messages. +@end table @item -e @cindex @code{-e} @@ -6857,7 +6898,7 @@ searched in the order specified. @item -j [@var{jobs}] @cindex @code{-j} -@itemx --jobs=[@var{jobs}] +@itemx --jobs[=@var{jobs}] @cindex @code{--jobs} Specifies the number of jobs (commands) to run simultaneously. With no argument, @code{make} runs as many jobs simultaneously as possible. If @@ -6920,7 +6961,9 @@ reading the makefiles; then execute as usual or as otherwise specified. This also prints the version information given by the @samp{-v} switch (see below). To print the data base without trying to remake any files, use @w{@samp{make -qp}}. To print the data base of predefined rules and -variables, use @w{@samp{make -p -f /dev/null}}. +variables, use @w{@samp{make -p -f /dev/null}}. The data base output +contains filename and linenumber information for command and variable +definitions, so it can be a useful debugging tool in complex environments. @item -q @cindex @code{-q} @@ -9107,7 +9150,7 @@ special treatment. @comment included by standards.texi. @include make-stds.texi -@node Quick Reference, Make Errors, Makefile Conventions, Top +@node Quick Reference, Error Messages, Makefile Conventions, Top @appendix Quick Reference This appendix summarizes the directives, text manipulation functions, @@ -9402,6 +9445,11 @@ The flags given to @code{make}. You can set this in the environment or a makefile to set flags.@* @xref{Options/Recursion, ,Communicating Options to a Sub-@code{make}}. +It is @emph{never} appropriate to use @code{MAKEFLAGS} directly on a +command line: its contents may not be quoted correctly for use in the +shell. Always allow recursive @code{make}'s to obtain these values +through the environment from its parent. + @item MAKECMDGOALS The targets given to @code{make} on the command line. Setting this @@ -9425,11 +9473,11 @@ order.@* @xref{Libraries/Search, ,Directory Search for Link Libraries}. @end table -@node Make Errors, Complex Makefile, Quick Reference, Top +@node Error Messages, Complex Makefile, Quick Reference, Top @comment node-name, next, previous, up @appendix Errors Generated by Make -Here is a list of the most common errors you might see generated by +Here is a list of the more common errors you might see generated by @code{make}, and some information about what they mean and how to fix them. @@ -9575,7 +9623,7 @@ sequential manner. @end table -@node Complex Makefile, Concept Index, Make Errors, Top +@node Complex Makefile, Concept Index, Error Messages, Top @appendix Complex Makefile Example Here is the makefile for the GNU @code{tar} program. This is a diff --git a/read.c b/read.c index 9f35753..f934460 100644 --- a/read.c +++ b/read.c @@ -313,7 +313,6 @@ read_makefile (filename, flags) { \ if (filenames != 0) \ { \ - int lineno = fileinfo.lineno; \ struct floc fi; \ fi.filenm = fileinfo.filenm; \ fi.lineno = tgts_started; \ @@ -331,7 +330,7 @@ read_makefile (filename, flags) fileinfo.lineno = 1; pattern_percent = 0; -/* cmds_started = fileinfo.lineno; */ + cmds_started = tgts_started = fileinfo.lineno; if (ISDB (DB_VERBOSE)) { diff --git a/tests/ChangeLog b/tests/ChangeLog index c742ac1..aca7225 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2000-04-04 Paul D. Smith + + * scripts/functions/word: wordlist doesn't swap arguments anymore. + 2000-03-27 Paul D. Smith * scripts/features/statipattrules: Test that static pattern rules diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word index f786e47..36e5102 100644 --- a/tests/scripts/functions/word +++ b/tests/scripts/functions/word @@ -1,33 +1,33 @@ -$description = "The following test creates a makefile to test the word, words,\n" - ."and wordlist functions.\n"; +# -*-perl-*- +$description = "Test the word, words, and wordlist functions.\n"; -$details = "The word function will return the number of words in a variable or\n" - ."the word specified. The test will produce a variable with a large\n" - ."number of words in it, determine the number of word and then read\n" - ."each one back.\n"; +$details = "\ +Produce a variable with a large number of words in it, +determine the number of words, and then read each one back.\n"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... -print MAKEFILE "string := word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl \n" - ."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n" - ."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n" - ."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n" - ."all: \n" - ."\t\@echo \$(words \$(string)) \n" - ."\t\@echo \$(words \$(string4)) \n" - ."\t\@echo \$(word 1, \$(string)) \n" - ."\t\@echo \$(word 100, \$(string)) \n" - ."\t\@echo \$(word 1, \$(string)) \n" - ."\t\@echo \$(word 1000, \$(string3)) \n" - ."\t\@echo \$(wordlist 3, 4, \$(string)) \n" - ."\t\@echo \$(wordlist 4, 3, \$(string)) \n" - ."\t\@echo \$(wordlist 1, 6, \$(string)) \n" - ."\t\@echo \$(wordlist 7, 5, \$(string)) \n" - ."\t\@echo \$(wordlist 100, 110, \$(string)) \n" - ."\t\@echo \$(wordlist 7, 10, \$(string2)) \n" -; +print MAKEFILE <<'EOF'; +string := word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl +string2 := $(string) $(string) $(string) $(string) $(string) $(string) $(string) +string3 := $(string2) $(string2) $(string2) $(string2) $(string2) $(string2) $(string2) +string4 := $(string3) $(string3) $(string3) $(string3) $(string3) $(string3) $(string3) +all: + @echo $(words $(string)) + @echo $(words $(string4)) + @echo $(word 1, $(string)) + @echo $(word 100, $(string)) + @echo $(word 1, $(string)) + @echo $(word 1000, $(string3)) + @echo $(wordlist 3, 4, $(string)) + @echo $(wordlist 4, 3, $(string)) + @echo $(wordlist 1, 6, $(string)) + @echo $(wordlist 5, 7, $(string)) + @echo $(wordlist 100, 110, $(string)) + @echo $(wordlist 7, 10, $(string2)) +EOF @@ -35,7 +35,7 @@ print MAKEFILE "string := word.pl general_test2.pl FORCE.pl word.pl generic_t close(MAKEFILE); -&run_make_with_options($makefile,"",&get_logfile,0); +&run_make_with_options($makefile, "", &get_logfile); # Create the answer to what should be produced by this Makefile @@ -47,7 +47,7 @@ $answer = "6\n" ."word.pl\n" ."\n" ."FORCE.pl word.pl\n" - ."FORCE.pl word.pl\n" + ."\n" ."word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl\n" ."generic_test.perl MAKEFILES_variable.pl\n" ."\n" @@ -58,13 +58,7 @@ $answer = "6\n" # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). -&compare_output($answer,&get_logfile(1)); +&compare_output($answer, &get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; - - - - - - diff --git a/tests/scripts/options/dash-n b/tests/scripts/options/dash-n index 98f1d21..35f317d 100644 --- a/tests/scripts/options/dash-n +++ b/tests/scripts/options/dash-n @@ -50,6 +50,11 @@ EOF close(MAKEFILE); &touch('b'); +# Sometimes, on my Solaris 2.5.1 box with a NetApp filesystem NFS-mounted, +# just touching b first then a isn't good enough: the nsec field in the +# stat result shows b is _newer_ than a once every 5 or 6 tries!!! I've +# no idea what this is about, but that's why there's a sleep(1) here... +sleep(1); &touch('a'); sleep(1); &touch('c');