free(f->rsrv);
f->rsrv = NULL;
- /* delete any associated sfpopen-data */
- if (f->proc)
- rv = _sfpclose(f);
-
if (!local) {
if (f->disc && (ex = SFRAISE(f, SF_FINAL, NULL)) != 0) {
rv = ex;
SFMTXSTART(f, NULL);
- if ((f->flags & SF_READ) && f->proc && (f->mode & SF_WRITE)) { /* make sure in read mode to check for read-ahead data */
- if (_sfmode(f, SF_READ, 0) < 0)
- SFMTXRETURN(f, NULL);
- } else if ((f->mode & SF_RDWR) != f->mode && _sfmode(f, 0, 0) < 0)
+ if ((f->mode & SF_RDWR) != f->mode && _sfmode(f, 0, 0) < 0)
SFMTXRETURN(f, NULL);
SFLOCK(f, 0);
uchar data[1]; /* data buffer */
};
-/* co-process structure */
- typedef struct _sfproc_s Sfproc_t;
- struct _sfproc_s {
- int pid; /* process id */
- uchar *rdata; /* read data being cached */
- int ndata; /* size of cached data */
- int size; /* buffer size */
- int file; /* saved file descriptor */
- int sigp; /* sigpipe protection needed */
- };
-
/* extensions to sfvprintf/sfvscanf */
#define FP_SET(fp,fn) (fp < 0 ? (fn += 1) : (fn = fp) )
#define FP_WIDTH 0
extern Sfextern_t _Sfextern;
extern Sftab_t _Sftable;
- extern int _sfpopen(Sfio_t *, int, int);
- extern int _sfpclose(Sfio_t *);
extern int _sfmode(Sfio_t *, int, int);
extern int _sfexcept(Sfio_t *, int, ssize_t, Sfdisc_t *);
extern Sfrsrv_t *_sfrsrv(Sfio_t *, ssize_t);
struct _sfdisc_s* disc; /* discipline */ \
struct _sfpool_s* pool; /* the pool containing this */ \
struct _sfrsrv_s* rsrv; /* reserved buffer */ \
- struct _sfproc_s* proc; /* coprocess id, etc. */ \
Sfoff_t lpos; /* last seek position */ \
size_t iosz; /* prefer size for I/O */
(struct _sfdisc_s*)(disc), /* disc */ \
(struct _sfpool_s*)0, /* pool */ \
(struct _sfrsrv_s*)0, /* rsrv */ \
- (struct _sfproc_s*)0, /* proc */ \
(Sfoff_t)0, /* lpos */ \
(size_t)0 /* iosz */ \
}
(f)->disc = (struct _sfdisc_s*)0, /* disc */ \
(f)->pool = (struct _sfpool_s*)0, /* pool */ \
(f)->rsrv = (struct _sfrsrv_s*)0, /* rsrv */ \
- (f)->proc = (struct _sfproc_s*)0, /* proc */ \
(f)->lpos = (Sfoff_t)0, /* lpos */ \
(f)->iosz = (size_t)0 /* iosz */ \
)
#include <sfio/sfhdr.h>
#include <stddef.h>
#include <stdint.h>
-#ifndef _WIN32
-#include <sys/wait.h>
-#endif
/* Functions to set a given stream to some desired mode
**
** 02/01/2001 (adaptive buffering)
*/
-/* the below is for protecting the application from SIGPIPE */
-#include <signal.h>
-typedef void (*Sfsignal_f) (int);
-#ifdef SIGPIPE
-static int _Sfsigp = 0; /* # of streams needing SIGPIPE protection */
-#endif
-
/* done at exiting time */
static void _sfcleanup(void)
{
return size >= 0 ? rsrv : NULL;
}
-/**
- * @param f
- * @param fd
- * @param pid
- */
-int _sfpopen(Sfio_t *f, int fd, int pid) {
- Sfproc_t *p;
-
- if (f->proc)
- return 0;
-
- if (!(p = f->proc = malloc(sizeof(Sfproc_t))))
- return -1;
-
- p->pid = pid;
- p->size = p->ndata = 0;
- p->rdata = NULL;
- p->file = fd;
- p->sigp = (pid >= 0 && (f->flags & SF_WRITE)) ? 1 : 0;
-
-#ifdef SIGPIPE /* protect from broken pipe signal */
- if (p->sigp) {
- Sfsignal_f handler;
-
- if ((handler = signal(SIGPIPE, SIG_IGN)) != SIG_DFL && handler != SIG_IGN)
- signal(SIGPIPE, handler); /* honor user handler */
- _Sfsigp += 1;
- }
-#endif
-
- return 0;
-}
-
-/**
- * @param f stream to close
- */
-int _sfpclose(Sfio_t * f)
-{
- Sfproc_t *p;
- int pid = 0, status;
-
- if (!(p = f->proc))
- return -1;
- f->proc = NULL;
-
- free(p->rdata);
-
- if (p->pid < 0)
- status = 0;
- else { /* close the associated stream */
- if (p->file >= 0)
- CLOSE(p->file);
-
- /* wait for process termination */
-#ifndef _WIN32
- while ((pid = waitpid(p->pid, &status, 0)) == -1
- && errno == EINTR);
-#endif
- if (pid < 0)
- status = -1;
-
-#ifdef SIGPIPE
- if (p->sigp && (_Sfsigp -= 1) <= 0) {
- Sfsignal_f handler;
- if ((handler = signal(SIGPIPE, SIG_DFL)) != SIG_DFL && handler != SIG_IGN)
- signal(SIGPIPE, handler); /* honor user handler */
- _Sfsigp = 0;
- }
-#endif
- }
-
- free(p);
- return status;
-}
-
-static int _sfpmode(Sfio_t * f, int type)
-{
- Sfproc_t *p;
-
- if (!(p = f->proc))
- return -1;
-
- if (type == SF_WRITE) { /* save unread data */
- p->ndata = f->endb - f->next;
- if (p->ndata > p->size) {
- free(p->rdata);
- if ((p->rdata = malloc(p->ndata)))
- p->size = p->ndata;
- else {
- p->size = 0;
- return -1;
- }
- }
- if (p->ndata > 0)
- memcpy(p->rdata, f->next, p->ndata);
- f->endb = f->data;
- } else { /* restore read data */
- if (p->ndata > f->size) /* may lose data!!! */
- p->ndata = f->size;
- if (p->ndata > 0) {
- memcpy(f->data, p->rdata, p->ndata);
- f->endb = f->data + p->ndata;
- p->ndata = 0;
- }
- }
-
- /* switch file descriptor */
- if (p->pid >= 0) {
- type = f->file;
- f->file = p->file;
- p->file = type;
- }
-
- return 0;
-}
-
/**
* @param f change r/w mode and sync file pointer for this stream
* @param wanted desired mode
f->next = f->endr = f->endw = f->endb = f->data;
f->mode = SF_READ | SF_LOCK;
- /* restore saved read data for coprocess */
- if (f->proc && _sfpmode(f, wanted) < 0)
- goto err_notify;
-
break;
case (SF_READ | SF_SYNCED): /* a previously sync-ed read stream */
break;
}
- /* save unread data before switching mode */
- if (f->proc && _sfpmode(f, wanted) < 0)
- goto err_notify;
-
/* reset buffer and seek pointer */
if (!(f->mode & SF_SYNCED)) {
intptr_t n = (intptr_t)(f->endb - f->next);
else {
int rv;
- /* make sure there is no hidden read data */
- if (f->proc && (f->flags & SF_READ) && (f->mode & SF_WRITE) &&
- _sfmode(f, SF_READ, local) < 0)
- SFMTXRETURN(f, NULL);
-
/* synchronize first */
SFLOCK(f, local);
rv = SFSYNC(f);
#endif
errno = oerrno;
}
-
- /* initialize side buffer for r+w unseekable streams */
- if (!f->proc && (f->bits & SF_BOTH))
- (void) _sfpopen(f, -1, -1);
}
}
f->endb = f->data + n;
f->here += n;
}
-
- if ((f->mode & SF_READ) && f->proc)
- f->next += n;
}
s = begs = (uchar *) buf;