📄 debug.c
字号:
/* * Move the file descriptor up high so it stays out of the way * of other processing, e.g. sendbackup. */ if (fd >= 0) { i = 0; fd_close[i++] = fd; while((db_fd = dup(fd)) < MIN_DB_FD) { fd_close[i++] = db_fd; } while(--i >= 0) { close(fd_close[i]); } db_file = fdopen(db_fd, "a"); } if (annotation) { /* * Make the first debug log file entry. */ debug_printf(_("pid %ld ruid %ld euid %ld: %s at %s"), (long)getpid(), (long)getuid(), (long)geteuid(), annotation, ctime(&open_time)); }}/* Get current GMT time and return a message timestamp. * Used for g_printf calls to logs and such. The return value * is to a static buffer, so it should be used immediately. * * @returns: timestamp */static char *msg_timestamp(void){ static char timestamp[128]; struct timeval tv; gettimeofday(&tv, NULL); g_snprintf(timestamp, SIZEOF(timestamp), "%lld.%06ld", (long long)tv.tv_sec, (long)tv.tv_usec); return timestamp;}/* * ---- public functions */voidset_logerror(void (*f)(char *)){ logerror_fn = f;}voiddebug_open(char *subdir){ int fd = -1; int i; char *s = NULL; mode_t mask; /* set up logging while we're here */ debug_setup_logging(); /* set 'dbgdir' and clean out old debug files */ debug_setup_1(NULL, subdir); /* * Create the new file with a unique sequence number. */ mask = (mode_t)umask((mode_t)0037); /* Allow the group read bit through */ /* iteratate through sequence numbers until we find one that * is not already in use */ for(i = 0; fd < 0; i++) { amfree(db_name); if ((db_name = get_debug_name(open_time, i)) == NULL) { error(_("Cannot create debug file name in %d tries."), i); /*NOTREACHED*/ } if ((s = newvstralloc(s, dbgdir, db_name, NULL)) == NULL) { error(_("Cannot allocate debug file name memory")); /*NOTREACHED*/ } if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) { if (errno != EEXIST) { error(_("Cannot create debug file \"%s\": %s"), s, strerror(errno)); /*NOTREACHED*/ } amfree(s); } } (void)umask(mask); /* Restore mask */ /* * Finish setup. * * Note: we release control of the string 's' points to. */ debug_setup_2(s, fd, "start");}voiddebug_reopen( char * dbfilename, char * annotation){ char *s = NULL; int fd; if (dbfilename == NULL) { return; } /* set 'dbgdir' and clean out old debug files */ debug_setup_1(NULL, NULL); /* * Reopen the file. */ if (*dbfilename == '/') { s = stralloc(dbfilename); } else { s = newvstralloc(s, dbgdir, dbfilename, NULL); } if ((fd = open(s, O_RDWR|O_APPEND)) < 0) { error(_("cannot reopen debug file %s"), dbfilename); /*NOTREACHED*/ } /* * Finish setup. * * Note: we release control of the string 's' points to. */ debug_setup_2(s, fd, annotation);}voiddebug_rename( char *config, char *subdir){ int fd = -1; int i; char *s = NULL; mode_t mask; if (!db_filename) return; /* set 'dbgdir' and clean out old debug files */ debug_setup_1(config, subdir); s = newvstralloc(s, dbgdir, db_name, NULL); if (strcmp(db_filename, s) == 0) { amfree(s); return; } mask = (mode_t)umask((mode_t)0037);#if defined(__CYGWIN__) /* * On cygwin, rename will not overwrite an existing file nor * will it rename a file that is open for writing... * * Rename file directly. Expect failure if file already exists * or is open by another user. */ i = 0; while (rename(db_filename, s) < 0) { if (errno != EEXIST) { /* * If the failure was not due to the target file name already * existing then we have bigger issues at hand so we keep * the existing file. */ dbprintf(_("Cannot rename \"%s\" to \"%s\": %s\n"), db_filename, s, strerror(errno)); s = newvstralloc(s, db_filename, NULL); i = -1; break; } /* * Files already exists: * Continue searching for a unique file name that will work. */ amfree(db_name); if ((db_name = get_debug_name(open_time, i++)) == NULL) { dbprintf(_("Cannot create unique debug file name")); break; } s = newvstralloc(s, dbgdir, db_name, NULL); } if (i >= 0) { /* * We need to close and reopen the original file handle to * release control of the original debug file name. */ if ((fd = open(s, O_WRONLY|O_APPEND, 0640)) >= 0) { /* * We can safely close the the original log file * since we now have a new working handle. */ db_fd = 2; fclose(db_file); db_file = NULL; } }#else /* check if a file with the same name already exists. */ if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) { for(i = 0; fd < 0; i++) { amfree(db_name); if ((db_name = get_debug_name(open_time, i)) == NULL) { dbprintf(_("Cannot create debug file")); break; } s = newvstralloc(s, dbgdir, db_name, NULL); if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) { if (errno != EEXIST) { dbprintf(_("Cannot create debug file: %s"), strerror(errno)); break; } } } } if (fd >= 0) { close(fd); if (rename(db_filename, s) == -1) { dbprintf(_("Cannot rename \"%s\" to \"%s\": %s\n"), db_filename, s, strerror(errno)); } fd = -1; }#endif (void)umask(mask); /* Restore mask */ /* * Finish setup. * * Note: we release control of the string 's' points to. */ debug_setup_2(s, fd, "rename");}voiddebug_close(void){ time_t curtime; time(&curtime); debug_printf(_("pid %ld finish time %s"), (long)getpid(), ctime(&curtime)); if(db_file && fclose(db_file) == EOF) { int save_errno = errno; db_file = NULL; /* prevent recursion */ g_fprintf(stderr, _("close debug file: %s"), strerror(save_errno)); /*NOTREACHED*/ } db_fd = 2; db_file = NULL; amfree(db_filename); amfree(db_name);}/* * Format and write a debug message to the process debug file. */printf_arglist_function(void debug_printf, const char *, format){ va_list argp; int save_errno; /* * It is common in the code to call dbprintf to write out * syserrno(errno) and then turn around and try to do something else * with errno (e.g. g_printf() or log()), so we make sure errno goes * back out with the same value it came in with. */ save_errno = errno; /* handle the default (stderr) if debug_open hasn't been called yet */ if(db_file == NULL && db_fd == 2) { db_file = stderr; } if(db_file != NULL) { if (db_file != stderr) g_fprintf(db_file, "%s: %s: ", msg_timestamp(), get_pname()); else g_fprintf(db_file, "%s: ", get_pname()); arglist_start(argp, format); g_vfprintf(db_file, format, argp); arglist_end(argp); fflush(db_file); } errno = save_errno;}intdebug_fd(void){ return db_fd;}FILE *debug_fp(void){ return db_file;}char *debug_fn(void){ return db_filename;}voiddebug_dup_stderr_to_debug(void){ if(db_fd != -1 && db_fd != STDERR_FILENO) { if(dup2(db_fd, STDERR_FILENO) != STDERR_FILENO) { error(_("can't redirect stderr to the debug file")); g_assert_not_reached(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -