/* * tailf -- Monitor the end of one or more log files. * * (C) 1997 Pharos IP Pty Ltd * $Id: tailf.c,v 1.2 1997-12-30 17:50:11+10 mbp Exp $ * $Source: /fn/cvsroot/pip/tools/tailf/tailf.c,v $ */ /* This uses polling, which is a bit ugly, but I can't seem to work * out how select() works -- it seems to always return immediately. * Anyhow, this is smaller and more friendly than 'tail -f'. * */ #include #include #include #include #include #include #define MAX_FILES 64 int nMonitored; int afdMonitored[MAX_FILES]; #define BUF_SIZE 4<<10 char abBuf[BUF_SIZE]; #define FD_STDOUT 1 #define SLEEP_SEC 0 #define SLEEP_USEC 100000 int fOpenFiles(int nArgs, char const * const * const apszArgs) { int iArg; int fd; char const * pszFile; nMonitored = 0; /* For each argument */ for (iArg = 1; iArg < nArgs; iArg++) { if (nMonitored >= MAX_FILES) { fputs("warning: too many files\n", stderr); break; } /* Try to open the file for reading */ pszFile = apszArgs[iArg]; fd = open(pszFile, O_RDONLY); if (fd < 0) { perror(pszFile); continue; } /* Seek to the end of the file */ if (lseek(fd, +1, SEEK_END) == -1) { perror(pszFile); continue; } /* If it was opened OK, add to the monitoring set */ afdMonitored[nMonitored++] = fd; } if (nMonitored == 0) { fputs("no files\n", stderr); return 0; } return 1; } int fMonitorFiles(void) { int rc; int i; int nbRead, nbWritten; int fd; struct timeval tvWait; /* Wait for a little while. */ tvWait.tv_sec = SLEEP_SEC; tvWait.tv_usec = SLEEP_USEC; rc = select(0, 0, 0, 0, &tvWait); if (rc < 0) { perror("select"); return 0; } /* Check all file descriptors for new data. */ for (i = 0; i < nMonitored; i++) { fd = afdMonitored[i]; nbRead = read(fd, abBuf, BUF_SIZE); if (nbRead < 0 || nbRead > BUF_SIZE) { perror("read"); return 0; } if (nbRead == 0) { /* eof */ continue; } nbWritten = write(1, abBuf, nbRead); if (nbWritten < 0 || nbWritten != nbRead) { perror("write"); return 0; } } return 1; } int main(int argc, char const * const * const argv) { if (!fOpenFiles(argc, argv)) return 1; while(fMonitorFiles()) ; return 1; } /* * Local variables: * c-basic-offset: 4 * End: */