67 if (fp == NULL)
goto error;
69 if (capacity == 0) capacity = 32768;
71 if (strchr(mode,
'r') && capacity > 32768) capacity = 32768;
73 fp->
buffer = (
char *) malloc(capacity);
74 if (fp->
buffer == NULL)
goto error;
97 static inline int writebuffer_is_nonempty(
hFILE *fp)
105 static ssize_t refill_buffer(
hFILE *fp)
121 if (n < 0) { fp->
has_errno = errno;
return n; }
122 else if (n == 0) fp->
at_eof = 1;
132 return (refill_buffer(fp) > 0)? (
unsigned char) *(fp->
begin++) : EOF;
139 ssize_t ret = refill_buffer(fp);
140 if (ret < 0)
return ret;
141 else if (ret == 0)
break;
145 if (n > nbytes) n = nbytes;
146 memcpy(buffer, fp->
begin, n);
152 ssize_t
hread2(
hFILE *fp,
void *destv,
size_t nbytes,
size_t nread)
155 char *dest = (
char *) destv;
156 dest += nread, nbytes -= nread;
159 while (nbytes * 2 >= capacity && !fp->
at_eof) {
161 if (n < 0) { fp->
has_errno = errno;
return n; }
162 else if (n == 0) fp->
at_eof = 1;
164 dest += n, nbytes -= n;
168 while (nbytes > 0 && !fp->
at_eof) {
170 ssize_t ret = refill_buffer(fp);
171 if (ret < 0)
return ret;
174 if (n > nbytes) n = nbytes;
175 memcpy(dest, fp->
begin, n);
177 dest += n, nbytes -= n;
186 static ssize_t flush_buffer(
hFILE *fp)
188 const char *buffer = fp->
buffer;
189 while (buffer < fp->
begin) {
191 if (n < 0) { fp->
has_errno = errno;
return n; }
202 if (flush_buffer(fp) < 0)
return EOF;
210 if (flush_buffer(fp) < 0)
return EOF;
217 ssize_t
hwrite2(
hFILE *fp,
const void *srcv,
size_t totalbytes,
size_t ncopied)
219 const char *src = (
const char *) srcv;
222 size_t remaining = totalbytes - ncopied;
225 ret = flush_buffer(fp);
226 if (ret < 0)
return ret;
229 while (remaining * 2 >= capacity) {
231 if (n < 0) { fp->
has_errno = errno;
return n; }
233 src += n, remaining -= n;
237 memcpy(fp->
begin, src, remaining);
238 fp->
begin += remaining;
246 return (
hwrite2(fp, text, totalbytes, ncopied) >= 0)? 0 : EOF;
253 if (writebuffer_is_nonempty(fp)) {
254 int ret = flush_buffer(fp);
255 if (ret < 0)
return ret;
259 if (pos < 0) { fp->
has_errno = errno;
return pos; }
273 if (writebuffer_is_nonempty(fp) &&
hflush(fp) < 0) err = fp->
has_errno;
297 #include <sys/socket.h>
298 #include <sys/stat.h>
303 #define HAVE_CLOSESOCKET
316 static ssize_t fd_read(
hFILE *fpv,
void *buffer,
size_t nbytes)
322 :
read(fp->
fd, buffer, nbytes);
323 }
while (n < 0 && errno == EINTR);
327 static ssize_t fd_write(
hFILE *fpv,
const void *buffer,
size_t nbytes)
333 :
write(fp->fd, buffer, nbytes);
334 }
while (n < 0 && errno == EINTR);
338 static off_t fd_seek(
hFILE *fpv, off_t offset,
int whence)
341 return lseek(fp->
fd, offset, whence);
344 static int fd_flush(
hFILE *fpv)
349 #ifdef HAVE_FDATASYNC
350 ret = fdatasync(fp->
fd);
356 if (ret < 0 && (errno == EINVAL || errno == ENOTSUP)) ret = 0;
357 }
while (ret < 0 && errno == EINTR);
361 static int fd_close(
hFILE *fpv)
366 #ifdef HAVE_CLOSESOCKET
367 ret = fp->
is_socket? closesocket(fp->
fd) : close(fp->fd);
371 }
while (ret < 0 && errno == EINTR);
377 fd_read, fd_write, fd_seek, fd_flush, fd_close
380 static size_t blksize(
int fd)
383 if (fstat(fd, &sbuf) != 0)
return 0;
384 return sbuf.st_blksize;
387 static hFILE *hopen_fd(
const char *filename,
const char *mode)
391 if (fd < 0)
goto error;
394 if (fp == NULL)
goto error;
402 if (fd >= 0) {
int save = errno; (void) close(fd); errno = save; }
410 if (fp == NULL)
return NULL;
413 fp->
is_socket = (strchr(mode,
's') != NULL);
418 static hFILE *hopen_fd_stdinout(
const char *mode)
420 int fd = (strchr(mode,
'r') != NULL)? STDIN_FILENO : STDOUT_FILENO;
427 int rdwr = 0, flags = 0;
429 for (s = mode; *s; s++)
431 case 'r': rdwr = O_RDONLY;
break;
432 case 'w': rdwr = O_WRONLY; flags |= O_CREAT | O_TRUNC;
break;
433 case 'a': rdwr = O_WRONLY; flags |= O_CREAT | O_APPEND;
break;
434 case '+': rdwr = O_RDWR;
break;
456 static ssize_t mem_read(
hFILE *fpv,
void *buffer,
size_t nbytes)
460 if (nbytes > avail) nbytes = avail;
461 memcpy(buffer, fp->
buffer + fp->
pos, nbytes);
466 static off_t mem_seek(
hFILE *fpv, off_t offset,
int whence)
469 size_t absoffset = (offset >= 0)? offset : -offset;
476 default: errno = EINVAL;
return -1;
479 if ((offset < 0 && absoffset > origin) ||
480 (offset >= 0 && absoffset > fp->
length - origin)) {
485 fp->
pos = origin + offset;
489 static int mem_close(
hFILE *fpv)
496 mem_read, NULL, mem_seek, NULL, mem_close
499 static hFILE *hopen_mem(
const char *data,
const char *mode)
502 if (strchr(mode,
'r') == NULL) { errno = EINVAL;
return NULL; }
505 if (fp == NULL)
return NULL;
508 fp->
length = strlen(data);
521 if (strncmp(fname,
"http://", 7) == 0 ||
522 strncmp(fname,
"ftp://", 6) == 0)
return hopen_net(fname, mode);
523 else if (strncmp(fname,
"data:", 5) == 0)
return hopen_mem(fname + 5, mode);
524 else if (strcmp(fname,
"-") == 0)
return hopen_fd_stdinout(mode);
525 else return hopen_fd(fname, mode);