~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to io.c

  • Committer: Arnold D. Robbins
  • Date: 2010-07-16 09:54:45 UTC
  • Revision ID: git-v1:f20ab7c3039a4023f41372bfe4bde3b16d481df7
Tags: gawk-3.0.4
Move to gawk-3.0.4.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 */
4
4
 
5
5
/* 
6
 
 * Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
 
6
 * Copyright (C) 1976, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
7
7
 * 
8
8
 * This file is part of GAWK, the GNU implementation of the
9
9
 * AWK Programming Language.
49
49
#define O_ACCMODE       (O_RDONLY|O_WRONLY|O_RDWR)
50
50
#endif
51
51
 
52
 
#include <assert.h>
53
 
 
54
52
#if ! defined(S_ISREG) && defined(S_IFREG)
55
53
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
56
54
#endif
95
93
static int pidopen P((IOBUF *iop, const char *name, const char *mode));
96
94
static int useropen P((IOBUF *iop, const char *name, const char *mode));
97
95
 
98
 
#if defined (MSDOS) && !defined (__GO32__)
 
96
#if defined (HAVE_POPEN_H)
99
97
#include "popen.h"
100
 
#define popen(c, m)     os_popen(c, m)
101
 
#define pclose(f)       os_pclose(f)
102
 
#else
103
 
#if defined (OS2)       /* OS/2, but not family mode */
104
 
#if defined (_MSC_VER)
105
 
#define popen(c, m)     _popen(c, m)
106
 
#define pclose(f)       _pclose(f)
107
 
#endif
108
 
#else
109
 
extern FILE     *popen();
110
 
#endif
111
98
#endif
112
99
 
113
100
static struct redirect *red_head = NULL;
125
112
 
126
113
static jmp_buf filebuf;         /* for do_nextfile() */
127
114
 
 
115
#ifdef VMS
 
116
/* File pointers have an extra level of indirection, and there are cases where
 
117
   `stdin' can be null.  That can crash gawk if fileno() is used as-is.  */
 
118
static int vmsrtl_fileno P((FILE *));
 
119
static int vmsrtl_fileno(fp) FILE *fp; { return fileno(fp); }
 
120
#undef fileno
 
121
#define fileno(FP) (((FP) && *(FP)) ? vmsrtl_fileno(FP) : -1)
 
122
#endif  /* VMS */
 
123
 
128
124
/* do_nextfile --- implement gawk "nextfile" extension */
129
125
 
130
126
void
487
483
                        /* too many files open -- close one and try again */
488
484
                        if (errno == EMFILE || errno == ENFILE)
489
485
                                close_one();
490
 
#ifdef HAVE_MMAP
 
486
#if defined __MINGW32__ || defined HAVE_MMAP
491
487
                        /* this works for solaris 2.5, not sunos */
492
 
                        else if (errno == 0)    /* HACK! */
 
488
                        /* it is also needed for MINGW32 */
 
489
                        else if (errno == 0)    /* HACK! */
493
490
                                close_one();
494
491
#endif
495
492
                        else {
573
570
 
574
571
        tmp = force_string(tree_eval(tree->subnode));
575
572
 
576
 
        /* icky special case: close(FILENAME) called. */
577
 
        if (tree->subnode == FILENAME_node
578
 
            || (tmp->stlen == FILENAME_node->var_value->stlen
579
 
                && STREQN(tmp->stptr, FILENAME_node->var_value->stptr, tmp->stlen))) {
580
 
                (void) nextfile(TRUE);
581
 
                free_temp(tmp);
582
 
                return tmp_number((AWKNUM) 0.0);
583
 
        }
584
 
 
585
573
        for (rp = red_head; rp != NULL; rp = rp->next) {
586
574
                if (strlen(rp->value) == tmp->stlen
587
575
                    && STREQN(rp->value, tmp->stptr, tmp->stlen))
588
576
                        break;
589
577
        }
 
578
 
590
579
        if (rp == NULL) {       /* no match */
591
 
                if (do_lint)
 
580
                /* icky special case: close(FILENAME) called. */
 
581
                if (tree->subnode == FILENAME_node
 
582
                    || (tmp->stlen == FILENAME_node->var_value->stlen
 
583
                        && STREQN(tmp->stptr, FILENAME_node->var_value->stptr, tmp->stlen))) {
 
584
                        (void) nextfile(TRUE);
 
585
                } else if (do_lint)
592
586
                        warning("close: `%.*s' is not an open file or pipe",
593
587
                                tmp->stlen, tmp->stptr);
 
588
 
594
589
                free_temp(tmp);
595
590
                return tmp_number((AWKNUM) 0.0);
596
591
        }
888
883
        int i;
889
884
 
890
885
        if (name[6] == 'g')
891
 
                sprintf(tbuf, "%d\n", getpgrp(getpgrp_arg()));
 
886
                sprintf(tbuf, "%d\n", (int) getpgrp(getpgrp_arg()));
892
887
        else if (name[6] == 'i')
893
 
                sprintf(tbuf, "%d\n", getpid());
 
888
                sprintf(tbuf, "%d\n", (int) getpid());
894
889
        else
895
 
                sprintf(tbuf, "%d\n", getppid());
 
890
                sprintf(tbuf, "%d\n", (int) getppid());
896
891
        i = strlen(tbuf);
897
892
        spec_setup(iop, i, TRUE);
898
893
        strcpy(iop->buf, tbuf);
923
918
        int ngroups;
924
919
#endif
925
920
 
926
 
        sprintf(tbuf, "%d %d %d %d", getuid(), geteuid(), getgid(), getegid());
 
921
        sprintf(tbuf, "%d %d %d %d", (int) getuid(), (int) geteuid(), (int) getgid(), (int) getegid());
927
922
 
928
923
        cp = tbuf + strlen(tbuf);
929
924
#if defined(NGROUPS_MAX) && NGROUPS_MAX > 0
1008
1003
        if (openfd == INVALID_HANDLE)
1009
1004
                openfd = open(name, flag, 0666);
1010
1005
        if (openfd != INVALID_HANDLE && fstat(openfd, &buf) > 0) 
1011
 
                if ((buf.st_mode & S_IFMT) == S_IFDIR)
 
1006
                if (S_ISDIR(buf.st_mode))
1012
1007
                        fatal("file `%s' is a directory", name);
1013
1008
        return iop_alloc(openfd, name, iop);
1014
1009
}
1120
1115
 * except if popen() provides real pipes too
1121
1116
 */
1122
1117
 
1123
 
#if defined(VMS) || defined(OS2) || defined (MSDOS)
 
1118
#if defined(VMS) || defined(OS2) || defined (MSDOS) || defined(WIN32)
1124
1119
 
1125
1120
/* gawk_popen --- open an IOBUF on a child process */
1126
1121
 
1135
1130
                return NULL;
1136
1131
        rp->iop = iop_alloc(fileno(current), cmd, NULL);
1137
1132
        if (rp->iop == NULL) {
1138
 
                (void) fclose(current);
 
1133
                (void) pclose(current);
1139
1134
                current = NULL;
1140
1135
        }
1141
1136
        rp->ifp = current;
1434
1429
        iop->name = name;
1435
1430
        iop->getrec = get_a_record;
1436
1431
#ifdef HAVE_MMAP
1437
 
        if (S_ISREG(sbuf.st_mode) && sbuf.st_size > 0) {
 
1432
        /* Use mmap only for regular files with positive sizes.
 
1433
           The size must fit into size_t, so that mmap works correctly.
 
1434
           Also, it must fit into int, so that iop->cnt won't overflow.  */
 
1435
        if (S_ISREG(sbuf.st_mode) && sbuf.st_size > 0
 
1436
            && sbuf.st_size == (size_t) sbuf.st_size
 
1437
            && sbuf.st_size == (int) sbuf.st_size) {
1438
1438
                register char *cp;
1439
1439
 
1440
1440
                iop->buf = iop->off = mmap((caddr_t) 0, sbuf.st_size,
1535
1535
                return EOF;
1536
1536
        }
1537
1537
 
1538
 
        if (grRS == FALSE)      /* special case:  RS == "" */
 
1538
        if (RS_is_null) /* special case:  RS == "" */
1539
1539
                rs = '\n';
1540
1540
        else
1541
1541
                rs = (char) grRS;
1648
1648
                 */
1649
1649
                if (! do_traditional && RSre != NULL)   /* regexp */
1650
1650
                        rsre = RSre;
1651
 
                else if (grRS == FALSE)         /* RS = "" */
 
1651
                else if (RS_is_null)            /* RS = "" */
1652
1652
                        rsre = RS_null_re;
1653
1653
                else
1654
1654
                        rsre = NULL;
1675
1675
                        /* cases 1 and 2 are simple, just keep going */
1676
1676
                        if (research(rsre, start, 0, iop->end - start, TRUE) == -1
1677
1677
                            || RESTART(rsre, start) == REEND(rsre, start)) {
 
1678
                                /*
 
1679
                                 * Leading newlines at the beginning of the file
 
1680
                                 * should be ignored. Whew!
 
1681
                                 */
 
1682
                                if (RS_is_null && *start == '\n') {
 
1683
                                        /*
 
1684
                                         * have to catch the case of a
 
1685
                                         * single newline at the front of
 
1686
                                         * the record, which the regex
 
1687
                                         * doesn't. gurr.
 
1688
                                         */
 
1689
                                        while (*start == '\n' && start < iop->end)
 
1690
                                                start++;
 
1691
                                        goto again;
 
1692
                                }
1678
1693
                                bp = iop->end;
1679
1694
                                continue;
1680
1695
                        }
1690
1705
                        /*
1691
1706
                         * Leading newlines at the beginning of the file
1692
1707
                         * should be ignored. Whew!
 
1708
                         *
 
1709
                         * Is this code ever executed?
1693
1710
                         */
1694
 
                        if (grRS == FALSE && RESTART(rsre, start) == 0) {
 
1711
                        if (RS_is_null && RESTART(rsre, start) == 0) {
1695
1712
                                start += REEND(rsre, start);
1696
1713
                                goto again;
1697
1714
                        }
1737
1754
                        bstart = bp;
1738
1755
                }
1739
1756
                *bp = '\0';
1740
 
        } else if (grRS == FALSE && iop->cnt == EOF) {
 
1757
        } else if (RS_is_null && iop->cnt == EOF) {
1741
1758
                /*
1742
1759
                 * special case, delete trailing newlines,
1743
1760
                 * should never be more than one.
1811
1828
                return EOF;
1812
1829
        }
1813
1830
 
1814
 
        if (grRS == FALSE)      /* special case:  RS == "" */
 
1831
        if (RS_is_null) /* special case:  RS == "" */
1815
1832
                rs = '\n';
1816
1833
        else
1817
1834
                rs = (char) grRS;
1821
1838
                rs = casetable[rs];
1822
1839
 
1823
1840
        /* if RS = "", skip leading newlines at the front of the file */
1824
 
        if (grRS == FALSE && iop->off == iop->buf) {
 
1841
        if (RS_is_null && iop->off == iop->buf) {
1825
1842
                for (bp = iop->off; *bp == '\n'; bp++)
1826
1843
                        continue;
1827
1844
 
1835
1852
         */
1836
1853
        if (! do_traditional && RSre != NULL)   /* regexp */
1837
1854
                rsre = RSre;
1838
 
        else if (grRS == FALSE)         /* RS = "" */
 
1855
        else if (RS_is_null)            /* RS = "" */
1839
1856
                rsre = RS_null_re;
1840
1857
        else
1841
1858
                rsre = NULL;
1862
1879
                        iop->off = iop->end;    /* all done with the record */
1863
1880
                        set_RT_to_null();
1864
1881
                        /* special case, don't allow trailing newlines */
1865
 
                        if (grRS == FALSE && *(iop->end - 1) == '\n')
 
1882
                        if (RS_is_null && *(iop->end - 1) == '\n')
1866
1883
                                return iop->end - start - 1;
1867
1884
                        else
1868
1885
                                return iop->end - start;