Various changes for GNO and ORCA/C compatibility.

This commit is contained in:
Stephen Heumann 2014-11-02 11:27:47 -06:00
parent 97e65e3480
commit d4b2c3ce8b
10 changed files with 56 additions and 77 deletions

View File

@ -895,8 +895,7 @@ pid_t xfork(void) FAST_FUNC;
pid_t spawn(char **argv) FAST_FUNC;
pid_t xspawn(char **argv) FAST_FUNC;
pid_t safe_waitpid(pid_t pid, int *wstat, int options) FAST_FUNC;
pid_t wait_any_nohang(int *wstat) FAST_FUNC;
pid_t safe_waitpid(pid_t pid, wait_status_t *wstat, int options) FAST_FUNC;
/* wait4pid: unlike waitpid, waits ONLY for one process.
* Returns sig + 0x180 if child is killed by signal.
* It's safe to pass negative 'pids' from failed [v]fork -
@ -1665,6 +1664,8 @@ extern const char bb_default_login_shell[] ALIGN1;
* can't be done with such byte-oriented operations anyway,
* we don't lose anything.
*/
#ifndef __ORCAC__
// ORCA/C barfs on (at least) isspace, so we'll just use the standard versions of these.
#undef isalnum
#undef isalpha
#undef isascii
@ -1742,6 +1743,7 @@ static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a)
/* NB: must not treat EOF as isgraph or isprint */
#define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
#define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)
#endif /* !defined(__ORCAC__) */
/* Simple unit-testing framework */

View File

@ -144,6 +144,7 @@
#ifndef __ORCAC__
# include <inttypes.h>
#else
# include <limits.h>
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
@ -154,13 +155,15 @@ typedef long intmax_t;
typedef unsigned long uintmax_t;
# define PRIxMAX "lx"
# define PRIdMAX "ld"
# define PRIuMAX "lu"
# define UINTMAX_MAX ULONG_MAX
typedef unsigned long uintptr_t;
#endif
/* ---- Size-saving "small" ints (arch-dependent) ----------- */
#if defined(i386) || defined(__x86_64__) || defined(__mips__) || defined(__cris__)
#if defined(i386) || defined(__x86_64__) || defined(__mips__) || defined(__cris__) || defined(__ORCAC__)
/* add other arches which benefit from this... */
typedef signed char smallint;
typedef unsigned char smalluint;
@ -484,10 +487,22 @@ extern ssize_t getline(char **lineptr, size_t *n, FILE *stream) FAST_FUNC;
#endif
#ifdef __GNO__
// GNO mkdir doesn't take a mode parameter
# define mkdir(path, mode) mkdir(path)
#endif
#if NSIG <= 32
typedef unsigned long sigmask_t;
#else
typedef unsigned long long sigmask_t;
#endif
#ifdef __GNO__
# include <sys/wait.h>
typedef union wait wait_status_t;
#else
typedef int wait_status_t;
#endif
#endif

View File

@ -30,13 +30,13 @@
* printf("endptr[0]:%c errno:%d EINVAL:%d\n", endptr[0], errno, EINVAL);
*/
static unsigned long long ret_ERANGE(void)
static uintmax_t ret_ERANGE(void)
{
errno = ERANGE; /* this ain't as small as it looks (on glibc) */
return ULLONG_MAX;
return UINTMAX_MAX;
}
static unsigned long long handle_errors(unsigned long long v, char **endp)
static uintmax_t handle_errors(uintmax_t v, char **endp)
{
char next_ch = **endp;

View File

@ -149,7 +149,7 @@ size_t FAST_FUNC wcstombs(char *dest, const wchar_t *src, size_t n)
wchar_t wc = *src++;
size_t len = wcrtomb_internal(dest, wc);
if (wc == L'\0')
if (wc == (wchar_t)0)
return org_n - n;
dest += len;
n -= len;
@ -162,7 +162,7 @@ size_t FAST_FUNC wcstombs(char *dest, const wchar_t *src, size_t n)
if (len > n)
break;
memcpy(dest, tbuf, len);
if (wc == L'\0')
if (wc == (wchar_t)0)
return org_n - n;
dest += len;
n -= len;

View File

@ -4,6 +4,7 @@
/* Like vfork, but calls fn(arg) in the child instead of returning.
* This is designed to match the semantics of GNO's fork2 call.
*/
#ifndef __GNO__
pid_t vfork_and_run(void (*fn)(void*) NORETURN, void *arg) {
pid_t pid = vfork();
@ -13,6 +14,11 @@ pid_t vfork_and_run(void (*fn)(void*) NORETURN, void *arg) {
return pid;
}
#else
pid_t vfork_and_run(void (*fn)(void*) NORETURN, void *arg) {
return fork2((fn), 1024, 0, "hush (forked)", 2, (arg));
}
#endif
pid_t xvfork_and_run(void (*fn)(void*) NORETURN, void *arg) {
pid_t pid = vfork_and_run(fn, arg);

View File

@ -67,9 +67,9 @@ unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base,
if (r >= lower && r <= upper)
return r;
range:
bb_error_msg_and_die("number %s is not in %llu..%llu range",
numstr, (unsigned long long)lower,
(unsigned long long)upper);
bb_error_msg_and_die("number %s is not in %" PRIuMAX "..%" PRIuMAX " range",
numstr, (uintmax_t)lower,
(uintmax_t)upper);
inval:
bb_error_msg_and_die("invalid number '%s'", numstr);
}

View File

@ -24,6 +24,7 @@
#include "libbb.h"
#ifndef __GNO__
/* Turn on nonblocking I/O on a fd */
int FAST_FUNC ndelay_on(int fd)
{
@ -42,6 +43,7 @@ int FAST_FUNC ndelay_off(int fd)
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
return flags;
}
#endif
void FAST_FUNC close_on_exec_on(int fd)
{
@ -75,7 +77,7 @@ char* FAST_FUNC utoa_to_buf(unsigned n, char *buf, unsigned buflen)
else
if (sizeof(n) == 8)
// 2^64-1 = 18446744073709551615
i = 10000000000000000000;
i = 10 ** 19;
#endif
else
BUG_sizeof();
@ -277,7 +279,7 @@ int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
return tcsetattr(STDIN_FILENO, TCSANOW, tp);
}
pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
pid_t FAST_FUNC safe_waitpid(pid_t pid, wait_status_t *wstat, int options)
{
pid_t r;
@ -287,26 +289,3 @@ pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
return r;
}
pid_t FAST_FUNC wait_any_nohang(int *wstat)
{
return safe_waitpid(-1, wstat, WNOHANG);
}
// Wait for the specified child PID to exit, returning child's error return.
int FAST_FUNC wait4pid(pid_t pid)
{
int status;
if (pid <= 0) {
/*errno = ECHILD; -- wrong. */
/* we expect errno to be already set from failed [v]fork/exec */
return -1;
}
if (safe_waitpid(pid, &status, 0) == -1)
return -1;
if (WIFEXITED(status))
return WEXITSTATUS(status);
if (WIFSIGNALED(status))
return WTERMSIG(status) + 0x180;
return 0;
}

View File

@ -439,32 +439,12 @@ IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
return r;
}
// Die with an error message if we can't bind a socket to an address.
void FAST_FUNC xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
{
if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
}
// Die with an error message if we can't listen for connections on a socket.
void FAST_FUNC xlisten(int s, int backlog)
{
if (listen(s, backlog)) bb_perror_msg_and_die("listen");
}
/* Die with an error message if sendto failed.
* Return bytes sent otherwise */
ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sockaddr *to,
socklen_t tolen)
{
ssize_t ret = sendto(s, buf, len, 0, to, tolen);
if (ret < 0) {
if (ENABLE_FEATURE_CLEAN_UP)
close(s);
bb_perror_msg_and_die("sendto");
}
return ret;
}
// xstat() - a stat() which dies on failure with meaningful error message
void FAST_FUNC xstat(const char *name, struct stat *stat_buf)
{
@ -566,15 +546,6 @@ int FAST_FUNC bb_xioctl(int fd, unsigned request, void *argp)
}
#endif
char* FAST_FUNC xmalloc_ttyname(int fd)
{
char buf[128];
int r = ttyname_r(fd, buf, sizeof(buf) - 1);
if (r)
return NULL;
return xstrdup(buf);
}
#if BB_MMU
pid_t FAST_FUNC xfork(void)
{

View File

@ -951,7 +951,9 @@ static const struct built_in_command bltins1[] = {
BLTIN("trap" , builtin_trap , "Trap signals"),
BLTIN("true" , builtin_true , NULL),
BLTIN("type" , builtin_type , "Show command type"),
#ifndef __GNO__
BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"),
#endif
BLTIN("umask" , builtin_umask , "Set file creation mask"),
BLTIN("unset" , builtin_unset , "Unset variables"),
BLTIN("wait" , builtin_wait , "Wait for process"),
@ -5977,7 +5979,8 @@ static int process_command_subs(o_string *dest, const char *s)
FILE *fp;
struct in_str pipe_str;
pid_t pid;
int status, ch, eol_cnt;
wait_status_t status;
int ch, eol_cnt;
fp = generate_stream_from_string(s, &pid);
@ -6043,6 +6046,7 @@ static void setup_heredoc(struct redir_struct *redir)
/* Try writing without forking. Newer kernels have
* dynamically growing pipes. Must use non-blocking write! */
#ifndef __GNO__
ndelay_on(pair.wr);
while (1) {
written = write(pair.wr, heredoc, len);
@ -6057,6 +6061,7 @@ static void setup_heredoc(struct redir_struct *redir)
heredoc += written;
}
ndelay_off(pair.wr);
#endif
/* Okay, pipe buffer was not big enough */
/* Note: we must not create a stray child (bastard? :)
@ -6756,11 +6761,7 @@ static void delete_finished_bg_job(struct pipe *pi)
static int checkjobs(struct pipe *fg_pipe)
{
int attributes;
#ifndef __GNO__
int status;
#else
union wait status;
#endif
wait_status_t status;
#if ENABLE_HUSH_JOB
struct pipe *pi;
#endif
@ -9126,11 +9127,7 @@ static int FAST_FUNC builtin_unset(char **argv)
static int FAST_FUNC builtin_wait(char **argv)
{
int ret = EXIT_SUCCESS;
#ifndef __GNO__
int status;
#else
union wait status;
#endif
wait_status_t status;
argv = skip_dash_dash(argv);
if (argv[0] == NULL) {

View File

@ -188,6 +188,10 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
* regardless of SA_RESTART-ness of that signal!
*/
errno = 0;
#ifndef __GNO__
// GNO doesn't have poll, so disable this for now. This disables the -t
// (timeout) flag and may interfere with signal handling, as mentioned above.
// TODO Do something more intelligent here.
pfd[0].fd = fd;
pfd[0].events = POLLIN;
if (poll(pfd, 1, timeout * 1000) != 1) {
@ -196,6 +200,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
retval = (const char *)(uintptr_t)1;
goto ret;
}
#endif
if (read(fd, &buffer[bufpos], 1) != 1) {
err = errno;
retval = (const char *)(uintptr_t)1;
@ -326,7 +331,7 @@ static const struct limits limits_tbl[] = {
enum {
OPT_hard = (1 << 0),
OPT_soft = (1 << 1),
OPT_soft = (1 << 1)
};
/* "-": treat args as parameters of option with ASCII code 1 */
@ -372,6 +377,9 @@ static const char ulimit_opt_string[] = "-HSa"
#endif
;
#ifndef __GNO__
// No ulimit support in GNO -- disable this for now.
static void printlim(unsigned opts, const struct rlimit *limit,
const struct limits *l)
{
@ -498,3 +506,4 @@ shell_builtin_ulimit(char **argv)
return 0;
}
#endif /* !defined(__GNO__) */