f



Accessing the return values of the first argument to a pipe

Please click on the following link to view my GNU Makefile

http://davin.50webs.com/J.T.W/tutorial-18-advanced-jtw.html

Could you please come up with some code that acts on the return
values of java and javac in my Makefile.  Presently the return
values of java and javac are ignored, which means that you
need to issue to following command before building the *.class
files from *.java files and building *.java files from *.jtw files.

make clean

If you don' t do this, then java will run some code that has
compilation errors earlier in the build process. (i.e. javac or
jtw-build-jtw.el)
0
Davin
9/30/2016 6:21:54 AM
comp.unix.programmer 10848 articles. 0 followers. kokososo56 (350) is leader. Post Follow

18 Replies
652 Views

Similar Articles

[PageSpeed] 7

Davin Pearson <davin.pearson@gmail.com> writes:
> Please click on the following link to view my GNU Makefile
>
> http://davin.50webs.com/J.T.W/tutorial-18-advanced-jtw.html
>
> Could you please come up with some code that acts on the return
> values of java and javac in my Makefile.  Presently the return
> values of java and javac are ignored, which means that you
> need to issue to following command before building the *.class
> files from *.java files and building *.java files from *.jtw files.

It's somewhat unclear what you're trying to do with this. The usual way
to do a multi-step compilation would be to let make detect that the
command failed which will then cause the procedure to be aborted.

What's the purpose of this line:

javac $(JAVAC_FLAGS) $$(find . -name "*.java") |& emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \ 
|& grep "input[0-9]:" - \ 
|& sed -e "s/input[0-9]://g" -

and specifically, why isn't javac called on the rule input files
(usually via $^ or $<) but all .java files found somewhere below the
current directory?
0
Rainer
9/30/2016 6:31:36 PM
On Fri, 2016-09-30, Rainer Weikusat wrote:
> Davin Pearson <davin.pearson@gmail.com> writes:
>> Please click on the following link to view my GNU Makefile
>>
>> http://davin.50webs.com/J.T.W/tutorial-18-advanced-jtw.html
>>
>> Could you please come up with some code that acts on the return
>> values of java and javac in my Makefile.  Presently the return
>> values of java and javac are ignored, which means that you
>> need to issue to following command before building the *.class
>> files from *.java files and building *.java files from *.jtw files.
>
> It's somewhat unclear what you're trying to do with this. The usual way
> to do a multi-step compilation would be to let make detect that the
> command failed which will then cause the procedure to be aborted.
>
> What's the purpose of this line:
>
> javac $(JAVAC_FLAGS) $$(find . -name "*.java") |& emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \ 
> |& grep "input[0-9]:" - \ 
> |& sed -e "s/input[0-9]://g" -
>
> and specifically, why isn't javac called on the rule input files
> (usually via $^ or $<) but all .java files found somewhere below the
> current directory?

I don't understand the goal, and I don't use Java, but I seem to
remember from the 1990s that javac wants to be handed all *.java in
one invocation.

Perhaps that means that Java and Make don't play nice with each other.
And perhaps (even though I like Make) that means the OP shouldn't try
to use Make for this task.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .
0
Jorgen
10/1/2016 9:18:43 AM
On Fri, 2016-09-30, Davin Pearson wrote:
> Please click on the following link to view my GNU Makefile
....

Responding to "Accessing the return values of the first argument to a
pipe" only: you could force the Makefile to use bash(1) for a shell,
and quoting its man page:

       The return status of a pipeline is the exit status of the last
       command, unless the pipefail option is enabled.  If pipefail is
       enabled, the pipeline's return status is the value of the last
       (rightmost) command to exit with a non-zero status, or zero if
       all commands exit successfully.  [...] The shell waits for all
       commands in the pipeline to terminate before returning a value.

But my gut feeling (which I cannot explain) is that if you need this,
you're using pipelines for the wrong job somehow.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .
0
Jorgen
10/1/2016 9:44:54 AM
Jorgen Grahn <grahn+nntp@snipabacken.se> writes:
> On Fri, 2016-09-30, Rainer Weikusat wrote:
>> Davin Pearson <davin.pearson@gmail.com> writes:
>>> Please click on the following link to view my GNU Makefile
>>>
>>> http://davin.50webs.com/J.T.W/tutorial-18-advanced-jtw.html
>>>
>>> Could you please come up with some code that acts on the return
>>> values of java and javac in my Makefile.  Presently the return
>>> values of java and javac are ignored, which means that you
>>> need to issue to following command before building the *.class
>>> files from *.java files and building *.java files from *.jtw files.
>>
>> It's somewhat unclear what you're trying to do with this. The usual way
>> to do a multi-step compilation would be to let make detect that the
>> command failed which will then cause the procedure to be aborted.
>>
>> What's the purpose of this line:
>>
>> javac $(JAVAC_FLAGS) $$(find . -name "*.java") |& emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \ 
>> |& grep "input[0-9]:" - \ 
>> |& sed -e "s/input[0-9]://g" -
>>
>> and specifically, why isn't javac called on the rule input files
>> (usually via $^ or $<) but all .java files found somewhere below the
>> current directory?
>
> I don't understand the goal, and I don't use Java, but I seem to
> remember from the 1990s that javac wants to be handed all *.java in
> one invocation.

[rw@duesterwald]/tmp $cat hello.java 
public class hello {
        public static void makeSomeNoise()
        {
                System.out.println("Denkste!");
        }
}
[rw@duesterwald]/tmp $cat NotAnObject.java 
class NotAnObject
{
        public static void main(String[] args)
        {
                hello.makeSomeNoise();
        }
}
[rw@duesterwald]/tmp $cat Makefile 
NotAnObject.class: NotAnObject.java hello.class

clean:
        -rm *.class

%.class: %.java
        javac $<
[rw@duesterwald]/tmp $make
javac hello.java
javac NotAnObject.java
[rw@duesterwald]/tmp $java NotAnObject 
Denkste!

---------------------------------------------

It's not necessary (for this simple example) to compile the two .java
files separately as the Java compiler (this one at least) will compile
hello.java upon encountering the class in the other file if a there's no
hello.class file but it's certainly possible.
0
Rainer
10/1/2016 11:11:04 AM
Jorgen Grahn <grahn+nntp@snipabacken.se> writes:
>On Fri, 2016-09-30, Rainer Weikusat wrote:
>> Davin Pearson <davin.pearson@gmail.com> writes:
>>> Please click on the following link to view my GNU Makefile
>>>
>>> http://davin.50webs.com/J.T.W/tutorial-18-advanced-jtw.html
>>>
>>> Could you please come up with some code that acts on the return
>>> values of java and javac in my Makefile.  Presently the return
>>> values of java and javac are ignored, which means that you
>>> need to issue to following command before building the *.class
>>> files from *.java files and building *.java files from *.jtw files.
>>
>> It's somewhat unclear what you're trying to do with this. The usual way
>> to do a multi-step compilation would be to let make detect that the
>> command failed which will then cause the procedure to be aborted.
>>
>> What's the purpose of this line:
>>
>> javac $(JAVAC_FLAGS) $$(find . -name "*.java") |& emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \ 
>> |& grep "input[0-9]:" - \ 
>> |& sed -e "s/input[0-9]://g" -
>>
>> and specifically, why isn't javac called on the rule input files
>> (usually via $^ or $<) but all .java files found somewhere below the
>> current directory?
>
>I don't understand the goal, and I don't use Java, but I seem to
>remember from the 1990s that javac wants to be handed all *.java in
>one invocation.

And thats's what ant(1) was developed to do, built java projects.

One can invoke ant from make, but it's better to just use ant standalone.


0
scott
10/1/2016 1:45:57 PM
On Saturday, October 1, 2016 at 7:31:39 AM UTC+13, Rainer Weikusat wrote:
> Davin Pearson <davin dot pearson at gmail dot com> writes:
> > Please click on the following link to view my GNU Makefile
> >
> > http://davin.50webs.com/J.T.W/tutorial-18-advanced-jtw.html
> >
> > Could you please come up with some code that acts on the return
> > values of java and javac in my Makefile.  Presently the return
> > values of java and javac are ignored, which means that you
> > need to issue to following command before building the *.class
> > files from *.java files and building *.java files from *.jtw files.
> 
> It's somewhat unclear what you're trying to do with this. The usual way
> to do a multi-step compilation would be to let make detect that the
> command failed which will then cause the procedure to be aborted.
> 
> What's the purpose of this line:
> 
> javac $(JAVAC_FLAGS) $$(find . -name "*.java") |& emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \ 
> |& grep "input[0-9]:" - \ 
> |& sed -e "s/input[0-9]://g" -
> 
> and specifically, why isn't javac called on the rule input files
> (usually via $^ or $<) but all .java files found somewhere below the
> current directory?

okay I have changed $$(find . -name "*.java") -> $^

0
Davin
10/3/2016 2:59:55 AM
On Saturday, October 1, 2016 at 10:44:57 PM UTC+13, Jorgen Grahn wrote:
> On Fri, 2016-09-30, Davin Pearson wrote:
> > Please click on the following link to view my GNU Makefile
> ...
> 
> Responding to "Accessing the return values of the first argument to a
> pipe" only: you could force the Makefile to use bash(1) for a shell,
> and quoting its man page:
> 
>        The return status of a pipeline is the exit status of the last
>        command, unless the pipefail option is enabled.  If pipefail is
>        enabled, the pipeline's return status is the value of the last
>        (rightmost) command to exit with a non-zero status, or zero if
>        all commands exit successfully.  [...] The shell waits for all
>        commands in the pipeline to terminate before returning a value.
> 
> But my gut feeling (which I cannot explain) is that if you need this,
> you're using pipelines for the wrong job somehow.

The pipes seem to work just fine with the option "set +o pipefail" set.

Thanks for your help with debugging my GNU Makefile.
0
Davin
10/3/2016 3:02:09 AM
Davin Pearson <davin.pearson@gmail.com> writes:
> On Saturday, October 1, 2016 at 10:44:57 PM UTC+13, Jorgen Grahn wrote:
>> On Fri, 2016-09-30, Davin Pearson wrote:
>> > Please click on the following link to view my GNU Makefile
>> ...
>> 
>> Responding to "Accessing the return values of the first argument to a
>> pipe" only: you could force the Makefile to use bash(1) for a shell,
>> and quoting its man page:
>> 
>>        The return status of a pipeline is the exit status of the last
>>        command, unless the pipefail option is enabled.  If pipefail is
>>        enabled, the pipeline's return status is the value of the last
>>        (rightmost) command to exit with a non-zero status, or zero if
>>        all commands exit successfully.  [...] The shell waits for all
>>        commands in the pipeline to terminate before returning a value.
>> 
>> But my gut feeling (which I cannot explain) is that if you need this,
>> you're using pipelines for the wrong job somehow.
>
> The pipes seem to work just fine with the option "set +o pipefail" set.
>
> Thanks for your help with debugging my GNU Makefile.

That's a bash feature and you can't generally count on bash being
available and/ or being the default system shell (/bin/sh). If the
purpose of the pipeline is just output reformatting, dropping it
altogether might be a good idea. Other options would be

	- redirect the javac output to a temporary and use a compound
          command like this (untested):

          javac $^ >/tmp/.javac.$$ && emacs ...  </tmp/.javac.$$

	- write a small program which provides your 'complex compiler
          command' transparently and which exits with status of the
          javac process.
0
Rainer
10/3/2016 1:04:11 PM
Rainer Weikusat <rweikusat@talktalk.net> wrote:
>
> What's the purpose of this line:
>
> javac $(JAVAC_FLAGS) $$(find . -name "*.java") |& emacs

In addition to the other remarks:
|& is a bashism an will not work under most system shells.
Use instead the more verbose but compatible  2>&1 |
0
Martin
10/3/2016 1:57:15 PM
Rainer Weikusat <rweikusat@talktalk.net> wrote:
> Davin Pearson <davin.pearson@gmail.com> writes:
>>
>> The pipes seem to work just fine with the option "set +o pipefail" set.
>>
>> Thanks for your help with debugging my GNU Makefile.
>
> That's a bash feature and you can't generally count on bash being
> available and/ or being the default system shell (/bin/sh).

A way to avoid this bashism without the suggestion of temporary files
is to use redirection. Something along the line of

exec 4>&1
status=`{ { javac ...  2>&1; echo $? >&3; } | { emacs ...; } >&4; } 3>&1`
exec 4>&-
[ $status -eq 0 ]

The above is pure shell quote; for make, you have to put it in one
line and quote it correspondingly (e.g. $$ instead of $ and
replacing newlines by ";" Maybe something more I forgot...)

See also https://github.com/cheusov/pipestatus

Setting Followup-To comp.unix.shell
0
Martin
10/3/2016 2:47:59 PM
On 10/03/2016 03:04 PM, Rainer Weikusat wrote:
> 	- redirect the javac output to a temporary and use a compound
>           command like this (untested):
>
>           javac $^ >/tmp/.javac.$$ && emacs ...  </tmp/.javac.$$

Depending on available memory for the shell and the amount of output, it might 
also work to capture javac output in a shell variable:

	javac_output=`javac $(JAVAC_FLAGS) $$(find . -name "*.java") 2>&1` \
	&& echo "$java_output" \
	| emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el \
	--funcall doit 2>&1 | grep "input[0-9]:" - 2>&1 \
	| sed -e "s/input[0-9]://g" - \
	|| ( echo "$java_output" >&2 ; exit 1)

might work just as well in a portable fashion and fail early if javac returns an 
error.

Thomas

0
Thomas
10/4/2016 11:47:11 AM
On Tuesday, October 4, 2016 at 2:04:16 AM UTC+13, Rainer Weikusat wrote:
> Davin Pearson <davin dot pearson at gmail dot com> writes:
> > On Saturday, October 1, 2016 at 10:44:57 PM UTC+13, Jorgen Grahn wrote:
> >> On Fri, 2016-09-30, Davin Pearson wrote:
> >> > Please click on the following link to view my GNU Makefile
> >> ...
> >> 
> >> Responding to "Accessing the return values of the first argument to a
> >> pipe" only: you could force the Makefile to use bash(1) for a shell,
> >> and quoting its man page:
> >> 
> >>        The return status of a pipeline is the exit status of the last
> >>        command, unless the pipefail option is enabled.  If pipefail is
> >>        enabled, the pipeline's return status is the value of the last
> >>        (rightmost) command to exit with a non-zero status, or zero if
> >>        all commands exit successfully.  [...] The shell waits for all
> >>        commands in the pipeline to terminate before returning a value.
> >> 
> >> But my gut feeling (which I cannot explain) is that if you need this,
> >> you're using pipelines for the wrong job somehow.
> >
> > The pipes seem to work just fine with the option "set +o pipefail" set.
> >
> > Thanks for your help with debugging my GNU Makefile.
> 
> That's a bash feature and you can't generally count on bash being
> available and/ or being the default system shell (/bin/sh). If the
> purpose of the pipeline is just output reformatting, dropping it
> altogether might be a good idea. Other options would be
> 
> 	- redirect the javac output to a temporary and use a compound
>           command like this (untested):
> 
>           javac $^ >/tmp/.javac.$$ && emacs ...  </tmp/.javac.$$

What does the $$ do? I realise that sh will see $, but what does $ on its own do?
 
> 	- write a small program which provides your 'complex compiler
>           command' transparently and which exits with status of the
>           javac process.

You just mentioned the javac call above.  Do you want me to write an elisp batch file script that calls javac inside of it?
0
Davin
10/5/2016 3:19:27 AM
Davin Pearson <davin.pearson@gmail.com> writes:
> On Tuesday, October 4, 2016 at 2:04:16 AM UTC+13, Rainer Weikusat wrote:
>> Davin Pearson <davin dot pearson at gmail dot com> writes:
>> > On Saturday, October 1, 2016 at 10:44:57 PM UTC+13, Jorgen Grahn wrote:
>> >> On Fri, 2016-09-30, Davin Pearson wrote:
>> >> > Please click on the following link to view my GNU Makefile
>> >> ...
>> >> 
>> >> Responding to "Accessing the return values of the first argument to a
>> >> pipe" only: you could force the Makefile to use bash(1) for a shell,
>> >> and quoting its man page:
>> >> 
>> >>        The return status of a pipeline is the exit status of the last
>> >>        command, unless the pipefail option is enabled.  If pipefail is
>> >>        enabled, the pipeline's return status is the value of the last
>> >>        (rightmost) command to exit with a non-zero status, or zero if
>> >>        all commands exit successfully.  [...] The shell waits for all
>> >>        commands in the pipeline to terminate before returning a value.
>> >> 
>> >> But my gut feeling (which I cannot explain) is that if you need this,
>> >> you're using pipelines for the wrong job somehow.
>> >
>> > The pipes seem to work just fine with the option "set +o pipefail" set.
>> >
>> > Thanks for your help with debugging my GNU Makefile.
>> 
>> That's a bash feature and you can't generally count on bash being
>> available and/ or being the default system shell (/bin/sh). If the
>> purpose of the pipeline is just output reformatting, dropping it
>> altogether might be a good idea. Other options would be
>> 
>> 	- redirect the javac output to a temporary and use a compound
>>           command like this (untested):
>> 
>>           javac $^ >/tmp/.javac.$$ && emacs ...  </tmp/.javac.$$
>
> What does the $$ do? I realise that sh will see $, but what does $ on
> its own do?

This should probably have been $$$$ which should end up as $$ in the
shell, representing the pid of the shell process.

>> 	- write a small program which provides your 'complex compiler
>>           command' transparently and which exits with status of the
>>           javac process.
>
> You just mentioned the javac call above.  Do you want me to write an
> elisp batch file script that calls javac inside of it?

Anything which has the pipeline built in and appears to make/ the shell as single
command existing with exit code of the javac process would do.

The complete pipeline is

emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \
|& grep "input[0-9]:" - \
|& sed -e "s/input[0-9]://g" - 

The grep selects lines containing a pattern and sed removes what matched
the pattern from theses line. This can be expressed with sed alone as

sed -n 's/input[0-9]://gp'

The -n means "don't print anything by default" and the /p flag means
"print the result of the substitution". As only lines containing the
pattern will trigger a substituation, other lines will be filtered out
implicitly.

The simplified pipeline could be put into a shell script and a pretty
trivial C program (that's what I'd use for a simple task like this)
could start a javac sub-process with its stdout and stderr redirected to
a pipe, followed by starting a 'remaining pipeline' process whose stdin
has been redirected from the pipe. It would then wait until both
coprocesses have terminated and exit with the status reported by the
first.
0
Rainer
10/5/2016 10:27:05 AM
On Wednesday, October 5, 2016 at 11:27:09 PM UTC+13, Rainer Weikusat wrote:
> Davin Pearson <davin dot pearson at gmail.com> writes:
> > On Tuesday, October 4, 2016 at 2:04:16 AM UTC+13, Rainer Weikusat wrote:
> >> Davin Pearson <davin dot pearson at gmail dot com> writes:
> >> > On Saturday, October 1, 2016 at 10:44:57 PM UTC+13, Jorgen Grahn wrote:
> >> >> On Fri, 2016-09-30, Davin Pearson wrote:
> >> >> > Please click on the following link to view my GNU Makefile
> >> >> ...
> >> >> 
> >> >> Responding to "Accessing the return values of the first argument to a
> >> >> pipe" only: you could force the Makefile to use bash(1) for a shell,
> >> >> and quoting its man page:
> >> >> 
> >> >>        The return status of a pipeline is the exit status of the last
> >> >>        command, unless the pipefail option is enabled.  If pipefail is
> >> >>        enabled, the pipeline's return status is the value of the last
> >> >>        (rightmost) command to exit with a non-zero status, or zero if
> >> >>        all commands exit successfully.  [...] The shell waits for all
> >> >>        commands in the pipeline to terminate before returning a value.
> >> >> 
> >> >> But my gut feeling (which I cannot explain) is that if you need this,
> >> >> you're using pipelines for the wrong job somehow.
> >> >
> >> > The pipes seem to work just fine with the option "set +o pipefail" set.
> >> >
> >> > Thanks for your help with debugging my GNU Makefile.
> >> 
> >> That's a bash feature and you can't generally count on bash being
> >> available and/ or being the default system shell (/bin/sh). If the
> >> purpose of the pipeline is just output reformatting, dropping it
> >> altogether might be a good idea. Other options would be
> >> 
> >> 	- redirect the javac output to a temporary and use a compound
> >>           command like this (untested):
> >> 
> >>           javac $^ >/tmp/.javac.$$ && emacs ...  </tmp/.javac.$$
> >
> > What does the $$ do? I realise that sh will see $, but what does $ on
> > its own do?
> 
> This should probably have been $$$$ which should end up as $$ in the
> shell, representing the pid of the shell process.
> 
> >> 	- write a small program which provides your 'complex compiler
> >>           command' transparently and which exits with status of the
> >>           javac process.
> >
> > You just mentioned the javac call above.  Do you want me to write an
> > elisp batch file script that calls javac inside of it?
> 
> Anything which has the pipeline built in and appears to make/ the shell as single
> command existing with exit code of the javac process would do.
> 
> The complete pipeline is
> 
> emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \
> |& grep "input[0-9]:" - \
> |& sed -e "s/input[0-9]://g" - 
> 
> The grep selects lines containing a pattern and sed removes what matched
> the pattern from theses line. This can be expressed with sed alone as
> 
> sed -n 's/input[0-9]://gp'
> 
> The -n means "don't print anything by default" and the /p flag means
> "print the result of the substitution". As only lines containing the
> pattern will trigger a substituation, other lines will be filtered out
> implicitly.
> 
> The simplified pipeline could be put into a shell script and a pretty
> trivial C program (that's what I'd use for a simple task like this)
> could start a javac sub-process with its stdout and stderr redirected to
> a pipe, followed by starting a 'remaining pipeline' process whose stdin
> has been redirected from the pipe. It would then wait until both
> coprocesses have terminated and exit with the status reported by the
> first.

Do I use the int system(const char*) command to do this?

How do I go about waiting until both processes have terminated?  Does the system command return when both processes have finished?

How do I get the return status of the first command?

Thanking you for your help...
0
Davin
10/8/2016 12:13:42 AM
Davin Pearson <davin.pearson@gmail.com> writes:
> On Wednesday, October 5, 2016 at 11:27:09 PM UTC+13, Rainer Weikusat wrote:

[...]

>> Anything which has the pipeline built in and appears to make/ the shell as single
>> command existing with exit code of the javac process would do.
>> 
>> The complete pipeline is
>> 
>> emacs --batch --eval "(setq *stump* \"$*\")" --load jtw-javac.el --funcall doit \
>> |& grep "input[0-9]:" - \
>> |& sed -e "s/input[0-9]://g" - 

[...]

>> The simplified pipeline could be put into a shell script and a pretty
>> trivial C program (that's what I'd use for a simple task like this)
>> could start a javac sub-process with its stdout and stderr redirected to
>> a pipe, followed by starting a 'remaining pipeline' process whose stdin
>> has been redirected from the pipe. It would then wait until both
>> coprocesses have terminated and exit with the status reported by the
>> first.
>
> Do I use the int system(const char*) command to do this?
>
> How do I go about waiting until both processes have terminated?  Does
> the system command return when both processes have finished?
>
> How do I get the return status of the first command?

Use the fork, Luke.

--------------
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#define PIPELINE	"grep"

static int die_(char const *fnc, char *sysc)
{
    fprintf(stderr, "%s: %s: %s(%d)", fnc, sysc, strerror(errno), errno);
    exit(1);

    return -1;
}

#define die(sysc) die_(__func__, sysc)

static int start_javac(char **argv, pid_t *pid)
{
    int fds[2], rc;

    rc = pipe(fds);
    rc != -1 || die("pipe");

    switch (*pid = fork()) {
    case -1:
	die("fork");

    case 0:
	close(*fds);
	
	dup2(fds[1], 1);
	dup2(fds[1], 2);
	close(fds[1]);

	*argv = "javac";
	execvp("javac", argv);
	die("execvp");
    }

    close(fds[1]);
    return *fds;
}

static void start_pipeline(int in_fd, char *stem)
{
    switch (fork()) {
    case -1:
	die("fork");

    case 0:
	dup2(in_fd, 0);
	close(in_fd);

	execlp(PIPELINE, PIPELINE, stem, (void *)0);
	die("execlp");
    }
}

static int wait_for_children(pid_t javac_pid)
{
    pid_t dead;
    int status, j_status;

    do {
	do
	    dead = wait(&status);
	while (dead == -1 && errno == EINTR);

	if (dead == javac_pid)  j_status = status;
    } while (dead != -1);

    if (errno != ECHILD) die("wait");
    return WEXITSTATUS(j_status);
}

int main(int argc, char **argv)
{
    pid_t javac_pid;
    char *stem;
    int out_fd, status;

    if (argc < 3) {
	fprintf(stderr, "Usage: cmpl <stem arg> <javac input file>+\n");
	exit(1);
    }

    ++argv;
    stem = *argv;

    out_fd = start_javac(argv, &javac_pid);
    start_pipeline(out_fd, stem);
    close(out_fd);

    status = wait_for_children(javac_pid);
    return status;
}
0
Rainer
10/9/2016 8:00:32 PM
On Monday, October 10, 2016 at 9:00:37 AM UTC+13, Rainer Weikusat wrote:
> Davin Pearson <davin dot pearson at gmail dot com> writes:
> > On Wednesday, October 5, 2016 at 11:27:09 PM UTC+13, Rainer Weikusat wrote:
> 

When I try to compile it, it gives me the following errors:

Should I really be using cygwin?

make 2016/fork/fork.run
* Compiling 2016/fork/fork.cc DEBUG
c:/MinGW/bin/g++.exe -g -O0 -I/cygdrive/c/MinGW/include/ -W -Wall -Wpointer-arith -Wformat -ffast-math -mwindows -c 2016/fork/fork.cc -o 2016/fork/fork.o
2016/fork/fork.cc:5:22: sys/wait.h: No such file or directory
2016/fork/fork.cc: In function `int start_javac(char**, pid_t*)':
2016/fork/fork.cc:23: `pipe' undeclared (first use this function)
2016/fork/fork.cc:23: (Each undeclared identifier is reported only once for 
   each function it appears in.)
2016/fork/fork.cc:26: `fork' undeclared (first use this function)
2016/fork/fork.cc: In function `int wait_for_children(int)':
2016/fork/fork.cc:71: `wait' undeclared (first use this function)
2016/fork/fork.cc:77: `WEXITSTATUS' undeclared (first use this function)
make: *** [Makefile.mk:73: 2016/fork/fork.o] Error 1

Compilation exited abnormally with code 2 at Mon Oct 10 01:48:22
Compilation took 1 second
0
Davin
10/10/2016 1:50:53 AM
On 2016-10-10, Davin Pearson <davin.pearson@gmail.com> wrote:
> On Monday, October 10, 2016 at 9:00:37 AM UTC+13, Rainer Weikusat wrote:
>> Davin Pearson <davin dot pearson at gmail dot com> writes:
>> > On Wednesday, October 5, 2016 at 11:27:09 PM UTC+13, Rainer Weikusat wrote:
>> 
>
> When I try to compile it, it gives me the following errors:
>
> Should I really be using cygwin?

Yes.

[plug] Please see this project:

http://www.kylheku.com/cygnal [/plug]

Cygwin is now LGPL-ed, so even if your program is proprietary,
closed-source, you can redistribute it on Windows, packaged
with Cygwin libs as its run-time.

The above Cygnal project (which I started myself just days
after the LGPL announcement in June) provides a binary drop-in
compatible version of the cygwin1.dll which changes certain
behaviors in Cygwin to make it nicer for "native" Windows
applications.

It's good enough for my use that I will never go anywhere near
MinGW.

-- 
TXR Programming Lanuage: http://nongnu.org/txr
Music DIY Mailing List:  http://www.kylheku.com/diy
ADA MP-1 Mailing List:   http://www.kylheku.com/mp1
0
Kaz
10/10/2016 2:21:52 AM
Davin Pearson <davin.pearson@gmail.com> writes:
> On Monday, October 10, 2016 at 9:00:37 AM UTC+13, Rainer Weikusat wrote:
>> Davin Pearson <davin dot pearson at gmail dot com> writes:
>> > On Wednesday, October 5, 2016 at 11:27:09 PM UTC+13, Rainer Weikusat wrote:
>> 
>
> When I try to compile it, it gives me the following errors:
>
> Should I really be using cygwin?
>
> make 2016/fork/fork.run
> * Compiling 2016/fork/fork.cc DEBUG
> c:/MinGW/bin/g++.exe -g -O0 -I/cygdrive/c/MinGW/include/ -W -Wall -Wpointer-arith -Wformat -ffast-math -mwindows -c 2016/fork/fork.cc -o 2016/fork/fork.o
> 2016/fork/fork.cc:5:22: sys/wait.h: No such file or directory

You should perhaps really go elsewhere for asking about your Windows
problems.
0
Rainer
10/10/2016 9:28:14 AM
Reply: