bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gawk] in-place edit request


From: Aharon Robbins
Subject: Re: [bug-gawk] in-place edit request
Date: Tue, 25 Dec 2012 23:08:50 +0200
User-agent: Heirloom mailx 12.5 6/20/10

Hi Andy.

The below is a start. It works OK on a terminal but I suspect there
could be issues with a regular file; one should probably do fgetpos / fsetpos
at save / restore, as John suggested, also (after the fflush).

It is probably also worth checking that fileno(stdout) is a regular file
before doing the fgetpos / fsetpos, as those will fail on a pipe or
tty and do who knows what on some other kind of device.

With respect to output_fp, I just did some quick grep-ing. Although
it is initialized to stdout, it is used mainly for debugging output;
only in do_print / do_printf is it used as the default output, and I
think that's actually a bug which I will fix.

In short, I think this is the right path for getting an in-place extension.
The shell script wrapper is then

        exec gawk -i inplace.awk "$@"

and inplace.awk becomes something like

        @load "setstdout"
        BEGINFILE {
                set_stdout(FILENAME "." PROCINFO["pid"])
        }
        ENDFILE {
                reset_stdout()
                system(sprintf("mv %s %s.bak && mv %s.%d %s",
                        FILENAME, FILENAME,
                        FILENAME, PROCINFO["pid"], FILENAME))
        }

If you have time to give it a go, that'd be great.  If it works, we
can get it into the dist, even.

Thanks,

Arnold

> Date: Sun, 23 Dec 2012 20:30:14 -0500
> From: "Andrew J. Schorr" <address@hidden>
> To: address@hidden
> Cc: address@hidden
> Subject: Re: [bug-gawk] in-place edit request
>
> Perhaps this recipe may work:
> http://stackoverflow.com/questions/4832603/how-could-i-temporary-redirect-stdout-to-a-file-in-a-c-program
>
> It is also discussed here:
> http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/redirecting-standard-io.html
>
> Here's a test harness for that approach.  It seems to work on Linux
> and on Cygwin:
>
> #include <stdio.h>
> #include <unistd.h>
> #include <fcntl.h>
>
> int
> main(int argc, char **argv)
> {
>    int bak, new;
>    char instr[1024];
>
>    puts("output on regular stdout");
>
>    /* switch stdout to argument file */
>    fflush(stdout);
>    bak = dup(1);
>    new = open(argv[1], O_WRONLY|O_CREAT, 0666);
>    dup2(new, 1);
>    close(new);
>
>    while (fgets(instr, sizeof(instr), stdin))
>       fputs(instr, stdout);
>
>    /* restore stdout */
>    fflush(stdout);
>    dup2(bak, 1);
>    close(bak);
>
>    puts("after returning to regular stdout");
>    return 0;
> }
>
> This obviously needs more error checking, but it seems to work.
> So perhaps this can be packaged into an extension function after all.
> Is this approach likely to work on all supported platforms?
>
> Regards,
> Andy



reply via email to

[Prev in Thread] Current Thread [Next in Thread]