All of lore.kernel.org
 help / color / mirror / Atom feed
* Help on pipe
@ 2009-07-10  6:22 Ardhan Madras
  2009-07-10  7:06 ` Michał Nazarewicz
  2009-07-10  7:27 ` David Lee
  0 siblings, 2 replies; 8+ messages in thread
From: Ardhan Madras @ 2009-07-10  6:22 UTC (permalink / raw)
  To: linux-c-programming

Hi,

I'm writing pipe demo:

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

int main(void)
{
  pid_t pid;
  int fds[2], ret;
  const char *sort = "/usr/bin/sort";
  char *argv[2] = { "sort", NULL };

  ret = pipe(fds);
  if (ret == -1) {
    perror("pipe");
    return -1;
  }
  pid = fork();
  if (pid == -1) {
    perror("fork");
    return -1;
  }

  if (pid == 0) {
    int ret;

    close(fds[1]);
    dup2(fds[0], STDIN_FILENO);

    ret = execve(sort, argv, NULL);
    if (ret == -1) {
      perror("execve");
    }
    close(fds[0]);
    _exit(0);
  }
  else {
    FILE *stream;

    close(fds[0]);
    stream = fdopen(fds[1], "w");
    if (!stream) {
      perror("fdopen");
      return -1;
    }
    fprintf(stream, "this\n");
    fprintf(stream, "means\n");
    fprintf(stream, "war\n");
    fflush(stream);
    waitpid(pid, &ret, 0);
    close(fds[1]);
  }
  return 0;
}

I want to send parent's data to the child as "sort" input, i don't
know why sort doesn't receive the data. Did i made mistake here?

Thanks before.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Help on pipe
  2009-07-10  6:22 Help on pipe Ardhan Madras
@ 2009-07-10  7:06 ` Michał Nazarewicz
  2009-07-10  7:34   ` Ardhan Madras
  2009-07-10 17:40   ` Glynn Clements
  2009-07-10  7:27 ` David Lee
  1 sibling, 2 replies; 8+ messages in thread
From: Michał Nazarewicz @ 2009-07-10  7:06 UTC (permalink / raw)
  To: Ardhan Madras, linux-c-programming

On Fri, 10 Jul 2009 08:22:54 +0200, Ardhan Madras <nightdecoder@gmail.com>  
wrote:

> #include <sys/types.h>
> #include <sys/wait.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <string.h>
>
> int main(void)
> {
>   pid_t pid;
>   int fds[2], ret;
>   const char *sort = "/usr/bin/sort";

"static const char sort[]" would be better IMO.

>   char *argv[2] = { "sort", NULL };

"static const char *argv[]" is definitly better here and does not produce  
warnings.  Your code discards "const" from pointer (a string literal).

>   ret = pipe(fds);
>   if (ret == -1) {
>     perror("pipe");
>     return -1;
>   }
>   pid = fork();
>   if (pid == -1) {
>     perror("fork");
>     return -1;
>   }

Personally I preffer something like:

   switch (fork()) {
   case -1: /* error */  break;
   case  0: /* child */  break;
   default: /* parent */
   }

but suit yourself.

>   if (pid == 0) {
>     int ret;

No need to define this variable here.  You already have such variable.

>
>     close(fds[1]);
>     dup2(fds[0], STDIN_FILENO);
>
>     ret = execve(sort, argv, NULL);
>     if (ret == -1) {
>       perror("execve");
>     }
>     close(fds[0]);
>     _exit(0);

No need to close(), and _exit(0) should be _exit(1) (or -1 if you will)  
since the chiled finished with error.

>   }
>   else {
>     FILE *stream;
>
>     close(fds[0]);
>     stream = fdopen(fds[1], "w");
>     if (!stream) {
>       perror("fdopen");
>       return -1;
>     }
>     fprintf(stream, "this\n");
>     fprintf(stream, "means\n");
>     fprintf(stream, "war\n");
>     fflush(stream);

And here, replace fflush() with fclose().  It seems, data is buffered on  
kernel level, not only libc level and fflush() cannot handle that.

>     waitpid(pid, &ret, 0);
>     close(fds[1]);

No need to close.

>   }
>   return 0;
> }

-- 
Best regards,                                            _     _
  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
  ..o | Computer Science,  Michał "mina86" Nazarewicz      (o o)
  ooo +-<m.nazarewicz@samsung.com>-<mina86@jabber.org>-ooO--(_)--Ooo--

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Help on pipe
  2009-07-10  6:22 Help on pipe Ardhan Madras
  2009-07-10  7:06 ` Michał Nazarewicz
@ 2009-07-10  7:27 ` David Lee
  1 sibling, 0 replies; 8+ messages in thread
From: David Lee @ 2009-07-10  7:27 UTC (permalink / raw)
  To: Ardhan Madras; +Cc: linux-c-programming

On Fri, Jul 10, 2009 at 2:22 PM, Ardhan Madras<nightdecoder@gmail.com> wrote:
> Hi,
>
> I'm writing pipe demo:
>
> #include <sys/types.h>
> #include <sys/wait.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <string.h>
>
> int main(void)
> {
>  pid_t pid;
>  int fds[2], ret;
>  const char *sort = "/usr/bin/sort";
>  char *argv[2] = { "sort", NULL };
>
>  ret = pipe(fds);
>  if (ret == -1) {
>    perror("pipe");
>    return -1;
>  }
>  pid = fork();
>  if (pid == -1) {
>    perror("fork");
>    return -1;
>  }
>
>  if (pid == 0) {
>    int ret;
>
>    close(fds[1]);
>    dup2(fds[0], STDIN_FILENO);
>
>    ret = execve(sort, argv, NULL);
>    if (ret == -1) {
>      perror("execve");
>    }
>    close(fds[0]);
>    _exit(0);
>  }
>  else {
>    FILE *stream;
>
>    close(fds[0]);
>    stream = fdopen(fds[1], "w");
>    if (!stream) {
>      perror("fdopen");
>      return -1;
>    }
>    fprintf(stream, "this\n");
>    fprintf(stream, "means\n");
>    fprintf(stream, "war\n");
>    fflush(stream);
>    waitpid(pid, &ret, 0);
>    close(fds[1]);
>  }
>  return 0;
> }
>
> I want to send parent's data to the child as "sort" input, i don't
> know why sort doesn't receive the data. Did i made mistake here?
>
> Thanks before.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

The sort program is waiting for an EOF (^D).

--- sort.c.orig 2009-07-10 15:54:36.000000000 +0800
+++ sort.c      2009-07-10 15:53:35.000000000 +0800
@@ -49,6 +49,7 @@
                fprintf(stream, "means\n");
                fprintf(stream, "war\n");
                fflush(stream);
+              fclose(stream);
                waitpid(pid, &ret, 0);
                close(fds[1]);
        }


-- 
Thanks,
Li Qun
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Help on pipe
  2009-07-10  7:06 ` Michał Nazarewicz
@ 2009-07-10  7:34   ` Ardhan Madras
  2009-07-10 17:40   ` Glynn Clements
  1 sibling, 0 replies; 8+ messages in thread
From: Ardhan Madras @ 2009-07-10  7:34 UTC (permalink / raw)
  To: Michał Nazarewicz

My demo can run. i use -Wall flag, the "const char *argv[2] = {
"sort", NULL }" as you said warned with:

pipe.c:35: warning: passing argument 2 of 'execve' from incompatible
pointer type.

but it's perfect for  "char * const argv[2] = { "sort", NULL }"

and i define "int ret" for both process, but i undestand forking
mechanism on GNU/Linux.

sorry i don't write the code cleanly.. My point is only to make the
"sort" working, im now understand that "sort" will always wait for
input until it's end (peer closed the input).

Thank you very much.



2009/7/10 Micha³ Nazarewicz <m.nazarewicz@samsung.com>:
> On Fri, 10 Jul 2009 08:22:54 +0200, Ardhan Madras <nightdecoder@gmail.com>
> wrote:
>
>> #include <sys/types.h>
>> #include <sys/wait.h>
>> #include <unistd.h>
>> #include <stdio.h>
>> #include <string.h>
>>
>> int main(void)
>> {
>>  pid_t pid;
>>  int fds[2], ret;
>>  const char *sort = "/usr/bin/sort";
>
> "static const char sort[]" would be better IMO.
>
>>  char *argv[2] = { "sort", NULL };
>
> "static const char *argv[]" is definitly better here and does not produce
> warnings.  Your code discards "const" from pointer (a string literal).
>
>>  ret = pipe(fds);
>>  if (ret == -1) {
>>    perror("pipe");
>>    return -1;
>>  }
>>  pid = fork();
>>  if (pid == -1) {
>>    perror("fork");
>>    return -1;
>>  }
>
> Personally I preffer something like:
>
>  switch (fork()) {
>  case -1: /* error */  break;
>  case  0: /* child */  break;
>  default: /* parent */
>  }
>
> but suit yourself.
>
>>  if (pid == 0) {
>>    int ret;
>
> No need to define this variable here.  You already have such variable.
>
>>
>>    close(fds[1]);
>>    dup2(fds[0], STDIN_FILENO);
>>
>>    ret = execve(sort, argv, NULL);
>>    if (ret == -1) {
>>      perror("execve");
>>    }
>>    close(fds[0]);
>>    _exit(0);
>
> No need to close(), and _exit(0) should be _exit(1) (or -1 if you will)
> since the chiled finished with error.
>
>>  }
>>  else {
>>    FILE *stream;
>>
>>    close(fds[0]);
>>    stream = fdopen(fds[1], "w");
>>    if (!stream) {
>>      perror("fdopen");
>>      return -1;
>>    }
>>    fprintf(stream, "this\n");
>>    fprintf(stream, "means\n");
>>    fprintf(stream, "war\n");
>>    fflush(stream);
>
> And here, replace fflush() with fclose().  It seems, data is buffered on
> kernel level, not only libc level and fflush() cannot handle that.
>
>>    waitpid(pid, &ret, 0);
>>    close(fds[1]);
>
> No need to close.
>
>>  }
>>  return 0;
>> }
>
> --
> Best regards,                                            _     _
>  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
>  ..o | Computer Science,  Micha³ "mina86" Nazarewicz      (o o)
>  ooo +-<m.nazarewicz@samsung.com>-<mina86@jabber.org>-ooO--(_)--Ooo--
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Help on pipe
  2009-07-10  7:06 ` Michał Nazarewicz
  2009-07-10  7:34   ` Ardhan Madras
@ 2009-07-10 17:40   ` Glynn Clements
  2009-07-11  3:41     ` David Lee
  2009-07-13  6:45     ` Michał Nazarewicz
  1 sibling, 2 replies; 8+ messages in thread
From: Glynn Clements @ 2009-07-10 17:40 UTC (permalink / raw)
  To: Michał Nazarewicz; +Cc: Ardhan Madras, linux-c-programming


Micha³ Nazarewicz wrote:

> >     waitpid(pid, &ret, 0);
> >     close(fds[1]);
> 
> No need to close.

There definitely is a need to close, but it should be fclose(stream)
*before* the waitpid(). As David points out, sort won't terminate
until it has finished reading its input.

David Lee wrote:

> The sort program is waiting for an EOF (^D).

Ctrl-D isn't EOF unless you're reading from a terminal. The TTY driver
"sends EOF" (i.e. causes read() to return a zero count) when you press
Ctrl-D (by default) if the driver is in canonical mode. Ctrl-D doesn't
have any significance in other contexts.

-- 
Glynn Clements <glynn@gclements.plus.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Help on pipe
  2009-07-10 17:40   ` Glynn Clements
@ 2009-07-11  3:41     ` David Lee
  2009-07-13  6:45     ` Michał Nazarewicz
  1 sibling, 0 replies; 8+ messages in thread
From: David Lee @ 2009-07-11  3:41 UTC (permalink / raw)
  To: Glynn Clements; +Cc: Michał Nazarewicz, Ardhan Madras, linux-c-programming

2009/7/11 Glynn Clements <glynn@gclements.plus.com>:
>
> Micha³ Nazarewicz wrote:
>
>> >     waitpid(pid, &ret, 0);
>> >     close(fds[1]);
>>
>> No need to close.
>
> There definitely is a need to close, but it should be fclose(stream)
> *before* the waitpid(). As David points out, sort won't terminate
> until it has finished reading its input.
>
> David Lee wrote:
>
>> The sort program is waiting for an EOF (^D).
>
> Ctrl-D isn't EOF unless you're reading from a terminal. The TTY driver
> "sends EOF" (i.e. causes read() to return a zero count) when you press
> Ctrl-D (by default) if the driver is in canonical mode. Ctrl-D doesn't
> have any significance in other contexts.
>
Definitely!  Thanks for pointing out. :-)
And BTW, `strace' is a handy tool for diagnosing this kind of problems.

> --
> Glynn Clements <glynn@gclements.plus.com>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

-- 
Thanks,
Li Qun
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Help on pipe
  2009-07-10 17:40   ` Glynn Clements
  2009-07-11  3:41     ` David Lee
@ 2009-07-13  6:45     ` Michał Nazarewicz
  1 sibling, 0 replies; 8+ messages in thread
From: Michał Nazarewicz @ 2009-07-13  6:45 UTC (permalink / raw)
  To: Glynn Clements; +Cc: Ardhan Madras, linux-c-programming

>>>     waitpid(pid, &ret, 0);
>>>     close(fds[1]);

> Michał Nazarewicz wrote:
>> No need to close.

On Fri, 10 Jul 2009 19:40:38 +0200, Glynn Clements  
<glynn@gclements.plus.com> wrote:
> There definitely is a need to close, but it should be fclose(stream)
> *before* the waitpid(). As David points out, sort won't terminate
> until it has finished reading its input.

Yes, yes... David already pointed out the problem is with EOF not  
buffering.

-- 
Best regards,                                            _     _
  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
  ..o | Computer Science,  Michał "mina86" Nazarewicz      (o o)
  ooo +-<m.nazarewicz@samsung.com>-<mina86@jabber.org>-ooO--(_)--Ooo--

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Help on pipe
@ 2009-07-10 18:21 Ardhan Madras
  0 siblings, 0 replies; 8+ messages in thread
From: Ardhan Madras @ 2009-07-10 18:21 UTC (permalink / raw)
  To: linux-c-programming

My demo can run. i use -Wall flag, the "const char *argv[2] = {
"sort", NULL }" as you said warned with:

pipe.c:35: warning: passing argument 2 of 'execve' from incompatible
pointer type.

but it's perfect for  "char * const argv[2] = { "sort", NULL }"

and i define "int ret" for both process, but i undestand forking
mechanism on GNU/Linux.

sorry i don't write the code cleanly.. My point is only to make the
"sort" working, im now understand that "sort" will always wait for
input until it's end (peer closed the input).

Thank you very much.



2009/7/10 Michał Nazarewicz <m.nazarewicz@samsung.com>:
> On Fri, 10 Jul 2009 08:22:54 +0200, Ardhan Madras <nightdecoder@gmail.com>
> wrote:
>
>> #include <sys/types.h>
>> #include <sys/wait.h>
>> #include <unistd.h>
>> #include <stdio.h>
>> #include <string.h>
>>
>> int main(void)
>> {
>>  pid_t pid;
>>  int fds[2], ret;
>>  const char *sort = "/usr/bin/sort";
>
> "static const char sort[]" would be better IMO.
>
>>  char *argv[2] = { "sort", NULL };
>
> "static const char *argv[]" is definitly better here and does not produce
> warnings.  Your code discards "const" from pointer (a string literal).
>
>>  ret = pipe(fds);
>>  if (ret == -1) {
>>    perror("pipe");
>>    return -1;
>>  }
>>  pid = fork();
>>  if (pid == -1) {
>>    perror("fork");
>>    return -1;
>>  }
>
> Personally I preffer something like:
>
>  switch (fork()) {
>  case -1: /* error */  break;
>  case  0: /* child */  break;
>  default: /* parent */
>  }
>
> but suit yourself.
>
>>  if (pid == 0) {
>>    int ret;
>
> No need to define this variable here.  You already have such variable.
>
>>
>>    close(fds[1]);
>>    dup2(fds[0], STDIN_FILENO);
>>
>>    ret = execve(sort, argv, NULL);
>>    if (ret == -1) {
>>      perror("execve");
>>    }
>>    close(fds[0]);
>>    _exit(0);
>
> No need to close(), and _exit(0) should be _exit(1) (or -1 if you will)
> since the chiled finished with error.
>
>>  }
>>  else {
>>    FILE *stream;
>>
>>    close(fds[0]);
>>    stream = fdopen(fds[1], "w");
>>    if (!stream) {
>>      perror("fdopen");
>>      return -1;
>>    }
>>    fprintf(stream, "this\n");
>>    fprintf(stream, "means\n");
>>    fprintf(stream, "war\n");
>>    fflush(stream);
>
> And here, replace fflush() with fclose().  It seems, data is buffered on
> kernel level, not only libc level and fflush() cannot handle that.
>
>>    waitpid(pid, &ret, 0);
>>    close(fds[1]);
>
> No need to close.
>
>>  }
>>  return 0;
>> }
>
> --
> Best regards,                                            _     _
>  .o. | Liege of Serenly Enlightened Majesty of         o' \,=./ `o
>  ..o | Computer Science,  Michał "mina86" Nazarewicz      (o o)
>  ooo +-<m.nazarewicz@samsung.com>-<mina86@jabber.org>-ooO--(_)--Ooo--
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html




_____________________________________________________________
Listen to KNAC, Hit the Home page and Tune In Live! ---> http://www.knac.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-07-13  6:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-10  6:22 Help on pipe Ardhan Madras
2009-07-10  7:06 ` Michał Nazarewicz
2009-07-10  7:34   ` Ardhan Madras
2009-07-10 17:40   ` Glynn Clements
2009-07-11  3:41     ` David Lee
2009-07-13  6:45     ` Michał Nazarewicz
2009-07-10  7:27 ` David Lee
2009-07-10 18:21 Ardhan Madras

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.