Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

BASIC is to computer programming as QWERTY is to typing. -- Seymour Papert


devel / comp.lang.c / Re: pipe a buffer to a program's stdin using popen

SubjectAuthor
* pipe a buffer to a program's stdin using popenJohn Forkosh
+* Re: pipe a buffer to a program's stdin using popenMark Bluemel
|+- Re: pipe a buffer to a program's stdin using popenMeredith Montgomery
|`- Re: pipe a buffer to a program's stdin using popenJohn Forkosh
+* Re: pipe a buffer to a program's stdin using popenKaz Kylheku
|+* Re: pipe a buffer to a program's stdin using popenKenny McCormack
||`- Re: pipe a buffer to a program's stdin using popenJohn Forkosh
|`* Re: pipe a buffer to a program's stdin using popenJohn Forkosh
| `* Re: pipe a buffer to a program's stdin using popenKaz Kylheku
|  `* Re: pipe a buffer to a program's stdin using popenJohn Forkosh
|   `- Re: pipe a buffer to a program's stdin using popenManfred
+* Re: pipe a buffer to a program's stdin using popenKeith Thompson
|`- Re: pipe a buffer to a program's stdin using popenKenny McCormack
`* Re: pipe a buffer to a program's stdin using popenLew Pitcher
 +* Re: pipe a buffer to a program's stdin using popenKenny McCormack
 |+- Re: pipe a buffer to a program's stdin using popenLew Pitcher
 |`* Re: pipe a buffer to a program's stdin using popenJohn Forkosh
 | `- Re: pipe a buffer to a program's stdin using popenKenny McCormack
 `- Re: pipe a buffer to a program's stdin using popenJohn Forkosh

1
pipe a buffer to a program's stdin using popen

<sqp79k$po6$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19761&group=comp.lang.c#19761

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: pipe a buffer to a program's stdin using popen
Date: Sat, 1 Jan 2022 09:35:48 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <sqp79k$po6$1@reader1.panix.com>
Injection-Date: Sat, 1 Jan 2022 09:35:48 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="26374"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Sat, 1 Jan 2022 09:35 UTC

Suppose I have a program that, in part, runs another program
using FILE *outptr=popen("some command string","r") and then
fread()'s its stdout from outptr. Now, if that other program
is otherpgm which reads input from its stdin, and I also want
that input to come from a file inputfile, then I could easily
just write FILE *outptr=popen("cat inputfile|otherpgm","r");

But here's the rub: rather than some inputfile on disk, my
program has an internal unsigned char buffer[9999] which is
what I want piped to otherpgm, but which I don't want written
to disk first. How can I get buffer piped to otherpgm's stdin
using popen()? Or some other mechanism, as long as I can read
otherpgm's stdout from within my program.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

Re: pipe a buffer to a program's stdin using popen

<0d5a369b-6e89-4b1b-9769-812406e84b05n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19762&group=comp.lang.c#19762

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:ad4:58cf:: with SMTP id dh15mr35686594qvb.125.1641036151902;
Sat, 01 Jan 2022 03:22:31 -0800 (PST)
X-Received: by 2002:ac8:5b90:: with SMTP id a16mr33935429qta.300.1641036151736;
Sat, 01 Jan 2022 03:22:31 -0800 (PST)
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!news.misty.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Sat, 1 Jan 2022 03:22:31 -0800 (PST)
In-Reply-To: <sqp79k$po6$1@reader1.panix.com>
Injection-Info: google-groups.googlegroups.com; posting-host=109.149.117.223; posting-account=3LA7mQoAAAByiBtHIUvpFq0_QEKnHGc9
NNTP-Posting-Host: 109.149.117.223
References: <sqp79k$po6$1@reader1.panix.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <0d5a369b-6e89-4b1b-9769-812406e84b05n@googlegroups.com>
Subject: Re: pipe a buffer to a program's stdin using popen
From: mark.blu...@gmail.com (Mark Bluemel)
Injection-Date: Sat, 01 Jan 2022 11:22:31 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Lines: 21
 by: Mark Bluemel - Sat, 1 Jan 2022 11:22 UTC

On Saturday, 1 January 2022 at 09:35:59 UTC, John Forkosh wrote:
> Suppose I have a program that, in part, runs another program
> using FILE *outptr=popen("some command string","r") and then
> fread()'s its stdout from outptr. Now, if that other program
> is otherpgm which reads input from its stdin, and I also want
> that input to come from a file inputfile, then I could easily
> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>
> But here's the rub: rather than some inputfile on disk, my
> program has an internal unsigned char buffer[9999] which is
> what I want piped to otherpgm, but which I don't want written
> to disk first. How can I get buffer piped to otherpgm's stdin
> using popen()? Or some other mechanism, as long as I can read
> otherpgm's stdout from within my program.
> --
> John Forkosh ( mailto: j...@f.com where j=john and f=forkosh )
popen() is part of the POSIX spec, I believe.

This is possibly better suited to comp.unix.programming or a similar newsgroup. I'd probably dig out a copy of https://en.wikipedia.org/wiki/Advanced_Programming_in_the_Unix_Environment and remind myself how to do this sort of thing. It would probably involve fork/exec and explicit pipe management.

Re: pipe a buffer to a program's stdin using popen

<86mtkfo7t7.fsf@levado.to>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19764&group=comp.lang.c#19764

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!ZLM1jiexBtedb4e/mq+x0Q.user.46.165.242.75.POSTED!not-for-mail
From: mmontgom...@levado.to (Meredith Montgomery)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sat, 01 Jan 2022 11:21:40 -0300
Organization: Aioe.org NNTP Server
Message-ID: <86mtkfo7t7.fsf@levado.to>
References: <sqp79k$po6$1@reader1.panix.com>
<0d5a369b-6e89-4b1b-9769-812406e84b05n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="59388"; posting-host="ZLM1jiexBtedb4e/mq+x0Q.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
X-Notice: Filtered by postfilter v. 0.9.2
Cancel-Lock: sha1:SD+p389xQJQpEgV15qzItekqOJI=
 by: Meredith Montgomery - Sat, 1 Jan 2022 14:21 UTC

Mark Bluemel <mark.bluemel@gmail.com> writes:

> On Saturday, 1 January 2022 at 09:35:59 UTC, John Forkosh wrote:
>> Suppose I have a program that, in part, runs another program
>> using FILE *outptr=popen("some command string","r") and then
>> fread()'s its stdout from outptr. Now, if that other program
>> is otherpgm which reads input from its stdin, and I also want
>> that input to come from a file inputfile, then I could easily
>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>
>> But here's the rub: rather than some inputfile on disk, my
>> program has an internal unsigned char buffer[9999] which is
>> what I want piped to otherpgm, but which I don't want written
>> to disk first. How can I get buffer piped to otherpgm's stdin
>> using popen()? Or some other mechanism, as long as I can read
>> otherpgm's stdout from within my program.
>> --
>> John Forkosh ( mailto: j...@f.com where j=john and f=forkosh )
> popen() is part of the POSIX spec, I believe.
>
> This is possibly better suited to comp.unix.programming or a similar
> newsgroup.

You mean

comp.unix.programmer

Re: pipe a buffer to a program's stdin using popen

<20220101101839.914@kylheku.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19773&group=comp.lang.c#19773

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: 480-992-...@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sat, 1 Jan 2022 19:51:01 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 52
Message-ID: <20220101101839.914@kylheku.com>
References: <sqp79k$po6$1@reader1.panix.com>
Injection-Date: Sat, 1 Jan 2022 19:51:01 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="73c30cd3ff102acfe1f81f3774ec797d";
logging-data="3178"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+RxH2EWmWUKaPO5bTbtpbu6f9fxzPZX0E="
User-Agent: slrn/1.0.3 (Linux)
Cancel-Lock: sha1:s6dGQtF7SEm6qf6SzwxTFRld+L8=
 by: Kaz Kylheku - Sat, 1 Jan 2022 19:51 UTC

On 2022-01-01, John Forkosh <forkosh@panix.com> wrote:
> Suppose I have a program that, in part, runs another program
> using FILE *outptr=popen("some command string","r") and then
> fread()'s its stdout from outptr. Now, if that other program
> is otherpgm which reads input from its stdin, and I also want
> that input to come from a file inputfile, then I could easily
> just write FILE *outptr=popen("cat inputfile|otherpgm","r");

That would be a useless use of cat; it could be done with:

FILE *outptr=popen("otherpgm < inputfile","r");
>
> But here's the rub: rather than some inputfile on disk, my
> program has an internal unsigned char buffer[9999] which is
> what I want piped to otherpgm, but which I don't want written
> to disk first. How can I get buffer piped to otherpgm's stdin
> using popen()? Or some other mechanism, as long as I can read
> otherpgm's stdout from within my program.

A program to which you send input while reading its output
is a coprocess. The popen function is for simple uses; it doesn't
support coprocesses. You have to cob those together yourself
with fork, exec, and various other functions.

With a coprocess, there is the risk of deadlock. It happens
like this: you write output for the process to read, while
it concurrently reads it and processes output. Because you're
writing, you're not reading. The process blocks trying to
write the data to you, and therefore stops reading. Since it
stops reading, you block writing to it.

In the general case, coprocesses require non-blocking I/O,
polling for input and output simultaneously, or else threads.
When the amount of data exchanged is small (so small that you can you
can rely on it all fitting into the pipe size on the given system)
deadlock may be avoided that way.

In the case of just wanting to feed a canned piece of data to
the process from memory, while reading its output, we can use
fork() to create a process which will do the feeding. We let
that run in the background. (Thus we have a multi-threaded solution via
multi-process, and do not need to juggle non-blocking I/O and polling.)

Just like in your original popen above, you have a "cat inputfile |
otherpgm" where cat is useless, a forked process is instantiated which
"cats" the memory buffer. That "memory cat" is not useless because a
piece of memory will not serve itself as a file.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

Re: pipe a buffer to a program's stdin using popen

<sqqfdr$2jpnj$1@news.xmission.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19774&group=comp.lang.c#19774

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gaze...@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sat, 1 Jan 2022 21:00:43 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <sqqfdr$2jpnj$1@news.xmission.com>
References: <sqp79k$po6$1@reader1.panix.com> <20220101101839.914@kylheku.com>
Injection-Date: Sat, 1 Jan 2022 21:00:43 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="2746099"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
 by: Kenny McCormack - Sat, 1 Jan 2022 21:00 UTC

In article <20220101101839.914@kylheku.com>,
Kaz Kylheku <480-992-1380@kylheku.com> wrote:
>On 2022-01-01, John Forkosh <forkosh@panix.com> wrote:
>> Suppose I have a program that, in part, runs another program
>> using FILE *outptr=popen("some command string","r") and then
>> fread()'s its stdout from outptr. Now, if that other program
>> is otherpgm which reads input from its stdin, and I also want
>> that input to come from a file inputfile, then I could easily
>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>
>That would be a useless use of cat; it could be done with:
>
> FILE *outptr=popen("otherpgm < inputfile","r");

Yeah, I noticed that, too. I think that, in this day and age, we can
probably ignore it - assume it was there only for pedagogic purposes, and
that OP actually knows better.

That said, two observations on the original question:

1) This is, of course, completely OT in clc. People who live their lives
around keeping clc pure and untainted by OT posts will no doubt start
jumping up and down about this any post now...

2) There are at least a half-dozen possible solutions to OP's problem that
spring to mind almost immediately. Which one is best will depend on two
things:
a) How deep OP's problem actually is. I.e., how much rigor is needed
in a solution - i.e., which solution is going to be "good enough".
b) OP's skill level - and how much grit-and-grime he is willing to put
up with.

That all said, one solution that comes to mind is to use bash's <<<
operator, like this:

sprintf(buffer,"otherpgm <<< '%s'",myinputstring);
FILE *outptr=popen(buffer,"r");

Now, the problem with this is that, on most systems, things run with
popen() don't get bash, even if bash is the standard and most commonly used
shell on the system. Sometimes, they get bash, but invoke it in a way that
disables most of the bash goodies (e.g., <<<).

Fixing this is left as an exercise for the reader...
(It *can* be done, but it gets messy)

--
The randomly chosen signature file that would have appeared here is more than 4
lines long. As such, it violates one or more Usenet RFCs. In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/FreeCollege

Re: pipe a buffer to a program's stdin using popen

<87fsq712p5.fsf@nosuchdomain.example.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19776&group=comp.lang.c#19776

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!feeder8.news.weretis.net!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Keith.S....@gmail.com (Keith Thompson)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sat, 01 Jan 2022 15:00:38 -0800
Organization: None to speak of
Lines: 21
Message-ID: <87fsq712p5.fsf@nosuchdomain.example.com>
References: <sqp79k$po6$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="431043dbf5bf54d703799e2d94f6f961";
logging-data="6243"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+BSI/CJ3SveGiU9Jxdc1Te"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:rNm3vODihgpHwRa00HQdljyhN+A=
sha1:RYFaTf6mEVjH4Lj3bh90osTvgUc=
 by: Keith Thompson - Sat, 1 Jan 2022 23:00 UTC

John Forkosh <forkosh@panix.com> writes:
> Suppose I have a program that, in part, runs another program
> using FILE *outptr=popen("some command string","r") and then
> fread()'s its stdout from outptr. Now, if that other program
> is otherpgm which reads input from its stdin, and I also want
> that input to come from a file inputfile, then I could easily
> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>
> But here's the rub: rather than some inputfile on disk, my
> program has an internal unsigned char buffer[9999] which is
> what I want piped to otherpgm, but which I don't want written
> to disk first. How can I get buffer piped to otherpgm's stdin
> using popen()? Or some other mechanism, as long as I can read
> otherpgm's stdout from within my program.

popen() is POSIX, not ISO C. Try comp.unix.programmer.

--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

Re: pipe a buffer to a program's stdin using popen

<sqqq0c$2jv6i$1@news.xmission.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19777&group=comp.lang.c#19777

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gaze...@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 00:01:16 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <sqqq0c$2jv6i$1@news.xmission.com>
References: <sqp79k$po6$1@reader1.panix.com> <87fsq712p5.fsf@nosuchdomain.example.com>
Injection-Date: Sun, 2 Jan 2022 00:01:16 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="2751698"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
 by: Kenny McCormack - Sun, 2 Jan 2022 00:01 UTC

In article <87fsq712p5.fsf@nosuchdomain.example.com>,
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>John Forkosh <forkosh@panix.com> writes:
>> Suppose I have a program that, in part, runs another program
>> using FILE *outptr=popen("some command string","r") and then
>> fread()'s its stdout from outptr. Now, if that other program
>> is otherpgm which reads input from its stdin, and I also want
>> that input to come from a file inputfile, then I could easily
>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>
>> But here's the rub: rather than some inputfile on disk, my
>> program has an internal unsigned char buffer[9999] which is
>> what I want piped to otherpgm, but which I don't want written
>> to disk first. How can I get buffer piped to otherpgm's stdin
>> using popen()? Or some other mechanism, as long as I can read
>> otherpgm's stdout from within my program.
>
>popen() is POSIX, not ISO C. Try comp.unix.programmer.

What'd I tell ya???

--
There are two kinds of Republicans: Billionaires and suckers.
Republicans: Please check your bank account and decide which one is you.

Re: pipe a buffer to a program's stdin using popen

<sqrq9o$lcv$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19782&group=comp.lang.c#19782

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 09:12:24 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <sqrq9o$lcv$1@reader1.panix.com>
References: <sqp79k$po6$1@reader1.panix.com> <20220101101839.914@kylheku.com> <sqqfdr$2jpnj$1@news.xmission.com>
Injection-Date: Sun, 2 Jan 2022 09:12:24 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="21919"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Sun, 2 Jan 2022 09:12 UTC

Kenny McCormack <gazelle@shell.xmission.com> wrote:
> Kaz Kylheku <480-992-1380@kylheku.com> wrote:
>> John Forkosh <forkosh@panix.com> wrote:
>>> Suppose I have a program that, in part, runs another program
>>> using FILE *outptr=popen("some command string","r") and then
>>> fread()'s its stdout from outptr. Now, if that other program
>>> is otherpgm which reads input from its stdin, and I also want
>>> that input to come from a file inputfile, then I could easily
>>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>
>>That would be a useless use of cat; it could be done with:
>>
>> FILE *outptr=popen("otherpgm < inputfile","r");
>
> Yeah, I noticed that, too. I think that, in this day and age, we can
> probably ignore it - assume it was there only for pedagogic purposes,
> and that OP actually knows better.

Yup (maybe "illustrative" rather than "pedagogic").

> That said, two observations on the original question:
>
> 1) This is, of course, completely OT in clc. People who live their
> lives around keeping clc pure and untainted by OT posts will no doubt
> start jumping up and down about this any post now...

Sorry about that, though I think maybe in stackexchange there'd possibly
be two simultaneously relevant tags: Unix C. I'm obviously interested
in implementing a solution, in C, whereby the C-relevance.

> 2) There are at least a half-dozen possible solutions to OP's problem
> that spring to mind almost immediately. Which one is best will depend
> on two things:
> a) How deep OP's problem actually is. I.e., how much rigor is needed
> in a solution - i.e., which solution is going to be "good enough".
If it works, it's good enough.

> b) OP's skill level - and how much grit-and-grime he is willing to put
> up with.
If it works, I'm probably willing to put up with it.

> That all said, one solution that comes to mind is to use bash's <<<
> operator, like this:
>
> sprintf(buffer,"otherpgm <<< '%s'",myinputstring);
> FILE *outptr=popen(buffer,"r");

Problem is that myinputstring (which is what I called
unsigned char buffer[9999] in original question) can be
many megabytes long, containing lots of hex chars (including \000).
If it were short and ascii, I might have illustratively
alternatively written
sprintf(buffer,"echo \"%s\" | otherpgm",myinputstring);
along the same lines as our "cat" discussion above.

> Now, the problem with this is that, on most systems,
> things run with popen() don't get bash, even if bash
> is the standard and most commonly used shell on the system.
> Sometimes, they get bash, but invoke it in a way that
> disables most of the bash goodies (e.g., <<<).
>
> Fixing this is left as an exercise for the reader...
> (It *can* be done, but it gets messy)

--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

Re: pipe a buffer to a program's stdin using popen

<sqrrav$k2e$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19783&group=comp.lang.c#19783

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 09:30:07 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <sqrrav$k2e$1@reader1.panix.com>
References: <sqp79k$po6$1@reader1.panix.com> <20220101101839.914@kylheku.com>
Injection-Date: Sun, 2 Jan 2022 09:30:07 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="20558"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Sun, 2 Jan 2022 09:30 UTC

Kaz Kylheku <480-992-1380@kylheku.com> wrote:
> On 2022-01-01, John Forkosh <forkosh@panix.com> wrote:
>> Suppose I have a program that, in part, runs another program
>> using FILE *outptr=popen("some command string","r") and then
>> fread()'s its stdout from outptr. Now, if that other program
>> is otherpgm which reads input from its stdin, and I also want
>> that input to come from a file inputfile, then I could easily
>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>
> That would be a useless use of cat; it could be done with:
> FILE *outptr=popen("otherpgm < inputfile","r");

Thanks, Kaz:
Yeah, I'm not actually doing either; the chosen illustration
was basically just pipes versus redirection, and since I was
kind of guessing the ultimate answer more likely involves pipes,
I illustrated it along those lines.

>> But here's the rub: rather than some inputfile on disk, my
>> program has an internal unsigned char buffer[9999] which is
>> what I want piped to otherpgm, but which I don't want written
>> to disk first. How can I get buffer piped to otherpgm's stdin
>> using popen()? Or some other mechanism, as long as I can read
>> otherpgm's stdout from within my program.

> A program to which you send input while reading its output
> is a coprocess. The popen function is for simple uses; it doesn't
> support coprocesses. You have to cob those together yourself
> with fork, exec, and various other functions.

Yeah, I've done a little, but not much, of that. And, as
suggested in a preceding followup, I actually have a hardback
paper copy of Stevens' APUE, which I occasionally refer to.
But I couldn't quite figure out what to do from his Chapters
14 and 15, assuming that's where an answer's buried.

> With a coprocess, there is the risk of deadlock. It happens
> like this: you write output for the process to read, while
> it concurrently reads it and processes output. Because you're
> writing, you're not reading. The process blocks trying to
> write the data to you, and therefore stops reading. Since it
> stops reading, you block writing to it.

Not a problem in my case. The 'otherpgm' reads all its input
before it writes anything.

> In the general case, coprocesses require non-blocking I/O,
> polling for input and output simultaneously, or else threads.
> When the amount of data exchanged is small (so small that you can you
> can rely on it all fitting into the pipe size on the given system)
> deadlock may be avoided that way.
>
> In the case of just wanting to feed a canned piece of data to
> the process from memory, while reading its output, we can use
> fork() to create a process which will do the feeding.

Feed how, exactly??? That had occurred to me (at least if I
correctly understand what you're saying), but as far as I could
tell that forked child is in exactly the same predicament as the
parent was in my original question: how does it pipe (or redirect
or whatever) a large unsigned char buffer[9999] (actually
malloc/realloc'ed, often larger than 20MB) from its memory to
the stdin of that 'otherpgm'?

> We let that run in the background. (Thus we have a multi-threaded
> solution via multi-process, and do not need to juggle non-blocking
> I/O and polling.)
>
> Just like in your original popen above, you have a "cat inputfile |
> otherpgm" where cat is useless, a forked process is instantiated which
> "cats" the memory buffer. That "memory cat" is not useless because a
> piece of memory will not serve itself as a file.

--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

Re: pipe a buffer to a program's stdin using popen

<sqrriq$k2e$2@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19784&group=comp.lang.c#19784

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 09:34:18 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <sqrriq$k2e$2@reader1.panix.com>
References: <sqp79k$po6$1@reader1.panix.com> <0d5a369b-6e89-4b1b-9769-812406e84b05n@googlegroups.com>
Injection-Date: Sun, 2 Jan 2022 09:34:18 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="20558"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Sun, 2 Jan 2022 09:34 UTC

Mark Bluemel <mark.bluemel@gmail.com> wrote:
> John Forkosh wrote:
>> Suppose I have a program that, in part, runs another program
>> using FILE *outptr=popen("some command string","r") and then
>> fread()'s its stdout from outptr. Now, if that other program
>> is otherpgm which reads input from its stdin, and I also want
>> that input to come from a file inputfile, then I could easily
>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>
>> But here's the rub: rather than some inputfile on disk, my
>> program has an internal unsigned char buffer[9999] which is
>> what I want piped to otherpgm, but which I don't want written
>> to disk first. How can I get buffer piped to otherpgm's stdin
>> using popen()? Or some other mechanism, as long as I can read
>> otherpgm's stdout from within my program.
>> --
>> John Forkosh ( mailto: j...@f.com where j=john and f=forkosh )
> popen() is part of the POSIX spec, I believe.
>
> This is possibly better suited to comp.unix.programming
> or a similar newsgroup. I'd probably dig out a copy of
> https://en.wikipedia.org/wiki/Advanced_Programming_in_the_Unix_Environment
> and remind myself how to do this sort of thing.
> It would probably involve fork/exec and explicit pipe management.

Thanks, Mark. Yeah, I actually have a hardback paper copy of APUE,
purchased in the 1990's. I've only occasionally (very occasionally)
used fork, etc, and couldn't quite figure out how to do what I want
from Chapters 14 and 15. The answer may well be there, but I couldn't
quite figure it out.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

Re: pipe a buffer to a program's stdin using popen

<sqs7a1$o59$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19786&group=comp.lang.c#19786

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitc...@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 12:54:25 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 28
Message-ID: <sqs7a1$o59$1@dont-email.me>
References: <sqp79k$po6$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 2 Jan 2022 12:54:25 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="b0e6fe5edf99c430a4d0d6b724e43c6e";
logging-data="24745"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/Hd4Vtd+VLc/oaIZ2PBJH+81c7e8rdPvo="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:ZC39v0QdRvacyoKNd49C4uhsXwU=
 by: Lew Pitcher - Sun, 2 Jan 2022 12:54 UTC

On Sat, 01 Jan 2022 09:35:48 +0000, John Forkosh wrote:

> Suppose I have a program that, in part, runs another program
> using FILE *outptr=popen("some command string","r") and then
> fread()'s its stdout from outptr. Now, if that other program
> is otherpgm which reads input from its stdin, and I also want
> that input to come from a file inputfile, then I could easily
> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>
> But here's the rub: rather than some inputfile on disk, my
> program has an internal unsigned char buffer[9999] which is
> what I want piped to otherpgm, but which I don't want written
> to disk first. How can I get buffer piped to otherpgm's stdin
> using popen()? Or some other mechanism, as long as I can read
> otherpgm's stdout from within my program.

Assuming a Unix-like environment,
pipe() to create a pair of unidirectional pipes
fork() to create a child process
in parent, close() the [0] pipe, and write() your data to the [1] pipe
in child, close(STDIN_FILENO), dup() the [1] pipe, and then exec() your
target "some command string" executable

If you want, we can have a more detailed discussion on comp.unix.programmer

--
Lew Pitcher
"In Skills, We Trust"

Re: pipe a buffer to a program's stdin using popen

<sqseaq$2ko37$1@news.xmission.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19788&group=comp.lang.c#19788

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gaze...@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 14:54:18 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <sqseaq$2ko37$1@news.xmission.com>
References: <sqp79k$po6$1@reader1.panix.com> <sqs7a1$o59$1@dont-email.me>
Injection-Date: Sun, 2 Jan 2022 14:54:18 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="2777191"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
 by: Kenny McCormack - Sun, 2 Jan 2022 14:54 UTC

In article <sqs7a1$o59$1@dont-email.me>,
Lew Pitcher <lew.pitcher@digitalfreehold.ca> wrote:
....
>Assuming a Unix-like environment,
> pipe() to create a pair of unidirectional pipes
> fork() to create a child process
> in parent, close() the [0] pipe, and write() your data to the [1] pipe
> in child, close(STDIN_FILENO), dup() the [1] pipe, and then exec() your
> target "some command string" executable

The problem with this is that, as Kaz alluded to, pipes are only guaranteed
to be at least 4096 bytes in size - and deadlock is possible. The original
post suggested that the input string was about 10K (which is already too
big) in size, but subsequent followups by OP have stated that it could be
multi-megabytes. So, you can't just shove it all into the pipe in one go
(w/o having the reader be reading some of it as you go).

Also, OP was using popen() to encapsulate the gory details of pipe/fork/dup/exec.
Going this route, he would lose the simplicity/elegance of popen().

>If you want, we can have a more detailed discussion on comp.unix.programmer

Quite so. I hope OP starts a thread there, so we can continue.

I wouldn't want to give any of the Not-Cs in this group anymore mental pain.

--
Faced with the choice between changing one's mind and proving that there is
no need to do so, almost everyone gets busy on the proof.

- John Kenneth Galbraith -

Re: pipe a buffer to a program's stdin using popen

<sqsgsm$f2r$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19789&group=comp.lang.c#19789

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitc...@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 15:37:59 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 34
Message-ID: <sqsgsm$f2r$1@dont-email.me>
References: <sqp79k$po6$1@reader1.panix.com> <sqs7a1$o59$1@dont-email.me>
<sqseaq$2ko37$1@news.xmission.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 2 Jan 2022 15:37:59 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="b0e6fe5edf99c430a4d0d6b724e43c6e";
logging-data="15451"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19fdEjB3GYyfIuZmjM12pyG03NyWeXoFTA="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:ijbSxRxhCS1MsdwAzIkuJcFBsWU=
 by: Lew Pitcher - Sun, 2 Jan 2022 15:37 UTC

On Sun, 02 Jan 2022 14:54:18 +0000, Kenny McCormack wrote:

> In article <sqs7a1$o59$1@dont-email.me>,
> Lew Pitcher <lew.pitcher@digitalfreehold.ca> wrote:
> ...

I posted this breadcrumb clue to give the OP a start in his
research. APUE covers all of these steps, and discusses the
resulting program design implications.

>>Assuming a Unix-like environment,
>> pipe() to create a pair of unidirectional pipes
>> fork() to create a child process
>> in parent, close() the [0] pipe, and write() your data to the [1] pipe
>> in child, close(STDIN_FILENO), dup() the [1] pipe, and then exec() your
>> target "some command string" executable
>
> The problem with this is that, as Kaz alluded to, pipes are only guaranteed
> to be at least 4096 bytes in size - and deadlock is possible.
[snip]

It was precisely this detail that prompted me to suggest that we continue the
conversation on comp.unix.programmer.

>>If you want, we can have a more detailed discussion on comp.unix.programmer
>
> Quite so. I hope OP starts a thread there, so we can continue.
>
> I wouldn't want to give any of the Not-Cs in this group anymore mental pain.

--
Lew Pitcher
"In Skills, We Trust"

Re: pipe a buffer to a program's stdin using popen

<sqsona$fmk$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19791&group=comp.lang.c#19791

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 17:51:38 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <sqsona$fmk$1@reader1.panix.com>
References: <sqp79k$po6$1@reader1.panix.com> <sqs7a1$o59$1@dont-email.me>
Injection-Date: Sun, 2 Jan 2022 17:51:38 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="16084"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Sun, 2 Jan 2022 17:51 UTC

Lew Pitcher <lew.pitcher@digitalfreehold.ca> wrote:
> John Forkosh wrote:
>> Suppose I have a program that, in part, runs another program
>> using FILE *outptr=popen("some command string","r") and then
>> fread()'s its stdout from outptr. Now, if that other program
>> is otherpgm which reads input from its stdin, and I also want
>> that input to come from a file inputfile, then I could easily
>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>
>> But here's the rub: rather than some inputfile on disk, my
>> program has an internal unsigned char buffer[9999] which is
>> what I want piped to otherpgm, but which I don't want written
>> to disk first. How can I get buffer piped to otherpgm's stdin
>> using popen()? Or some other mechanism, as long as I can read
>> otherpgm's stdout from within my program.
>
> Assuming a Unix-like environment,
> pipe() to create a pair of unidirectional pipes
> fork() to create a child process
> in parent, close() the [0] pipe, and write() your data to the [1] pipe
> in child, close(STDIN_FILENO), dup() the [1] pipe, and then exec() your
> target "some command string" executable
> If you want, we can have a more detailed discussion on comp.unix.programmer

Thanks, Lew, that looks like a real good synopsis, modulo Kenny's
pipe size followup remark which might pose a problem. Let me take
another look through APUE with your synopsis in mind, and maybe I
can figure it out from there without too much more detailed disc-
ussion. Google, e.g.,
http://unixwiz.net/techtips/remap-pipe-fds.html
also turned up what seems to be some useful discussion.

And, again, apologies to those (as Kenny put it), "Not-Cs in this
group". However, I did notice a whole bunch of "Beautiful Russian
Women" posts (from "outpost season") in comp.unix.programmer, and
nobody seemed to be complaining much. I suppose beautiful Russian
women are just more interesting than Unix pipes. (Maybe we should
instead be discussing their 'stdin's and 'stdout's?:)
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

Re: pipe a buffer to a program's stdin using popen

<sqsp80$fmk$2@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19792&group=comp.lang.c#19792

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 18:00:32 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <sqsp80$fmk$2@reader1.panix.com>
References: <sqp79k$po6$1@reader1.panix.com> <sqs7a1$o59$1@dont-email.me> <sqseaq$2ko37$1@news.xmission.com>
Injection-Date: Sun, 2 Jan 2022 18:00:32 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="16084"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Sun, 2 Jan 2022 18:00 UTC

Kenny McCormack <gazelle@shell.xmission.com> wrote:
> Lew Pitcher <lew.pitcher@digitalfreehold.ca> wrote:
> ...
>>Assuming a Unix-like environment,
>> pipe() to create a pair of unidirectional pipes
>> fork() to create a child process
>> in parent, close() the [0] pipe, and write() your data to the [1] pipe
>> in child, close(STDIN_FILENO), dup() the [1] pipe, and then exec() your
>> target "some command string" executable
>
> The problem with this is that, as Kaz alluded to, pipes are only guaranteed
> to be at least 4096 bytes in size - and deadlock is possible. The original
> post suggested that the input string was about 10K (which is already too
> big) in size, but subsequent followups by OP have stated that it could be
> multi-megabytes. So, you can't just shove it all into the pipe in one go
> (w/o having the reader be reading some of it as you go).

Yeah, definitely can be multi-MB input to stdin (when I originally
wrote "unsigned char buffer[9999]", I hadn't meant to imply that as
a maximum). Thanks for the additional warning, and I'll explicitly
look for that discussion while munging through APUE again.

> Also, OP was using popen() to encapsulate the gory details of
> pipe/fork/dup/exec. Going this route, he would lose the
> simplicity/elegance of popen().

Yeah, I already pretty much figured out from the preceding discussion
that "lose the simplicity/elegance" was a foregone conclusion.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

Re: pipe a buffer to a program's stdin using popen

<sqspdh$2ksqd$1@news.xmission.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19793&group=comp.lang.c#19793

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!xmission!nnrp.xmission!.POSTED.shell.xmission.com!not-for-mail
From: gaze...@shell.xmission.com (Kenny McCormack)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Sun, 2 Jan 2022 18:03:29 -0000 (UTC)
Organization: The official candy of the new Millennium
Message-ID: <sqspdh$2ksqd$1@news.xmission.com>
References: <sqp79k$po6$1@reader1.panix.com> <sqs7a1$o59$1@dont-email.me> <sqseaq$2ko37$1@news.xmission.com> <sqsp80$fmk$2@reader1.panix.com>
Injection-Date: Sun, 2 Jan 2022 18:03:29 -0000 (UTC)
Injection-Info: news.xmission.com; posting-host="shell.xmission.com:166.70.8.4";
logging-data="2782029"; mail-complaints-to="abuse@xmission.com"
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
Originator: gazelle@shell.xmission.com (Kenny McCormack)
 by: Kenny McCormack - Sun, 2 Jan 2022 18:03 UTC

In article <sqsp80$fmk$2@reader1.panix.com>,
John Forkosh <forkosh@panix.com> wrote:
....
>> Also, OP was using popen() to encapsulate the gory details of
>> pipe/fork/dup/exec. Going this route, he would lose the
>> simplicity/elegance of popen().
>
>Yeah, I already pretty much figured out from the preceding discussion
>that "lose the simplicity/elegance" was a foregone conclusion.

It's not.

I have in mind a solution that is simple, elegant and Linux-specific. It
does not require you to give up using popen().

Once we get this moved to comp.unix.programmer, we can discuss it further.

--
I love the poorly educated.

Re: pipe a buffer to a program's stdin using popen

<20220102155759.587@kylheku.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19794&group=comp.lang.c#19794

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: 480-992-...@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Mon, 3 Jan 2022 00:03:23 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 91
Message-ID: <20220102155759.587@kylheku.com>
References: <sqp79k$po6$1@reader1.panix.com>
<20220101101839.914@kylheku.com> <sqrrav$k2e$1@reader1.panix.com>
Injection-Date: Mon, 3 Jan 2022 00:03:23 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="984d492342ad2c050949660973b80bc8";
logging-data="7434"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+cgvo3xsrJy6Ps/l60QTak9HjaHCd1DMQ="
User-Agent: slrn/1.0.3 (Linux)
Cancel-Lock: sha1:rPFqS80UfC978xJ9iKOZSBbShdU=
 by: Kaz Kylheku - Mon, 3 Jan 2022 00:03 UTC

On 2022-01-02, John Forkosh <forkosh@panix.com> wrote:
> Kaz Kylheku <480-992-1380@kylheku.com> wrote:
>> On 2022-01-01, John Forkosh <forkosh@panix.com> wrote:
>>> Suppose I have a program that, in part, runs another program
>>> using FILE *outptr=popen("some command string","r") and then
>>> fread()'s its stdout from outptr. Now, if that other program
>>> is otherpgm which reads input from its stdin, and I also want
>>> that input to come from a file inputfile, then I could easily
>>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>
>> That would be a useless use of cat; it could be done with:
>> FILE *outptr=popen("otherpgm < inputfile","r");
>
> Thanks, Kaz:
> Yeah, I'm not actually doing either; the chosen illustration
> was basically just pipes versus redirection, and since I was
> kind of guessing the ultimate answer more likely involves pipes,
> I illustrated it along those lines.
>
>>> But here's the rub: rather than some inputfile on disk, my
>>> program has an internal unsigned char buffer[9999] which is
>>> what I want piped to otherpgm, but which I don't want written
>>> to disk first. How can I get buffer piped to otherpgm's stdin
>>> using popen()? Or some other mechanism, as long as I can read
>>> otherpgm's stdout from within my program.
>
>> A program to which you send input while reading its output
>> is a coprocess. The popen function is for simple uses; it doesn't
>> support coprocesses. You have to cob those together yourself
>> with fork, exec, and various other functions.
>
> Yeah, I've done a little, but not much, of that. And, as
> suggested in a preceding followup, I actually have a hardback
> paper copy of Stevens' APUE, which I occasionally refer to.
> But I couldn't quite figure out what to do from his Chapters
> 14 and 15, assuming that's where an answer's buried.
>
>> With a coprocess, there is the risk of deadlock. It happens
>> like this: you write output for the process to read, while
>> it concurrently reads it and processes output. Because you're
>> writing, you're not reading. The process blocks trying to
>> write the data to you, and therefore stops reading. Since it
>> stops reading, you block writing to it.
>
> Not a problem in my case. The 'otherpgm' reads all its input
> before it writes anything.

That only exacerbates deadlock.

>
>> In the general case, coprocesses require non-blocking I/O,
>> polling for input and output simultaneously, or else threads.
>> When the amount of data exchanged is small (so small that you can you
>> can rely on it all fitting into the pipe size on the given system)
>> deadlock may be avoided that way.
>>
>> In the case of just wanting to feed a canned piece of data to
>> the process from memory, while reading its output, we can use
>> fork() to create a process which will do the feeding.
>
> Feed how, exactly??? That had occurred to me (at least if I

The feeding process (forked child) just sits in a loop sending the bytes
to one end of a pipe. That pipe is installed as the standard input
of the coprocess.

> correctly understand what you're saying), but as far as I could
> tell that forked child is in exactly the same predicament as the
> parent was in my original question: how does it pipe (or redirect
> or whatever) a large unsigned char buffer[9999] (actually
> malloc/realloc'ed, often larger than 20MB) from its memory to
> the stdin of that 'otherpgm'?

Your shell can do it:

cat_memory()
{
echo "string in shell's memory"
}

upcased=$(cat_memory | tr '[a-z]' '[A-Z]')

# upcased is now "STRING IN SHELL'S MEMORY"

The shell forks a process which calls the function (i.e. does not exec
anything external). And it forks a process for the "tr" command. As it's
doing that, it hooks up the pipes in all the right ways and so it goes.

The shell itself goes into a loop reading the output of the pipe,
so that it can gather it into a string via the $(...) syntax, and then
assign that to a variable when it's done.

Re: pipe a buffer to a program's stdin using popen

<squar8$166$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19797&group=comp.lang.c#19797

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Mon, 3 Jan 2022 08:07:04 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <squar8$166$1@reader1.panix.com>
References: <sqp79k$po6$1@reader1.panix.com> <20220101101839.914@kylheku.com> <sqrrav$k2e$1@reader1.panix.com> <20220102155759.587@kylheku.com>
Injection-Date: Mon, 3 Jan 2022 08:07:04 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="1222"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Mon, 3 Jan 2022 08:07 UTC

Kaz Kylheku <480-992-1380@kylheku.com> wrote:
> John Forkosh <forkosh@panix.com> wrote:
>> Kaz Kylheku <480-992-1380@kylheku.com> wrote:
>>> On 2022-01-01, John Forkosh <forkosh@panix.com> wrote:
>>>> Suppose I have a program that, in part, runs another program
>>>> using FILE *outptr=popen("some command string","r") and then
>>>> fread()'s its stdout from outptr. Now, if that other program
>>>> is otherpgm which reads input from its stdin, and I also want
>>>> that input to come from a file inputfile, then I could easily
>>>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>>
>>> That would be a useless use of cat; it could be done with:
>>> FILE *outptr=popen("otherpgm < inputfile","r");
>>
>> Thanks, Kaz:
>> Yeah, I'm not actually doing either; the chosen illustration
>> was basically just pipes versus redirection, and since I was
>> kind of guessing the ultimate answer more likely involves pipes,
>> I illustrated it along those lines.
>>
>>>> But here's the rub: rather than some inputfile on disk, my
>>>> program has an internal unsigned char buffer[9999] which is
>>>> what I want piped to otherpgm, but which I don't want written
>>>> to disk first. How can I get buffer piped to otherpgm's stdin
>>>> using popen()? Or some other mechanism, as long as I can read
>>>> otherpgm's stdout from within my program.
>>
>>> A program to which you send input while reading its output
>>> is a coprocess. The popen function is for simple uses; it doesn't
>>> support coprocesses. You have to cob those together yourself
>>> with fork, exec, and various other functions.
>>
>> Yeah, I've done a little, but not much, of that. And, as
>> suggested in a preceding followup, I actually have a hardback
>> paper copy of Stevens' APUE, which I occasionally refer to.
>> But I couldn't quite figure out what to do from his Chapters
>> 14 and 15, assuming that's where an answer's buried.
>>
>>> With a coprocess, there is the risk of deadlock. It happens
>>> like this: you write output for the process to read, while
>>> it concurrently reads it and processes output. Because you're
>>> writing, you're not reading. The process blocks trying to
>>> write the data to you, and therefore stops reading. Since it
>>> stops reading, you block writing to it.
>>
>> Not a problem in my case. The 'otherpgm' reads all its input
>> before it writes anything.
>
> That only exacerbates deadlock.

Oops, my bad. Guess I've got even more reading to do than I thought,
before I can wrap my head around how to do this properly.

>>> In the general case, coprocesses require non-blocking I/O,
>>> polling for input and output simultaneously, or else threads.
>>> When the amount of data exchanged is small (so small that you can you
>>> can rely on it all fitting into the pipe size on the given system)
>>> deadlock may be avoided that way.
>>>
>>> In the case of just wanting to feed a canned piece of data to
>>> the process from memory, while reading its output, we can use
>>> fork() to create a process which will do the feeding.
>>
>> Feed how, exactly??? That had occurred to me (at least if I
>
> The feeding process (forked child) just sits in a loop sending the bytes
> to one end of a pipe. That pipe is installed as the standard input
> of the coprocess.

Yeah, the synopsis posted by Lew
>> pipe() to create a pair of unidirectional pipes
>> fork() to create a child process
>> in parent, close() the [0] pipe, and write() your data to the [1] pipe
>> in child, close(STDIN_FILENO), dup() the [1] pipe, and then exec() your
>> target "some command string" executable
seems like a good outline to guide my further APUE reading,
maybe along with the example (also cited earlier) at
http://unixwiz.net/techtips/remap-pipe-fds.html

>> correctly understand what you're saying), but as far as I could
>> tell that forked child is in exactly the same predicament as the
>> parent was in my original question: how does it pipe (or redirect
>> or whatever) a large unsigned char buffer[9999] (actually
>> malloc/realloc'ed, often larger than 20MB) from its memory to
>> the stdin of that 'otherpgm'?
>
> Your shell can do it:
>
> cat_memory()
> {
> echo "string in shell's memory"
> }
>
> upcased=$(cat_memory | tr '[a-z]' '[A-Z]')
>
> # upcased is now "STRING IN SHELL'S MEMORY"
>
> The shell forks a process which calls the function (i.e. does not exec
> anything external). And it forks a process for the "tr" command. As it's
> doing that, it hooks up the pipes in all the right ways and so it goes.
>
> The shell itself goes into a loop reading the output of the pipe,
> so that it can gather it into a string via the $(...) syntax, and then
> assign that to a variable when it's done.

Thanks, Kaz, Kenny, Lew, Keith...
Sounded to me like straightforward functionality when I initially
asked how to do it, and therefore supposed there'd be a pretty easy
and straightforward way to implement it. But now seems to be a bit
harder than I expected. I'll nevertheless continue studying APUE and
all the stuff you've suggested, but for the time being just continue
using the already-coded-and-working (but inelegant) solution -- just
write the first program's output to a /tmp/file and then popen() the
second program with an "-f /tmp/file" to read that file (and finally
rm it). But I'll eventually re-implement that with your suggestions.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

Re: pipe a buffer to a program's stdin using popen

<sqvrad$bpi$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=19816&group=comp.lang.c#19816

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!TGB7PaTLuKrCBV1tLjiy3g.user.46.165.242.75.POSTED!not-for-mail
From: non...@add.invalid (Manfred)
Newsgroups: comp.lang.c
Subject: Re: pipe a buffer to a program's stdin using popen
Date: Mon, 3 Jan 2022 22:54:21 +0100
Organization: Aioe.org NNTP Server
Message-ID: <sqvrad$bpi$1@gioia.aioe.org>
References: <sqp79k$po6$1@reader1.panix.com> <20220101101839.914@kylheku.com>
<sqrrav$k2e$1@reader1.panix.com> <20220102155759.587@kylheku.com>
<squar8$166$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: gioia.aioe.org; logging-data="12082"; posting-host="TGB7PaTLuKrCBV1tLjiy3g.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.4.1
Content-Language: en-US
X-Notice: Filtered by postfilter v. 0.9.2
 by: Manfred - Mon, 3 Jan 2022 21:54 UTC

On 1/3/2022 9:07 AM, John Forkosh wrote:
> Kaz Kylheku <480-992-1380@kylheku.com> wrote:
>> John Forkosh <forkosh@panix.com> wrote:
>>> Kaz Kylheku <480-992-1380@kylheku.com> wrote:
>>>> On 2022-01-01, John Forkosh <forkosh@panix.com> wrote:
>>>>> Suppose I have a program that, in part, runs another program
>>>>> using FILE *outptr=popen("some command string","r") and then
>>>>> fread()'s its stdout from outptr. Now, if that other program
>>>>> is otherpgm which reads input from its stdin, and I also want
>>>>> that input to come from a file inputfile, then I could easily
>>>>> just write FILE *outptr=popen("cat inputfile|otherpgm","r");
>>>>
>>>> That would be a useless use of cat; it could be done with:
>>>> FILE *outptr=popen("otherpgm < inputfile","r");
>>>
>>> Thanks, Kaz:
>>> Yeah, I'm not actually doing either; the chosen illustration
>>> was basically just pipes versus redirection, and since I was
>>> kind of guessing the ultimate answer more likely involves pipes,
>>> I illustrated it along those lines.
>>>
>>>>> But here's the rub: rather than some inputfile on disk, my
>>>>> program has an internal unsigned char buffer[9999] which is
>>>>> what I want piped to otherpgm, but which I don't want written
>>>>> to disk first. How can I get buffer piped to otherpgm's stdin
>>>>> using popen()? Or some other mechanism, as long as I can read
>>>>> otherpgm's stdout from within my program.
>>>
>>>> A program to which you send input while reading its output
>>>> is a coprocess. The popen function is for simple uses; it doesn't
>>>> support coprocesses. You have to cob those together yourself
>>>> with fork, exec, and various other functions.
>>>
>>> Yeah, I've done a little, but not much, of that. And, as
>>> suggested in a preceding followup, I actually have a hardback
>>> paper copy of Stevens' APUE, which I occasionally refer to.
>>> But I couldn't quite figure out what to do from his Chapters
>>> 14 and 15, assuming that's where an answer's buried.
>>>
>>>> With a coprocess, there is the risk of deadlock. It happens
>>>> like this: you write output for the process to read, while
>>>> it concurrently reads it and processes output. Because you're
>>>> writing, you're not reading. The process blocks trying to
>>>> write the data to you, and therefore stops reading. Since it
>>>> stops reading, you block writing to it.
>>>
>>> Not a problem in my case. The 'otherpgm' reads all its input
>>> before it writes anything.
>>
>> That only exacerbates deadlock.
>
> Oops, my bad. Guess I've got even more reading to do than I thought,
> before I can wrap my head around how to do this properly.
>
>>>> In the general case, coprocesses require non-blocking I/O,
>>>> polling for input and output simultaneously, or else threads.
>>>> When the amount of data exchanged is small (so small that you can you
>>>> can rely on it all fitting into the pipe size on the given system)
>>>> deadlock may be avoided that way.
>>>>
>>>> In the case of just wanting to feed a canned piece of data to
>>>> the process from memory, while reading its output, we can use
>>>> fork() to create a process which will do the feeding.
>>>
>>> Feed how, exactly??? That had occurred to me (at least if I
>>
>> The feeding process (forked child) just sits in a loop sending the bytes
>> to one end of a pipe. That pipe is installed as the standard input
>> of the coprocess.
>
> Yeah, the synopsis posted by Lew
> >> pipe() to create a pair of unidirectional pipes
> >> fork() to create a child process
> >> in parent, close() the [0] pipe, and write() your data to the [1] pipe

I don't want to confuse things, but, while the above is correct (parent
closes p[0] and writes to p[1]), the part below is not:
child should close p[1], and read from p[0]. If you need to read from
stdin, then I believe the [0] pipe should be dup'd to stdin accordingly
(I've not used dup myself too much).

See 'man pipe' for a clear description and example code of this part.

> >> in child, close(STDIN_FILENO), dup() the [1] pipe, and then exec() your
> >> target "some command string" executable
> seems like a good outline to guide my further APUE reading,
> maybe along with the example (also cited earlier) at
> http://unixwiz.net/techtips/remap-pipe-fds.html
>
>>> correctly understand what you're saying), but as far as I could
>>> tell that forked child is in exactly the same predicament as the
>>> parent was in my original question: how does it pipe (or redirect
>>> or whatever) a large unsigned char buffer[9999] (actually
>>> malloc/realloc'ed, often larger than 20MB) from its memory to
>>> the stdin of that 'otherpgm'?
>>
>> Your shell can do it:
>>
>> cat_memory()
>> {
>> echo "string in shell's memory"
>> }
>>
>> upcased=$(cat_memory | tr '[a-z]' '[A-Z]')
>>
>> # upcased is now "STRING IN SHELL'S MEMORY"
>>
>> The shell forks a process which calls the function (i.e. does not exec
>> anything external). And it forks a process for the "tr" command. As it's
>> doing that, it hooks up the pipes in all the right ways and so it goes.
>>
>> The shell itself goes into a loop reading the output of the pipe,
>> so that it can gather it into a string via the $(...) syntax, and then
>> assign that to a variable when it's done.
>
> Thanks, Kaz, Kenny, Lew, Keith...
> Sounded to me like straightforward functionality when I initially
> asked how to do it, and therefore supposed there'd be a pretty easy
> and straightforward way to implement it. But now seems to be a bit
> harder than I expected. I'll nevertheless continue studying APUE and
> all the stuff you've suggested, but for the time being just continue
> using the already-coded-and-working (but inelegant) solution -- just
> write the first program's output to a /tmp/file and then popen() the
> second program with an "-f /tmp/file" to read that file (and finally
> rm it). But I'll eventually re-implement that with your suggestions.

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor