003 File Manager
Current Path:
/usr/src/contrib/sendmail/libsm
usr
/
src
/
contrib
/
sendmail
/
libsm
/
📁
..
📄
Makefile
(346 B)
📄
Makefile.m4
(1.92 KB)
📄
README
(4.42 KB)
📄
assert.c
(4.13 KB)
📄
assert.html
(13.86 KB)
📄
b-strcmp.c
(3.4 KB)
📄
b-strl.c
(5 KB)
📄
cdefs.html
(2.39 KB)
📄
cf.c
(1.97 KB)
📄
clock.c
(13.89 KB)
📄
clrerr.c
(872 B)
📄
config.c
(4.47 KB)
📄
debug.c
(8.91 KB)
📄
debug.html
(7.68 KB)
📄
errstring.c
(6.03 KB)
📄
exc.c
(13.05 KB)
📄
exc.html
(23.27 KB)
📄
fclose.c
(3.13 KB)
📄
feof.c
(961 B)
📄
ferror.c
(932 B)
📄
fflush.c
(3.1 KB)
📄
fget.c
(2.37 KB)
📄
findfp.c
(10.65 KB)
📄
flags.c
(1.27 KB)
📄
fopen.c
(8.3 KB)
📄
fpos.c
(3.12 KB)
📄
fprintf.c
(1.35 KB)
📄
fpurge.c
(1.15 KB)
📄
fput.c
(1.25 KB)
📄
fread.c
(2.28 KB)
📄
fscanf.c
(1.34 KB)
📄
fseek.c
(7.25 KB)
📄
fvwrite.c
(6.24 KB)
📄
fvwrite.h
(740 B)
📄
fwalk.c
(1.41 KB)
📄
fwrite.c
(1.54 KB)
📄
gen.html
(910 B)
📄
get.c
(1.12 KB)
📄
glue.h
(731 B)
📄
heap.c
(17.29 KB)
📄
heap.html
(13.07 KB)
📄
index.html
(5.95 KB)
📄
inet6_ntop.c
(1.1 KB)
📄
io.html
(26.6 KB)
📄
ldap.c
(35.72 KB)
📄
local.h
(9.42 KB)
📄
makebuf.c
(3.36 KB)
📄
match.c
(2.77 KB)
📄
mbdb.c
(16.61 KB)
📄
memstat.c
(5.13 KB)
📄
mpeix.c
(13.84 KB)
📄
niprop.c
(4.64 KB)
📄
notify.c
(3.32 KB)
📄
put.c
(1.61 KB)
📄
refill.c
(7.09 KB)
📄
rewind.c
(1.08 KB)
📄
rpool.c
(11.54 KB)
📄
rpool.html
(6.08 KB)
📄
sem.c
(4.41 KB)
📄
setvbuf.c
(4.2 KB)
📄
shm.c
(2.62 KB)
📄
signal.c
(6.75 KB)
📄
smstdio.c
(6.14 KB)
📄
snprintf.c
(2.29 KB)
📄
sscanf.c
(2.26 KB)
📄
stdio.c
(9.7 KB)
📄
strcasecmp.c
(3.14 KB)
📄
strdup.c
(2.79 KB)
📄
strerror.c
(1.27 KB)
📄
strexit.c
(2.76 KB)
📄
string.c
(1.29 KB)
📄
stringf.c
(1.77 KB)
📄
strio.c
(9.18 KB)
📄
strl.c
(7.52 KB)
📄
strrevcmp.c
(1.61 KB)
📄
strto.c
(5.45 KB)
📄
syslogio.c
(4.11 KB)
📄
t-cf.c
(934 B)
📄
t-event.c
(1.79 KB)
📄
t-exc.c
(2.75 KB)
📄
t-fget.c
(1.71 KB)
📄
t-float.c
(1.78 KB)
📄
t-fopen.c
(875 B)
📄
t-heap.c
(1.3 KB)
📄
t-inet6_ntop.c
(1.4 KB)
📄
t-match.c
(1.1 KB)
📄
t-memstat.c
(2.17 KB)
📄
t-notify.c
(1.81 KB)
📄
t-path.c
(742 B)
📄
t-qic.c
(5.43 KB)
📄
t-rpool.c
(1.5 KB)
📄
t-scanf.c
(1.38 KB)
📄
t-sem.c
(5.85 KB)
📄
t-shm.c
(4.42 KB)
📄
t-smstdio.c
(1.55 KB)
📄
t-string.c
(968 B)
📄
t-strio.c
(775 B)
📄
t-strl.c
(3.53 KB)
📄
t-strrevcmp.c
(994 B)
📄
t-types.c
(2.7 KB)
📄
test.c
(2.73 KB)
📄
ungetc.c
(3.93 KB)
📄
util.c
(4.46 KB)
📄
vasprintf.c
(2.91 KB)
📄
vfprintf.c
(24.09 KB)
📄
vfscanf.c
(18.76 KB)
📄
vprintf.c
(999 B)
📄
vsnprintf.c
(1.87 KB)
📄
wbuf.c
(2.51 KB)
📄
wsetup.c
(1.88 KB)
📄
xtrap.c
(653 B)
Editing: clock.c
/* * Copyright (c) 1998-2004 Proofpoint, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. * */ #include <sm/gen.h> SM_RCSID("@(#)$Id: clock.c,v 1.48 2013-11-22 20:51:42 ca Exp $") #include <unistd.h> #include <time.h> #include <errno.h> #if SM_CONF_SETITIMER # include <sm/time.h> #endif #include <sm/heap.h> #include <sm/debug.h> #include <sm/bitops.h> #include <sm/clock.h> #include "local.h" #if _FFR_SLEEP_USE_SELECT > 0 # include <sys/types.h> #endif #if defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 # include <syslog.h> #endif #ifndef sigmask # define sigmask(s) (1 << ((s) - 1)) #endif /* ** SM_SETEVENTM -- set an event to happen at a specific time in milliseconds. ** ** Events are stored in a sorted list for fast processing. ** An event only applies to the process that set it. ** Source is #ifdef'd to work with older OS's that don't have setitimer() ** (that is, don't have a timer granularity less than 1 second). ** ** Parameters: ** intvl -- interval until next event occurs (milliseconds). ** func -- function to call on event. ** arg -- argument to func on event. ** ** Returns: ** On success returns the SM_EVENT entry created. ** On failure returns NULL. ** ** Side Effects: ** none. */ static SM_EVENT *volatile SmEventQueue; /* head of event queue */ static SM_EVENT *volatile SmFreeEventList; /* list of free events */ SM_EVENT * sm_seteventm(intvl, func, arg) int intvl; void (*func)__P((int)); int arg; { ENTER_CRITICAL(); if (SmFreeEventList == NULL) { SmFreeEventList = (SM_EVENT *) sm_pmalloc_x(sizeof *SmFreeEventList); SmFreeEventList->ev_link = NULL; } LEAVE_CRITICAL(); return sm_sigsafe_seteventm(intvl, func, arg); } /* ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE ** DOING. */ SM_EVENT * sm_sigsafe_seteventm(intvl, func, arg) int intvl; void (*func)__P((int)); int arg; { register SM_EVENT **evp; register SM_EVENT *ev; #if SM_CONF_SETITIMER auto struct timeval now, nowi, ival; auto struct itimerval itime; #else auto time_t now, nowi; #endif int wasblocked; /* negative times are not allowed */ if (intvl <= 0) return NULL; wasblocked = sm_blocksignal(SIGALRM); #if SM_CONF_SETITIMER ival.tv_sec = intvl / 1000; ival.tv_usec = (intvl - ival.tv_sec * 1000) * 10; (void) gettimeofday(&now, NULL); nowi = now; timeradd(&now, &ival, &nowi); #else /* SM_CONF_SETITIMER */ now = time(NULL); nowi = now + (time_t)(intvl / 1000); #endif /* SM_CONF_SETITIMER */ /* search event queue for correct position */ for (evp = (SM_EVENT **) (&SmEventQueue); (ev = *evp) != NULL; evp = &ev->ev_link) { #if SM_CONF_SETITIMER if (timercmp(&(ev->ev_time), &nowi, >=)) #else if (ev->ev_time >= nowi) #endif break; } ENTER_CRITICAL(); if (SmFreeEventList == NULL) { /* ** This shouldn't happen. If called from sm_seteventm(), ** we have just malloced a SmFreeEventList entry. If ** called from a signal handler, it should have been ** from an existing event which sm_tick() just added to ** SmFreeEventList. */ LEAVE_CRITICAL(); if (wasblocked == 0) (void) sm_releasesignal(SIGALRM); return NULL; } else { ev = SmFreeEventList; SmFreeEventList = ev->ev_link; } LEAVE_CRITICAL(); /* insert new event */ ev->ev_time = nowi; ev->ev_func = func; ev->ev_arg = arg; ev->ev_pid = getpid(); ENTER_CRITICAL(); ev->ev_link = *evp; *evp = ev; LEAVE_CRITICAL(); (void) sm_signal(SIGALRM, sm_tick); # if SM_CONF_SETITIMER timersub(&SmEventQueue->ev_time, &now, &itime.it_value); itime.it_interval.tv_sec = 0; itime.it_interval.tv_usec = 0; if (itime.it_value.tv_sec < 0) itime.it_value.tv_sec = 0; if (itime.it_value.tv_sec == 0 && itime.it_value.tv_usec == 0) itime.it_value.tv_usec = 1000; (void) setitimer(ITIMER_REAL, &itime, NULL); # else /* SM_CONF_SETITIMER */ intvl = SmEventQueue->ev_time - now; (void) alarm((unsigned) (intvl < 1 ? 1 : intvl)); # endif /* SM_CONF_SETITIMER */ if (wasblocked == 0) (void) sm_releasesignal(SIGALRM); return ev; } /* ** SM_CLREVENT -- remove an event from the event queue. ** ** Parameters: ** ev -- pointer to event to remove. ** ** Returns: ** none. ** ** Side Effects: ** arranges for event ev to not happen. */ void sm_clrevent(ev) register SM_EVENT *ev; { register SM_EVENT **evp; int wasblocked; # if SM_CONF_SETITIMER struct itimerval clr; # endif if (ev == NULL) return; /* find the parent event */ wasblocked = sm_blocksignal(SIGALRM); for (evp = (SM_EVENT **) (&SmEventQueue); *evp != NULL; evp = &(*evp)->ev_link) { if (*evp == ev) break; } /* now remove it */ if (*evp != NULL) { ENTER_CRITICAL(); *evp = ev->ev_link; ev->ev_link = SmFreeEventList; SmFreeEventList = ev; LEAVE_CRITICAL(); } /* restore clocks and pick up anything spare */ if (wasblocked == 0) (void) sm_releasesignal(SIGALRM); if (SmEventQueue != NULL) (void) kill(getpid(), SIGALRM); else { /* nothing left in event queue, no need for an alarm */ # if SM_CONF_SETITIMER clr.it_interval.tv_sec = 0; clr.it_interval.tv_usec = 0; clr.it_value.tv_sec = 0; clr.it_value.tv_usec = 0; (void) setitimer(ITIMER_REAL, &clr, NULL); # else /* SM_CONF_SETITIMER */ (void) alarm(0); # endif /* SM_CONF_SETITIMER */ } } /* ** SM_CLEAR_EVENTS -- remove all events from the event queue. ** ** Parameters: ** none. ** ** Returns: ** none. */ void sm_clear_events() { register SM_EVENT *ev; #if SM_CONF_SETITIMER struct itimerval clr; #endif int wasblocked; /* nothing will be left in event queue, no need for an alarm */ #if SM_CONF_SETITIMER clr.it_interval.tv_sec = 0; clr.it_interval.tv_usec = 0; clr.it_value.tv_sec = 0; clr.it_value.tv_usec = 0; (void) setitimer(ITIMER_REAL, &clr, NULL); #else /* SM_CONF_SETITIMER */ (void) alarm(0); #endif /* SM_CONF_SETITIMER */ if (SmEventQueue == NULL) return; wasblocked = sm_blocksignal(SIGALRM); /* find the end of the EventQueue */ for (ev = SmEventQueue; ev->ev_link != NULL; ev = ev->ev_link) continue; ENTER_CRITICAL(); ev->ev_link = SmFreeEventList; SmFreeEventList = SmEventQueue; SmEventQueue = NULL; LEAVE_CRITICAL(); /* restore clocks and pick up anything spare */ if (wasblocked == 0) (void) sm_releasesignal(SIGALRM); } /* ** SM_TICK -- take a clock tick ** ** Called by the alarm clock. This routine runs events as needed. ** Always called as a signal handler, so we assume that SIGALRM ** has been blocked. ** ** Parameters: ** One that is ignored; for compatibility with signal handlers. ** ** Returns: ** none. ** ** Side Effects: ** calls the next function in EventQueue. ** ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE ** DOING. */ /* ARGSUSED */ SIGFUNC_DECL sm_tick(sig) int sig; { register SM_EVENT *ev; pid_t mypid; int save_errno = errno; #if SM_CONF_SETITIMER struct itimerval clr; struct timeval now; #else register time_t now; #endif /* SM_CONF_SETITIMER */ #if SM_CONF_SETITIMER clr.it_interval.tv_sec = 0; clr.it_interval.tv_usec = 0; clr.it_value.tv_sec = 0; clr.it_value.tv_usec = 0; (void) setitimer(ITIMER_REAL, &clr, NULL); gettimeofday(&now, NULL); #else /* SM_CONF_SETITIMER */ (void) alarm(0); now = time(NULL); #endif /* SM_CONF_SETITIMER */ FIX_SYSV_SIGNAL(sig, sm_tick); errno = save_errno; CHECK_CRITICAL(sig); mypid = getpid(); while (PendingSignal != 0) { int sigbit = 0; int sig = 0; if (bitset(PEND_SIGHUP, PendingSignal)) { sigbit = PEND_SIGHUP; sig = SIGHUP; } else if (bitset(PEND_SIGINT, PendingSignal)) { sigbit = PEND_SIGINT; sig = SIGINT; } else if (bitset(PEND_SIGTERM, PendingSignal)) { sigbit = PEND_SIGTERM; sig = SIGTERM; } else if (bitset(PEND_SIGUSR1, PendingSignal)) { sigbit = PEND_SIGUSR1; sig = SIGUSR1; } else { /* If we get here, we are in trouble */ abort(); } PendingSignal &= ~sigbit; kill(mypid, sig); } #if SM_CONF_SETITIMER gettimeofday(&now, NULL); #else now = time(NULL); #endif while ((ev = SmEventQueue) != NULL && (ev->ev_pid != mypid || #if SM_CONF_SETITIMER timercmp(&ev->ev_time, &now, <=) #else ev->ev_time <= now #endif )) { void (*f)__P((int)); int arg; pid_t pid; /* process the event on the top of the queue */ ev = SmEventQueue; SmEventQueue = SmEventQueue->ev_link; /* we must be careful in here because ev_func may not return */ f = ev->ev_func; arg = ev->ev_arg; pid = ev->ev_pid; ENTER_CRITICAL(); ev->ev_link = SmFreeEventList; SmFreeEventList = ev; LEAVE_CRITICAL(); if (pid != getpid()) continue; if (SmEventQueue != NULL) { #if SM_CONF_SETITIMER if (timercmp(&SmEventQueue->ev_time, &now, >)) { timersub(&SmEventQueue->ev_time, &now, &clr.it_value); clr.it_interval.tv_sec = 0; clr.it_interval.tv_usec = 0; if (clr.it_value.tv_sec < 0) clr.it_value.tv_sec = 0; if (clr.it_value.tv_sec == 0 && clr.it_value.tv_usec == 0) clr.it_value.tv_usec = 1000; (void) setitimer(ITIMER_REAL, &clr, NULL); } else { clr.it_interval.tv_sec = 0; clr.it_interval.tv_usec = 0; clr.it_value.tv_sec = 3; clr.it_value.tv_usec = 0; (void) setitimer(ITIMER_REAL, &clr, NULL); } #else /* SM_CONF_SETITIMER */ if (SmEventQueue->ev_time > now) (void) alarm((unsigned) (SmEventQueue->ev_time - now)); else (void) alarm(3); #endif /* SM_CONF_SETITIMER */ } /* call ev_func */ errno = save_errno; (*f)(arg); #if SM_CONF_SETITIMER clr.it_interval.tv_sec = 0; clr.it_interval.tv_usec = 0; clr.it_value.tv_sec = 0; clr.it_value.tv_usec = 0; (void) setitimer(ITIMER_REAL, &clr, NULL); gettimeofday(&now, NULL); #else /* SM_CONF_SETITIMER */ (void) alarm(0); now = time(NULL); #endif /* SM_CONF_SETITIMER */ } if (SmEventQueue != NULL) { #if SM_CONF_SETITIMER timersub(&SmEventQueue->ev_time, &now, &clr.it_value); clr.it_interval.tv_sec = 0; clr.it_interval.tv_usec = 0; if (clr.it_value.tv_sec < 0) clr.it_value.tv_sec = 0; if (clr.it_value.tv_sec == 0 && clr.it_value.tv_usec == 0) clr.it_value.tv_usec = 1000; (void) setitimer(ITIMER_REAL, &clr, NULL); #else /* SM_CONF_SETITIMER */ (void) alarm((unsigned) (SmEventQueue->ev_time - now)); #endif /* SM_CONF_SETITIMER */ } errno = save_errno; return SIGFUNC_RETURN; } /* ** SLEEP -- a version of sleep that works with this stuff ** ** Because Unix sleep uses the alarm facility, I must reimplement ** it here. ** ** Parameters: ** intvl -- time to sleep. ** ** Returns: ** zero. ** ** Side Effects: ** waits for intvl time. However, other events can ** be run during that interval. */ # if !HAVE_NANOSLEEP static void sm_endsleep __P((int)); static bool volatile SmSleepDone; # endif #ifndef SLEEP_T # define SLEEP_T unsigned int #endif SLEEP_T sleep(intvl) unsigned int intvl; { #if HAVE_NANOSLEEP struct timespec rqtp; if (intvl == 0) return (SLEEP_T) 0; rqtp.tv_sec = intvl; rqtp.tv_nsec = 0; nanosleep(&rqtp, NULL); return (SLEEP_T) 0; #else /* HAVE_NANOSLEEP */ int was_held; SM_EVENT *ev; #if _FFR_SLEEP_USE_SELECT > 0 int r; # if _FFR_SLEEP_USE_SELECT > 0 struct timeval sm_io_to; # endif #endif /* _FFR_SLEEP_USE_SELECT > 0 */ #if SM_CONF_SETITIMER struct timeval now, begin, diff; # if _FFR_SLEEP_USE_SELECT > 0 struct timeval slpv; # endif #else /* SM_CONF_SETITIMER */ time_t begin, now; #endif /* SM_CONF_SETITIMER */ if (intvl == 0) return (SLEEP_T) 0; #if defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 if (intvl > _FFR_MAX_SLEEP_TIME) { syslog(LOG_ERR, "sleep: interval=%u exceeds max value %d", intvl, _FFR_MAX_SLEEP_TIME); # if 0 SM_ASSERT(intvl < (unsigned int) INT_MAX); # endif intvl = _FFR_MAX_SLEEP_TIME; } #endif /* defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 */ SmSleepDone = false; #if SM_CONF_SETITIMER # if _FFR_SLEEP_USE_SELECT > 0 slpv.tv_sec = intvl; slpv.tv_usec = 0; # endif (void) gettimeofday(&now, NULL); begin = now; #else /* SM_CONF_SETITIMER */ now = begin = time(NULL); #endif /* SM_CONF_SETITIMER */ ev = sm_setevent((time_t) intvl, sm_endsleep, 0); if (ev == NULL) { /* COMPLAIN */ #if 0 syslog(LOG_ERR, "sleep: sm_setevent(%u) failed", intvl); #endif SmSleepDone = true; } was_held = sm_releasesignal(SIGALRM); while (!SmSleepDone) { #if SM_CONF_SETITIMER (void) gettimeofday(&now, NULL); timersub(&now, &begin, &diff); if (diff.tv_sec < 0 || (diff.tv_sec == 0 && diff.tv_usec == 0)) break; # if _FFR_SLEEP_USE_SELECT > 0 timersub(&slpv, &diff, &sm_io_to); # endif #else /* SM_CONF_SETITIMER */ now = time(NULL); /* ** Check whether time expired before signal is released. ** Due to the granularity of time() add 1 to be on the ** safe side. */ if (!(begin + (time_t) intvl + 1 > now)) break; # if _FFR_SLEEP_USE_SELECT > 0 sm_io_to.tv_sec = intvl - (now - begin); if (sm_io_to.tv_sec <= 0) sm_io_to.tv_sec = 1; sm_io_to.tv_usec = 0; # endif /* _FFR_SLEEP_USE_SELECT > 0 */ #endif /* SM_CONF_SETITIMER */ #if _FFR_SLEEP_USE_SELECT > 0 if (intvl <= _FFR_SLEEP_USE_SELECT) { r = select(0, NULL, NULL, NULL, &sm_io_to); if (r == 0) break; } else #endif /* _FFR_SLEEP_USE_SELECT > 0 */ (void) pause(); } /* if out of the loop without the event being triggered remove it */ if (!SmSleepDone) sm_clrevent(ev); if (was_held > 0) (void) sm_blocksignal(SIGALRM); return (SLEEP_T) 0; #endif /* HAVE_NANOSLEEP */ } #if !HAVE_NANOSLEEP static void sm_endsleep(ignore) int ignore; { /* ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE ** DOING. */ SmSleepDone = true; } #endif /* !HAVE_NANOSLEEP */
Upload File
Create Folder