Hi, I am wondering how do I state in a C program that my input is comming from a pipe ? For example: ls | ./myprog ? Thanks, Raul
On Sun, 27 Apr 2003, Anders Johansson wrote:
On Sunday 27 April 2003 18:33, Raúl Gutiérrez Segalés wrote:
Hi,
I am wondering how do I state in a C program that my input is comming from a pipe ?
For example:
ls | ./myprog
You get that on standard input, file descriptor 0
so read(stdin, buf, 100) shall do it ?
On Sunday 27 April 2003 19:43, Raúl Gutiérrez Segalés wrote:
On Sun, 27 Apr 2003, Anders Johansson wrote:
On Sunday 27 April 2003 18:33, Raúl Gutiérrez Segalés wrote:
Hi,
I am wondering how do I state in a C program that my input is comming from a pipe ?
For example:
ls | ./myprog
You get that on standard input, file descriptor 0
so read(stdin, buf, 100) shall do it ?
andjoh@winona:~/src> cat test.c #include <stdio.h> #include <unistd.h> int main(int argc, char argv[]){ char buf[100]; ssize_t size; size=read(0, buf, 100); if(size > 0){ buf[size]='\0'; printf("Received string: %s\n", buf); } exit(0); } andjoh@winona:~/src> gcc -o testC test.c andjoh@winona:~/src> echo foo|./testC Received string: foo andjoh@winona:~/src> Seems to work. Note that stdin is FILE *, not a file descriptor. #include <stdio.h> int main(int argc, char argv[]){ char buf[100]; size_t size; size=fread(buf, 1, 100, stdin); if(size > 0){ buf[size]='\0'; printf("Received string: %s\n", buf); } exit(0); } or using getc, or one of the other reading functions. man stdio man unlocked_stdio
On Sunday 27 April 2003 20:10, Anders Johansson wrote:
#include <stdio.h> #include <unistd.h>
int main(int argc, char argv[]){ char buf[100]; ssize_t size;
size=read(0, buf, 100); if(size > 0){ buf[size]='\0';
printf("Received string: %s\n", buf); } exit(0); } <snip> #include <stdio.h>
int main(int argc, char argv[]){ char buf[100]; size_t size;
size=fread(buf, 1, 100, stdin); if(size > 0){ buf[size]='\0';
printf("Received string: %s\n", buf); } exit(0); }
and yes, I'm aware of the bug in those programs :)
On Sun, 27 Apr 2003, Anders Johansson wrote:
On Sunday 27 April 2003 20:10, Anders Johansson wrote:
#include <stdio.h> #include <unistd.h>
int main(int argc, char argv[]){ char buf[100]; ssize_t size;
size=read(0, buf, 100); if(size > 0){ buf[size]='\0';
printf("Received string: %s\n", buf); } exit(0); } <snip> #include <stdio.h>
int main(int argc, char argv[]){ char buf[100]; size_t size;
size=fread(buf, 1, 100, stdin); if(size > 0){ buf[size]='\0';
printf("Received string: %s\n", buf); } exit(0); }
and yes, I'm aware of the bug in those programs :)
Enlight me, I only see one, no protection against buffer overflows..
On Monday 28 April 2003 03:48, Raúl Gutiérrez Segalés wrote: <snip>
char buf[100];
<snip>
buf[size]='\0';
Enlight me, I only see one, no protection against buffer overflows..
That would be the one. There is a protection against buffer overflows, in that both read and fread state how many bytes they want. Sadly, I wrote it a bit too quickly, and potentially 101 bytes could be put in a 100 byte buffer. Oh well, whaddyawant for a nickel, a rubber biscuit?
On Monday 28 April 2003 06:24, Anders Johansson wrote:
On Monday 28 April 2003 03:48, Raúl Gutiérrez Segalés wrote: <snip>
char buf[100];
<snip>
buf[size]='\0';
Enlight me, I only see one, no protection against buffer overflows..
That would be the one. There is a protection against buffer overflows, in that both read and fread state how many bytes they want. Sadly, I wrote it a bit too quickly, and potentially 101 bytes could be put in a 100 byte buffer.
And bug no. 2 is that neither fread nor read check for EOL, only EOF, so if you had a program that sent this program three bytes followed by EOL (say, hitting enter on the keyboard) it wouldn't do anything, just block.
While checking the mailq on the BLU server yesterday I noticed over 300 messages queued up for a single user (from a listserv). postfix has a program, postsuper that can be used to delete email from the queue, but first the mail queue needs to be parsed. Simple solution in C: Use the popen(3) function: Here is a short code fragment: #include <stdio.h> #include <string.h> #include <errno.h> int main() { FILE *ipipe; char buf[256]; if ((ipipe = popen("mailq", "r")) == NULL) { fprintf(stderr, "Popen error:%s\n", strerror(errno)); exit(-1); while (fgets(buf, sizeof(buf), ipipe)) { /**** process the buffer **** The first line contains the queue id, subsequent **** lines contain email addresses and error messages **** each queue id is terminated by an empty line. ****/ } pclose(ipipe); return 0; } In my case, I put all the queue entries into a linked list and matched them to some keywords entered by the user then built another command for postsuper. You can do a similar thing with postsuper by calling it once with input from standard input: /* Code frag */ FILE *opipe; if ((opipe = popen("postsuper -d -", "w")) == NULL) { fprintf(stderr, "Popen error:%s\n", strerror(errno)); exit(-1); /* foreach queue id to be deleted */ printf("%s", ll->qid); /* End foreach */ pclose(opipe); -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Monday 28 April 2003 16:51, Jerry Feldman wrote:
In my case, I put all the queue entries into a linked list and matched them to some keywords entered by the user then built another command for postsuper. You can do a similar thing with postsuper by calling it once with input from standard input: /* Code frag */ FILE *opipe; if ((opipe = popen("postsuper -d -", "w")) == NULL) { fprintf(stderr, "Popen error:%s\n", strerror(errno)); exit(-1); /* foreach queue id to be deleted */ printf("%s", ll->qid);
typo? fprintf(opipe, "%s", ll-qid);
On Mon, 28 Apr 2003 17:17:55 +0200 Anders Johansson <andjoh@rydsbo.net> wrote:
On Monday 28 April 2003 16:51, Jerry Feldman wrote:
In my case, I put all the queue entries into a linked list and matched them to some keywords entered by the user then built another command for postsuper. You can do a similar thing with postsuper by calling it once with input from standard input: /* Code frag */ FILE *opipe; if ((opipe = popen("postsuper -d -", "w")) == NULL) { fprintf(stderr, "Popen error:%s\n", strerror(errno)); exit(-1); /* foreach queue id to be deleted */ printf("%s", ll->qid);
typo?
fprintf(opipe, "%s", ll-qid); Yes, I stand corrected. In any case it works fine. IMHO, I think that the most useful thing that Ken Thompson put into Unix was pipes.
-- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
participants (3)
-
Anders Johansson
-
Jerry Feldman
-
Raúl Gutiérrez Segalés