2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Miscellaneous Bacula memory and thread safe routines
21 * Generally, these are interfaces to system or standard
24 * Bacula utility functions are in util.c
30 #include "lib/bregex.h"
35 static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;
36 static pthread_cond_t timer = PTHREAD_COND_INITIALIZER;
41 POOLMEM *quote_string(POOLMEM *snew, const char *old)
52 for (i=0; old[i]; i++) {
81 * Quote a where (list of addresses separated by spaces)
83 POOLMEM *quote_where(POOLMEM *snew, const char *old)
94 for (i=0; old[i]; i++) {
120 * This routine is a somewhat safer unlink in that it
121 * allows you to run a regex on the filename before
122 * excepting it. It also requires the file to be in
123 * the working directory.
125 int safer_unlink(const char *pathname, const char *regx)
130 const int nmatch = 30;
131 regmatch_t pmatch[nmatch];
134 /* Name must start with working directory */
135 if (strncmp(pathname, working_directory, strlen(working_directory)) != 0) {
136 Pmsg1(000, "Safe_unlink excluded: %s\n", pathname);
140 /* Compile regex expression */
141 rc = regcomp(&preg1, regx, REG_EXTENDED);
143 regerror(rc, &preg1, prbuf, sizeof(prbuf));
144 Pmsg2(000, _("safe_unlink could not compile regex pattern \"%s\" ERR=%s\n"),
149 /* Unlink files that match regexes */
150 if (regexec(&preg1, pathname, nmatch, pmatch, 0) == 0) {
151 Dmsg1(100, "safe_unlink unlinking: %s\n", pathname);
152 rtn = unlink(pathname);
154 Pmsg2(000, "safe_unlink regex failed: regex=%s file=%s\n", regx, pathname);
162 * This routine will sleep (sec, microsec). Note, however, that if a
163 * signal occurs, it will return early. It is up to the caller
164 * to recall this routine if he/she REALLY wants to sleep the
167 int bmicrosleep(int32_t sec, int32_t usec)
169 struct timespec timeout;
174 timeout.tv_sec = sec;
175 timeout.tv_nsec = usec * 1000;
177 #ifdef HAVE_NANOSLEEP
178 stat = nanosleep(&timeout, NULL);
179 if (!(stat < 0 && errno == ENOSYS)) {
182 /* If we reach here it is because nanosleep is not supported by the OS */
185 /* Do it the old way */
186 gettimeofday(&tv, &tz);
187 timeout.tv_nsec += tv.tv_usec * 1000;
188 timeout.tv_sec += tv.tv_sec;
189 while (timeout.tv_nsec >= 1000000000) {
190 timeout.tv_nsec -= 1000000000;
194 Dmsg2(200, "pthread_cond_timedwait sec=%d usec=%d\n", sec, usec);
195 /* Note, this unlocks mutex during the sleep */
197 stat = pthread_cond_timedwait(&timer, &timer_mutex, &timeout);
200 Dmsg2(200, "pthread_cond_timedwait stat=%d ERR=%s\n", stat,
208 * Guarantee that the string is properly terminated */
209 char *bstrncpy(char *dest, const char *src, int maxlen)
211 strncpy(dest, src, maxlen-1);
217 * Guarantee that the string is properly terminated */
218 char *bstrncpy(char *dest, POOL_MEM &src, int maxlen)
220 strncpy(dest, src.c_str(), maxlen-1);
226 * Note: Here the maxlen is the maximum length permitted
227 * stored in dest, while on Unix systems, it is the maximum characters
228 * that may be copied from src.
230 char *bstrncat(char *dest, const char *src, int maxlen)
232 int len = strlen(dest);
233 if (len < maxlen-1) {
234 strncpy(dest+len, src, maxlen-len-1);
241 * Note: Here the maxlen is the maximum length permitted
242 * stored in dest, while on Unix systems, it is the maximum characters
243 * that may be copied from src.
245 char *bstrncat(char *dest, POOL_MEM &src, int maxlen)
247 int len = strlen(dest);
248 if (len < maxlen-1) {
249 strncpy(dest+len, src.c_str(), maxlen-len-1);
256 * Allows one or both pointers to be NULL
258 bool bstrcmp(const char *s1, const char *s2)
260 if (s1 == s2) return true;
261 if (s1 == NULL || s2 == NULL) return false;
262 return strcmp(s1, s2) == 0;
266 * Allows one or both pointers to be NULL
268 bool bstrcasecmp(const char *s1, const char *s2)
270 if (s1 == s2) return true;
271 if (s1 == NULL || s2 == NULL) return false;
272 return strcasecmp(s1, s2) == 0;
277 * Get character length of UTF-8 string
280 * U-00000000 - U-0000007F: 0xxxxxxx
281 * U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
282 * U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
283 * U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
284 * U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
285 * U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
287 int cstrlen(const char *str)
289 uint8_t *p = (uint8_t *)str;
295 if ((*p & 0xC0) != 0xC0) {
300 if ((*p & 0xD0) == 0xC0) {
305 if ((*p & 0xF0) == 0xD0) {
310 if ((*p & 0xF8) == 0xF0) {
315 if ((*p & 0xFC) == 0xF8) {
320 if ((*p & 0xFE) == 0xFC) {
325 p++; /* Shouln't get here but must advance */
330 /* We need to disable the malloc() macro if SMARTALLOC is not used,
331 * else, it points to b_malloc() and causes problems.
340 void *bmalloc(size_t size)
345 buf = sm_malloc(file, line, size);
351 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
357 void *b_malloc(const char *file, int line, size_t size)
362 buf = sm_malloc(file, line, size);
368 e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
374 void bfree(void *buf)
377 sm_free(__FILE__, __LINE__, buf);
383 void *brealloc (void *buf, size_t size)
386 buf = sm_realloc(__FILE__, __LINE__, buf, size);
388 buf = realloc(buf, size);
392 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
398 void *bcalloc(size_t size1, size_t size2)
402 buf = calloc(size1, size2);
405 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
410 /* Code now in src/lib/bsnprintf.c */
411 #ifndef USE_BSNPRINTF
417 int bsnprintf(char *str, int32_t size, const char *fmt, ...)
422 va_start(arg_ptr, fmt);
423 len = bvsnprintf(str, size, fmt, arg_ptr);
429 * Implement vsnprintf()
431 int bvsnprintf(char *str, int32_t size, const char *format, va_list ap)
433 #ifdef HAVE_VSNPRINTF
435 len = vsnprintf(str, size, format, ap);
443 buflen = size > BIG_BUF ? size : BIG_BUF;
444 buf = get_memory(buflen);
445 len = vsprintf(buf, format, ap);
447 Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
449 memcpy(str, buf, len);
450 str[len] = 0; /* len excludes the null */
455 #endif /* USE_BSNPRINTF */
457 #ifndef HAVE_LOCALTIME_R
459 struct tm *localtime_r(const time_t *timep, struct tm *tm)
461 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
465 ltm = localtime(timep);
467 memcpy(tm, ltm, sizeof(struct tm));
470 return ltm ? tm : NULL;
472 #endif /* HAVE_LOCALTIME_R */
474 #ifndef HAVE_READDIR_R
478 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
480 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
486 ndir = readdir(dirp);
489 memcpy(entry, ndir, sizeof(struct dirent));
490 strcpy(entry->d_name, ndir->d_name);
500 #endif /* HAVE_READDIR_R */
503 int b_strerror(int errnum, char *buf, size_t bufsiz)
505 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
511 msg = strerror(errnum);
513 msg = _("Bad errno");
516 bstrncpy(buf, msg, bufsiz);
522 /* These routines are not normally turned on */
524 void b_memset(const char *file, int line, void *mem, int val, size_t num)
526 /* Testing for 2000 byte zero at beginning of Volume block */
527 if (num > 1900 && num < 3000) {
528 Pmsg3(000, _("Memset for %d bytes at %s:%d\n"), (int)num, file, line);
530 memset(mem, val, num);
534 #if !defined(HAVE_WIN32)
535 static int del_pid_file_ok = FALSE;
537 static int pid_fd = -1;
539 #ifdef HAVE_FCNTL_LOCK
540 /* a convenient function [un]lock file using fnctl()
541 * code must be in F_UNLCK, F_RDLCK, F_WRLCK
542 * return -1 for error and errno is set
544 int fcntl_lock(int fd, int code)
548 l.l_whence = l.l_start = l.l_len = 0;
550 return fcntl(fd, F_SETLK, &l);
554 /* Create a disk pid "lock" file
556 * 0: Error with the error message in errmsg
558 * 2: Successs, but a previous file was found
560 #if !defined(HAVE_FCNTL_LOCK) || defined(HAVE_WIN32)
561 int create_lock_file(char *fname, const char *progname, const char *filetype, POOLMEM **errmsg, int *fd)
564 #if !defined(HAVE_WIN32)
570 if (stat(fname, &statp) == 0) {
571 /* File exists, see what we have */
573 if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
574 read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
575 sscanf(pidbuf, "%d", &oldpid) != 1) {
577 Mmsg(errmsg, _("Cannot open %s file. %s ERR=%s\n"), filetype, fname,
579 close(pidfd); /* if it was successfully opened */
582 /* Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and
583 * since they use a deterministic algorithm for assigning PIDs, we can have
584 * pid conflicts with the old PID file after a reboot.
585 * The intent the following code is to check if the oldpid read from the pid
586 * file is the same as the currently executing process's pid,
587 * and if oldpid == getpid(), skip the attempt to
588 * kill(oldpid,0), since the attempt is guaranteed to succeed,
589 * but the success won't actually mean that there is an
590 * another Bacula process already running.
591 * For more details see bug #797.
593 if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) {
594 Mmsg(errmsg, _("%s is already running. pid=%d\nCheck file %s\n"),
595 progname, oldpid, fname);
598 /* He is not alive, so take over file ownership */
599 unlink(fname); /* remove stale pid file */
602 /* Create new pid file */
603 if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
604 len = sprintf(pidbuf, "%d\n", (int)getpid());
605 write(pidfd, pidbuf, len);
607 /* ret is already 1 */
610 Mmsg(errmsg, _("Could not open %s file. %s ERR=%s\n"), filetype, fname, be.bstrerror());
616 #else /* defined(HAVE_FCNTL_LOCK) */
617 int create_lock_file(char *fname, const char *progname, const char *filetype, POOLMEM **errmsg, int *fd)
623 /* Open the pidfile for writing */
624 if ((*fd = open(fname, O_CREAT|O_RDWR, 0640)) >= 0) {
625 if (fcntl_lock(*fd, F_WRLCK) == -1) {
627 /* already locked by someone else, try to read the pid */
628 if (read(*fd, &pidbuf, sizeof(pidbuf)) > 0 &&
629 sscanf(pidbuf, "%d", &oldpid) == 1) {
630 Mmsg(errmsg, _("%s is already running. pid=%d, check file %s\n"),
631 progname, oldpid, fname);
633 Mmsg(errmsg, _("Cannot lock %s file. %s ERR=%s\n"), filetype, fname, be.bstrerror());
640 len = sprintf(pidbuf, "%d\n", (int)getpid());
641 write(*fd, pidbuf, len);
642 /* KEEP THE FILE OPEN TO KEEP THE LOCK !!! */
646 Mmsg(errmsg, _("Cannot not open %s file. %s ERR=%s\n"), filetype, fname, be.bstrerror());
653 * Create a standard "Unix" pid file.
655 void create_pid_file(char *dir, const char *progname, int port)
657 POOLMEM *errmsg = get_pool_memory(PM_MESSAGE);
658 POOLMEM *fname = get_pool_memory(PM_FNAME);
660 Mmsg(fname, "%s/%s.%d.pid", dir, progname, port);
661 if (create_lock_file(fname, progname, "pid", &errmsg, &pid_fd) == 0) {
662 Emsg1(M_ERROR_TERM, 0, "%s", errmsg);
665 #if !defined(HAVE_WIN32)
666 del_pid_file_ok = TRUE; /* we created it so we can delete it */
669 free_pool_memory(fname);
670 free_pool_memory(errmsg);
674 * Delete the pid file if we created it
676 int delete_pid_file(char *dir, const char *progname, int port)
678 #if !defined(HAVE_WIN32)
679 POOLMEM *fname = get_pool_memory(PM_FNAME);
683 if (!del_pid_file_ok) {
684 free_pool_memory(fname);
687 del_pid_file_ok = FALSE;
688 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
690 free_pool_memory(fname);
698 uint64_t last_jobs_addr;
699 uint64_t reserved[20];
702 static struct s_state_hdr state_hdr = {
709 * Open and read the state file for the daemon
711 void read_state_file(char *dir, const char *progname, int port)
716 POOLMEM *fname = get_pool_memory(PM_FNAME);
717 struct s_state_hdr hdr;
718 int hdr_size = sizeof(hdr);
720 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
721 /* If file exists, see what we have */
722 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
723 if ((sfd = open(fname, O_RDONLY|O_BINARY)) < 0) {
725 Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
726 sfd, (int)sizeof(hdr), be.bstrerror());
729 if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
731 Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
732 sfd, (int)stat, hdr_size, be.bstrerror());
735 if (hdr.version != state_hdr.version) {
736 Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
737 state_hdr.version, hdr.version);
741 if (strcmp(hdr.id, state_hdr.id) != 0) {
742 Dmsg0(000, "State file header id invalid.\n");
745 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
746 if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
757 free_pool_memory(fname);
761 * Write the state file
763 static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
765 void write_state_file(char *dir, const char *progname, int port)
769 POOLMEM *fname = get_pool_memory(PM_FNAME);
771 P(state_mutex); /* Only one job at a time can call here */
772 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
773 /* Create new state file */
775 if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
777 Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.bstrerror());
778 Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.bstrerror());
781 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
783 Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror());
786 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
787 state_hdr.last_jobs_addr = sizeof(state_hdr);
788 state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
789 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
790 if (lseek(sfd, 0, SEEK_SET) < 0) {
792 Dmsg1(000, "lseek error: ERR=%s\n", be.bstrerror());
795 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
797 Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.bstrerror());
801 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
810 free_pool_memory(fname);
814 /* BSDI does not have this. This is a *poor* simulation */
817 strtoll(const char *ptr, char **endptr, int base)
819 return (long long int)strtod(ptr, endptr);
824 * Bacula's implementation of fgets(). The difference is that it handles
825 * being interrupted by a signal (e.g. a SIGCHLD).
828 char *bfgets(char *s, int size, FILE *fd)
833 for (int i=0; i < size-1; i++) {
837 } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
847 if (ch == '\r') { /* Support for Mac/Windows file format */
849 if (ch != '\n') { /* Mac (\r only) */
850 (void)ungetc(ch, fd); /* Push next character back to fd */
863 * Bacula's implementation of fgets(). The difference is that it handles
864 * being interrupted by a signal (e.g. a SIGCHLD) and it has a
865 * different calling sequence which implements input lines of
866 * up to a million characters.
868 char *bfgets(POOLMEM *&s, FILE *fd)
875 soft_max = sizeof_pool_memory(s) - 10;
880 } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
890 if (soft_max > 1000000) {
893 s = check_pool_memory_size(s, soft_max+10000);
894 soft_max = sizeof_pool_memory(s) - 10;
898 if (ch == '\r') { /* Support for Mac/Windows file format */
900 if (ch != '\n') { /* Mac (\r only) */
901 (void)ungetc(ch, fd); /* Push next character back to fd */
914 * Make a "unique" filename. It is important that if
915 * called again with the same "what" that the result
916 * will be identical. This allows us to use the file
917 * without saving its name, and re-generate the name
918 * so that it can be deleted.
920 void make_unique_filename(POOLMEM **name, int Id, char *what)
922 Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);
925 char *escape_filename(const char *file_path)
927 if (file_path == NULL || strpbrk(file_path, "\"\\") == NULL) {
931 char *escaped_path = (char *)bmalloc(2 * (strlen(file_path) + 1));
932 char *cur_char = escaped_path;
935 if (*file_path == '\\' || *file_path == '"') {
939 *cur_char++ = *file_path++;
948 * For the moment preventing suspensions is only
949 * implemented on Windows.
952 void prevent_os_suspensions()
955 void allow_os_suspensions()
960 #if HAVE_BACKTRACE && HAVE_GCC
961 /* if some names are not resolved you can try using : addr2line, like this
962 * $ addr2line -e bin/bacula-sd -a 0x43cd11
964 * use the the -rdynamic option in the linker, like this
965 * $ LDFLAGS="-rdynamic" make setup
968 #include <execinfo.h>
971 const size_t max_depth = 100;
973 void *stack_addrs[max_depth];
974 char **stack_strings;
976 stack_depth = backtrace(stack_addrs, max_depth);
977 stack_strings = backtrace_symbols(stack_addrs, stack_depth);
979 for (size_t i = 3; i < stack_depth; i++) {
980 size_t sz = 200; /* just a guess, template names will go much wider */
981 char *function = (char *)actuallymalloc(sz);
982 char *begin = 0, *end = 0;
983 /* find the parentheses and address offset surrounding the mangled name */
984 for (char *j = stack_strings[i]; *j; ++j) {
987 } else if (*j == '+') {
994 /* found our mangled name, now in [begin, end] */
997 char *ret = abi::__cxa_demangle(begin, function, &sz, &status);
999 /* return value may be a realloc() of the input */
1002 /* demangling failed, just pretend it's a C function with no args */
1003 strncpy(function, begin, sz);
1004 strncat(function, "()", sz);
1005 function[sz-1] = '\0';
1007 Pmsg2(000, " %s:%s\n", stack_strings[i], function);
1010 /* didn't find the mangled name, just print the whole line */
1011 Pmsg1(000, " %s\n", stack_strings[i]);
1013 actuallyfree(function);
1015 actuallyfree(stack_strings); /* malloc()ed by backtrace_symbols */
1017 #else /* HAVE_BACKTRACE && HAVE_GCC */
1018 void stack_trace() {}
1019 #endif /* HAVE_BACKTRACE && HAVE_GCC */
1021 #ifdef HAVE_SYS_STATVFS_H
1022 #include <sys/statvfs.h>
1024 #define statvfs statfs
1026 /* statvfs.h defines ST_APPEND, which is also used by Bacula */
1030 int fs_get_free_space(const char *path, int64_t *freeval, int64_t *totalval)
1035 if (statvfs(path, &st) == 0) {
1036 *freeval = (uint64_t)st.f_bavail * (uint64_t)st.f_frsize;
1037 *totalval = (uint64_t)st.f_blocks * (uint64_t)st.f_frsize;
1042 *totalval = *freeval = 0;
1046 /* This function is used after a fork, the memory manager is not be initialized
1047 * properly, so we must stay simple.
1049 void setup_env(char *envp[])
1052 #if defined(HAVE_SETENV)
1054 for (int i=0; envp[i] ; i++) {
1055 p = strchr(envp[i], '='); /* HOME=/tmp */
1057 *p=0; /* HOME\0tmp\0 */
1058 setenv(envp[i], p+1, true);
1062 #elif defined(HAVE_PUTENV)
1063 for (int i=0; envp[i] ; i++) {
1067 #error "putenv() and setenv() are not available on this system"
1072 /* Small function to copy a file somewhere else,
1073 * for debug purpose.
1075 int copyfile(const char *src, const char *dst)
1077 int fd_src=-1, fd_dst=-1;
1081 fd_src = open(src, O_RDONLY);
1083 Dmsg2(0, "Unable to open %s ERR=%s\n", src, be.bstrerror(errno));
1086 fd_dst = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0600);
1088 Dmsg2(0, "Unable to open %s ERR=%s\n", dst, be.bstrerror(errno));
1092 while ((len = read(fd_src, buf, sizeof(buf))) > 0)
1094 char *out_ptr = buf;
1096 lenw = write(fd_dst, out_ptr, len);
1100 } else if (errno != EINTR) {
1101 Dmsg3(0, "Unable to write %d bytes in %s. ERR=%s\n", len, dst, be.bstrerror(errno));
1109 if (close(fd_dst) < 0) {
1110 Dmsg2(0, "Unable to close %s properly. ERR=%s\n", dst, be.bstrerror(errno));
1122 /* The poll() code is currently disabled */
1128 int fd_wait_data(int fd, fd_wait_mode mode, int sec, int msec)
1131 struct pollfd fds[NB_EVENT]; /* The structure for one event */
1134 fds[0].events = (mode == WAIT_READ) ? POLLIN : POLLOUT;
1136 ret = poll(fds, NB_EVENT, sec * 1000 + msec);
1138 /* Check if poll actually succeed */
1140 case 0: /* timeout; no event detected */
1143 case -1: /* report error and abort */
1147 if (fds[0].revents & POLLIN || fds[0].revents & POLLOUT) {
1151 return -1; /* unexpected... */
1154 return -1; /* unexpected... */
1158 /* The select() code with a bigger fd_set was tested on Linux, FreeBSD and SunOS */
1159 #if defined(HAVE_LINUX_OS) || defined(HAVE_FREEBSD_OS) || defined(HAVE_SUN_OS) || defined(HAVE_WIN32)
1160 #define SELECT_MAX_FD 7990
1162 #define SELECT_MAX_FD 1023 /* For others, we keep it low */
1165 int fd_wait_data(int fd, fd_wait_mode mode, int sec, int msec)
1168 /* TODO: Allocate the fd_set when fd > SELECT_MAX_FD */
1176 if (fd > SELECT_MAX_FD) {
1177 Pmsg1(0, "Too many open files for the current system fd=%d\n", fd);
1181 memset(&bfd_buf, 0, sizeof(bfd_buf)); /* FD_ZERO(&fdset) */
1182 FD_SET((unsigned)fd, &fdset);
1185 tv.tv_usec = msec * 1000;
1187 if (mode == WAIT_READ) {
1188 ret = select(fd + 1, &fdset, NULL, NULL, &tv);
1190 } else { /* WAIT_WRITE */
1191 ret = select(fd + 1, NULL, &fdset, NULL, &tv);
1195 case 0: /* timeout */
1198 return -1; /* error return */
1206 /* Use SOCK_CLOEXEC option when calling accept(). If not available,
1207 * do it ourself (but with a race condition...)
1209 int baccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
1213 fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
1215 fd = accept(sockfd, addr, addrlen);
1217 # ifdef HAVE_DECL_FD_CLOEXEC
1219 int tmp_errno = errno;
1220 if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) < 0) {
1222 Dmsg2(0, "Unable to set the CLOEXEC flag on fd=%d ERR=%s\n", fd, be.bstrerror());
1227 # endif /* HAVE_DECL_FD_CLOEXEC */
1228 #endif /* HAVE_ACCEPT4 */
1233 FILE *bfopen(const char *path, const char *mode)
1238 bstrncpy(options, mode, sizeof(options));
1240 #if defined(HAVE_STREAM_CLOEXEC)
1241 bstrncat(options, STREAM_CLOEXEC, sizeof(options));
1244 fp = fopen(path, options);
1246 #if !defined(HAVE_STREAM_CLOEXEC) && defined(HAVE_DECL_FD_CLOEXEC)
1248 int fd = fileno(fp);
1250 int tmp_errno = errno;
1251 if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) < 0) {
1253 Dmsg2(0, "Unable to set the CLOEXEC flag on fd=%d ERR=%s\n", fd, be.bstrerror());
1264 /* The main idea of the test is pretty simple, we have a writer and a reader, and
1265 * they wait a little bit to read or send data over the fifo.
1266 * So, for the first packets, the writer will wait, then the reader will wait
1267 * read/write requests should always be fast. Only the time of the fd_wait_data()
1270 #include "findlib/namedpipe.h"
1271 #define PIPENAME "/tmp/wait.pipe.%d"
1273 #define NBPACKETS 10
1274 #define BUFSIZE 128*512 /* The pipe size looks to be 65K */
1282 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
1283 pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
1296 bsnprintf(buf, sizeof(buf), PIPENAME, j->nb);
1297 if (namedpipe_create(&p, buf, 0600) < 0) {
1299 Dmsg2(0, "R: Unable to create the fifo %s. ERR=%s\n", buf, be.bstrerror());
1303 fd = namedpipe_open(&p, buf, O_RDONLY);
1306 Dmsg2(0, "R: Unable to open the fifo %s. ERR=%s\n", buf, be.bstrerror());
1311 pthread_cond_wait(&cond, &cond_mutex);
1313 for (int i = 0; i < NBPACKETS; i++) {
1314 if (i < (NBPACKETS/2)) {
1317 s = get_current_btime();
1318 r = fd_wait_data(fd, WAIT_READ, 10, 0);
1320 e = get_current_btime();
1321 Dmsg2(0, "Wait to read pkt %d %lldms\n",i, (int64_t) (e - s));
1323 if (i <= NBPACKETS/2) {
1324 ASSERT2((e-s) < 10000, "In the 1st phase, we are blocking the process");
1326 ASSERT2((e-s) > 10000, "In the 2nd phase, the writer is slowing down things");
1329 s = get_current_btime();
1330 nb = read(fd, buf, sizeof(buf));
1331 e = get_current_btime();
1332 Dmsg3(0, "Read pkt %d %d bytes in %lldms\n",i, (int)nb, (int64_t) (e - s));
1333 ASSERT2((e-s) < 10000, "The read operation should be FAST");
1349 bsnprintf(buf, sizeof(buf), PIPENAME, j->nb);
1351 if (namedpipe_create(&p, buf, 0600) < 0) {
1353 Dmsg2(0, "W: Unable to create the fifo %s. ERR=%s\n", buf, be.bstrerror());
1358 fd = namedpipe_open(&p, buf, O_WRONLY);
1361 Dmsg2(0, "W: Unable to open the fifo %s. ERR=%s\n", buf, be.bstrerror());
1368 pthread_cond_wait(&cond, &cond_mutex);
1373 for (int i=0; i < NBPACKETS; i++) {
1374 if (i > (NBPACKETS/2)) {
1377 s = get_current_btime();
1378 if (fd_wait_data(fd, WAIT_WRITE, 10, 0) > 0) {
1379 e = get_current_btime();
1380 Dmsg2(0, "Wait to write pkt %d %lldms\n",i, (int64_t) (e - s));
1382 if (i == 0 || i > NBPACKETS/2) { /* The first packet doesn't count */
1383 ASSERT2((e-s) < 100000, "In the 2nd phase, it's fast to send, we are the blocker");
1385 ASSERT2((e-s) > 100000, "In the 1st phase, we wait for the reader");
1388 s = get_current_btime();
1389 nb = write(fd, buf, sizeof(buf));
1390 e = get_current_btime();
1391 Dmsg3(0, "Wrote pkt %d %d bytes in %lldms\n", i, (int)nb, (int64_t) (e - s));
1392 ASSERT2((e-s) < 100000, "The write operation should never block");
1399 int main(int argc, char **argv)
1401 job pthread_list[10000];
1402 int j = (argc >= 2) ? atoi(argv[1]) : 1;
1403 int maxfd = (argc == 3) ? atoi(argv[2]) : 0;
1408 set_debug_flags((char *)"h");
1410 for (int i=3; i < maxfd; i++) {
1411 open("/dev/null", O_RDONLY);
1414 for (int i=0; i < j; i++) {
1415 pthread_list[i].nb=i;
1416 pthread_create(&pthread_list[i].writer, NULL, th2, &pthread_list[i]);
1417 pthread_create(&pthread_list[i].reader, NULL, th1, &pthread_list[i]);
1420 while (nb_ready < j*2) {
1424 Dmsg0(0, "All threads are started\n");
1426 pthread_cond_broadcast(&cond);
1429 for (int i=0; i < j; i++) {
1430 pthread_join(pthread_list[i].writer, NULL);
1431 pthread_join(pthread_list[i].reader, NULL);
1434 for (int i=3; i < maxfd; i++) {