// PCA These calls to debug are rather sketchy because they may allocate memory. Fortunately they only occur if an error occurs. int set_child_group(job_t *j, process_t *p, int print_errors) { int res = 0; if (job_get_flag(j, JOB_CONTROL)) { if (!j->pgid) { j->pgid = p->pid; } if (setpgid(p->pid, j->pgid)) { if (getpgid(p->pid) != j->pgid && print_errors) { char pid_buff[128]; char job_id_buff[128]; char getpgid_buff[128]; char job_pgid_buff[128]; format_long_safe(pid_buff, p->pid); format_long_safe(job_id_buff, j->job_id); format_long_safe(getpgid_buff, getpgid(p->pid)); format_long_safe(job_pgid_buff, j->pgid); debug_safe(1, "Could not send process %s, '%s' in job %s, '%s' from group %s to group %s", pid_buff, p->argv0_cstr(), job_id_buff, j->command_cstr(), getpgid_buff, job_pgid_buff); safe_perror("setpgid"); res = -1; } } } else { j->pgid = getpid(); } if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND)) { if (tcsetpgrp(0, j->pgid) && print_errors) { char job_id_buff[128]; format_long_safe(job_id_buff, j->job_id); debug_safe(1, "Could not send job %s ('%s') to foreground", job_id_buff, j->command_cstr()); safe_perror("tcsetpgrp"); res = -1; } } return res; }
// In general, strerror is not async-safe, and therefore we cannot use it directly. So instead we // have to grub through sys_nerr and sys_errlist directly On GNU toolchain, this will produce a // deprecation warning from the linker (!!), which appears impossible to suppress! const char *safe_strerror(int err) { #if defined(__UCLIBC__) // uClibc does not have sys_errlist, however, its strerror is believed to be async-safe. // See issue #808. return strerror(err); #elif defined(HAVE__SYS__ERRS) || defined(HAVE_SYS_ERRLIST) #ifdef HAVE_SYS_ERRLIST if (err >= 0 && err < sys_nerr && sys_errlist[err] != NULL) { return sys_errlist[err]; } #elif defined(HAVE__SYS__ERRS) extern const char _sys_errs[]; extern const int _sys_index[]; extern int _sys_num_err; if (err >= 0 && err < _sys_num_err) { return &_sys_errs[_sys_index[err]]; } #endif // either HAVE__SYS__ERRS or HAVE_SYS_ERRLIST #endif // defined(HAVE__SYS__ERRS) || defined(HAVE_SYS_ERRLIST) int saved_err = errno; static char buff[384]; // use a shared buffer for this case char errnum_buff[64]; format_long_safe(errnum_buff, err); buff[0] = '\0'; safe_append(buff, "unknown error (errno was ", sizeof buff); safe_append(buff, errnum_buff, sizeof buff); safe_append(buff, ")", sizeof buff); errno = saved_err; return buff; }
static bool write_color(char *todo, unsigned char idx, bool is_fg) { bool result = false; if (idx < 16 || term256_support_is_native()) { /* Use tparm */ putp( tparm( todo, idx ) ); result = true; } else { /* We are attempting to bypass the term here. Generate the ANSI escape sequence ourself. */ char stridx[128]; format_long_safe(stridx, (long)idx); char buff[128] = "\x1b["; strcat(buff, is_fg ? "38;5;" : "48;5;"); strcat(buff, stridx); strcat(buff, "m"); write_loop(STDOUT_FILENO, buff, strlen(buff)); result = true; } return result; }
const char *safe_strerror(int err) { if (err >= 0 && err < sys_nerr && sys_errlist[err] != NULL) { return sys_errlist[err]; } else { int saved_err = errno; /* Use a shared buffer for this case */ static char buff[384]; char errnum_buff[64]; format_long_safe(errnum_buff, err); buff[0] = '\0'; safe_append(buff, "unknown error (errno was ", sizeof buff); safe_append(buff, errnum_buff, sizeof buff); safe_append(buff, ")", sizeof buff); errno = saved_err; return buff; } }
/* Cover for debug_safe that can take an int. The format string should expect a %s */ static void debug_safe_int(int level, const char *format, int val) { char buff[128]; format_long_safe(buff, val); debug_safe(level, format, buff); }