henry@utzoo.UUCP (Henry Spencer) (04/23/85)
As has been noted in the past, awk(1) has an annoying limitation on the number of files it can send output to. It's hard to get around this, since the file opens are implicit and there is no way to explicitly close a file that is no longer needed. However, it's possible, and not even very hard, to eliminate this problem in one particular case. When the file is being used for appending (">>" redirection), then closing it and re-opening it is a no-op. The following changes to awk will let it re-use append-mode file descriptors when it runs low on descriptors. There's a substantial performance loss, of course, but it occurs only when you are genuinely using more files than awk would normally permit. All these changes are in awk/run.c. Line numbers should be considered approximate only. Add the following new member to the "files" struct: 13a14 > int appending; Add the following new declaration to the local variables in the function redirprint(): 844a846 > int app; Make the following changes to code early in redirprint(): 852,856c854,867 < for (i=0; i<FILENUM; i++) < if (files[i].fp == 0) < break; < if (i >= FILENUM) < error(FATAL, "too many output files %d", i); --- > app = -1; > for (i=0; i<FILENUM && files[i].fp != 0; i++) > if (files[i].appending) > app = i; > if (i >= FILENUM && app == -1) > error(FATAL, "too many output files %d", i); > if (i >= FILENUM) { /* but there is an append we can close */ > fclose(files[app].fp); > files[app].fp = 0; > free(files[app].fname); > files[app].fname = 0; > files[app].appending = 0; > i = app; > } And, slightly further down in redirprint(), add the following line just after the "files[i].fname = tostring(x.optr->sval);" line: 865a877 > files[i].appending = (a == APPEND) ? 1 : 0; Note that this code makes no attempt to intelligently choose *which* append-mode file descriptor to close; it probably ought to use LRU or something like that. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry