openbmc/build/tmp/deploy/sdk/witherspoon-2019-08-08/sysroots/armv6-openbmc-linux-gnueabi/usr/src/debug/util-linux/2.33.2-r0/util-linux-2.33.2/term-utils/ttymsg.c
char* ttymsg(struct iovec* iov, size_t iovcnt, char* line, int tmout)
{
    static char device[MAXNAMLEN];
    static char errbuf[ERR_BUFLEN];
    size_t cnt, left;
    ssize_t wret;
    struct iovec localiov[6];
    int fd, forked = 0;
    ssize_t len = 0;

    if (iovcnt > ARRAY_SIZE(localiov))
    {
        snprintf(errbuf, sizeof(errbuf), _("internal error: too many iov's"));
        return errbuf;
    }

    /* The old code here rejected the line argument when it contained a '/',
       saying: "A slash may be an attempt to break security...".
       However, if a user can control the line argument here
       then he can make this routine write to /dev/hda or /dev/sda
       already. So, this test was worthless, and these days it is
       also wrong since people use /dev/pts/xxx. */

    len = snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line);
    if (len < 0 || (size_t)len >= sizeof(device))
    {
        snprintf(errbuf, sizeof(errbuf), _("excessively long line arg"));
        return errbuf;
    }

    /*
     * open will fail on slip lines or exclusive-use lines
     * if not running as root; not an error.
     */
    if ((fd = open(device, O_WRONLY | O_NONBLOCK, 0)) < 0)
    {
        if (errno == EBUSY || errno == EACCES)
            return NULL;

        len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
        if (len < 0 || (size_t)len >= sizeof(errbuf))
            snprintf(errbuf, sizeof(errbuf), _("open failed"));
        return errbuf;
    }

    for (cnt = left = 0; cnt < iovcnt; ++cnt)
        left += iov[cnt].iov_len;

    for (;;)
    {
        wret = writev(fd, iov, iovcnt);
        if (wret >= (ssize_t)left)
            break;
        if (wret >= 0)
        {
            left -= wret;
            if (iov != localiov)
            {
                memmove(localiov, iov, iovcnt * sizeof(struct iovec));
                iov = localiov;
            }
            for (cnt = 0; wret >= (ssize_t)iov->iov_len; ++cnt)
            {
                wret -= iov->iov_len;
                ++iov;
                --iovcnt;
            }
            if (wret)
            {
                iov->iov_base = (char*)iov->iov_base + wret;
                iov->iov_len -= wret;
            }
            continue;
        }
        if (errno == EWOULDBLOCK)
        {
            int cpid, flags;
            sigset_t sigmask;

            if (forked)
            {
                close(fd);
                _exit(EXIT_FAILURE);
            }
            cpid = fork();
            if (cpid < 0)
            {
                len = snprintf(errbuf, sizeof(errbuf), _("fork: %m"));
                if (len < 0 || (size_t)len >= sizeof(errbuf))
                    snprintf(errbuf, sizeof(errbuf), _("cannot fork"));
                close(fd);
                return errbuf;
            }
            if (cpid)
            { /* parent */
                close(fd);
                return NULL;
            }
            forked++;
            /* wait at most tmout seconds */
            signal(SIGALRM, SIG_DFL);
            signal(SIGTERM, SIG_DFL); /* XXX */
            sigemptyset(&sigmask);
            sigprocmask(SIG_SETMASK, &sigmask, NULL);
            alarm((u_int)tmout);
            flags = fcntl(fd, F_GETFL);
            fcntl(flags, F_SETFL, (long)(flags & ~O_NONBLOCK));
            continue;
        }
        /*
         * We get ENODEV on a slip line if we're running as root,
         * and EIO if the line just went away.
         */
        if (errno == ENODEV || errno == EIO)
            break;
        if (close_fd(fd) != 0)
            warn(_("write failed: %s"), device);
        if (forked)
            _exit(EXIT_FAILURE);

        len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
        if (len < 0 || (size_t)len >= sizeof(errbuf))
            snprintf(errbuf, sizeof(errbuf),
                     _("%s: BAD ERROR, message is "
                       "far too long"),
                     device);
        return errbuf;
    }

    if (forked)
        _exit(EXIT_SUCCESS);
    return NULL;
}
/*
 * Display the contents of a uio structure on a terminal.  Used by wall(1),
 * syslogd(8), and talkd(8).  Forks and finishes in child if write would block,
 * waiting up to tmout seconds.  Returns pointer to error string on unexpected
 * error; string is not newline-terminated.  Various "normal" errors are
 * ignored (exclusive-use, lack of permission, etc.).
 */
Display the contents of a uio structure on a terminal.
Display the contents of a uio structure on a terminal .
char* ttymsg(struct iovec* iov, size_t iovcnt, char* line, int tmout)
{
    static char device[MAXNAMLEN];
    static char errbuf[ERR_BUFLEN];
    size_t cnt, left;
    ssize_t wret;
    struct iovec localiov[6];
    int fd, forked = 0;
    ssize_t len = 0;
    if (iovcnt > ARRAY_SIZE(localiov))
    {
        snprintf(errbuf, sizeof(errbuf), _("internal error: too many iov's"));
        return errbuf;
    }
    len = snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line);
    if (len < 0 || (size_t)len >= sizeof(device))
    {
        snprintf(errbuf, sizeof(errbuf), _("excessively long line arg"));
        return errbuf;
    }
    if ((fd = open(device, O_WRONLY | O_NONBLOCK, 0)) < 0)
    {
        if (errno == EBUSY || errno == EACCES)
            return NULL;
        len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
        if (len < 0 || (size_t)len >= sizeof(errbuf))
            snprintf(errbuf, sizeof(errbuf), _("open failed"));
        return errbuf;
    }
    for (cnt = left = 0; cnt < iovcnt; ++cnt)
        left += iov[cnt].iov_len;
    for (;;)
    {
        wret = writev(fd, iov, iovcnt);
        if (wret >= (ssize_t)left)
            break;
        if (wret >= 0)
        {
            left -= wret;
            if (iov != localiov)
            {
                memmove(localiov, iov, iovcnt * sizeof(struct iovec));
                iov = localiov;
            }
            for (cnt = 0; wret >= (ssize_t)iov->iov_len; ++cnt)
            {
                wret -= iov->iov_len;
                ++iov;
                --iovcnt;
            }
            if (wret)
            {
                iov->iov_base = (char*)iov->iov_base + wret;
                iov->iov_len -= wret;
            }
            continue;
        }
        if (errno == EWOULDBLOCK)
        {
            int cpid, flags;
            sigset_t sigmask;
            if (forked)
            {
                close(fd);
                _exit(EXIT_FAILURE);
            }
            cpid = fork();
            if (cpid < 0)
            {
                len = snprintf(errbuf, sizeof(errbuf), _("fork: %m"));
                if (len < 0 || (size_t)len >= sizeof(errbuf))
                    snprintf(errbuf, sizeof(errbuf), _("cannot fork"));
                close(fd);
                return errbuf;
            }
            if (cpid)
            { 
                close(fd);
                return NULL;
            }
            forked++;
            signal(SIGALRM, SIG_DFL);
            signal(SIGTERM, SIG_DFL); 
            sigemptyset(&sigmask);
            sigprocmask(SIG_SETMASK, &sigmask, NULL);
            alarm((u_int)tmout);
            flags = fcntl(fd, F_GETFL);
            fcntl(flags, F_SETFL, (long)(flags & ~O_NONBLOCK));
            continue;
        }
        if (errno == ENODEV || errno == EIO)
            break;
        if (close_fd(fd) != 0)
            warn(_("write failed: %s"), device);
        if (forked)
            _exit(EXIT_FAILURE);
        len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
        if (len < 0 || (size_t)len >= sizeof(errbuf))
            snprintf(errbuf, sizeof(errbuf),
                     _("%s: BAD ERROR, message is "
                       "far too long"),
                     device);
        return errbuf;
    }
    if (forked)
        _exit(EXIT_SUCCESS);
    return NULL;
}
char * ttymsg ( struct iovec * iov , size_t iovcnt , char * line , int tmout ) { static char device [ MAXNAMLEN ] ; static char errbuf [ ERR_BUFLEN ] ; size_t cnt , left ; ssize_t wret ; struct iovec localiov [ 6 ] ; int fd , forked = 0 ; ssize_t len = 0 ; if ( iovcnt > ARRAY_SIZE ( localiov ) ) { snprintf ( errbuf , sizeof ( errbuf ) , _ ( " " ) ) ; return errbuf ; } len = snprintf ( device , sizeof ( device ) , " " , _PATH_DEV , line ) ; if ( len < 0 || ( size_t ) len >= sizeof ( device ) ) { snprintf ( errbuf , sizeof ( errbuf ) , _ ( " " ) ) ; return errbuf ; } if ( ( fd = open ( device , O_WRONLY | O_NONBLOCK , 0 ) ) < 0 ) { if ( errno == EBUSY || errno == EACCES ) return NULL ; len = snprintf ( errbuf , sizeof ( errbuf ) , " " , device ) ; if ( len < 0 || ( size_t ) len >= sizeof ( errbuf ) ) snprintf ( errbuf , sizeof ( errbuf ) , _ ( " " ) ) ; return errbuf ; } for ( cnt = left = 0 ; cnt < iovcnt ; ++ cnt ) left += iov [ cnt ] . iov_len ; for ( ; ; ) { wret = writev ( fd , iov , iovcnt ) ; if ( wret >= ( ssize_t ) left ) break ; if ( wret >= 0 ) { left -= wret ; if ( iov != localiov ) { memmove ( localiov , iov , iovcnt * sizeof ( struct iovec ) ) ; iov = localiov ; } for ( cnt = 0 ; wret >= ( ssize_t ) iov -> iov_len ; ++ cnt ) { wret -= iov -> iov_len ; ++ iov ; -- iovcnt ; } if ( wret ) { iov -> iov_base = ( char * ) iov -> iov_base + wret ; iov -> iov_len -= wret ; } continue ; } if ( errno == EWOULDBLOCK ) { int cpid , flags ; sigset_t sigmask ; if ( forked ) { close ( fd ) ; _exit ( EXIT_FAILURE ) ; } cpid = fork ( ) ; if ( cpid < 0 ) { len = snprintf ( errbuf , sizeof ( errbuf ) , _ ( " " ) ) ; if ( len < 0 || ( size_t ) len >= sizeof ( errbuf ) ) snprintf ( errbuf , sizeof ( errbuf ) , _ ( " " ) ) ; close ( fd ) ; return errbuf ; } if ( cpid ) { close ( fd ) ; return NULL ; } forked ++ ; signal ( SIGALRM , SIG_DFL ) ; signal ( SIGTERM , SIG_DFL ) ; sigemptyset ( & sigmask ) ; sigprocmask ( SIG_SETMASK , & sigmask , NULL ) ; alarm ( ( u_int ) tmout ) ; flags = fcntl ( fd , F_GETFL ) ; fcntl ( flags , F_SETFL , ( long ) ( flags & ~ O_NONBLOCK ) ) ; continue ; } if ( errno == ENODEV || errno == EIO ) break ; if ( close_fd ( fd ) != 0 ) warn ( _ ( " " ) , device ) ; if ( forked ) _exit ( EXIT_FAILURE ) ; len = snprintf ( errbuf , sizeof ( errbuf ) , " " , device ) ; if ( len < 0 || ( size_t ) len >= sizeof ( errbuf ) ) snprintf ( errbuf , sizeof ( errbuf ) , _ ( " " " " ) , device ) ; return errbuf ; } if ( forked ) _exit ( EXIT_SUCCESS ) ; return NULL ; }
Display the contents of a uio structure on a terminal.
Display the contents of a uio structure on a terminal .
/* The old code here rejected the line argument when it contained a '/',
       saying: "A slash may be an attempt to break security...".
       However, if a user can control the line argument here
       then he can make this routine write to /dev/hda or /dev/sda
       already. So, this test was worthless, and these days it is
       also wrong since people use /dev/pts/xxx. */ /*
     * open will fail on slip lines or exclusive-use lines
     * if not running as root; not an error.
     */ /* parent */ /* wait at most tmout seconds */ /* XXX */ /*
         * We get ENODEV on a slip line if we're running as root,
         * and EIO if the line just went away.
         */