Chet Ramey wrote:
Linda Walsh wrote:
When under linux (2.6.30.x), I type
ulimit -p and get a return value of "8".
from the man page this is in 512-byte blocks and may not be set.
It's set at build time. Look at builtins/ulimit.def:pipesize() and
builtins/psize.sh (which uses builtins/psize.c).
Chet
What is supposed to be controlling?
When I create a pipe with the pipe system call, and try writing
blocks of data from a master(parent) to a child, I get very large values for
bytes sent in one write or read in one read from the pipe.
More like it's a limitation on some physical memory constraint.
When I think of a pipe size for reads/writes, I am thinking creating
a pipe with the system call 'pipe', and optionally using the dup2 operation
to connect one processes writes to stdout to another processes stdin -- but
they still both are talking to a plain unix pipe, no?
The first limit I hit is on a read or write of a 2GB block
(the write returns about 4K short of writing 2GB, and the child receives
the same block of len 2GB-4K).
That's alot more than 8 512-Byte blocks.
Test program is attached (to compile you'd need
to pass "-lrt" to gcc as it uses the real-time clock to time the writes).
#define __USE_LARGEFILE64 1
#include
#include
#include
#include
#include
#define PAR_WAIT_TO_HUP 3
int pipefd[2];
int controlfd[2];
int pid;
void getout(int stat, char * msg) {
char errmsg[128];
char *id;
id=(pid>0)?"parent":" child";
snprintf(errmsg, sizeof(errmsg), "%s: %s", id, msg);
perror(errmsg);
if (pid>0) {
close(pipefd[1]);
close(controlfd[0]);
sleep(PAR_WAIT_TO_HUP);
kill(pid, 1); /* SIGHUP */
} else {
close(pipefd[0]);
close(controlfd[1]);
}
exit(stat);
}
void sighandler() {
char errmsg[128];
char *id;
id=(pid>0)?"parent":" child";
snprintf(errmsg, sizeof(errmsg), "%s: %s", id,
"SIGPIPE: We are talking, but nobody's listening!\n");
getout(8, "pipe write");
}
typedef struct timespec * timeval;
timeval get_elapsed(timeval elapsed, timeval start, timeval end) {
int borrow=0;
double result;
if (start->tv_nsec >end->tv_nsec) {
end->tv_nsec += 1000*1000*1000;
borrow=1;
}
elapsed->tv_nsec = end->tv_nsec - start->tv_nsec;
if (borrow) --end->tv_sec;
elapsed->tv_sec = end->tv_sec - start->tv_sec;
return elapsed;
}
char * ht (char *buff, int bufflen, timeval tv) {
bzero(buff, bufflen);
/* if time sex and nsecs both equal 0 return zero */
if (tv->tv_sec==0 && tv->tv_nsec==0) {
snprintf(buff, bufflen, "0.0 seconds");
return buff;
}
/* if < 1 sec, display fraction in nano, micro or milli- seconds */
if (tv->tv_sec==0 && tv->tv_nsec!=0) {
char * unit;
int nanos=tv->tv_nsec;
if (nanos<1000) {
unit="ns";
} else if (nanos < 100 && nanos>=1000) {
nanos/=1000;
unit="µs";
} else {
nanos/=100;
unit="ms";
}
snprintf(buff, bufflen, "%d%s", nanos, unit);
} else if (tv->tv_sec > 0) {
double t = ((double) tv->tv_sec) + ((double)
tv->tv_nsec)/(double)10.0;
snprintf(buff, bufflen, "%-5.3lf seconds", t);
}
return buff;
}
typedef const char * String;
static const String suffixes [] = {"B", "KB", "MB", "GB", "TB"};
static const int num_suffixes = sizeof(suffixes)/sizeof(String);
char * h (char *buff, int bufflen, unsigned long nb) {
int si=0;
int index_of_last_suffix = num_suffixes-1;
bzero(buff, bufflen);
for (si=0; si1023 && (nb % 1024)==0; ++si) {
nb >>= 10;
}
snprintf(buff, bufflen, "%d%s", nb, suffixes[si]);
return buff;
}
child_pipe_reader() {
unsigned long buffsize; /* units of 1K */
unsigned long bytes_read;
char * cbuff;
/* child reader */
close(pipefd[1]);
close(controlfd[0]);
while (1) {
char lbuff[20];
char fbuff[20];
struct timespec start, end, elapsed;
double secs;
bytes_read=read(pipefd[0], &buffsize, sizeof(buffsize));
if (bytes_read <0 ) {
getout(14, "reading size of buffer from parent");
}
if (bytes_read != sizeof(buffsize)) {
getout(15, "wrong number of bytes read for
sizeof(buffsize)");