int xopen(const char *path, int oflag, ...) { int res; if ((oflag & O_CREAT) == 0) { while ((res = open(path, oflag)) == -1 && errno == EINTR) if (handle_pending_signals()) break; } else { va_list ap; mode_t mode; va_start(ap, oflag); /* "int" should actually be "mode_t after default argument promotions". "int" is the best guess we have, "mode_t" used to be "unsigned short", which we obviously can't use. */ mode = va_arg(ap, int); va_end(ap); while ((res = open(path, oflag, mode)) == -1 && errno == EINTR) if (handle_pending_signals()) break; } return res; }
/* update timers called from mainloop() after the select() times out If select() does not time out, rtc will be updated too much, so I had to put an old_rtc in and compare the two clocks :P */ void update_timers(void) { static time_t old_rtc = (time_t)0UL; int tdiff; User *usr, *usr_next; rtc = time(NULL); if (!old_rtc) { old_rtc = rtc; return; } tdiff = (int)((unsigned long)rtc - (unsigned long)old_rtc); old_rtc = rtc; /* update the user timers */ for(usr = AllUsers; usr != NULL; usr = usr_next) { usr_next = usr->next; if (usr->timerq == NULL) continue; update_timerqueue(&usr->timerq, usr, tdiff); } /* now process timers that are not bound to a user temporarily block signals, as there are signals that modify the global timerq */ block_timer_signals(SIG_BLOCK); update_timerqueue(&timerq, NULL, tdiff); block_timer_signals(SIG_UNBLOCK); handle_pending_signals(); }
void xclosedir(DIR *dirp) { while (closedir(dirp) == -1 && errno == EINTR) if (handle_pending_signals()) break; }
void xclose(int fildes) { if (fildes < 0) return; while (close(fildes) == -1 && errno == EINTR) handle_pending_signals(); }
/* * fname -- Pathname to lock * pollinterval -- Interval (miliseconds) to check for lock, -1 return */ int dot_lock(const char *fname, int pollinterval) { char path[MAXPATHLEN]; sigset_t nset, oset; int retval; (void)sigemptyset(&nset); (void)sigaddset(&nset, SIGHUP); (void)sigaddset(&nset, SIGINT); (void)sigaddset(&nset, SIGQUIT); (void)sigaddset(&nset, SIGTERM); (void)sigaddset(&nset, SIGTTIN); (void)sigaddset(&nset, SIGTTOU); (void)sigaddset(&nset, SIGTSTP); (void)sigaddset(&nset, SIGCHLD); (void)snprintf(path, sizeof(path), "%s.lock", fname); retval = -1; for (;;) { handle_pending_signals(); (void)sigprocmask(SIG_BLOCK, &nset, &oset); if (create_exclusive(path) != -1) { (void)sigprocmask(SIG_SETMASK, &oset, NULL); retval = 0; break; } else (void)sigprocmask(SIG_SETMASK, &oset, NULL); if (errno != EEXIST) break; if (pollinterval) { if (pollinterval == -1) { errno = EEXIST; break; } (void)usleep((unsigned int)pollinterval * 1000); } } handle_pending_signals(); return retval; }
static int xdup2(int fildes, int fildes2) { int res; while ((res = dup2(fildes, fildes2)) == -1 && errno == EINTR) handle_pending_signals(); return res; }
int xcreat(const char *path, mode_t mode) { int res; while ((res = creat(path, mode)) == -1 && errno == EINTR) handle_pending_signals(); return res; }
int xtcsetattr(int fildes, int optional_actions, const struct termios *termios_p) { int res; while ((res = tcsetattr(fildes, optional_actions, termios_p)) == -1 && errno == EINTR) handle_pending_signals(); return res; }
ssize_t xwrite(int fildes, const void *buf, size_t nbyte) { ssize_t res; /* This is where we will be blocked most of the time, so handle signals that didn't interrupt any system call. */ do handle_pending_signals(); while ((res = write(fildes, buf, nbyte)) == -1 && errno == EINTR); return res; }
struct passwd * xgetpwuid(uid_t xuid) { struct passwd *res; errno = 0; while ((res = getpwuid(xuid)) == NULL && errno == EINTR) { handle_pending_signals(); errno = 0; } return res; }
struct passwd * xgetpwnam(const char *name) { struct passwd *res; errno = 0; while ((res = getpwnam(name)) == NULL && errno == EINTR) { handle_pending_signals(); errno = 0; } return res; }
struct group * xgetgrgid(gid_t xgid) { struct group *res; errno = 0; while ((res = getgrgid(xgid)) == NULL && errno == EINTR) { handle_pending_signals(); errno = 0; } return res; }
int event_loop( long timeout ) { long max_fd = 0; fd_set fds_read, fds_write, fds_exception; if( ! create_event_set( &fds_read, &fds_write, &fds_exception, &max_fd ) ) return -1; time_t now = rel_time(0L); long alarm_time = alarm_getnext(); // Reduce 'timeout' to ensure the next scheduled alarm occurs on time if( alarm_time >= 0 ) { if( alarm_time > now ) { if( timeout > ( alarm_time - now )) timeout = alarm_time - now; } else timeout = 0; } #ifdef USE_PSELECT // If I know there are signals which need processing, reset the select timeout to 0 // Signals are normally blocked, so these would be manufactured events. struct timespec tm = { timeout / 1000, (timeout % 1000) * 1000 * 1000 }; if( event_signals.event_signal_pending_count ) tm.tv_nsec = tm.tv_sec = 0; int rc = pselect( (int) max_fd, &fds_read, &fds_write, &fds_exception, &tm, &event_signals.event_signal_default ); #else // expect queued signals to occur immediately sigprocmask( SIG_SETMASK, &event_signals.event_signal_default, NULL ); sleep(0); if( event_signals.event_signal_pending_count ) timeout = 0; struct timeval tm = { timeout / 1000, (timeout % 1000) * 1000 }; #if 0 #ifndef NDEBUG int i = 0; printf("READ: "); for(i=0;i<64;i++) if(FD_ISSET(i,&fds_read)) { printf("%d ",i); if( fcntl( i, F_GETFL ) < 0 ) printf("*"); } printf("WRITE: "); for(i=0;i<64;i++) if(FD_ISSET(i,&fds_write)) { printf("%d ",i); if( fcntl( i, F_GETFL ) < 0 ) printf("*"); } printf("EXCEPTION: "); for(i=0;i<64;i++) if(FD_ISSET(i,&fds_exception)) { printf("%d ",i); if( fcntl( i, F_GETFL ) < 0 ) printf("*"); } printf("\n"); #endif #endif #ifndef NDEBUG //printf("calling select...");fflush(stdout); #endif int rc = select( max_fd, &fds_read, &fds_write, &fds_exception, &tm ); #ifndef NDEBUG //printf("done\n");fflush(stdout); #endif #endif sigprocmask(SIG_BLOCK, &event_signals.event_signal_mask, NULL); if( rc < 0 ) { if( (errno != EINTR) #ifdef mips && (errno != ENOENT) #endif ) { d_printf("(p)select returned %d (errno = %d - %s)\n",rc, errno, strerror(errno)); exit(0); return -1; } else { return 0; // timeout - nothing to do } } if( event_signals.event_signal_pending_count ) { //d_printf("Calling handle_pending_signals()\n"); handle_pending_signals(); } //d_printf("Calling handle_event_set()\n"); rc = handle_event_set( &fds_read, &fds_write, &fds_exception ); if( !rc ) { //d_printf("Calling handle_timer_events()\n"); handle_timer_events(); } return 0; }
/*ARGSUSED*/ static void auto_lock(void) { #ifndef NO_CRYPT int i; char *srpp = NULL; struct passwd *pw; #undef XCRYPT #if defined(HAVE_AUTH_H) && defined(HAVE_GETAUTHUID) struct authorization *apw; extern char *crypt16 (const char *, const char *); # define XCRYPT(pw, a, b) crypt16(a, b) if ((pw = xgetpwuid(euid)) != NULL && /* effective user passwd */ (apw = getauthuid(euid)) != NULL) /* enhanced ultrix passwd */ srpp = apw->a_password; #elif defined(HAVE_SHADOW_H) struct spwd *spw; # define XCRYPT(pw, a, b) crypt(a, b) if ((pw = xgetpwuid(euid)) != NULL) { /* effective user passwd */ errno = 0; while ((spw = getspnam(pw->pw_name)) == NULL && errno == EINTR) { handle_pending_signals(); errno = 0; } if (spw != NULL) /* shadowed passwd */ srpp = spw->sp_pwdp; } #else #ifdef __CYGWIN__ # define XCRYPT(pw, a, b) cygwin_xcrypt(pw, a, b) #else # define XCRYPT(pw, a, b) crypt(a, b) #endif #if !defined(__MVS__) if ((pw = xgetpwuid(euid)) != NULL) /* effective user passwd */ srpp = pw->pw_passwd; #endif /* !MVS */ #endif if (srpp == NULL) { auto_logout(); /*NOTREACHED*/ return; } setalarm(0); /* Not for locking any more */ xputchar('\n'); for (i = 0; i < 5; i++) { const char *crpp; char *pp; #ifdef AFS char *afsname; Char *safs; if ((safs = varval(STRafsuser)) != STRNULL) afsname = short2str(safs); else if ((afsname = getenv("AFSUSER")) == NULL) afsname = pw->pw_name; #endif pp = xgetpass("Password:"******"\nIncorrect passwd for %s\n"), pw->pw_name); } #endif /* NO_CRYPT */ auto_logout(); }