#include <sm/time.h>
#if !SM_CONF_MEMCHR
# include <memory.h>
#endif
#include <sm/heap.h>
int sm_flush __P((SM_FILE_T *, int *));
SM_FILE_T *smfp __P((void));
int sm_refill __P((SM_FILE_T *, int));
void sm_init __P((void));
void sm_cleanup __P((void));
void sm_makebuf __P((SM_FILE_T *));
int sm_whatbuf __P((SM_FILE_T *, size_t *, int *));
int sm_fwalk __P((int (*)(SM_FILE_T *, int *), int *));
int sm_wsetup __P((SM_FILE_T *));
int sm_flags __P((int));
SM_FILE_T *sm_fp __P((const SM_FILE_T *, const int, SM_FILE_T *));
int sm_vprintf __P((int, char const *, va_list));
ssize_t sm_stdread __P((SM_FILE_T *, char *, size_t));
ssize_t sm_stdwrite __P((SM_FILE_T *, char const *, size_t));
off_t sm_stdseek __P((SM_FILE_T *, off_t, int));
int sm_stdclose __P((SM_FILE_T *));
int sm_stdopen __P((SM_FILE_T *, const void *, int, const void *));
int sm_stdfdopen __P((SM_FILE_T *, const void *, int, const void *));
int sm_stdsetinfo __P((SM_FILE_T *, int , void *));
int sm_stdgetinfo __P((SM_FILE_T *, int , void *));
ssize_t sm_stdioread __P((SM_FILE_T *, char *, size_t));
ssize_t sm_stdiowrite __P((SM_FILE_T *, char const *, size_t));
off_t sm_stdioseek __P((SM_FILE_T *, off_t, int));
int sm_stdioclose __P((SM_FILE_T *));
int sm_stdioopen __P((SM_FILE_T *, const void *, int, const void *));
int sm_stdiosetinfo __P((SM_FILE_T *, int , void *));
int sm_stdiogetinfo __P((SM_FILE_T *, int , void *));
ssize_t sm_strread __P((SM_FILE_T *, char *, size_t));
ssize_t sm_strwrite __P((SM_FILE_T *, char const *, size_t));
off_t sm_strseek __P((SM_FILE_T *, off_t, int));
int sm_strclose __P((SM_FILE_T *));
int sm_stropen __P((SM_FILE_T *, const void *, int, const void *));
int sm_strsetinfo __P((SM_FILE_T *, int , void *));
int sm_strgetinfo __P((SM_FILE_T *, int , void *));
ssize_t sm_syslogread __P((SM_FILE_T *, char *, size_t));
ssize_t sm_syslogwrite __P((SM_FILE_T *, char const *, size_t));
off_t sm_syslogseek __P((SM_FILE_T *, off_t, int));
int sm_syslogclose __P((SM_FILE_T *));
int sm_syslogopen __P((SM_FILE_T *, const void *, int, const void *));
int sm_syslogsetinfo __P((SM_FILE_T *, int , void *));
int sm_sysloggetinfo __P((SM_FILE_T *, int , void *));
extern bool Sm_IO_DidInit;
#define cantwrite(fp) \
((((fp)->f_flags & SMWR) == 0 || (fp)->f_bf.smb_base == NULL) && \
sm_wsetup(fp))
#define HASUB(fp) ((fp)->f_ub.smb_base != NULL)
#define FREEUB(fp) \
{ \
if ((fp)->f_ub.smb_base != (fp)->f_ubuf) \
sm_free((char *)(fp)->f_ub.smb_base); \
(fp)->f_ub.smb_base = NULL; \
}
extern const char SmFileMagic[];
#define SM_ALIGN(p) (((unsigned long)(p) + SM_ALIGN_BITS) & ~SM_ALIGN_BITS)
#define sm_io_flockfile(fp) ((void) 0)
#define sm_io_funlockfile(fp) ((void) 0)
int sm_flags __P((int));
#ifndef FDSET_CAST
# define FDSET_CAST
#endif
# define SM_CONVERT_TIME(fp, fd, val, time) { \
if (((fd) = sm_io_getinfo(fp, SM_IO_WHAT_FD, NULL)) == -1) \
{ \
\
errno = 0; \
} \
if ((val) == SM_TIME_DEFAULT) \
(val) = (fp)->f_timeout; \
if ((val) == SM_TIME_IMMEDIATE || (val) == SM_TIME_FOREVER) \
{ \
(time)->tv_sec = 0; \
(time)->tv_usec = 0; \
} \
else \
{ \
(time)->tv_sec = (val) / 1000; \
(time)->tv_usec = ((val) - ((time)->tv_sec * 1000)) * 1000; \
} \
if ((val) == SM_TIME_FOREVER) \
{ \
if ((fp)->f_timeoutstate == SM_TIME_NONBLOCK && (fd) != -1) \
{ \
int ret; \
ret = fcntl((fd), F_GETFL, 0); \
if (ret == -1 || fcntl((fd), F_SETFL, \
ret & ~O_NONBLOCK) == -1) \
{ \
\
return SM_IO_EOF; \
} \
(fp)->f_timeoutstate = SM_TIME_BLOCK; \
if ((fp)->f_modefp != NULL) \
(fp)->f_modefp->f_timeoutstate = SM_TIME_BLOCK; \
} \
} \
else { \
if ((fp)->f_timeoutstate == SM_TIME_BLOCK && (fd) != -1) \
{ \
int ret; \
ret = fcntl((fd), F_GETFL, 0); \
if (ret == -1 || fcntl((fd), F_SETFL, \
ret | O_NONBLOCK) == -1) \
{ \
\
return SM_IO_EOF; \
} \
(fp)->f_timeoutstate = SM_TIME_NONBLOCK; \
if ((fp)->f_modefp != NULL) \
(fp)->f_modefp->f_timeoutstate = SM_TIME_NONBLOCK; \
} \
} \
}
#define SM_IO_WR_TIMEOUT(fp, fd, to) { \
struct timeval sm_io_to_before, sm_io_to_after, sm_io_to_diff; \
struct timeval sm_io_to; \
int sm_io_to_sel; \
fd_set sm_io_to_mask, sm_io_x_mask; \
errno = 0; \
if ((to) == SM_TIME_DEFAULT) \
(to) = (fp)->f_timeout; \
if ((to) == SM_TIME_IMMEDIATE) \
{ \
errno = EAGAIN; \
return SM_IO_EOF; \
} \
else if ((to) == SM_TIME_FOREVER) \
{ \
errno = EINVAL; \
return SM_IO_EOF; \
} \
else \
{ \
sm_io_to.tv_sec = (to) / 1000; \
sm_io_to.tv_usec = ((to) - (sm_io_to.tv_sec * 1000)) * 1000; \
} \
if (FD_SETSIZE > 0 && (fd) >= FD_SETSIZE) \
{ \
errno = EINVAL; \
return SM_IO_EOF; \
} \
FD_ZERO(&sm_io_to_mask); \
FD_SET((fd), &sm_io_to_mask); \
FD_ZERO(&sm_io_x_mask); \
FD_SET((fd), &sm_io_x_mask); \
if (gettimeofday(&sm_io_to_before, NULL) < 0) \
return SM_IO_EOF; \
do \
{ \
sm_io_to_sel = select((fd) + 1, NULL, &sm_io_to_mask, \
&sm_io_x_mask, &sm_io_to); \
} while (sm_io_to_sel < 0 && errno == EINTR); \
if (sm_io_to_sel < 0) \
{ \
\
return SM_IO_EOF; \
} \
else if (sm_io_to_sel == 0) \
{ \
\
errno = EAGAIN; \
return SM_IO_EOF; \
} \
\
if (gettimeofday(&sm_io_to_after, NULL) < 0) \
return SM_IO_EOF; \
timersub(&sm_io_to_after, &sm_io_to_before, &sm_io_to_diff); \
(to) -= (sm_io_to_diff.tv_sec * 1000); \
(to) -= (sm_io_to_diff.tv_usec / 1000); \
if ((to) < 0) \
(to) = 0; \
}
#define IS_IO_ERROR(fd, ret, to) \
((fd) < 0 || \
((ret) < 0 && errno != EAGAIN && errno != EWOULDBLOCK) || \
(to) == SM_TIME_FOREVER)