VirtualBox

Changeset 1292 in kBuild


Ignore:
Timestamp:
Dec 1, 2007 3:30:16 AM (17 years ago)
Author:
bird
Message:

Added kmk_builtin_test and kmk_test - a slightly modified version of /bin/test.

Location:
trunk/src/kmk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.kmk

    r1263 r1292  
    175175        kmkbuiltin/rm.c \
    176176        kmkbuiltin/rmdir.c \
     177        kmkbuiltin/test.c \
    177178
    178179## Some profiling
     
    199200        kmk_rm \
    200201        kmk_rmdir \
     202        kmk_test \
    201203        kDepIDB \
    202204
     
    268270kmk_rmdir_SOURCES = \
    269271        kmkbuiltin/rmdir.c
     272
     273kmk_test_TEMPLATE = BIN-KMK
     274kmk_test_DEFS = kmk_builtin_test=main
     275kmk_test_SOURCES = \
     276        kmkbuiltin/test.c
    270277
    271278kDepIDB_TEMPLATE = BIN-KMK
  • trunk/src/kmk/kmkbuiltin.c

    r1290 r1292  
    205205    else if (!strcmp(pszCmd, "rmdir"))
    206206        rc = kmk_builtin_rmdir(argc, argv, environ);
    207     /*else if (!strcmp(pszCmd, "test"))
    208         rc = kmk_builtin_test(argc, argv, environ, ppapszArgvToSpawn);*/
     207    else if (!strcmp(pszCmd, "test"))
     208        rc = kmk_builtin_test(argc, argv, environ, ppapszArgvToSpawn);
    209209    /* rarely used commands: */
    210210    else if (!strcmp(pszCmd, "cp"))
  • trunk/src/kmk/kmkbuiltin.h

    r1290 r1292  
    4949extern int kmk_builtin_rm(int argc, char **argv, char **envp);
    5050extern int kmk_builtin_rmdir(int argc, char **argv, char **envp);
     51extern int kmk_builtin_test(int argc, char **argv, char **envp, char ***ppapszArgvSpawn);
    5152extern int kmk_builtin_kDepIDB(int argc, char **argv, char **envp);
    5253
  • trunk/src/kmk/kmkbuiltin/mscfakes.h

    r1117 r1292  
    110110#define fchmod(fd, mode) 0              /** @todo implement fchmod! */
    111111#define geteuid()  0
     112#define getegid()  0
    112113#define lstat(path, s) stat(path, s)
    113114#define lchmod(path, mod) chmod(path, mod)
  • trunk/src/kmk/kmkbuiltin/test.c

    r1291 r1292  
    1111 */
    1212
    13 #include <sys/cdefs.h>
     13/*#include <sys/cdefs.h>
    1414#ifndef lint
    1515__RCSID("$NetBSD: test.c,v 1.33 2007/06/24 18:54:58 christos Exp $");
    16 #endif
     16#endif*/
    1717
    1818#include <sys/stat.h>
     
    2020
    2121#include <ctype.h>
    22 #include <err.h>
     22#include "err.h"
    2323#include <errno.h>
    2424#include <limits.h>
     
    2626#include <stdlib.h>
    2727#include <string.h>
    28 #include <unistd.h>
     28#ifdef _MSC_VER
     29# include <direct.h>
     30# include <io.h>
     31# include <process.h>
     32# include "mscfakes.h"
     33#else
     34# include <unistd.h>
     35#endif
    2936#include <stdarg.h>
     37#include <sys/stat.h>
     38
     39#include "kmkbuiltin.h"
     40
     41#ifndef __arraycount
     42# define __arraycount(a)        ( sizeof(a) / sizeof(a[0]) )
     43#endif
     44
    3045
    3146/* test(1) accepts the following grammar:
     
    156171static struct t_op const *t_wp_op;
    157172
    158 static void syntax(const char *, const char *);
     173static int syntax(const char *, const char *);
    159174static int oexpr(enum token);
    160175static int aexpr(enum token);
     
    170185static int olderf(const char *, const char *);
    171186static int equalf(const char *, const char *);
    172 
    173 #if defined(SHELL)
    174 extern void error(const char *, ...) __attribute__((__noreturn__));
    175 extern void *ckmalloc(size_t);
    176 #else
    177 static void error(const char *, ...) __attribute__((__noreturn__));
    178 
    179 static void
    180 error(const char *msg, ...)
    181 {
    182         va_list ap;
    183 
    184         va_start(ap, msg);
    185         verrx(2, msg, ap);
    186         /*NOTREACHED*/
    187         va_end(ap);
    188 }
    189 
    190 static void *ckmalloc(size_t);
    191 static void *
    192 ckmalloc(size_t nbytes)
    193 {
    194         void *p = malloc(nbytes);
    195 
    196         if (!p)
    197                 error("Not enough memory!");
    198         return p;
    199 }
    200 #endif
    201 
    202 #ifdef SHELL
    203 int testcmd(int, char **);
    204 
    205 int
    206 testcmd(int argc, char **argv)
    207 #else
    208 int main(int, char *[]);
    209 
    210 int
    211 main(int argc, char *argv[])
     187static int usage(const char *);
     188
     189#ifdef kmk_builtin_test
     190extern void *xmalloc(unsigned int);
     191#else
     192static void *xmalloc(unsigned int sz)
     193{
     194    void *p = malloc(sz);
     195    if (!p) {
     196            fprintf(stderr, "%s: malloc(%u) failed\n", g_progname, sz);
     197            exit(1);
     198    }
     199    return p;
     200}
     201#endif
     202
     203#ifdef kmk_builtin_test
     204int kmk_builtin_test(int argc, char **argv)
     205#else
     206int kmk_builtin_test(int argc, char **argv, char **envp, char ***ppapszArgvSpawn)
    212207#endif
    213208{
    214209        int res;
    215         const char *argv0;
    216 
    217 #ifdef SHELL
    218         argv0 = argv[0];
    219 #else
    220         setprogname(argv[0]);
    221         argv0 = getprogname();
    222 #endif
    223         if (strcmp(argv0, "[") == 0) {
     210        char **argv_spawn;
     211        int i;
     212
     213        g_progname = argv[0];
     214
     215        /* look for the '--', '--help' and '--version'. */
     216        argv_spawn = NULL;
     217        for (i = 1; i < argc; i++) {
     218                if (   argv[i][0] == '-'
     219                    && argv[i][1] == '-') {
     220                        if (argv[i][2] == '\0') {
     221                                argc = i;
     222                                argv[i] = NULL;
     223                                argv_spawn = &argv[i + 1];
     224                                break;
     225                        }
     226                        if (!strcmp(argv[i], "--help"))
     227                                return usage(argv[0]);
     228                        if (!strcmp(argv[i], "--version"))
     229                                return kbuild_version(argv[0]);
     230                }
     231        }
     232
     233        /* are we '['? then check for ']'. */
     234        if (strcmp(g_progname, "[") == 0) { /** @todo should skip the path in g_progname */
    224235                if (strcmp(argv[--argc], "]"))
    225                         error("missing ]");
     236                        return errx(1, "missing ]");
    226237                argv[argc] = NULL;
    227238        }
    228239
     240        /* evaluate the expression */
    229241        if (argc < 2)
    230                 return 1;
    231 
    232         t_wp = &argv[1];
    233         res = !oexpr(t_lex(*t_wp));
    234 
    235         if (*t_wp != NULL && *++t_wp != NULL)
    236                 syntax(*t_wp, "unexpected operator");
     242                res = 1;
     243        else {
     244                t_wp = &argv[1];
     245                res = oexpr(t_lex(*t_wp));
     246                if (res != -42 && *t_wp != NULL && *++t_wp != NULL)
     247                        res = syntax(*t_wp, "unexpected operator");
     248                if (res == -42)
     249                        return 1; /* don't mix syntax errors with the argv_spawn ignore */
     250                res = !res;
     251        }
     252
     253        /* anything to execute on success? */
     254        if (argv_spawn) {
     255                if (res != 0 || !argv_spawn[0])
     256                        res = 0; /* ignored */
     257                else {
     258#ifdef kmk_builtin_test
     259                        /* try exec the specified process */
     260# if defined(_MSC_VER)
     261                        res = _spawnvp(_P_WAIT, argv_spawn[0], argv_spawn);
     262                        if (res == -1)
     263                            res = err(1, "_spawnvp(_P_WAIT,%s,..)", argv_spawn[i]);
     264# else
     265                        execvp(argv_spawn[i], &argv_spawn[i]);
     266                        res = err(1, "execvp(%s,..)", argv_spawn[i]);
     267# endif
     268#else /* in kmk */
     269                        /* let job.c spawn the process, make a job.c style argv_spawn copy. */
     270                        char *buf, *cur, **argv_new;
     271                        size_t sz = 0;
     272                        int argc_new = 0;
     273                        while (argv_spawn[argc_new]) {
     274                                size_t len = strlen(argv_spawn[argc_new]) + 1;
     275                                sz += (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
     276                                argc_new++;
     277                        }
     278
     279                        argv_new = xmalloc((argc_new + 1) * sizeof(char *));
     280                        buf = cur = xmalloc(argc_new * sizeof(char *));
     281                        for (i = 0; i < argc_new; i++) {
     282                                size_t len = strlen(argv_spawn[i]) + 1;
     283                                argv_new[i] = memcpy(cur, argv_spawn[i], len);
     284                                cur += (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
     285                        }
     286                        argv_new[i] = NULL;
     287
     288                        *ppapszArgvSpawn = argv_new;
     289                        res = 0;
     290#endif /* in kmk */
     291                }
     292        }
    237293
    238294        return res;
    239295}
    240296
    241 static void
     297static int
    242298syntax(const char *op, const char *msg)
    243299{
    244300
    245301        if (op && *op)
    246                 error("%s: %s", op, msg);
     302                errx(1, "%s: %s", op, msg);
    247303        else
    248                 error("%s", msg);
     304                errx(1, "%s", msg);
     305        return -42;
    249306}
    250307
     
    255312
    256313        res = aexpr(n);
    257         if (*t_wp == NULL)
     314        if (res == -42 || *t_wp == NULL)
    258315                return res;
    259         if (t_lex(*++t_wp) == BOR)
    260                 return oexpr(t_lex(*++t_wp)) || res;
     316        if (t_lex(*++t_wp) == BOR) {
     317                int res2 = oexpr(t_lex(*++t_wp));
     318                return res2 != -42 ? res2 || res : res2;
     319        }
    261320        t_wp--;
    262321        return res;
     
    269328
    270329        res = nexpr(n);
    271         if (*t_wp == NULL)
     330        if (res == -42 || *t_wp == NULL)
    272331                return res;
    273         if (t_lex(*++t_wp) == BAND)
    274                 return aexpr(t_lex(*++t_wp)) && res;
     332        if (t_lex(*++t_wp) == BAND) {
     333                int res2 = aexpr(t_lex(*++t_wp));
     334                return res2 != -42 ? res2 && res : res2;
     335        }
    275336        t_wp--;
    276337        return res;
     
    280341nexpr(enum token n)
    281342{
    282 
    283         if (n == UNOT)
    284                 return !nexpr(t_lex(*++t_wp));
     343        if (n == UNOT) {
     344                int res = nexpr(t_lex(*++t_wp));
     345                return res != -42 ? !res : res;
     346        }
    285347        return primary(n);
    286348}
     
    298360                        return 0;       /* missing expression */
    299361                res = oexpr(nn);
    300                 if (t_lex(*++t_wp) != RPAREN)
    301                         syntax(NULL, "closing paren expected");
     362                if (res != -42 && t_lex(*++t_wp) != RPAREN)
     363                        return syntax(NULL, "closing paren expected");
    302364                return res;
    303365        }
     
    305367                /* unary expression */
    306368                if (*++t_wp == NULL)
    307                         syntax(t_wp_op->op_text, "argument expected");
     369                        return syntax(t_wp_op->op_text, "argument expected");
    308370                switch (n) {
    309371                case STREZ:
     
    320382        if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) {
    321383                return binop();
    322         }         
     384        }
    323385
    324386        return strlen(*t_wp) > 0;
     
    336398
    337399        if ((opnd2 = *++t_wp) == NULL)
    338                 syntax(op->op_text, "argument expected");
    339                
     400                return syntax(op->op_text, "argument expected");
     401
    340402        switch (op->op_num) {
    341403        case STREQ:
     
    368430                abort();
    369431                /* NOTREACHED */
     432#ifdef _MSC_VER
     433                return -42;
     434#endif
    370435        }
    371436}
     
    449514 * can never fail for root for any existing files, i.e. files for which 'test
    450515 * -e' succeeds.)
    451  * 
     516 *
    452517 * The rationale for 1003.1-2001 suggests that the wording was "clarified" in
    453518 * 1003.1-2001 to align with the 1003.2b draft.  1003.2b Draft 12 (July 1999),
    454519 * which is the latest copy I have, does carry the same suggested wording as is
    455520 * in 1003.1-2001, with its rationale saying:
    456  * 
     521 *
    457522 *      This change is a clarification and is the result of interpretation
    458523 *      request PASC 1003.2-92 #23 submitted for IEEE Std 1003.2-1992.
    459  * 
     524 *
    460525 * That interpretation can be found here:
    461  * 
     526 *
    462527 *   http://www.pasc.org/interps/unofficial/db/p1003.2/pasc-1003.2-23.html
    463  * 
     528 *
    464529 * Not terribly helpful, unfortunately.  I wonder who that fence sitter was.
    465  * 
     530 *
    466531 * Worse, IMVNSHO, I think the authors of 1003.2b-D12 have mis-interpreted the
    467532 * PASC interpretation and appear to be gone against at least one widely used
     
    473538 * "test" and is, I believe, one of the reasons why direct use of access() was
    474539 * avoided in some more recent implementations!
    475  * 
     540 *
    476541 * I have always interpreted '-r' to match '-w' and '-x' as per the original
    477542 * wording in 1003.2-1992, not the other way around.  I think 1003.2b goes much
     
    480545 * open() since we already know very well how it will work -- existance of the
    481546 * file is all that matters to open() for root.
    482  * 
     547 *
    483548 * Unfortunately the SVID is no help at all (which is, I guess, partly why
    484549 * we're in this mess in the first place :-).
    485  * 
     550 *
    486551 * The SysV implementation (at least in the 'test' builtin in /bin/sh) does use
    487552 * access(name, 2) even though it also goes to much greater lengths for '-x'
     
    496561test_access(struct stat *sp, mode_t stmode)
    497562{
    498         gid_t *groups;
     563#ifdef _MSC_VER
     564        /* just pretend to be root for now. */
     565        stmode = (stmode << 6) | (stmode << 3) | stmode;
     566        return !!(sp->st_mode & stmode);
     567#else
     568        gid_t *groups;
    499569        register int n;
    500570        uid_t euid;
     
    519589                if ((maxgroups = getgroups(0, NULL)) <= 0)
    520590                        maxgroups = NGROUPS_MAX;        /* pre-POSIX system? */
    521                 groups = ckmalloc((maxgroups + 1) * sizeof(gid_t));
     591                groups = xmalloc((maxgroups + 1) * sizeof(gid_t));
    522592                n = getgroups(maxgroups, groups);
    523593                while (--n >= 0) {
     
    530600        }
    531601
    532         return sp->st_mode & stmode;
     602        return !!(sp->st_mode & stmode);
     603#endif
    533604}
    534605
     
    555626                return S_ISDIR(s.st_mode);
    556627        case FILCDEV:
     628#ifdef S_ISCHR
    557629                return S_ISCHR(s.st_mode);
     630#else
     631                return 0;
     632#endif
    558633        case FILBDEV:
     634#ifdef S_ISBLK
    559635                return S_ISBLK(s.st_mode);
     636#else
     637                return 0;
     638#endif
    560639        case FILFIFO:
     640#ifdef S_ISFIFO
    561641                return S_ISFIFO(s.st_mode);
     642#else
     643                return 0;
     644#endif
    562645        case FILSOCK:
     646#ifdef S_ISSOCK
    563647                return S_ISSOCK(s.st_mode);
     648#else
     649                return 0;
     650#endif
    564651        case FILSYM:
     652#ifdef S_ISLNK
    565653                return S_ISLNK(s.st_mode);
     654#else
     655                return 0;
     656#endif
    566657        case FILSUID:
    567658                return (s.st_mode & S_ISUID) != 0;
     
    569660                return (s.st_mode & S_ISGID) != 0;
    570661        case FILSTCK:
     662#ifdef S_ISVTX
    571663                return (s.st_mode & S_ISVTX) != 0;
     664#else
     665                return 0;
     666#endif
    572667        case FILGZ:
    573668                return s.st_size > (off_t)0;
     
    659754                return 0;
    660755        if ((op = findop(s)) != NULL)
    661                 return op->op_type == BINOP && (t[0] != ')' || t[1] != '\0'); 
     756                return op->op_type == BINOP && (t[0] != ')' || t[1] != '\0');
    662757        return 0;
    663758}
     
    674769
    675770        if (errno != 0)
    676               error("%s: out of range", s);
     771              return errx(-42, "%s: out of range", s);
    677772
    678773        while (isspace((unsigned char)*p))
    679774              p++;
    680        
     775
    681776        if (*p)
    682               error("%s: bad number", s);
     777              return errx(-42, "%s: bad number", s);
    683778
    684779        return (int) r;
     
    715810                b1.st_ino == b2.st_ino);
    716811}
     812
     813static int
     814usage(const char *argv0)
     815{
     816        fprintf(stdout,
     817                "usage: %s expression [-- <prog> [args]]\n", argv0);
     818        return 0; /* only used in --help. */
     819}
  • trunk/src/kmk/variable.c

    r1180 r1292  
    11101110#ifdef CONFIG_WITH_KMK_BUILTIN
    11111111  /* The supported kMk Builtin commands. */
    1112   (void) define_variable ("KMK_BUILTIN", 11, "append cat cp cmp echo install kDepIDB ln md5sum mkdir mv printf rm rmdir", o_default, 0);
     1112  (void) define_variable ("KMK_BUILTIN", 11, "append cat cp cmp echo install kDepIDB ln md5sum mkdir mv printf rm rmdir test", o_default, 0);
    11131113#endif
    11141114
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette