local.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: local.h,v 1.51.2.2 2004/01/09 18:32:44 ca Exp $
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
** Information local to this implementation of stdio,
** in particular, macros and private variables.
*/
#if !SM_CONF_MEMCHR
# include <memory.h>
#endif /* !SM_CONF_MEMCHR */
void sm_cleanup __P((void));
/* std io functions */
/* stdio io functions */
/* string io functions */
/* syslog io functions */
#ifndef timersub
do \
{ \
{ \
} \
} while (0)
#endif /* !timersub */
#ifndef timeradd
do \
{ \
{ \
} \
} while (0)
#endif /* !timeradd */
#ifndef timercmp
#endif /* !timercmp */
extern bool Sm_IO_DidInit;
/* Return true iff the given SM_FILE_T cannot be written now. */
/*
** Test whether the given stdio file has an active ungetc buffer;
** release such a buffer, without restoring ordinary unread data.
*/
{ \
}
extern const char SmFileMagic[];
#define sm_io_flockfile(fp) ((void) 0)
#define sm_io_funlockfile(fp) ((void) 0)
#ifndef FDSET_CAST
# define FDSET_CAST /* empty cast for fd_set arg to select */
#endif
/*
** SM_CONVERT_TIME -- convert the API timeout flag for select() usage.
**
** This takes a 'fp' (a file type pointer) and obtains the "raw"
** file descriptor (fd) if possible. The 'fd' is needed to possibly
** switch the mode of the file (blocking/non-blocking) to match
** the type of timeout. If timeout is SM_TIME_FOREVER then the
** timeout using select won't be needed and the file is best placed
** in blocking mode. If there is to be a finite timeout then the file
** is best placed in non-blocking mode. Then, if not enough can be
** written, select() can be used to test when something can be written
** yet still timeout if the wait is too long.
** If the mode is already in the correct state we don't change it.
** Iff (yes "iff") the 'fd' is "-1" in value then the mode change
** will not happen. This situation arises when a late-binding-to-disk
** file type is in use. An example of this is the sendmail buffered
**
** Parameters
** fp -- the file pointer the timeout is for
** fd -- to become the file descriptor value from 'fp'
** val -- the timeout value to be converted
** time -- a struct timeval holding the converted value
**
** Returns
** nothing, this is flow-through code
**
** Side Effects:
** May or may not change the mode of a currently open file.
** The file mode may be changed to O_NONBLOCK or ~O_NONBLOCK
** (meaning block). This is done to best match the type of
** timeout and for (possible) use with select().
*/
{ \
/* can't get an fd, likely internal 'fake' fp */ \
errno = 0; \
} \
if ((val) == SM_TIME_DEFAULT) \
{ \
} \
else \
{ \
} \
if ((val) == SM_TIME_FOREVER) \
{ \
{ \
int ret; \
{ \
/* errno should be set */ \
return SM_IO_EOF; \
} \
} \
} \
else { \
{ \
int ret; \
{ \
/* errno should be set */ \
return SM_IO_EOF; \
} \
} \
} \
}
/*
** SM_IO_WR_TIMEOUT -- setup the timeout for the write
**
** This #define uses a select() to wait for the 'fd' to become writable.
** The select() can be active for up to 'to' time. The select may not
** use all of the the 'to' time. Hence, the amount of "wall-clock" time is
** measured to decide how much to subtract from 'to' to update it. On some
** the updating of 'to' must be done ourselves; a copy of 'to' is passed
** since a BSD-like system will have updated it and we don't want to
** double the time used!
** Note: if a valid 'fd' doesn't exist yet, don't use this (e.g. the
**
** Parameters
** fd -- a file descriptor for doing select() with
** timeout -- the original user set value.
**
** Returns
** nothing, this is flow through code
**
** Side Effects:
** adjusts 'timeout' for time used
*/
int sm_io_to_sel; \
errno = 0; \
if ((to) == SM_TIME_DEFAULT) \
if ((to) == SM_TIME_IMMEDIATE) \
{ \
return SM_IO_EOF; \
} \
else if ((to) == SM_TIME_FOREVER) \
{ \
return SM_IO_EOF; \
} \
else \
{ \
} \
{ \
return SM_IO_EOF; \
} \
FD_ZERO(&sm_io_to_mask); \
FD_ZERO(&sm_io_x_mask); \
return SM_IO_EOF; \
&sm_io_to); \
if (sm_io_to_sel < 0) \
{ \
/* something went wrong, errno set */ \
return SM_IO_EOF; \
} \
else if (sm_io_to_sel == 0) \
{ \
/* timeout */ \
return SM_IO_EOF; \
} \
/* else loop again */ \
return SM_IO_EOF; \
if ((to) < 0) \
(to) = 0; \
}
/*
** If there is no 'fd' just error (we can't timeout). If the timeout
** is SM_TIME_FOREVER then there is no need to do a timeout with
** select since this will be a real error. If the error is not
** EAGAIN/EWOULDBLOCK (from a nonblocking) then it's a real error.
** Specify the condition here as macro so it can be used in several places.
*/
((fd) < 0 || \
(to) == SM_TIME_FOREVER)