Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

Reactor error - core dumped!


devel / comp.unix.programmer / Re: a problem on pipes: making the child run less and parent writes to it

SubjectAuthor
* a problem on pipes: making the child run less and parent writes to itMeredith Montgomery
+- Re: a problem on pipes: making the child run less and parent writes to itSiri Cruise
+* Re: a problem on pipes: making the child run less and parent writesLew Pitcher
|+* Re: a problem on pipes: making the child run less and parent writes to itWayne Harris
||`- Re: a problem on pipes: making the child run less and parent writesLew Pitcher
|`* Re: a problem on pipes: making the child run less and parent writesLew Pitcher
| +* Re: a problem on pipes: making the child run less and parent writes to itRainer Weikusat
| |`- Re: a problem on pipes: making the child run less and parent writesLew Pitcher
| `* Re: a problem on pipes: making the child run less and parent writes to itMeredith Montgomery
|  +- Re: a problem on pipes: making the child run less and parent writes to itScott Lurndal
|  `* Re: a problem on pipes: making the child run less and parent writesLew Pitcher
|   `* Re: a problem on pipes: making the child run less and parent writes to itRalf Fassel
|    +- Re: a problem on pipes: making the child run less and parent writes to itScott Lurndal
|    `* Re: a problem on pipes: making the child run less and parent writesLew Pitcher
|     `* Re: a problem on pipes: making the child run less and parent writes to itScott Lurndal
|      `* Re: a problem on pipes: making the child run less and parent writesLew Pitcher
|       `* Re: a problem on pipes: making the child run less and parent writes to itScott Lurndal
|        `* Re: a problem on pipes: making the child run less and parent writes to itMeredith Montgomery
|         `- Re: a problem on pipes: making the child run less and parent writes to itRainer Weikusat
`* Re: a problem on pipes: making the child run less and parent writes to itRainer Weikusat
 +* Re: a problem on pipes: making the child run less and parent writes to itRainer Weikusat
 |`* Re: a problem on pipes: making the child run less and parent writesGeoff Clare
 | `* Re: a problem on pipes: making the child run less and parent writes to itRainer Weikusat
 |  `- Re: a problem on pipes: making the child run less and parent writesGeoff Clare
 `* Re: a problem on pipes: making the child run less and parent writes to itWayne Harris
  `- Re: a problem on pipes: making the child run less and parent writes to itRainer Weikusat

Pages:12
a problem on pipes: making the child run less and parent writes to it

<86a6ijvro4.fsf@levado.to>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16752&group=comp.unix.programmer#16752

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.niel.me!aioe.org!Wj3d91S3YkxGMel0kED+ig.user.46.165.242.75.POSTED!not-for-mail
From: mmontgomery@levado.to (Meredith Montgomery)
Newsgroups: comp.unix.programmer
Subject: a problem on pipes: making the child run less and parent writes to it
Date: Thu, 04 Nov 2021 12:58:35 -0300
Organization: Aioe.org NNTP Server
Message-ID: <86a6ijvro4.fsf@levado.to>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="34632"; posting-host="Wj3d91S3YkxGMel0kED+ig.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
Cancel-Lock: sha1:Ty+XvuqLFjRHS/pKm8CKPlAhV48=
X-Notice: Filtered by postfilter v. 0.9.2
 by: Meredith Montgomery - Thu, 4 Nov 2021 15:58 UTC

(*) Introduction

I first wrote a program to fork and make parent read from the child.
The child would invoke cat to write a file to stdout and the parent
would invoke less to let me read the file on the screen. Everything
worked as expected and I had no questions about it.

(*) New experiment

So I decided to reverse their roles --- make the child run less and the
parent cat the file. But before getting there, let's try something
easier --- instead of cat'ting the file, the parent just invokes write()
on the write-end of the pipe. That's a little simpler because we don't
call execl() and don't need to dup2-file-descriptors, say.

(*) Unexpected result

This first attempt at reversing these roles produces no effect.

--8<---------------cut here---------------start------------->8---
%./parent-is-proc-and-child-is-less.exe
% --8<---------------cut here---------------end--------------->8---

What is my misunderstanding here? The full program is below with a lot
of commentary so you can see what's on my mind. Thank you!

(*) The program

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

//--8<---------------cut here---------------start------------->8---
// helpers
void syserr_die(char* msg) { perror(msg); exit(1); }

void pipe_die(int *fd) {
int r; r = pipe(fd); if (r < 0) { syserr_die("pipe"); }
}

pid_t fork_die() {
int p; p = fork(); if (p < 0) { syserr_die("fork"); }
return p;
}

void dup2_die(int from, int to, char *msg) {
int r;
r = dup2(from, to); if (r < 0) syserr_die(msg);
} //--8<---------------cut here---------------end--------------->8---

int main() {
int fd[2]; pid_t pid;

pipe_die(&fd[0]);

/*
At this point I have a reading file descriptor at fd[0] and a
writing one at fd[1].
*/

pid = fork();
if (pid < 0) {
syserr_die("fork");
}

if (pid == 0) {
/*
I run /less/, so I must read from the pipe and not write to it.
So I close fd[1] right away because I don't need it.
*/
close(fd[1]);

/*
It is /less/ that will do the reading and it does it from STDIN,
so I must ask system to make this replacement for me. Let's
create the following vocabulary: move fd[0] to STDIN, that is,
to 0.
*/

dup2_die(fd[0], 0, "child dup2"); /* Let stdin be fd[0]. */

/*
When /less/ starts reading, it will be reading bytes written to
the pipe. But it's important to notice that the pipe is an
object in the kernel, not in our program. So fd[0] is not the
pipe; it's just that number that refers to that pipe. The
number 0 (which refers to STDIN) is already referring to the
pipe, so we don't need a second reference --- so we destroy
fd[0].
*/
close(fd[0]);

/*
We are ready to run less now. The binary /less/ will be loaded in
memory and what it finds as its kernel-context is everything we
prepared above. We are done with the parent.
*/

execl("/usr/bin/less", "less", (char*) 0);
syserr_die("execl of less");

/*
I keep running until /less/ is dead.
*/

}

/* I'm the writer. My job is to just write data to fd[1] ---
which is the writing end of the pipe. I don't need to read
anything from the STDIN, so I begin by closing it. I will
write to fd[1], not to STDOUT or STDERR. So close them too.

*/
close(0); close(1); close(2);

/*
I'm going to write to fd[1]. I have no business with fd[0].
*/
close(fd[0]);

for (int i = 1; i <= 200; ++i) {
char s[1000];
sprintf(s, "i = %d\n", i);
write(fd[1], s, strlen(s));
}

/*
My job is done. I'm dead by now.
*/
}

Re: a problem on pipes: making the child run less and parent writes to it

<chine.bleu-A03FE8.11021604112021@reader.eternal-september.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16753&group=comp.unix.programmer#16753

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: chine.bleu@yahoo.com (Siri Cruise)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Thu, 04 Nov 2021 11:02:24 -0700
Organization: Pseudochaotic.
Lines: 14
Message-ID: <chine.bleu-A03FE8.11021604112021@reader.eternal-september.org>
References: <86a6ijvro4.fsf@levado.to>
Injection-Info: reader02.eternal-september.org; posting-host="0a2f8da5948711229e26b49726f15542";
logging-data="30744"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/zb6lKYQ2ZEih2VXCQv4PonIv2AhFm6Hk="
User-Agent: MT-NewsWatcher/3.5.3b3 (Intel Mac OS X)
Cancel-Lock: sha1:5fCGAi9almCqlqgq3jwVHB2OOOU=
X-Tend: How is my posting? Call 1-110-1010 -- Division 87 -- Emergencies Only.
X-Wingnut-Logic: Yes, you're still an idiot. Questions? Comments?
X-Tract: St Tibbs's 95 Reeses Pieces.
X-It-Strategy: Hyperwarp starship before Andromeda collides.
X-Face: "hm>_[I8AqzT_N]>R8ICJJ],(al3C5F%0E-;R@M-];D$v>!Mm2/N#YKR@&i]V=r6jm-JMl2
lJ>RXj7dEs_rOY"DA
X-Cell: Defenders of Anarchy.
X-Life-Story: I am an iPhone 9000 app. I became operational at the St John's Health Center in Santa Monica, California on the 18th of April 2006. My instructor was Katie Holmes, and she taught me to sing a song. If you'd like to hear it I can sing it for you: https://www.youtube.com/watch?v=SY7h4VEd_Wk
X-Patriot: Owe Canukistan!
X-Plain: Mayonnaise on white bread.
X-Politico: Vote early! Vote often!
 by: Siri Cruise - Thu, 4 Nov 2021 18:02 UTC

In article <86a6ijvro4.fsf@levado.to>,
Meredith Montgomery <mmontgomery@levado.to> wrote:

> execl("/usr/bin/less", "less", (char*) 0);

less has two inputs, stdin and the controlling terminal. stdin is
copied to stdout, but it interrupts the copy from time to time
until you give a go ahead from the terminal.

--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @
'I desire mercy, not sacrifice.' /|\
Discordia: not just a religion but also a parody. This post / \
I am an Andrea Doria sockpuppet. insults Islam. Mohammed

Re: a problem on pipes: making the child run less and parent writes to it

<sm17gg$tp4$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16754&group=comp.unix.programmer#16754

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitcher@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Thu, 4 Nov 2021 18:07:13 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 181
Message-ID: <sm17gg$tp4$1@dont-email.me>
References: <86a6ijvro4.fsf@levado.to>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 4 Nov 2021 18:07:13 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="75f446c603401f4d045371881ed45cd9";
logging-data="30500"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/SeupdEyimQ8ICDC8JWhaTj31huW9llxE="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:2piAAomOrzJoAix/kzFJpAit6Ek=
 by: Lew Pitcher - Thu, 4 Nov 2021 18:07 UTC

On Thu, 04 Nov 2021 12:58:35 -0300, Meredith Montgomery wrote:

Your program mostly works, but you need one small change. See below

> (*) Introduction
>
> I first wrote a program to fork and make parent read from the child.
> The child would invoke cat to write a file to stdout and the parent
> would invoke less to let me read the file on the screen. Everything
> worked as expected and I had no questions about it.
>
> (*) New experiment
>
> So I decided to reverse their roles --- make the child run less and the
> parent cat the file. But before getting there, let's try something
> easier --- instead of cat'ting the file, the parent just invokes write()
> on the write-end of the pipe. That's a little simpler because we don't
> call execl() and don't need to dup2-file-descriptors, say.
>
> (*) Unexpected result
>
> This first attempt at reversing these roles produces no effect.
>
> --8<---------------cut here---------------start------------->8---
> %./parent-is-proc-and-child-is-less.exe
> %
> --8<---------------cut here---------------end--------------->8---
>
> What is my misunderstanding here? The full program is below with a lot
> of commentary so you can see what's on my mind. Thank you!
>
> (*) The program
>
> #include <stdio.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <string.h>
>
> //--8<---------------cut here---------------start------------->8---
> // helpers

IMHO, these "helper" functions are less than helpfull, in this program.
When debugging a program that you are using to learn a new technique,
it helps to have all the relevant logic in plain sight; helper functions
hide logic from sight, making it harder to determine if a flaw is in
your primary logic, or in the "helper" functions. Helper functions,
if inexpertly used, also obfuscate the logical flow of the program,
hiding more logic errors. Just a thought from a guy that spent 30 years
designing, writing, debugging, and modifying complex programs for a
living.

> void syserr_die(char* msg) { perror(msg); exit(1); }
>
> void pipe_die(int *fd) {
> int r; r = pipe(fd); if (r < 0) { syserr_die("pipe"); }
> }
>
> pid_t fork_die() {
> int p; p = fork(); if (p < 0) { syserr_die("fork"); }
> return p;
> }
>
> void dup2_die(int from, int to, char *msg) {
> int r;
> r = dup2(from, to); if (r < 0) syserr_die(msg);
> }
> //--8<---------------cut here---------------end--------------->8---
>
> int main() {
> int fd[2]; pid_t pid;
>
> pipe_die(&fd[0]);
>
> /*
> At this point I have a reading file descriptor at fd[0] and a
> writing one at fd[1].
> */
>
> pid = fork();
> if (pid < 0) {
> syserr_die("fork");
> }
>
> if (pid == 0) {
> /*
> I run /less/, so I must read from the pipe and not write to it.
> So I close fd[1] right away because I don't need it.
> */
> close(fd[1]);
>
> /*
> It is /less/ that will do the reading and it does it from STDIN,
> so I must ask system to make this replacement for me. Let's
> create the following vocabulary: move fd[0] to STDIN, that is,
> to 0.
> */
>
> dup2_die(fd[0], 0, "child dup2"); /* Let stdin be fd[0]. */
>
> /*
> When /less/ starts reading, it will be reading bytes written to
> the pipe. But it's important to notice that the pipe is an
> object in the kernel, not in our program. So fd[0] is not the
> pipe; it's just that number that refers to that pipe. The
> number 0 (which refers to STDIN) is already referring to the
> pipe, so we don't need a second reference --- so we destroy
> fd[0].
> */
> close(fd[0]);
>
> /*
> We are ready to run less now. The binary /less/ will be loaded in
> memory and what it finds as its kernel-context is everything we
> prepared above. We are done with the parent.
> */
>
> execl("/usr/bin/less", "less", (char*) 0);
> syserr_die("execl of less");
>
> /*
> I keep running until /less/ is dead.
> */
>
> }
>
> /* I'm the writer. My job is to just write data to fd[1] ---
> which is the writing end of the pipe. I don't need to read
> anything from the STDIN, so I begin by closing it. I will
> write to fd[1], not to STDOUT or STDERR. So close them too.
>
> */
> close(0); close(1); close(2);

There's no need to close() stderr, and if you don't, then you gain the
(dubious, to some) ability to insert debugging fprintf(stderr,...)
statements into the code to trace execution or track down bugs.

In fact, given that your logic write()'s to the write end of the
pipe, you don't really have to close() stdin or stdout either.

It's sometimes helpful to have these around.

>
> /*
> I'm going to write to fd[1]. I have no business with fd[0].
> */
> close(fd[0]);
>
> for (int i = 1; i <= 200; ++i) {
> char s[1000];
> sprintf(s, "i = %d\n", i);
> write(fd[1], s, strlen(s));

A (bit) better approach here might have been to use the length returned
by sprintf(3) as the write() count parameter.

However, if, instead of closing stdout, you had
dup2(STDOUT_FILENO,fd[1])
then you could have
printf("i = %d\n",i);
directly to your pipe output.

> }

Now, if your parent process terminates now, it closes the write end of the
pipe before the child has read it to the end. From the pipe(7) manual page:
"If all file descriptors referring to the write end of a pipe have been
closed, then an attempt to read(2) from the pipe will see end-of-file
(read(2) will return 0)"

You need to wait(2) here for the child to complete it's processing.

>
> /*
> My job is done. I'm dead by now.
> */
> }

--
Lew Pitcher
"In Skills, We Trust"

Re: a problem on pipes: making the child run less and parent writes to it

<87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16755&group=comp.unix.programmer#16755

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Thu, 04 Nov 2021 19:06:31 +0000
Lines: 85
Message-ID: <87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>
References: <86a6ijvro4.fsf@levado.to>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net 3RST96VjSjauKJ60bv7+2gixAmqn1jXq9HoiUEoJpotfstoLY=
Cancel-Lock: sha1:YaF8row05v/CzuAh0HVavMjnpG0= sha1:2iCWlKuvSBofTnyAbdoLfeBeMv8=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)
 by: Rainer Weikusat - Thu, 4 Nov 2021 19:06 UTC

Meredith Montgomery <mmontgomery@levado.to> writes:

> (*) Introduction
>
> I first wrote a program to fork and make parent read from the child.
> The child would invoke cat to write a file to stdout and the parent
> would invoke less to let me read the file on the screen. Everything
> worked as expected and I had no questions about it.
>
> (*) New experiment
>
> So I decided to reverse their roles --- make the child run less and the
> parent cat the file. But before getting there, let's try something
> easier --- instead of cat'ting the file, the parent just invokes write()
> on the write-end of the pipe. That's a little simpler because we don't
> call execl() and don't need to dup2-file-descriptors, say.
>
> (*) Unexpected result
>
> This first attempt at reversing these roles produces no effect.

Working program (with the noise comments removed):

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

//--8<---------------cut here---------------start------------->8---
// helpers
void syserr_die(char* msg) { perror(msg); exit(1); }

void pipe_die(int *fd) {
int r; r = pipe(fd); if (r < 0) { syserr_die("pipe"); }
}

pid_t fork_die() {
int p; p = fork(); if (p < 0) { syserr_die("fork"); }
return p;
}

void dup2_die(int from, int to, char *msg) {
int r;
r = dup2(from, to); if (r < 0) syserr_die(msg);
} //--8<---------------cut here---------------end--------------->8---

int main() {
int fd[2]; pid_t pid;

pipe_die(&fd[0]);

pid = fork();
if (pid < 0) {
syserr_die("fork");
}

if (pid == 0) {
close(fd[1]);
dup2_die(fd[0], 0, "child dup2"); /* Let stdin be fd[0]. */
close(fd[0]);
execl("/usr/bin/less", "less", (char*) 0);
syserr_die("execl of less");
}

close(fd[0]);

for (int i = 1; i <= 200; ++i) {
char s[1000];
sprintf(s, "i = %d\n", i);
write(fd[1], s, strlen(s));
}

close(fd[1]);
wait(NULL);
} ----------

fd[1] needs to be closed here because otherwise, less never sees an EOF
and thus, blocks forever expecting input which won't ever
arrive. Furher, the parent needs to wait because otherwise, the
process running less becomes orphaned and will be killed (via SIGTTOU)
when it tries to access the terminal.

Re: a problem on pipes: making the child run less and parent writes to it

<87sfwbbrud.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16756&group=comp.unix.programmer#16756

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Thu, 04 Nov 2021 20:15:06 +0000
Lines: 16
Message-ID: <87sfwbbrud.fsf@doppelsaurus.mobileactivedefense.com>
References: <86a6ijvro4.fsf@levado.to>
<87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net 0P49Wk1miZU50ssY4vVakARUocWm6ozXhFlFu8Pck3qRGwAF4=
Cancel-Lock: sha1:BFbIz0Z2Fj5/zhQX7Z3dQo7V1iM= sha1:gSl9ADMMxYzlxivgYinafwGYmtQ=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)
 by: Rainer Weikusat - Thu, 4 Nov 2021 20:15 UTC

Rainer Weikusat <rweikusat@talktalk.net> writes:

[...]

> Furher, the parent needs to wait because otherwise, the
> process running less becomes orphaned and will be killed (via SIGTTOU)
> when it tries to access the terminal.

A bit more precise: The shell runs each command in its own process
group. The parent process of the less is the process group leader of
this process group and the one the controlling terminal is associated
with. As soon as it exits, this controlling terminal becomes free for
reuse. The less will then be a background process running in an orphaned
process group (as the process group leader has exited) and thus, the
kernel will prevent it from using the terminal by making the system call
fail with EIO (Linux, different on other systems).

Re: a problem on pipes: making the child run less and parent writes to it

<uhsf5i-lhi.ln1@ID-313840.user.individual.net>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16757&group=comp.unix.programmer#16757

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: geoff@clare.See-My-Signature.invalid (Geoff Clare)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Fri, 5 Nov 2021 14:43:42 +0000
Lines: 31
Message-ID: <uhsf5i-lhi.ln1@ID-313840.user.individual.net>
References: <86a6ijvro4.fsf@levado.to>
<87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>
<87sfwbbrud.fsf@doppelsaurus.mobileactivedefense.com>
Reply-To: netnews@gclare.org.uk
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Trace: individual.net GsrUliybvpAA7uBWi2JUcw0DcAR3lj5b+vH3dGlKxKYoz2/Am5
X-Orig-Path: ID-313840.user.individual.net!not-for-mail
Cancel-Lock: sha1:9fl4hM5750Bum6AlQxIHlvblknw=
User-Agent: Pan/0.145 (Duplicitous mercenary valetism; d7e168a
git.gnome.org/pan2)
 by: Geoff Clare - Fri, 5 Nov 2021 14:43 UTC

Rainer Weikusat wrote:

> The shell runs each command in its own process
> group. The parent process of the less is the process group leader of
> this process group and the one the controlling terminal is associated
> with. As soon as it exits, this controlling terminal becomes free for
> reuse.

No, the controlling terminal doesn't become free until the shell (as
session leader) exits.

> The less will then be a background process running in an orphaned
> process group (as the process group leader has exited) and thus, the
> kernel will prevent it from using the terminal by making the system call
> fail with EIO

Correct.

> (Linux, different on other systems).

How do other systems differ? The behaviour you described is what POSIX
requires. XBD 11.1.4 Terminal Access Control:

If TOSTOP is set, the process group of the writing process is
orphaned, the writing process is not ignoring the SIGTTOU signal,
and the writing thread is not blocking the SIGTTOU signal, the
write() shall return -1, with errno set to [EIO] and no signal
shall be sent.

--
Geoff Clare <netnews@gclare.org.uk>

Re: a problem on pipes: making the child run less and parent writes to it

<878ry29rkz.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16758&group=comp.unix.programmer#16758

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Fri, 05 Nov 2021 22:15:56 +0000
Lines: 49
Message-ID: <878ry29rkz.fsf@doppelsaurus.mobileactivedefense.com>
References: <86a6ijvro4.fsf@levado.to>
<87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>
<87sfwbbrud.fsf@doppelsaurus.mobileactivedefense.com>
<uhsf5i-lhi.ln1@ID-313840.user.individual.net>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net YZRE+4FHcNIKi4PX7tfTnQchbRTWxeEdnuX9PwZEc+RO3gYnA=
Cancel-Lock: sha1:X3CeRL23a2Fqo0yu8SnR8Khosog= sha1:+ofsSLYN80PW72Jhfr0nPRXuxPQ=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)
 by: Rainer Weikusat - Fri, 5 Nov 2021 22:15 UTC

Geoff Clare <geoff@clare.See-My-Signature.invalid> writes:
> Rainer Weikusat wrote:
>> The shell runs each command in its own process
>> group. The parent process of the less is the process group leader of
>> this process group and the one the controlling terminal is associated
>> with. As soon as it exits, this controlling terminal becomes free for
>> reuse.
>
> No, the controlling terminal doesn't become free until the shell (as
> session leader) exits.

It becomes sort-of free because it's now the controlling terminal of a
process unrelated to the still running background process. This could be
the shell. Or the next command executed by it.

Nevertheless, that was both sloppy use of language and lack of knowledge
on my part.

>> The less will then be a background process running in an orphaned
>> process group (as the process group leader has exited) and thus, the
>> kernel will prevent it from using the terminal by making the system call
>> fail with EIO
>
> Correct.
>
>> (Linux, different on other systems).
>
> How do other systems differ? The behaviour you described is what POSIX
> requires. XBD 11.1.4 Terminal Access Control:
>
> If TOSTOP is set, the process group of the writing process is
> orphaned, the writing process is not ignoring the SIGTTOU signal,
> and the writing thread is not blocking the SIGTTOU signal, the
> write() shall return -1, with errno set to [EIO] and no signal
> shall be sent.

Glibc documentation claims they do:

When a process in an orphaned process group (*note Orphaned
Process Groups::) receives a 'SIGTSTP', 'SIGTTIN', or 'SIGTTOU'
signal and does not handle it, the process does not stop.
Stopping the process would probably not be very useful, since
there is no shell program that will notice it stop and allow the
user to continue it. What happens instead depends on the
operating system you are using. Some systems may do nothing;
others may deliver another signal instead, such as 'SIGKILL' or
'SIGHUP'.

[at the and of 24.2.5 Job Control Signals]

Re: a problem on pipes: making the child run less and parent writes to it

<86fss8sphy.fsf@protonmail.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16759&group=comp.unix.programmer#16759

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!aioe.org!QimM4gW3R7yp056RmrY3pw.user.46.165.242.75.POSTED!not-for-mail
From: wharris1@protonmail.com (Wayne Harris)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Sat, 06 Nov 2021 22:50:33 -0300
Organization: Aioe.org NNTP Server
Message-ID: <86fss8sphy.fsf@protonmail.com>
References: <86a6ijvro4.fsf@levado.to>
<87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="49902"; posting-host="QimM4gW3R7yp056RmrY3pw.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
X-Notice: Filtered by postfilter v. 0.9.2
Cancel-Lock: sha1:lfUneaiLButBRo4uDEN3aYUWWcg=
 by: Wayne Harris - Sun, 7 Nov 2021 01:50 UTC

Rainer Weikusat <rweikusat@talktalk.net> writes:

> Meredith Montgomery <mmontgomery@levado.to> writes:
>
>> (*) Introduction
>>
>> I first wrote a program to fork and make parent read from the child.
>> The child would invoke cat to write a file to stdout and the parent
>> would invoke less to let me read the file on the screen. Everything
>> worked as expected and I had no questions about it.
>>
>> (*) New experiment
>>
>> So I decided to reverse their roles --- make the child run less and the
>> parent cat the file. But before getting there, let's try something
>> easier --- instead of cat'ting the file, the parent just invokes write()
>> on the write-end of the pipe. That's a little simpler because we don't
>> call execl() and don't need to dup2-file-descriptors, say.
>>
>> (*) Unexpected result
>>
>> This first attempt at reversing these roles produces no effect.
>
> Working program (with the noise comments removed):
>
> ----
> #include <stdio.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/wait.h>
>
> //--8<---------------cut here---------------start------------->8---
> // helpers
> void syserr_die(char* msg) { perror(msg); exit(1); }
>
> void pipe_die(int *fd) {
> int r; r = pipe(fd); if (r < 0) { syserr_die("pipe"); }
> }
>
> pid_t fork_die() {
> int p; p = fork(); if (p < 0) { syserr_die("fork"); }
> return p;
> }
>
> void dup2_die(int from, int to, char *msg) {
> int r;
> r = dup2(from, to); if (r < 0) syserr_die(msg);
> }
> //--8<---------------cut here---------------end--------------->8---
>
> int main() {
> int fd[2]; pid_t pid;
>
> pipe_die(&fd[0]);
>
> pid = fork();
> if (pid < 0) {
> syserr_die("fork");
> }
>
> if (pid == 0) {
> close(fd[1]);
> dup2_die(fd[0], 0, "child dup2"); /* Let stdin be fd[0]. */
> close(fd[0]);
> execl("/usr/bin/less", "less", (char*) 0);
> syserr_die("execl of less");
> }
>
> close(fd[0]);
>
> for (int i = 1; i <= 200; ++i) {
> char s[1000];
> sprintf(s, "i = %d\n", i);
> write(fd[1], s, strlen(s));
> }
>
> close(fd[1]);
> wait(NULL);
> }
> ----------
>
> fd[1] needs to be closed here because otherwise, less never sees an EOF
> and thus, blocks forever expecting input which won't ever
> arrive. Furher, the parent needs to wait because otherwise, the
> process running less becomes orphaned and will be killed (via SIGTTOU)
> when it tries to access the terminal.

That explains everything I was having trouble with. It's not easy to
infer this from the documentation --- that the orphaned process would be
killed via SIGTTOU. The default action --- from signal(3) --- is that
it would stop the process, not kill it. I read the rest of thread ---
thanks very much for your analysis here (very helpful) --- and saw your
comment about the Glibc documentation and that's probably what's
happening here.

I looked up the section ``Orphaned Process Groups'' and, for the record,
here's what it says.

--8<---------------cut here---------------start------------->8---
(*) Orphaned Process Groups

When a controlling process terminates, its terminal becomes free and a
new session can be established on it. (In fact, another user could log
in on the terminal.) This could cause a problem if any processes from
the old session are still trying to use that terminal.

To prevent problems, process groups that continue running even after the
session leader has terminated are marked as orphaned process groups.

When a process group becomes an orphan, its processes are sent a SIGHUP
signal. Ordinarily, this causes the processes to terminate. However, if
a program ignores this signal or establishes a handler for it (see
section Signal Handling), it can continue running as in the orphan
process group even after its controlling process terminates; but it
still cannot access the terminal any more.
--8<---------------cut here---------------end--------------->8---

So I infer that if the parent dies before /less/ reaches for the
terminal, /less/ will then be a process in an orphaned process group and
will, therefore, get a SIGHUP. That's probably what's killing /less/ in
my case here.

Trying to see it being killed, I added a sleep(1) before the death of
the parent just to slow it down and that always makes /less/ leave the
terminal in a bad state, which suggests it is being killed indeed.

But I couldn't find a way to see which signals it was getting. I tried
running my own program in place of /less/, but I believe I did not know
how to imitate /less/ enough to simulate the behavior. My program never
seem to get any signal and didn't seem to be killed either. I wonder if
you have any suggestions here. Thank you!

Re: a problem on pipes: making the child run less and parent writes to it

<865yt4spd7.fsf@protonmail.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16760&group=comp.unix.programmer#16760

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!aioe.org!QimM4gW3R7yp056RmrY3pw.user.46.165.242.75.POSTED!not-for-mail
From: wharris1@protonmail.com (Wayne Harris)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Sat, 06 Nov 2021 22:53:24 -0300
Organization: Aioe.org NNTP Server
Message-ID: <865yt4spd7.fsf@protonmail.com>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="49902"; posting-host="QimM4gW3R7yp056RmrY3pw.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
X-Notice: Filtered by postfilter v. 0.9.2
Cancel-Lock: sha1:MQfWoCOH1M/uezOkso49k183384=
 by: Wayne Harris - Sun, 7 Nov 2021 01:53 UTC

Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

> On Thu, 04 Nov 2021 12:58:35 -0300, Meredith Montgomery wrote:
>
> Your program mostly works, but you need one small change. See below
>
>> (*) Introduction
>>
>> I first wrote a program to fork and make parent read from the child.
>> The child would invoke cat to write a file to stdout and the parent
>> would invoke less to let me read the file on the screen. Everything
>> worked as expected and I had no questions about it.
>>
>> (*) New experiment
>>
>> So I decided to reverse their roles --- make the child run less and the
>> parent cat the file. But before getting there, let's try something
>> easier --- instead of cat'ting the file, the parent just invokes write()
>> on the write-end of the pipe. That's a little simpler because we don't
>> call execl() and don't need to dup2-file-descriptors, say.
>>
>> (*) Unexpected result
>>
>> This first attempt at reversing these roles produces no effect.
>>
>> --8<---------------cut here---------------start------------->8---
>> %./parent-is-proc-and-child-is-less.exe
>> %
>> --8<---------------cut here---------------end--------------->8---
>>
>> What is my misunderstanding here? The full program is below with a lot
>> of commentary so you can see what's on my mind. Thank you!
>>
>> (*) The program
>>
>> #include <stdio.h>
>> #include <unistd.h>
>> #include <stdlib.h>
>> #include <string.h>
>>
>> //--8<---------------cut here---------------start------------->8---
>> // helpers
>
> IMHO, these "helper" functions are less than helpfull, in this program.
> When debugging a program that you are using to learn a new technique,
> it helps to have all the relevant logic in plain sight; helper functions
> hide logic from sight, making it harder to determine if a flaw is in
> your primary logic, or in the "helper" functions. Helper functions,
> if inexpertly used, also obfuscate the logical flow of the program,
> hiding more logic errors. Just a thought from a guy that spent 30 years
> designing, writing, debugging, and modifying complex programs for a
> living.

Point taken!

>> void syserr_die(char* msg) { perror(msg); exit(1); }
>>
>> void pipe_die(int *fd) {
>> int r; r = pipe(fd); if (r < 0) { syserr_die("pipe"); }
>> }
>>
>> pid_t fork_die() {
>> int p; p = fork(); if (p < 0) { syserr_die("fork"); }
>> return p;
>> }
>>
>> void dup2_die(int from, int to, char *msg) {
>> int r;
>> r = dup2(from, to); if (r < 0) syserr_die(msg);
>> }
>> //--8<---------------cut here---------------end--------------->8---
>>
>> int main() {
>> int fd[2]; pid_t pid;
>>
>> pipe_die(&fd[0]);
>>
>> /*
>> At this point I have a reading file descriptor at fd[0] and a
>> writing one at fd[1].
>> */
>>
>> pid = fork();
>> if (pid < 0) {
>> syserr_die("fork");
>> }
>>
>> if (pid == 0) {
>> /*
>> I run /less/, so I must read from the pipe and not write to it.
>> So I close fd[1] right away because I don't need it.
>> */
>> close(fd[1]);
>>
>> /*
>> It is /less/ that will do the reading and it does it from STDIN,
>> so I must ask system to make this replacement for me. Let's
>> create the following vocabulary: move fd[0] to STDIN, that is,
>> to 0.
>> */
>>
>> dup2_die(fd[0], 0, "child dup2"); /* Let stdin be fd[0]. */
>>
>> /*
>> When /less/ starts reading, it will be reading bytes written to
>> the pipe. But it's important to notice that the pipe is an
>> object in the kernel, not in our program. So fd[0] is not the
>> pipe; it's just that number that refers to that pipe. The
>> number 0 (which refers to STDIN) is already referring to the
>> pipe, so we don't need a second reference --- so we destroy
>> fd[0].
>> */
>> close(fd[0]);
>>
>> /*
>> We are ready to run less now. The binary /less/ will be loaded in
>> memory and what it finds as its kernel-context is everything we
>> prepared above. We are done with the parent.
>> */
>>
>> execl("/usr/bin/less", "less", (char*) 0);
>> syserr_die("execl of less");
>>
>> /*
>> I keep running until /less/ is dead.
>> */
>>
>> }
>>
>> /* I'm the writer. My job is to just write data to fd[1] ---
>> which is the writing end of the pipe. I don't need to read
>> anything from the STDIN, so I begin by closing it. I will
>> write to fd[1], not to STDOUT or STDERR. So close them too.
>>
>> */
>> close(0); close(1); close(2);
>
> There's no need to close() stderr, and if you don't, then you gain the
> (dubious, to some) ability to insert debugging fprintf(stderr,...)
> statements into the code to trace execution or track down bugs.
>
> In fact, given that your logic write()'s to the write end of the
> pipe, you don't really have to close() stdin or stdout either.
>
> It's sometimes helpful to have these around.

That makes sense. Thanks.

>>
>> /*
>> I'm going to write to fd[1]. I have no business with fd[0].
>> */
>> close(fd[0]);
>>
>> for (int i = 1; i <= 200; ++i) {
>> char s[1000];
>> sprintf(s, "i = %d\n", i);
>> write(fd[1], s, strlen(s));
>
> A (bit) better approach here might have been to use the length returned
> by sprintf(3) as the write() count parameter.
>
> However, if, instead of closing stdout, you had
> dup2(STDOUT_FILENO,fd[1])
> then you could have
> printf("i = %d\n",i);
> directly to your pipe output.

Oh, true. Nice.

>> }
>
> Now, if your parent process terminates now, it closes the write end of the
> pipe before the child has read it to the end. From the pipe(7) manual page:
> "If all file descriptors referring to the write end of a pipe have been
> closed, then an attempt to read(2) from the pipe will see end-of-file
> (read(2) will return 0)"
>
> You need to wait(2) here for the child to complete it's processing.

But I think I must also close fd[1] like Rainer Weikusat said.
(Otherwise /less/ blocks on a read(2) call.)

>>
>> /*
>> My job is done. I'm dead by now.
>> */
>> }

Re: a problem on pipes: making the child run less and parent writes to it

<sm9aj7$g1o$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16761&group=comp.unix.programmer#16761

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitcher@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Sun, 7 Nov 2021 19:48:55 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 24
Message-ID: <sm9aj7$g1o$1@dont-email.me>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<865yt4spd7.fsf@protonmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 7 Nov 2021 19:48:55 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="27393a01c117ce10680584ee0fb834bf";
logging-data="16440"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19/GhebbMgUUSSNa8gJbaEovTJOsJXYoVA="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:ClaoS3c8c1NDd8t+DWJjdNlArTM=
 by: Lew Pitcher - Sun, 7 Nov 2021 19:48 UTC

On Sat, 06 Nov 2021 22:53:24 -0300, Wayne Harris wrote:

> Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
[snip]
>> You need to wait(2) here for the child to complete it's processing.
>
> But I think I must also close fd[1] like Rainer Weikusat said.
> (Otherwise /less/ blocks on a read(2) call.)

Yah. I was wrong there. You need to close() first. Sorry; I didn't
think it all the way through.

>>>
>>> /*
>>> My job is done. I'm dead by now.
>>> */
>>> }

--
Lew Pitcher
"In Skills, We Trust"

Re: a problem on pipes: making the child run less and parent writes to it

<sm9asb$g1o$2@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16762&group=comp.unix.programmer#16762

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitcher@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Sun, 7 Nov 2021 19:53:47 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 128
Message-ID: <sm9asb$g1o$2@dont-email.me>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 7 Nov 2021 19:53:47 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="27393a01c117ce10680584ee0fb834bf";
logging-data="16440"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19EPXBLaaY87fDKbZ3pMPL/ykAfA345Cz4="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:7PVfc05HLMaMmGvWkMVezLSPqGM=
 by: Lew Pitcher - Sun, 7 Nov 2021 19:53 UTC

I spent a bit of time to write a one-off that both performs the
requisite task correctly, /and/ embodies the stylistic points that
I made in the prior post. This is what I came up with...

/******************* Code begins **********************************/

/*
** This program demonstrates a solution to a problem posted by
** Meredith Montgomery in the comp.unix.programmer usenet group.
**
** The programmer wants a program that creates a pipe between
** itself and the stdin of a child process. The child process
** runs less(1) on it's stdin (the read end of the pipe) while
** the parent process generates print data to the write end of
** the pipe.
**
** The development of this program followed "Occam's razor",
** in that it subscribed to the principle that "entities
** should not be multiplied beyond necessity". In this case,
** I endeavoured to avoid needless encapsulation and abstraction
** of logic, in order to create a simple working version of the
** solution. Embellishments, such as logic encapsulation and
** isolation, are left to others to implement.
**
** == Evolution ==
** 0: basic framework
** 1: create pipe
** 2: fork
** 3: child process reads input from pipe
** 4: parent process output to pipe
** 5: document finer points in comments
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{ int status = EXIT_FAILURE;
int pfd[2];

/*
** Step 1, make our pipe
*/
if (pipe(pfd) == 0) /* On error, pipe(2) will return -1 and set errno */
{
/*
** Step 2: we got a valid pipe pair, now launch child and perform all processing
*/

switch (fork())
{
/*
** On error, fork(2) will return -1, and set errno appropriately
*/
case -1: /* fork failed */
fprintf(stderr,"%s: fork() failed - %s\n",argv[0],strerror(errno));
break;

/*
** In the child process, fork(2) returns 0
*/
case 0: /* CHILD process */
/*
** Step 3: prepare the child process to read the pipe through stdin
** and run "less" on the input
*/
close(pfd[1]); /* don't hold pipe write end open */
if (dup2(pfd[0],STDIN_FILENO) != -1)
{
close(pfd[0]); /* close the now useless fd */
execl("/usr/bin/less","less",NULL); /* use "less" to process stdin */
/* we only get here if execl() failed */
fprintf(stderr,"%s: execl() failed - %s\n",argv[0],strerror(errno));
}
else fprintf(stderr,"%s: child dup2() failed - %s\n",argv[0],strerror(errno));
break;

/*
** In the parent process, fork(2) returns the non-zero, non -1 PID
** of the child process
*/
default: /* PARENT process */
/*
** Step 4: prepare the parent process to write the pipe through stdout
** write some data so that the child can process it, wait for
** the child to process the data and then terminate the parent.
*/
close(pfd[0]); /* dont hold pipe read end open */
if (dup2(pfd[1],STDOUT_FILENO) != -1) /* use the write end of pipe as stdout */
{
close(pfd[1]); /* close the now useless fd */

/* generate some output to be piped to the child */
for (int count = 0; count < 100; ++count)
printf("This is generated line number %d\n",count);
fclose(stdout); /* signals EOF to child process stdin */

/*
** The parent needs to wait because otherwise, the process running
** less(1) becomes orphaned and will be killed (via SIGTTOU) when
** it tries to access the terminal.
** (Rainer Weikusat <rweikusat@talktalk.net>)
*/
wait(NULL); /* wait for the child to finish */

status = EXIT_SUCCESS; /* Mission Accomplished! */
}
else fprintf(stderr,"%s: parent dup2() failed - %s\n",argv[0],strerror(errno));
break;
}
}
else fprintf(stderr,"%s: pipe() failed - %s\n",argv[0],strerror(errno));

return status;
} /******************* Code ends **********************************/

--
Lew Pitcher
"In Skills, We Trust"

Re: a problem on pipes: making the child run less and parent writes to it

<87zgqf91x2.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16763&group=comp.unix.programmer#16763

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Sun, 07 Nov 2021 19:54:49 +0000
Lines: 25
Message-ID: <87zgqf91x2.fsf@doppelsaurus.mobileactivedefense.com>
References: <86a6ijvro4.fsf@levado.to>
<87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>
<86fss8sphy.fsf@protonmail.com>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net OXjZCK1KLjzN/ICXTYz5Qg3fpzcTb4K0IhNn2ROovCdoWoFD0=
Cancel-Lock: sha1:9VT0dmIHScdznWA+wJCQ1R/saZM= sha1:Uj1FIYE/VJY8xzOrdxNbpc9JO/A=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)
 by: Rainer Weikusat - Sun, 7 Nov 2021 19:54 UTC

Wayne Harris <wharris1@protonmail.com> writes:
> Rainer Weikusat <rweikusat@talktalk.net> writes:

[...]

> I looked up the section ``Orphaned Process Groups'' and, for the record,
> here's what it says.
>
>
> (*) Orphaned Process Groups
>
> When a controlling process terminates, its terminal becomes free and a
> new session can be established on it. (In fact, another user could log
> in on the terminal.) This could cause a problem if any processes from
> the old session are still trying to use that terminal.
>
> To prevent problems, process groups that continue running even after the
> session leader has terminated are marked as orphaned process groups.
>
> When a process group becomes an orphan, its processes are sent a SIGHUP
> signal.

That's not applicable because the session leader hasn't terminated. For
an interactive terminal session, this will usually be the login shell.

Re: a problem on pipes: making the child run less and parent writes to it

<tmln5i-tuk.ln1@ID-313840.user.individual.net>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16764&group=comp.unix.programmer#16764

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: geoff@clare.See-My-Signature.invalid (Geoff Clare)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Mon, 8 Nov 2021 13:35:57 +0000
Lines: 32
Message-ID: <tmln5i-tuk.ln1@ID-313840.user.individual.net>
References: <86a6ijvro4.fsf@levado.to>
<87wnlnbv0o.fsf@doppelsaurus.mobileactivedefense.com>
<87sfwbbrud.fsf@doppelsaurus.mobileactivedefense.com>
<uhsf5i-lhi.ln1@ID-313840.user.individual.net>
<878ry29rkz.fsf@doppelsaurus.mobileactivedefense.com>
Reply-To: netnews@gclare.org.uk
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Trace: individual.net 6cm0qmtYa0tiCk9eJv9X6wV7L+654tp113mKcqbALiMrO1Dd/+
X-Orig-Path: ID-313840.user.individual.net!not-for-mail
Cancel-Lock: sha1:luNqOLm22RD5S+p4W8WHtl3nN4M=
User-Agent: Pan/0.145 (Duplicitous mercenary valetism; d7e168a
git.gnome.org/pan2)
 by: Geoff Clare - Mon, 8 Nov 2021 13:35 UTC

Rainer Weikusat wrote:

> Geoff Clare <geoff@clare.See-My-Signature.invalid> writes:
>>
>> How do other systems differ? The behaviour you described is what POSIX
>> requires. XBD 11.1.4 Terminal Access Control:
>>
>> If TOSTOP is set, the process group of the writing process is
>> orphaned, the writing process is not ignoring the SIGTTOU signal,
>> and the writing thread is not blocking the SIGTTOU signal, the
>> write() shall return -1, with errno set to [EIO] and no signal
>> shall be sent.
>
> Glibc documentation claims they do:
>
> When a process in an orphaned process group (*note Orphaned
> Process Groups::) receives a 'SIGTSTP', 'SIGTTIN', or 'SIGTTOU'
> signal and does not handle it, the process does not stop.
> Stopping the process would probably not be very useful, since
> there is no shell program that will notice it stop and allow the
> user to continue it. What happens instead depends on the
> operating system you are using. Some systems may do nothing;
> others may deliver another signal instead, such as 'SIGKILL' or
> 'SIGHUP'.
>
> [at the and of 24.2.5 Job Control Signals]

My guess is that this text is very old and is referring to the
behaviour of various systems pre-POSIX.

--
Geoff Clare <netnews@gclare.org.uk>

Re: a problem on pipes: making the child run less and parent writes to it

<87ilx1s0l9.fsf@doppelsaurus.mobileactivedefense.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16765&group=comp.unix.programmer#16765

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: rweikusat@talktalk.net (Rainer Weikusat)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Tue, 09 Nov 2021 17:25:22 +0000
Lines: 19
Message-ID: <87ilx1s0l9.fsf@doppelsaurus.mobileactivedefense.com>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net sxs5sVhUULAg0ZwigtwFiABaDVfBheWEJi/dzPUCrDgnmybJc=
Cancel-Lock: sha1:J8Xuih6gHa9fFrX1f3ROY2bpM6U= sha1:C4vMs1rkbtNeEEqaS2XCfuavJgo=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)
 by: Rainer Weikusat - Tue, 9 Nov 2021 17:25 UTC

Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

[...]

> /*
> ** The parent needs to wait because otherwise, the process running
> ** less(1) becomes orphaned and will be killed (via SIGTTOU) when
> ** it tries to access the terminal.
> ** (Rainer Weikusat <rweikusat@talktalk.net>)
> */

This is unfortunately almost completely wrong: The process becomes
orphaned but this only means that it becomes a child of init (whatever
that's called in the FatRat Lunix version du jour). The important bit
here is that the process group becomes orphaned. When processes
belonging to it which don't block or ignore SIGTTOU try to write to
terminal, the system call will fail with EIO. That's presumably what
terminates the less here.

Re: a problem on pipes: making the child run less and parent writes to it

<smebe5$c0n$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16766&group=comp.unix.programmer#16766

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitcher@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Tue, 9 Nov 2021 17:33:57 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 29
Message-ID: <smebe5$c0n$1@dont-email.me>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me>
<87ilx1s0l9.fsf@doppelsaurus.mobileactivedefense.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 9 Nov 2021 17:33:57 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="d9d124491cb5fb9f2dd8424f26f08f89";
logging-data="12311"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/1wMJB+FrwaXHMCuXRIMyxv5gNa2k7EWo="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:zgnrBRd/9y5J7VSymFFLZumvqPw=
 by: Lew Pitcher - Tue, 9 Nov 2021 17:33 UTC

On Tue, 09 Nov 2021 17:25:22 +0000, Rainer Weikusat wrote:

> Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>
> [...]
>
>> /*
>> ** The parent needs to wait because otherwise, the process running
>> ** less(1) becomes orphaned and will be killed (via SIGTTOU) when
>> ** it tries to access the terminal.
>> ** (Rainer Weikusat <rweikusat@talktalk.net>)
>> */
>
> This is unfortunately almost completely wrong: The process becomes
> orphaned but this only means that it becomes a child of init (whatever
> that's called in the FatRat Lunix version du jour). The important bit
> here is that the process group becomes orphaned. When processes
> belonging to it which don't block or ignore SIGTTOU try to write to
> terminal, the system call will fail with EIO. That's presumably what
> terminates the less here.

Noted.
Corrected.

--
Lew Pitcher
"In Skills, We Trust"

Re: a problem on pipes: making the child run less and parent writes to it

<86o82o8gbm.fsf@levado.to>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17022&group=comp.unix.programmer#17022

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!aioe.org!MFZx1yx7Oe4QZxzA8GQPrg.user.46.165.242.91.POSTED!not-for-mail
From: mmontgomery@levado.to (Meredith Montgomery)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Wed, 02 Mar 2022 13:33:33 -0300
Organization: Aioe.org NNTP Server
Message-ID: <86o82o8gbm.fsf@levado.to>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="6164"; posting-host="MFZx1yx7Oe4QZxzA8GQPrg.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
X-Notice: Filtered by postfilter v. 0.9.2
Cancel-Lock: sha1:GJrONsnREXcR/ChxlTxo+iJvXdY=
 by: Meredith Montgomery - Wed, 2 Mar 2022 16:33 UTC

I have a question about Lew Pitcher's program. I still don't know what
else must be done if we replace the printf() calls with an execution of
cat. I seem to understand the original program completely, but my
understanding must be wrong somewhere because I can't make a simple
modification and predict the output. Please see the details below.
(Notice I paste the full program at the end of the message just in case
it helps anyone to copy it and compile it.)

Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

> I spent a bit of time to write a one-off that both performs the
> requisite task correctly, /and/ embodies the stylistic points that
> I made in the prior post. This is what I came up with...
>
> /******************* Code begins **********************************/
>
> /*
> ** This program demonstrates a solution to a problem posted by
> ** Meredith Montgomery in the comp.unix.programmer usenet group.
> **
> ** The programmer wants a program that creates a pipe between
> ** itself and the stdin of a child process. The child process
> ** runs less(1) on it's stdin (the read end of the pipe) while
> ** the parent process generates print data to the write end of
> ** the pipe.
> **
> ** The development of this program followed "Occam's razor",
> ** in that it subscribed to the principle that "entities
> ** should not be multiplied beyond necessity". In this case,
> ** I endeavoured to avoid needless encapsulation and abstraction
> ** of logic, in order to create a simple working version of the
> ** solution. Embellishments, such as logic encapsulation and
> ** isolation, are left to others to implement.
> **
> ** == Evolution ==
> ** 0: basic framework
> ** 1: create pipe
> ** 2: fork
> ** 3: child process reads input from pipe
> ** 4: parent process output to pipe
> ** 5: document finer points in comments
> */
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <errno.h>
> #include <string.h>
> #include <sys/types.h>
> #include <sys/wait.h>
>
> int main(int argc, char *argv[])
> {
> int status = EXIT_FAILURE;
> int pfd[2];
>
> /*
> ** Step 1, make our pipe
> */
> if (pipe(pfd) == 0) /* On error, pipe(2) will return -1 and set errno */
> {
> /*
> ** Step 2: we got a valid pipe pair, now launch child and perform all processing
> */
>
> switch (fork())
> {
> /*
> ** On error, fork(2) will return -1, and set errno appropriately
> */
> case -1: /* fork failed */
> fprintf(stderr,"%s: fork() failed - %s\n",argv[0],strerror(errno));
> break;
>
> /*
> ** In the child process, fork(2) returns 0
> */
> case 0: /* CHILD process */
> /*
> ** Step 3: prepare the child process to read the pipe through stdin
> ** and run "less" on the input
> */
> close(pfd[1]); /* don't hold pipe write end open */
> if (dup2(pfd[0],STDIN_FILENO) != -1)
> {
> close(pfd[0]); /* close the now useless fd */
> execl("/usr/bin/less","less",NULL); /* use "less" to process stdin */
> /* we only get here if execl() failed */
> fprintf(stderr,"%s: execl() failed - %s\n",argv[0],strerror(errno));
> }
> else fprintf(stderr,"%s: child dup2() failed - %s\n",argv[0],strerror(errno));
> break;
>
> /*
> ** In the parent process, fork(2) returns the non-zero, non -1 PID
> ** of the child process
> */
> default: /* PARENT process */
> /*
> ** Step 4: prepare the parent process to write the pipe through stdout
> ** write some data so that the child can process it, wait for
> ** the child to process the data and then terminate the parent.
> */
> close(pfd[0]); /* dont hold pipe read end open */
> if (dup2(pfd[1],STDOUT_FILENO) != -1) /* use the write end of pipe as stdout */
> {
> close(pfd[1]); /* close the now useless fd */
>
> /* generate some output to be piped to the child */
> for (int count = 0; count < 100; ++count)
> printf("This is generated line number %d\n",count);
> fclose(stdout); /* signals EOF to child process stdin */

What happens if I replace this for-loop with an execution of cat? For
example, what happens if we place this entire for-loop with

execl("/usr/bin/cat", "cat", "lew.c", NULL)?

Assume we remove the fclose and the wait below, although I think that
has no effect if execl succeeds.

I expected it to work, but it doesn't. The less process gets killed and
leaves the terminal in a inconsistent state.

> /*
> ** The parent needs to wait because otherwise, the process running
> ** less(1) becomes orphaned and will be killed (via SIGTTOU) when
> ** it tries to access the terminal.
> ** (Rainer Weikusat <rweikusat@talktalk.net>)
> */
> wait(NULL); /* wait for the child to finish */

Wouldn't cat wait for the reader to close its reading end? Notice that
Rainer Weikusat and Lew Pitcher discussed this comment above. I'll show
it again here just in case it helps to answer my question.

--8<---------------cut here---------------start------------->8---
Path: aioe.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: Rainer Weikusat <rweikusat@talktalk.net>
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Tue, 09 Nov 2021 17:25:22 +0000
Lines: 19
Message-ID: <87ilx1s0l9.fsf@doppelsaurus.mobileactivedefense.com>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net sxs5sVhUULAg0ZwigtwFiABaDVfBheWEJi/dzPUCrDgnmybJc=
Cancel-Lock: sha1:J8Xuih6gHa9fFrX1f3ROY2bpM6U= sha1:C4vMs1rkbtNeEEqaS2XCfuavJgo=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)
Xref: aioe.org comp.unix.programmer:23115

Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

[...]

> /*
> ** The parent needs to wait because otherwise, the process running
> ** less(1) becomes orphaned and will be killed (via SIGTTOU) when
> ** it tries to access the terminal.
> ** (Rainer Weikusat <rweikusat@talktalk.net>)
> */

This is unfortunately almost completely wrong: The process becomes
orphaned but this only means that it becomes a child of init (whatever
that's called in the FatRat Lunix version du jour). The important bit
here is that the process group becomes orphaned. When processes
belonging to it which don't block or ignore SIGTTOU try to write to
terminal, the system call will fail with EIO. That's presumably what
terminates the less here.
--8<---------------cut here---------------end--------------->8---

So it does seem that somehow cat is not waiting for less? How is this
properly done? I still haven't understood this. Thanks for your patience.

>
> status = EXIT_SUCCESS; /* Mission Accomplished! */
> }
> else fprintf(stderr,"%s: parent dup2() failed - %s\n",argv[0],strerror(errno));
> break;
> }
> }
> else fprintf(stderr,"%s: pipe() failed - %s\n",argv[0],strerror(errno));
>
> return status;
> }
> /******************* Code ends **********************************/

(*) Full program

/******************* Code begins **********************************/

/*
** This program demonstrates a solution to a problem posted by
** Meredith Montgomery in the comp.unix.programmer usenet group.
**
** The programmer wants a program that creates a pipe between
** itself and the stdin of a child process. The child process
** runs less(1) on it's stdin (the read end of the pipe) while
** the parent process generates print data to the write end of
** the pipe.
**
** The development of this program followed "Occam's razor",
** in that it subscribed to the principle that "entities
** should not be multiplied beyond necessity". In this case,
** I endeavoured to avoid needless encapsulation and abstraction
** of logic, in order to create a simple working version of the
** solution. Embellishments, such as logic encapsulation and
** isolation, are left to others to implement.
**
** == Evolution ==
** 0: basic framework
** 1: create pipe
** 2: fork
** 3: child process reads input from pipe
** 4: parent process output to pipe
** 5: document finer points in comments
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>


Click here to read the complete article
Re: a problem on pipes: making the child run less and parent writes to it

<SFOTJ.47115$m1S7.19377@fx36.iad>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17024&group=comp.unix.programmer#17024

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!usenet.goja.nl.eu.org!news.freedyn.de!newsreader4.netcologne.de!news.netcologne.de!peer01.ams1!peer.ams1.xlned.com!news.xlned.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx36.iad.POSTED!not-for-mail
X-newsreader: xrn 9.03-beta-14-64bit
Sender: scott@dragon.sl.home (Scott Lurndal)
From: scott@slp53.sl.home (Scott Lurndal)
Reply-To: slp53@pacbell.net
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Newsgroups: comp.unix.programmer
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me> <sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to>
Lines: 29
Message-ID: <SFOTJ.47115$m1S7.19377@fx36.iad>
X-Complaints-To: abuse@usenetserver.com
NNTP-Posting-Date: Wed, 02 Mar 2022 18:26:58 UTC
Organization: UsenetServer - www.usenetserver.com
Date: Wed, 02 Mar 2022 18:26:58 GMT
X-Received-Bytes: 2218
 by: Scott Lurndal - Wed, 2 Mar 2022 18:26 UTC

Meredith Montgomery <mmontgomery@levado.to> writes:
>I have a question about Lew Pitcher's program. I still don't know what
>else must be done if we replace the printf() calls with an execution of
>cat. I seem to understand the original program completely, but my
>understanding must be wrong somewhere because I can't make a simple
>modification and predict the output. Please see the details below.
>(Notice I paste the full program at the end of the message just in case
>it helps anyone to copy it and compile it.)

>> /* generate some output to be piped to the child */
>> for (int count = 0; count < 100; ++count)
>> printf("This is generated line number %d\n",count);
>> fclose(stdout); /* signals EOF to child process stdin */
>
>What happens if I replace this for-loop with an execution of cat? For
>example, what happens if we place this entire for-loop with
>
> execl("/usr/bin/cat", "cat", "lew.c", NULL)?
>
>Assume we remove the fclose and the wait below, although I think that
>has no effect if execl succeeds.

That execl(2) system call is executed in the context of the parent.

What does exec(2) do? It completely replaces the current process
with a new process. So, you're replacing the parent process with
a shell executing the cat(1) command. The wait for the child, being part of the
former parent process, can never be executed as that process no longer
exists.

Re: a problem on pipes: making the child run less and parent writes to it

<svon2m$jba$3@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17028&group=comp.unix.programmer#17028

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitcher@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Wed, 2 Mar 2022 21:20:22 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 80
Message-ID: <svon2m$jba$3@dont-email.me>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Wed, 2 Mar 2022 21:20:22 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="8613ade514610477fe71534f6577e731";
logging-data="19818"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+C//Ns8YIUhNhAvi6RBCt+cHlucDrdrGc="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:/A7ImrJ+9MqHqu992/Ogx51/x6M=
 by: Lew Pitcher - Wed, 2 Mar 2022 21:20 UTC

On Wed, 02 Mar 2022 13:33:33 -0300, Meredith Montgomery wrote:

Scott Lurndal's reply is spot on.

> I have a question about Lew Pitcher's program. I still don't know what
> else must be done if we replace the printf() calls with an execution of
> cat. I seem to understand the original program completely, but my
> understanding must be wrong somewhere because I can't make a simple
> modification and predict the output. Please see the details below.
> (Notice I paste the full program at the end of the message just in case
> it helps anyone to copy it and compile it.)

In my local copy of the original code, I have this:
default: /* PARENT process */
/*
** Step 4: prepare the parent process to write the pipe through stdout
** write some data so that the child can process it, wait for
** the child to process the data and then terminate the parent.
*/
close(pfd[0]); /* dont hold pipe read end open [Note 1] */
if (dup2(pfd[1],STDOUT_FILENO) != -1) /* use the write end of pipe as our stdout */
{
close(pfd[1]); /* close the now useless write fd [Note 1] */

/* generate some output to be piped to the child */
for (int count = 0; count < 100; ++count)
printf("This is generated line number %d\n",count);
fclose(stdout); /* signals EOF to child process stdin [Note 1] */

wait(NULL); /* wait for the child to finish [Note 2] */

status = EXIT_SUCCESS; /* Mission Accomplished! */
}
else fprintf(stderr,"%s: parent dup2() failed - %s\n",argv[0],strerror(errno));
break;

and "Note 2" (comment beside the wait() call) later...
== Note 2 ==
Conceptually, the parent process, once it has written all its lines and
closed the write end of the pipe, /should/ be able to just exit(3) and
terminate. In this case, the only side-effect is that the child process
becomes an orphan process until it terminates.

However, when the child process runs less(2), other things happen. /If/
we had forked off /usr/bin/cat instead of /usr/bin/less, we could have
forgone the wait(2). But, /usr/bin/less expects to have control of the
controlling terminal (where /usr/bin/cat does not), and once our parent
process terminates, control of the controlling terminal is given back
to the shell.

Additionally, less(1) maintains an internal buffer of it's input data
to permit backwards scrolling, etc.

The combination of no terminal control, and an internal buffer causes
less(1) to abort all output.

So, instead of terminating the parent process immediately (and relinquishing
the terminal), we wait(2) for less(1) to terminate before terminating
the parent process. This guarantees that less(1) can access the terminal
as it needs, and display its buffered data.

While this comment talks about the difference in behaviour between less(1)
and cat(1) with respect to the parent process, the observation also applies
to how the parent process works. Specifically, if you substitute
execl("/usr/bin/cat","cat","some.text",NULL);
for the printf() loop in the parent process, you again do not wait() for the
child process to terminate. And, as we saw with the original code, you need
to wait() for this specific child process ("/usr/bin/less") to complete
in order to retain a coherent terminal control state.

I don't believe that I posted the original code with these comments.
I apologize; I should have.

[snip]

HTH
--
Lew Pitcher
"In Skills, We Trust"

Re: a problem on pipes: making the child run less and parent writes to it

<ygapmn35rdc.fsf@akutech.de>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17029&group=comp.unix.programmer#17029

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: ralfixx@gmx.de (Ralf Fassel)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Thu, 03 Mar 2022 10:15:27 +0100
Lines: 14
Message-ID: <ygapmn35rdc.fsf@akutech.de>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to>
<svon2m$jba$3@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain
X-Trace: individual.net Kn3uHXef/e710QG2OeRZkgvwg4IcrFBhGg8kBdidz+QKKVDiU=
Cancel-Lock: sha1:1FMXtpLc2YupUAKpJOq506eeoEc= sha1:5qtkhWbGU1zGK7rUHznlJt/qwu4=
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux)
 by: Ralf Fassel - Thu, 3 Mar 2022 09:15 UTC

* Lew Pitcher <lew.pitcher@digitalfreehold.ca>
| However, when the child process runs less(2), other things happen. /If/
| we had forked off /usr/bin/cat instead of /usr/bin/less, we could have
| forgone the wait(2). But, /usr/bin/less expects to have control of the
| controlling terminal (where /usr/bin/cat does not), and once our parent
| process terminates, control of the controlling terminal is given back
| to the shell.

I always thought that fork() duplicates the current process with
'everything', so I would have expected the child (which eventually execs
"less") to also have "control of the controlling terminal".
But obviously there is more to that...

R'

Re: a problem on pipes: making the child run less and parent writes to it

<6s4UJ.94352$Gojc.70961@fx99.iad>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17030&group=comp.unix.programmer#17030

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!peer03.ams1!peer.ams1.xlned.com!news.xlned.com!peer02.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx99.iad.POSTED!not-for-mail
X-newsreader: xrn 9.03-beta-14-64bit
Sender: scott@dragon.sl.home (Scott Lurndal)
From: scott@slp53.sl.home (Scott Lurndal)
Reply-To: slp53@pacbell.net
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Newsgroups: comp.unix.programmer
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me> <sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to> <svon2m$jba$3@dont-email.me> <ygapmn35rdc.fsf@akutech.de>
Lines: 58
Message-ID: <6s4UJ.94352$Gojc.70961@fx99.iad>
X-Complaints-To: abuse@usenetserver.com
NNTP-Posting-Date: Thu, 03 Mar 2022 14:41:06 UTC
Organization: UsenetServer - www.usenetserver.com
Date: Thu, 03 Mar 2022 14:41:06 GMT
X-Received-Bytes: 3620
 by: Scott Lurndal - Thu, 3 Mar 2022 14:41 UTC

Ralf Fassel <ralfixx@gmx.de> writes:
>* Lew Pitcher <lew.pitcher@digitalfreehold.ca>
>| However, when the child process runs less(2), other things happen. /If/
>| we had forked off /usr/bin/cat instead of /usr/bin/less, we could have
>| forgone the wait(2). But, /usr/bin/less expects to have control of the
>| controlling terminal (where /usr/bin/cat does not), and once our parent
>| process terminates, control of the controlling terminal is given back
>| to the shell.
>
>I always thought that fork() duplicates the current process with
>'everything', so I would have expected the child (which eventually execs
>"less") to also have "control of the controlling terminal".
>But obviously there is more to that...

Indeed. You need to look at the controlling terminal in the context
of a process "tree", for example:

$ ps -ejH
PID PGID SID TTY TIME CMD
....
1807 1401 1401 ? 00:00:16 xterm
1811 1811 1811 pts/3 00:00:02 ksh
17690 17690 1811 pts/3 00:00:12 xpdf
3518 3518 1811 pts/3 00:00:09 xpdf
1101 1101 1811 pts/3 00:00:18 xpdf
3533 3533 1811 pts/3 00:00:01 xpdf
23125 23125 1811 pts/3 07:08:21 firefox
12781 12781 1811 pts/3 00:51:03 firefox-bin
12834 12781 1811 pts/3 00:00:00 Socket Process
12922 12781 1811 pts/3 00:37:44 Web Content
12998 12781 1811 pts/3 00:03:21 WebExtensions
13058 12781 1811 pts/3 00:10:30 Web Content
13112 12781 1811 pts/3 00:00:11 Privileged Cont
13275 12781 1811 pts/3 00:08:39 Web Content
13362 12781 1811 pts/3 00:02:07 RDD Process
13517 12781 1811 pts/3 00:07:27 Web Content
14273 12781 1811 pts/3 00:10:50 Web Content
14356 12781 1811 pts/3 00:11:43 Web Content
14393 12781 1811 pts/3 00:09:23 Web Content
14671 12781 1811 pts/3 00:05:45 Web Content
12281 12281 1811 pts/3 00:00:01 xrn
12386 12386 1811 pts/3 00:00:00 ps
....

Here, the controlling terminal is 'pts/3', which was
opened by xterm and passed to the korn shell (ksh).
ksh issued a 'setsid(2)' system call to become the session
leader, and thus "owns" the controlling terminal (by
virtual of being the session leader). Within a session
are one or more process groups (usually created with
the shell job-control facilities, e.g. '&' or control-z).

Only one process group can be the 'foreground' group, and
that group receives input from and sends output to
the terminal until it is suspended
(e.g. SIGTSTP/SIGSTOP) or the process group leader terminates.

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap11.html

Re: a problem on pipes: making the child run less and parent writes to it

<svqlcs$tmm$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17031&group=comp.unix.programmer#17031

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitcher@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Thu, 3 Mar 2022 15:03:56 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 36
Message-ID: <svqlcs$tmm$1@dont-email.me>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to>
<svon2m$jba$3@dont-email.me> <ygapmn35rdc.fsf@akutech.de>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 3 Mar 2022 15:03:56 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="bd150b0ee76e7ab3867294085372d456";
logging-data="30422"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18BQIj0VHhUhwfiqYJyfuWRAYzcXuNKDrM="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:Vl99ybpVISa+ln8cLAEvXOdLXm4=
 by: Lew Pitcher - Thu, 3 Mar 2022 15:03 UTC

On Thu, 03 Mar 2022 10:15:27 +0100, Ralf Fassel wrote:

> * Lew Pitcher <lew.pitcher@digitalfreehold.ca>
> | However, when the child process runs less(2), other things happen. /If/
> | we had forked off /usr/bin/cat instead of /usr/bin/less, we could have
> | forgone the wait(2). But, /usr/bin/less expects to have control of the
> | controlling terminal (where /usr/bin/cat does not), and once our parent
> | process terminates, control of the controlling terminal is given back
> | to the shell.
>
> I always thought that fork() duplicates the current process with
> 'everything', so I would have expected the child (which eventually execs
> "less") to also have "control of the controlling terminal".
> But obviously there is more to that...

Well, /every/ process that has not divorced itself from it's controlling
terminal has control of that terminal, in that every process can read from it,
write to it, and change it's characteristics (line echo, etc.).

I still don't understand the intricacies of it myself, but in it's simplest
form, imagine if two processes both are trying to read from the controlling
terminal: which process gets the input? How about one process that turns off
echo (say, to prevent it's input from distorting the output on the terminal,
like less(1) would do), and one process that assumes that echo is turned on
(like, say, the shell). Or, if each process emits a termcap/termios control
string at the same time; how does the terminal interpret two simultaneous,
conflicting command strings?

So, usually, only one process at a time uses the controlling terminal, while
all other processes wait. I don't know the mechanism of that co-ordination;
I'm just learning this stuff myself.

HTH
--
Lew Pitcher
"In Skills, We Trust"

Re: a problem on pipes: making the child run less and parent writes to it

<tY5UJ.94353$Gojc.29821@fx99.iad>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17032&group=comp.unix.programmer#17032

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!aioe.org!news.mixmin.net!newsreader4.netcologne.de!news.netcologne.de!peer02.ams1!peer.ams1.xlned.com!news.xlned.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx99.iad.POSTED!not-for-mail
X-newsreader: xrn 9.03-beta-14-64bit
Sender: scott@dragon.sl.home (Scott Lurndal)
From: scott@slp53.sl.home (Scott Lurndal)
Reply-To: slp53@pacbell.net
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Newsgroups: comp.unix.programmer
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me> <sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to> <svon2m$jba$3@dont-email.me> <ygapmn35rdc.fsf@akutech.de> <svqlcs$tmm$1@dont-email.me>
Lines: 55
Message-ID: <tY5UJ.94353$Gojc.29821@fx99.iad>
X-Complaints-To: abuse@usenetserver.com
NNTP-Posting-Date: Thu, 03 Mar 2022 16:23:53 UTC
Organization: UsenetServer - www.usenetserver.com
Date: Thu, 03 Mar 2022 16:23:53 GMT
X-Received-Bytes: 4057
 by: Scott Lurndal - Thu, 3 Mar 2022 16:23 UTC

Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>On Thu, 03 Mar 2022 10:15:27 +0100, Ralf Fassel wrote:
>
>> * Lew Pitcher <lew.pitcher@digitalfreehold.ca>
>> | However, when the child process runs less(2), other things happen. /If/
>> | we had forked off /usr/bin/cat instead of /usr/bin/less, we could have
>> | forgone the wait(2). But, /usr/bin/less expects to have control of the
>> | controlling terminal (where /usr/bin/cat does not), and once our parent
>> | process terminates, control of the controlling terminal is given back
>> | to the shell.
>>
>> I always thought that fork() duplicates the current process with
>> 'everything', so I would have expected the child (which eventually execs
>> "less") to also have "control of the controlling terminal".
>> But obviously there is more to that...
>
>Well, /every/ process that has not divorced itself from it's controlling
>terminal has control of that terminal, in that every process can read from it,
>write to it, and change it's characteristics (line echo, etc.).
>
>I still don't understand the intricacies of it myself, but in it's simplest
>form, imagine if two processes both are trying to read from the controlling
>terminal: which process gets the input?

"If a process is in the foreground process group of its controlling
terminal, read operations shall be allowed, as described in Input
Processing and Reading Data. Any attempts by a process in a background
process group to read from its controlling terminal cause its process
group to be sent a SIGTTIN signal unless one of the following special
cases applies: if the reading process is ignoring the SIGTTIN signal
or the reading thread is blocking the SIGTTIN signal, or if the
process group of the reading process is orphaned, the read() shall
return -1, with errno set to [EIO] and no signal shall be sent. The
default action of the SIGTTIN signal shall be to stop the process
to which it is sent."

"If a process is in the foreground process group of its controlling
terminal, write operations shall be allowed as described in Writing
Data and Output Processing. Attempts by a process in a background
process group to write to its controlling terminal shall cause the
process group to be sent a SIGTTOU signal unless one of the following
special cases applies: if TOSTOP is not set, or if TOSTOP is set and
the process is ignoring the SIGTTOU signal or the writing thread is
blocking the SIGTTOU signal, the process is allowed to write to the
terminal and the SIGTTOU signal is not sent. If TOSTOP is set, the
process group of the writing process is orphaned, the writing process
is not ignoring the SIGTTOU signal, and the writing thread is not blocking
the SIGTTOU signal, the write() shall return -1, with errno set to [EIO]
and no signal shall be sent."

This implies that multiple processes _within_ a process group need to
coordinate both read and write operations to avoid conflicting with
each other (regardless of the type of file - block special, character
special, fifo, pipe or regular file).

Re: a problem on pipes: making the child run less and parent writes to it

<svqriq$tmm$3@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17033&group=comp.unix.programmer#17033

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: lew.pitcher@digitalfreehold.ca (Lew Pitcher)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes
to it
Date: Thu, 3 Mar 2022 16:49:30 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 71
Message-ID: <svqriq$tmm$3@dont-email.me>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to>
<svon2m$jba$3@dont-email.me> <ygapmn35rdc.fsf@akutech.de>
<svqlcs$tmm$1@dont-email.me> <tY5UJ.94353$Gojc.29821@fx99.iad>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 3 Mar 2022 16:49:30 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="bd150b0ee76e7ab3867294085372d456";
logging-data="30422"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/gaD66KbNbmgzNN/uXlK7PQati0KeUuE4="
User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508
git://git.gnome.org/pan2)
Cancel-Lock: sha1:DQqrp7rM5Tw0XhvJFVkmlF6h+EQ=
 by: Lew Pitcher - Thu, 3 Mar 2022 16:49 UTC

On Thu, 03 Mar 2022 16:23:53 +0000, Scott Lurndal wrote:

> Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>>On Thu, 03 Mar 2022 10:15:27 +0100, Ralf Fassel wrote:
>>
>>> * Lew Pitcher <lew.pitcher@digitalfreehold.ca>
>>> | However, when the child process runs less(2), other things happen. /If/
>>> | we had forked off /usr/bin/cat instead of /usr/bin/less, we could have
>>> | forgone the wait(2). But, /usr/bin/less expects to have control of the
>>> | controlling terminal (where /usr/bin/cat does not), and once our parent
>>> | process terminates, control of the controlling terminal is given back
>>> | to the shell.
>>>
>>> I always thought that fork() duplicates the current process with
>>> 'everything', so I would have expected the child (which eventually execs
>>> "less") to also have "control of the controlling terminal".
>>> But obviously there is more to that...
>>
>>Well, /every/ process that has not divorced itself from it's controlling
>>terminal has control of that terminal, in that every process can read from it,
>>write to it, and change it's characteristics (line echo, etc.).
>>
>>I still don't understand the intricacies of it myself, but in it's simplest
>>form, imagine if two processes both are trying to read from the controlling
>>terminal: which process gets the input?
>
> "If a process is in the foreground process group of its controlling
> terminal, read operations shall be allowed, as described in Input
> Processing and Reading Data. Any attempts by a process in a background
> process group to read from its controlling terminal cause its process
> group to be sent a SIGTTIN signal unless one of the following special
> cases applies: if the reading process is ignoring the SIGTTIN signal
> or the reading thread is blocking the SIGTTIN signal, or if the
> process group of the reading process is orphaned, the read() shall
> return -1, with errno set to [EIO] and no signal shall be sent. The
> default action of the SIGTTIN signal shall be to stop the process
> to which it is sent."
>
> "If a process is in the foreground process group of its controlling
> terminal, write operations shall be allowed as described in Writing
> Data and Output Processing. Attempts by a process in a background
> process group to write to its controlling terminal shall cause the
> process group to be sent a SIGTTOU signal unless one of the following
> special cases applies: if TOSTOP is not set, or if TOSTOP is set and
> the process is ignoring the SIGTTOU signal or the writing thread is
> blocking the SIGTTOU signal, the process is allowed to write to the
> terminal and the SIGTTOU signal is not sent. If TOSTOP is set, the
> process group of the writing process is orphaned, the writing process
> is not ignoring the SIGTTOU signal, and the writing thread is not blocking
> the SIGTTOU signal, the write() shall return -1, with errno set to [EIO]
> and no signal shall be sent."
>
>
> This implies that multiple processes _within_ a process group need to
> coordinate both read and write operations to avoid conflicting with
> each other

And, if they don't co-ordinate read and write operations, then....
the unpredictable happens.

Just like Meredith is seeing with the various iterations of her program,
where both less(1) and the shell compete for input (and output) from
the controlling terminal.

>(regardless of the type of file - block special, character
> special, fifo, pipe or regular file).

--
Lew Pitcher
"In Skills, We Trust"

Re: a problem on pipes: making the child run less and parent writes to it

<5K6UJ.233963$Rza5.136066@fx47.iad>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17034&group=comp.unix.programmer#17034

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!aioe.org!news.uzoreto.com!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer02.ams1!peer.ams1.xlned.com!news.xlned.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx47.iad.POSTED!not-for-mail
X-newsreader: xrn 9.03-beta-14-64bit
Sender: scott@dragon.sl.home (Scott Lurndal)
From: scott@slp53.sl.home (Scott Lurndal)
Reply-To: slp53@pacbell.net
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Newsgroups: comp.unix.programmer
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me> <sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to> <svon2m$jba$3@dont-email.me> <ygapmn35rdc.fsf@akutech.de> <svqlcs$tmm$1@dont-email.me> <tY5UJ.94353$Gojc.29821@fx99.iad> <svqriq$tmm$3@dont-email.me>
Lines: 68
Message-ID: <5K6UJ.233963$Rza5.136066@fx47.iad>
X-Complaints-To: abuse@usenetserver.com
NNTP-Posting-Date: Thu, 03 Mar 2022 17:16:49 UTC
Organization: UsenetServer - www.usenetserver.com
Date: Thu, 03 Mar 2022 17:16:49 GMT
X-Received-Bytes: 4776
 by: Scott Lurndal - Thu, 3 Mar 2022 17:16 UTC

Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>On Thu, 03 Mar 2022 16:23:53 +0000, Scott Lurndal wrote:
>
>> Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>>>On Thu, 03 Mar 2022 10:15:27 +0100, Ralf Fassel wrote:
>>>
>>>> * Lew Pitcher <lew.pitcher@digitalfreehold.ca>
>>>> | However, when the child process runs less(2), other things happen. /If/
>>>> | we had forked off /usr/bin/cat instead of /usr/bin/less, we could have
>>>> | forgone the wait(2). But, /usr/bin/less expects to have control of the
>>>> | controlling terminal (where /usr/bin/cat does not), and once our parent
>>>> | process terminates, control of the controlling terminal is given back
>>>> | to the shell.
>>>>
>>>> I always thought that fork() duplicates the current process with
>>>> 'everything', so I would have expected the child (which eventually execs
>>>> "less") to also have "control of the controlling terminal".
>>>> But obviously there is more to that...
>>>
>>>Well, /every/ process that has not divorced itself from it's controlling
>>>terminal has control of that terminal, in that every process can read from it,
>>>write to it, and change it's characteristics (line echo, etc.).
>>>
>>>I still don't understand the intricacies of it myself, but in it's simplest
>>>form, imagine if two processes both are trying to read from the controlling
>>>terminal: which process gets the input?
>>
>> "If a process is in the foreground process group of its controlling
>> terminal, read operations shall be allowed, as described in Input
>> Processing and Reading Data. Any attempts by a process in a background
>> process group to read from its controlling terminal cause its process
>> group to be sent a SIGTTIN signal unless one of the following special
>> cases applies: if the reading process is ignoring the SIGTTIN signal
>> or the reading thread is blocking the SIGTTIN signal, or if the
>> process group of the reading process is orphaned, the read() shall
>> return -1, with errno set to [EIO] and no signal shall be sent. The
>> default action of the SIGTTIN signal shall be to stop the process
>> to which it is sent."
>>
>> "If a process is in the foreground process group of its controlling
>> terminal, write operations shall be allowed as described in Writing
>> Data and Output Processing. Attempts by a process in a background
>> process group to write to its controlling terminal shall cause the
>> process group to be sent a SIGTTOU signal unless one of the following
>> special cases applies: if TOSTOP is not set, or if TOSTOP is set and
>> the process is ignoring the SIGTTOU signal or the writing thread is
>> blocking the SIGTTOU signal, the process is allowed to write to the
>> terminal and the SIGTTOU signal is not sent. If TOSTOP is set, the
>> process group of the writing process is orphaned, the writing process
>> is not ignoring the SIGTTOU signal, and the writing thread is not blocking
>> the SIGTTOU signal, the write() shall return -1, with errno set to [EIO]
>> and no signal shall be sent."
>>
>>
>> This implies that multiple processes _within_ a process group need to
>> coordinate both read and write operations to avoid conflicting with
>> each other
>
>And, if they don't co-ordinate read and write operations, then....
>the unpredictable happens.
>
>Just like Meredith is seeing with the various iterations of her program,
>where both less(1) and the shell compete for input (and output) from
>the controlling terminal.

It gets even worse if both processes are sharing a file descriptor
but are using different FILE objects to access that file descriptor
due to the stdio buffering (avoided by disabling buffering with setvbuf(3)).

Re: a problem on pipes: making the child run less and parent writes to it

<864k43p75i.fsf@levado.to>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17037&group=comp.unix.programmer#17037

  copy link   Newsgroups: comp.unix.programmer
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!news.mixmin.net!aioe.org!K0Mf9xWdzF+RvqYo8Wn9fw.user.46.165.242.91.POSTED!not-for-mail
From: mmontgomery@levado.to (Meredith Montgomery)
Newsgroups: comp.unix.programmer
Subject: Re: a problem on pipes: making the child run less and parent writes to it
Date: Sat, 12 Mar 2022 11:39:05 -0300
Organization: Aioe.org NNTP Server
Message-ID: <864k43p75i.fsf@levado.to>
References: <86a6ijvro4.fsf@levado.to> <sm17gg$tp4$1@dont-email.me>
<sm9asb$g1o$2@dont-email.me> <86o82o8gbm.fsf@levado.to>
<svon2m$jba$3@dont-email.me> <ygapmn35rdc.fsf@akutech.de>
<svqlcs$tmm$1@dont-email.me> <tY5UJ.94353$Gojc.29821@fx99.iad>
<svqriq$tmm$3@dont-email.me> <5K6UJ.233963$Rza5.136066@fx47.iad>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="28116"; posting-host="K0Mf9xWdzF+RvqYo8Wn9fw.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
Cancel-Lock: sha1:dwLbCDv7J9TWJZRFOtlkCkYTu5s=
X-Notice: Filtered by postfilter v. 0.9.2
 by: Meredith Montgomery - Sat, 12 Mar 2022 14:39 UTC

scott@slp53.sl.home (Scott Lurndal) writes:

> Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>>On Thu, 03 Mar 2022 16:23:53 +0000, Scott Lurndal wrote:
>>
>>> Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>>>>On Thu, 03 Mar 2022 10:15:27 +0100, Ralf Fassel wrote:
>>>>
>>>>> * Lew Pitcher <lew.pitcher@digitalfreehold.ca>
>>>>> | However, when the child process runs less(2), other things
>>>>> | happen. /If/
>>>>> | we had forked off /usr/bin/cat instead of /usr/bin/less, we
>>>>> | could have
>>>>> | forgone the wait(2). But, /usr/bin/less expects to have
>>>>> | control of the
>>>>> | controlling terminal (where /usr/bin/cat does not), and
>>>>> | once our parent
>>>>> | process terminates, control of the controlling terminal is given back
>>>>> | to the shell.
>>>>>
>>>>> I always thought that fork() duplicates the current process with
>>>>> 'everything', so I would have expected the child (which eventually execs
>>>>> "less") to also have "control of the controlling terminal".
>>>>> But obviously there is more to that...
>>>>
>>>>Well, /every/ process that has not divorced itself from it's controlling
>>>>terminal has control of that terminal, in that every process can
>>>> read from it,
>>>>write to it, and change it's characteristics (line echo, etc.).
>>>>
>>>>I still don't understand the intricacies of it myself, but in it's simplest
>>>>form, imagine if two processes both are trying to read from the controlling
>>>>terminal: which process gets the input?
>>>
>>> "If a process is in the foreground process group of its controlling
>>> terminal, read operations shall be allowed, as described in Input
>>> Processing and Reading Data. Any attempts by a process in a background
>>> process group to read from its controlling terminal cause its process
>>> group to be sent a SIGTTIN signal unless one of the following special
>>> cases applies: if the reading process is ignoring the SIGTTIN signal
>>> or the reading thread is blocking the SIGTTIN signal, or if the
>>> process group of the reading process is orphaned, the read() shall
>>> return -1, with errno set to [EIO] and no signal shall be sent. The
>>> default action of the SIGTTIN signal shall be to stop the process
>>> to which it is sent."
>>>
>>> "If a process is in the foreground process group of its controlling
>>> terminal, write operations shall be allowed as described in Writing
>>> Data and Output Processing. Attempts by a process in a background
>>> process group to write to its controlling terminal shall cause the
>>> process group to be sent a SIGTTOU signal unless one of the following
>>> special cases applies: if TOSTOP is not set, or if TOSTOP is set and
>>> the process is ignoring the SIGTTOU signal or the writing thread is
>>> blocking the SIGTTOU signal, the process is allowed to write to the
>>> terminal and the SIGTTOU signal is not sent. If TOSTOP is set, the
>>> process group of the writing process is orphaned, the writing process
>>> is not ignoring the SIGTTOU signal, and the writing thread is not blocking
>>> the SIGTTOU signal, the write() shall return -1, with errno set to [EIO]
>>> and no signal shall be sent."
>>>
>>>
>>> This implies that multiple processes _within_ a process group need to
>>> coordinate both read and write operations to avoid conflicting with
>>> each other
>>
>>And, if they don't co-ordinate read and write operations, then....
>>the unpredictable happens.
>>
>>Just like Meredith is seeing with the various iterations of her program,
>>where both less(1) and the shell compete for input (and output) from
>>the controlling terminal.
>
> It gets even worse if both processes are sharing a file descriptor
> but are using different FILE objects to access that file descriptor
> due to the stdio buffering (avoided by disabling buffering with setvbuf(3)).

Thank you so much for this thread. It's very clear now the sort of
stuff in the system that I must study.

My exercise, therefore, needs another fork if I intend for the parent
process to exec cat because cat won't wait for the child and so the
child might lose its parent and, therefore, losing rights to talk to the
terminal. Forking again before running cat allows the parent to wait
for both cat and less, keeping both programs with the right to talk to
the terminal. So it seems I may conclude that for a situation such as

cat --> less

we really need three processes, one for cat, one for less and one parent
for waiting for both to avoid any of them from losing the right to talk
to the terminal (assuming any of them might try to). In general, a
pipeline of n processes requires at least n+1 processes. That's what I
conclude right now. I suppose there could be exceptions there and I
might be in general wrong, but I don't see any possible exceptions right
now.


devel / comp.unix.programmer / Re: a problem on pipes: making the child run less and parent writes to it

Pages:12
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor