Whoops, here is the source.

And here is how I'm compiling:

gcc -I../lib script.c -o script.exe

Hoping maybe a better command line parm list to avoid problem in
previous post.

Regards,
Perry
/*
 * Copyright (c) 1980 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * 1999-02-22 Arkadiusz Mi�kiewicz <[EMAIL PROTECTED]>
 * - added Native Language Support
 *
 * 2000-07-30 Per Andreas Buer <[EMAIL PROTECTED]> - added "q"-option
 */

/*
 * script
 */
/* PJD  */
#include <locale.h>
/* PJD  */

#include <stdio.h>
#include <stdlib.h>
#include <paths.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/signal.h>
#include "nls.h"

#ifdef __linux__
#include <unistd.h>
#include <string.h>
#endif

/* #include "../defines.h" */
#ifdef HAVE_openpty
#include <pty.h>
#endif

void finish(int);
void done(void);
void fail(void);
void resize(int);
void fixtty(void);
void getmaster(void);
void getslave(void);
void doinput(void);
void dooutput(void);
void doshell(void);

char    *shell;
FILE    *fscript;
int     master;
int     slave;
int     child;
int     subchild;
char    *fname;

struct  termios tt;
struct  winsize win;
int     lb;
int     l;
#ifndef HAVE_openpty
char    line[] = "/dev/ptyXX";
#endif
int     aflg = 0;
int     fflg = 0;
int     qflg = 0;

static char *progname;

static void
die_if_symlink(char *fn) {
        struct stat s;

        if (lstat(fn, &s) == 0 && S_ISLNK(s.st_mode)) {
                fprintf(stderr,
                        _("Warning: `%s' is a symlink.\n"
                          "Use `%s [options] %s' if you really "
                          "want to use it.\n"
                          "Script not started.\n"),
                        fn, progname, fn);
                exit(1);
        }
}

int
main(int argc, char **argv) {
        extern int optind;
        char *p;
        int ch;

        progname = argv[0];
        if ((p = strrchr(progname, '/')) != NULL)
                progname = p+1;


        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
        
        if (argc == 2) {
                if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
                        printf(_("%s from %s\n"),
                               progname, util_linux_version);
                        return 0;
                }
        }

        while ((ch = getopt(argc, argv, "afq")) != EOF)
                switch((char)ch) {
                case 'a':
                        aflg++;
                        break;
                case 'f':
                        fflg++;
                        break;
                case 'q':
                        qflg++;
                        break;
                case '?':
                default:
                        fprintf(stderr,
                                _("usage: script [-a] [-f] [-q] [file]\n"));
                        exit(1);
                }
        argc -= optind;
        argv += optind;

        if (argc > 0)
                fname = argv[0];
        else {
                fname = "typescript";
                die_if_symlink(fname);
        }
        if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) {
                perror(fname);
                fail();
        }

        shell = getenv("SHELL");
        if (shell == NULL)
                shell = _PATH_BSHELL;

        getmaster();
        if (!qflg)
                printf(_("Script started, file is %s\n"), fname);
        fixtty();

        (void) signal(SIGCHLD, finish);
        child = fork();
        if (child < 0) {
                perror("fork");
                fail();
        }
        if (child == 0) {
                subchild = child = fork();
                if (child < 0) {
                        perror("fork");
                        fail();
                }
                if (child)
                        dooutput();
                else
                        doshell();
        } else
                (void) signal(SIGWINCH, resize);
        doinput();

        return 0;
}

void
doinput() {
        register int cc;
        char ibuf[BUFSIZ];

        (void) fclose(fscript);

        while ((cc = read(0, ibuf, BUFSIZ)) > 0)
                (void) write(master, ibuf, cc);
        done();
}

#include <sys/wait.h>

void
finish(int dummy) {
        int status;
        register int pid;
        register int die = 0;

        while ((pid = wait3(&status, WNOHANG, 0)) > 0)
                if (pid == child)
                        die = 1;

        if (die)
                done();
}

void
resize(int dummy) {
        /* transmit window change information to the child */
        (void) ioctl(0, TIOCGWINSZ, (char *)&win);
        (void) ioctl(slave, TIOCSWINSZ, (char *)&win);

        kill(child, SIGWINCH);
}

void
dooutput() {
        register int cc;
        time_t tvec;
        char obuf[BUFSIZ];

        (void) close(0);
#ifdef HAVE_openpty
        (void) close(slave);
#endif
        tvec = time((time_t *)NULL);
        fprintf(fscript, _("Script started on %s"), ctime(&tvec));
        for (;;) {
                cc = read(master, obuf, sizeof (obuf));
                if (cc <= 0)
                        break;
                (void) write(1, obuf, cc);
                (void) fwrite(obuf, 1, cc, fscript);
                if (fflg)
                        (void) fflush(fscript);
        }
        done();
}

void
doshell() {
        /***
        int t;

        t = open(_PATH_TTY, O_RDWR);
        if (t >= 0) {
                (void) ioctl(t, TIOCNOTTY, (char *)0);
                (void) close(t);
        }
        ***/
        getslave();
        (void) close(master);
        (void) fclose(fscript);
        (void) dup2(slave, 0);
        (void) dup2(slave, 1);
        (void) dup2(slave, 2);
        (void) close(slave);
#ifdef __linux__
        execl(shell, strrchr(shell, '/') + 1, "-i", 0);
#else
        execl(shell, "sh", "-i", 0);
#endif
        perror(shell);
        fail();
}

void
fixtty() {
        struct termios rtt;

        rtt = tt;
        cfmakeraw(&rtt);
        rtt.c_lflag &= ~ECHO;
        (void) tcsetattr(0, TCSAFLUSH, &rtt);
}

void
fail() {

        (void) kill(0, SIGTERM);
        done();
}

void
done() {
        time_t tvec;

        if (subchild) {
                if (!qflg) {
                        tvec = time((time_t *)NULL);
                        fprintf(fscript, _("\nScript done on %s"),
                                ctime(&tvec));
                }
                (void) fclose(fscript);
                (void) close(master);
        } else {
                (void) tcsetattr(0, TCSAFLUSH, &tt);
                if (!qflg)
                        printf(_("Script done, file is %s\n"), fname);
        }
        exit(0);
}

void
getmaster() {
#ifdef HAVE_openpty
        (void) tcgetattr(0, &tt);
        (void) ioctl(0, TIOCGWINSZ, (char *)&win);
        if (openpty(&master, &slave, NULL, &tt, &win) < 0) {
                fprintf(stderr, _("openpty failed\n"));
                fail();
        }
#else
        char *pty, *bank, *cp;
        struct stat stb;

        pty = &line[strlen("/dev/ptyp")];
        for (bank = "pqrs"; *bank; bank++) {
                line[strlen("/dev/pty")] = *bank;
                *pty = '0';
                if (stat(line, &stb) < 0)
                        break;
                for (cp = "0123456789abcdef"; *cp; cp++) {
                        *pty = *cp;
                        master = open(line, O_RDWR);
                        if (master >= 0) {
                                char *tp = &line[strlen("/dev/")];
                                int ok;

                                /* verify slave side is usable */
                                *tp = 't';
                                ok = access(line, R_OK|W_OK) == 0;
                                *tp = 'p';
                                if (ok) {
                                        (void) tcgetattr(0, &tt);
                                        (void) ioctl(0, TIOCGWINSZ, 
                                                (char *)&win);
                                        return;
                                }
                                (void) close(master);
                        }
                }
        }
        fprintf(stderr, _("Out of pty's\n"));
        fail();
#endif /* not HAVE_openpty */
}

void
getslave() {
#ifndef HAVE_openpty
        line[strlen("/dev/")] = 't';
        slave = open(line, O_RDWR);
        if (slave < 0) {
                perror(line);
                fail();
        }
        (void) tcsetattr(slave, TCSAFLUSH, &tt);
        (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
#endif
        (void) setsid();
/* PJD  (void) ioctl(slave, TIOCSCTTY, 0); */
        (void) ioctl(slave, O_NOCTTY, 0);
}

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to