Changeset 3645 for branches


Ignore:
Timestamp:
May 19, 2008, 1:42:37 AM (17 years ago)
Author:
bird
Message:

Proper argument passing - finally!

Location:
branches/libc-0.6/src/emx
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/include/include.smak

    r1381 r3645  
    5858$(INS)include/InnoTekLIBC/%.h: include/InnoTekLIBC/%.h
    5959        $(call CP,$<,$@)
     60       
     61INS.FILES += $(addprefix $(INS), $(wildcard include/klibc/*.h))
     62$(INS)include/klibc/%.h: include/klibc/%.h
     63        $(call CP,$<,$@)       
  • branches/libc-0.6/src/emx/include/sys/process.h

    r2289 r3645  
    4343#define P_UNRELATED  0x40000
    4444#define P_DEBUGDESC  0x80000
     45#define P_NOUNIXARGV 0x100000
    4546
    4647#endif
  • branches/libc-0.6/src/emx/src/lib/misc/response.c

    r2433 r3645  
    55#include <stdlib.h>
    66#include <string.h>
    7 #include <emx/startup.h>
     7#include <klibc/startup.h>
    88
    99#define RPUT(x) do \
     
    3030  for (i = 1; i < old_argc; ++i)
    3131    if (old_argv[i] != NULL
    32         && !(old_argv[i][-1] & (_ARG_DQUOTE|_ARG_WILDCARD))
     32        && !(old_argv[i][-1] & (__KLIBC_ARG_DQUOTE | __KLIBC_ARG_WILDCARD | __KLIBC_ARG_SHELL))
    3333        && old_argv[i][0] == '@')
    3434      break;
     
    3939    {
    4040      if (i == 0 || old_argv[i] == NULL
    41           || (old_argv[i][-1] & (_ARG_DQUOTE|_ARG_WILDCARD))
     41          || (old_argv[i][-1] & (__KLIBC_ARG_DQUOTE | __KLIBC_ARG_WILDCARD | __KLIBC_ARG_SHELL))
    4242          || old_argv[i][0] != '@'
    4343          || (f = fopen (old_argv[i]+1, "rt")) == NULL)
     
    4545      else
    4646        {
    47           line[0] = _ARG_NONZERO|_ARG_RESPONSE;
     47          line[0] = __KLIBC_ARG_NONZERO | __KLIBC_ARG_RESPONSE;
    4848          while (fgets (line+1, sizeof (line)-1, f) != NULL)
    4949            {
  • branches/libc-0.6/src/emx/src/lib/misc/wildcard.c

    r732 r3645  
    55#include <stdlib.h>
    66#include <string.h>
    7 #include <emx/startup.h>
    87#include <emx/syscalls.h>
     8#include <klibc/startup.h>
    99
    1010#define WPUT(x) do { \
     
    3232  for (i = 1; i < old_argc; ++i)
    3333    if (old_argv[i] != NULL &&
    34         !(old_argv[i][-1] & (_ARG_DQUOTE|_ARG_RESPONSE)) &&
     34        !(old_argv[i][-1] & (__KLIBC_ARG_DQUOTE | __KLIBC_ARG_RESPONSE | __KLIBC_ARG_ARGV | __KLIBC_ARG_SHELL)) &&
    3535        strpbrk (old_argv[i], "?*") != NULL)
    3636      break;
     
    4141    {
    4242      if (i == 0 || old_argv[i] == NULL
    43           || (old_argv[i][-1] & (_ARG_DQUOTE|_ARG_RESPONSE))
     43          || (old_argv[i][-1] & (__KLIBC_ARG_DQUOTE | __KLIBC_ARG_RESPONSE | __KLIBC_ARG_ARGV | __KLIBC_ARG_SHELL))
    4444          || strpbrk (old_argv[i], "?*") == NULL
    4545          || __findfirst (old_argv[i], 0x10, &find) != 0)
     
    4747      else
    4848        {
    49           line[0] = _ARG_NONZERO|_ARG_WILDCARD;
     49          line[0] = __KLIBC_ARG_NONZERO | __KLIBC_ARG_WILDCARD;
    5050          strcpy (line+1, old_argv[i]);
    5151          p = _getname (line + 1);
  • branches/libc-0.6/src/emx/src/lib/sys/__init.c

    r2990 r3645  
    3232#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_INITTERM
    3333#include <InnoTekLIBC/logstrict.h>
     34#include <klibc/startup.h>
    3435#include "b_signal.h"
    3536
     
    4546*******************************************************************************/
    4647static int parse_args(const char *src, char **argv, char *pool);
    47 static int verify_end_of_single_quote(const char *src);
     48/*static int verify_end_of_single_quote(const char *src);*/
    4849
    4950
     
    8182{
    8283    int   quote;
     84    char  ch;
    8385    char  flags;
    8486    char *flag_ptr;
     
    9799    }
    98100    ++src;
    99     for (;;)
     101
     102    /* Check for the kLIBC signature used for unix arguments. */
     103    if (    src[0] != '\177'
     104        ||  src[1] != 'k'
     105        ||  src[2] != 'L'
     106        ||  src[3] != 'I'
     107        ||  src[4] != 'B'
     108        ||  src[5] != 'C'
     109        ||  src[6] != '\177'
     110        ||  src[7] != '\0')
    100111    {
    101         while (WHITE(*src))
    102             ++src;
    103         if (*src == 0)
    104             break;
    105         if (!pool)
     112        /* Convert from OS/2 command line convention to C/Unix. */
     113        for (;;)
    106114        {
    107             flags = _ARG_NONZERO;
    108             flag_ptr = &flags;
    109             arg_size++;
     115            while (WHITE(*src))
     116                ++src;
     117            if (*src == 0)
     118                break;
     119            if (!pool)
     120            {
     121                flags = _ARG_NONZERO;
     122                flag_ptr = &flags;
     123                arg_size++;
     124            }
     125            else
     126            {
     127                flag_ptr = pool;
     128                PUTC((char)_ARG_NONZERO);
     129            }
     130            arg_pos = arg_size;
     131            PUTV;
     132            quote = 0;
     133            for (;;)
     134            {
     135                /* End quote. */
     136                if (*src == quote && quote)
     137                    quote = 0;
     138                /* Start of double quote. */
     139                else if (!quote && *src == '"')
     140                {
     141                    quote = '"';
     142                    *flag_ptr |= _ARG_DQUOTE;
     143                }
     144                /*
     145                 * Only permit the single quote to be used at the start of an argument or
     146                 * within an already quoted one. This restriction is necessary to support
     147                 * unquoted filenames containing the single quote char.
     148                 */
     149                else if (   !quote && *src == '\''
     150                         && (   arg_pos == arg_size
     151                             || (*flag_ptr & _ARG_DQUOTE)))
     152                {
     153                    quote = '\'';
     154                    *flag_ptr |= _ARG_DQUOTE;
     155                }
     156                /*
     157                 * The escape character. This is truly magic/weird.
     158                 * It doesn't escape anything unless it's in front of a
     159                 * double quote character. EMX weirdness...
     160                 * (Ok, not escaping more than necessary is ok when using \ as path
     161                 * separator, but why weird interpretation of \\\\"asdf"?
     162                 */
     163                else if (*src == '\\' && quote != '\'')
     164                {
     165                    int cSlashes = 0;
     166                    do
     167                    {
     168                        cSlashes++;
     169                        src++;
     170                    } while (*src == '\\');
     171   
     172                    if (*src == '"')
     173                    {
     174                        /* Treat it is as escapes. */
     175                        while (cSlashes >= 2)
     176                        {
     177                            PUTC('\\');
     178                            cSlashes -= 2;
     179                        }
     180                        if (cSlashes & 1)
     181                            PUTC(*src);
     182                        else
     183                            src--;
     184                    }
     185                    else
     186                    {
     187                        /* unmodified, no escaping. */
     188                        while (cSlashes-- > 0)
     189                            PUTC('\\');
     190                        src--;
     191                    }
     192                }
     193                /* Check for end of argument. */
     194                else if (*src == 0 || (WHITE(*src) && !quote))
     195                    break;
     196                /* Normal character. */
     197                else
     198                    PUTC(*src);
     199                ++src;
     200            }
     201            PUTC(0);
     202        }
     203    }
     204    else
     205    {
     206        /* The kLIBC spawn packs exactly what we want, including the flag at [-1]. */
     207        src += sizeof(__KLIBC_ARG_SIGNATURE);
     208        if (pool)
     209        {
     210            /* copying */
     211            while (*src)
     212            {
     213                LIBC_ASSERT((unsigned)*src & __KLIBC_ARG_NONZERO);
     214                argc++;
     215                *argv++ = pool + 1;
     216                do
     217                {
     218                    *pool++ = ch = *src++;
     219                } while (ch);
     220            }
    110221        }
    111222        else
    112223        {
    113             flag_ptr = pool;
    114             PUTC((char)_ARG_NONZERO);
     224            /* counting */
     225            while (*src)
     226            {
     227                LIBC_ASSERT((unsigned)*src & __KLIBC_ARG_NONZERO);
     228                argc++;
     229                do
     230                {
     231                    arg_size++;
     232                    ch = *src++;
     233                } while (ch);
     234            }
    115235        }
    116         arg_pos = arg_size;
    117         PUTV;
    118         quote = 0;
    119         for (;;)
    120         {
    121             /* End quote. */
    122             if (*src == quote && quote)
    123                 quote = 0;
    124             /* Start of double quote. */
    125             else if (!quote && *src == '"')
    126             {
    127                 quote = '"';
    128                 *flag_ptr |= _ARG_DQUOTE;
    129             }
    130             /*
    131              * Only permit the single quote to be used at the start of an argument or
    132              * within an already quoted one. This restriction is necessary to support
    133              * unquoted filenames containing the single quote char.
    134              */
    135             else if (   !quote && *src == '\''
    136                      && (   arg_pos == arg_size
    137                          || (*flag_ptr & _ARG_DQUOTE)))
    138             {
    139                 quote = '\'';
    140                 *flag_ptr |= _ARG_DQUOTE;
    141             }
    142             /*
    143              * The escape character. This is truly magic/weird.
    144              * It doesn't escape anything unless it's in front of a
    145              * double quote character. EMX weirdness...
    146              * (Ok, not escaping more than necessary is ok when using \ as path
    147              * separator, but why weird interpretation of \\\\"asdf"?
    148              */
    149             else if (*src == '\\' && quote != '\'')
    150             {
    151                 int cSlashes = 0;
    152                 do
    153                 {
    154                     cSlashes++;
    155                     src++;
    156                 } while (*src == '\\');
    157 
    158                 if (*src == '"')
    159                 {
    160                     /* Treat it is as escapes. */
    161                     while (cSlashes >= 2)
    162                     {
    163                         PUTC('\\');
    164                         cSlashes -= 2;
    165                     }
    166                     if (cSlashes & 1)
    167                         PUTC(*src);
    168                     else
    169                         src--;
    170                 }
    171                 else
    172                 {
    173                     /* unmodified, no escaping. */
    174                     while (cSlashes-- > 0)
    175                         PUTC('\\');
    176                     src--;
    177                 }
    178             }
    179             /* Check for end of argument. */
    180             else if (*src == 0 || (WHITE(*src) && !quote))
    181                 break;
    182             /* Normal character. */
    183             else
    184                 PUTC(*src);
    185             ++src;
    186         }
    187         PUTC(0);
    188236    }
    189237    return arg_size;
     
    191239
    192240
     241#if 0
    193242/**
    194243 * This is a hack to prevent us from messing up filenames that
     
    200249 */
    201250static int verify_end_of_single_quote(const char *src);
     251#endif
    202252
    203253
  • branches/libc-0.6/src/emx/src/lib/sys/__spawnve.c

    r3643 r3645  
    1919#include <InnoTekLIBC/sharedpm.h>
    2020#include <InnoTekLIBC/backend.h>
     21#include <klibc/startup.h>
    2122#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_PROCESS
    2223#include <InnoTekLIBC/logstrict.h>
     
    179180    LIBCLOG_ENTER("np=%p:{mode=%#x}\n", (void *)np, np->mode);
    180181    FS_VAR();
     182    char szLineBuf[512];
    181183
    182184    /*
     
    220222
    221223    /*
    222      * cmd.exe and 4os2.exe needs different argument handling.
     224     * cmd.exe and 4os2.exe needs different argument handling, and
     225     * starting with kLIBC 0.6.4 we can pass argv directly to LIBC
     226     * programs.
    223227     * (1 == cmd or 4os2 shell, 0 == anything else)
    224228     */
     229    enum { args_standard, args_cmd, args_unix } enmMethod = args_standard;
    225230    char *psz = _getname(pszPgmName);
    226     int method = stricmp(psz, "cmd.exe") == 0
    227               || stricmp(psz, "4os2.exe") == 0;
     231    if (   stricmp(psz, "cmd.exe") == 0
     232        || stricmp(psz, "4os2.exe") == 0)
     233        enmMethod = args_cmd;
     234    else
     235    {
     236        HFILE hFile = NULLHANDLE;
     237        ULONG ulAction = 0;
     238        rc = DosOpen((PCSZ)pszPgmName, &hFile, &ulAction, 0, FILE_NORMAL,
     239                     OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
     240                     OPEN_FLAGS_SEQUENTIAL | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
     241                     NULL);
     242        if (!rc)
     243        {
     244            ULONG cbRead = 0;
     245            rc = DosRead(hFile, szLineBuf, sizeof(szLineBuf), &cbRead);
     246            DosClose(hFile);
     247            if (rc)
     248                LIBCLOG_ERROR("DosRead - rc=%d (%s)\n", rc, pszPgmName);
     249            else if (   cbRead >= __KLIBC_STUB_MIN_SIZE
     250                     && szLineBuf[0] == 'M'
     251                     && szLineBuf[1] == 'Z'
     252                     && !memcmp(&szLineBuf[__KLIBC_STUB_SIGNATURE_OFF], __KLIBC_STUB_SIGNATURE_BASE, sizeof(__KLIBC_STUB_SIGNATURE_BASE) - 1)
     253                    )
     254            {
     255                char const *pchVer = &szLineBuf[__KLIBC_STUB_SIGNATURE_OFF + sizeof(__KLIBC_STUB_SIGNATURE_BASE) - 1];
     256                if (*pchVer >= '0' && *pchVer <= '9')
     257                    enmMethod = !(np->mode & P_NOUNIXARGV) ? args_unix : args_standard;
     258            }
     259            /** @todo move the hash bang handling up here. */
     260            /*else if (!rc && szLineBuf[0] == '#')
     261            {
     262            } */
     263        }
     264        /* Catch some plain failures here, leave the rest for later. */
     265        else if (   rc == ERROR_FILE_NOT_FOUND
     266                 || rc == ERROR_PATH_NOT_FOUND)
     267        {
     268            _sys_set_errno(rc);
     269            LIBCLOG_RETURN_INT(-1);
     270        }
     271        else
     272            LIBCLOG_ERROR("rc=%d (%s)\n", rc, pszPgmName);
     273    }
    228274
    229275    /*
     
    235281    char       *pszArg = NULL;
    236282    size_t      cbArgs = 0;
     283    int         i;
     284
    237285    if (np->arg_count > 0)
    238286    {
     
    243291        pszArg += cch; pszSrc += cch;
    244292    }
    245     int i;
    246     for (i = 1; i < np->arg_count; ++i)
     293    if (enmMethod == args_unix)
    247294    {
    248         if (i > 1)
     295        /* first arg is the signature. */
     296        ADD(sizeof(__KLIBC_ARG_SIGNATURE));
     297        memcpy(pszArg, __KLIBC_ARG_SIGNATURE, sizeof(__KLIBC_ARG_SIGNATURE));
     298        pszArg += sizeof(__KLIBC_ARG_SIGNATURE);
     299
     300        /* then comes the argument vector. */
     301        for (i = 1; i < np->arg_count; ++i)
    249302        {
    250             ADD(1);
    251             *pszArg++ = ' ';
     303            unsigned char chFlags = *pszSrc++;
     304            chFlags &= __KLIBC_ARG_MASK;
     305            chFlags |= __KLIBC_ARG_ARGV;
     306            cch = strlen(pszSrc) + 1;
     307            ADD(cch + 1);
     308            *pszArg++ = chFlags;
     309            memcpy(pszArg, pszSrc, cch);
     310            pszArg += cch;
     311            pszSrc += cch;
    252312        }
    253         ++pszSrc;                    /* skip flags byte */
    254         BOOL fQuote = FALSE;
    255         if (*pszSrc == 0)
    256             fQuote = TRUE;
    257         else if (ulMode & P_QUOTE)
     313
     314        /* the double termination. */
     315        ADD(1);
     316        *pszArg = '\0';
     317    }
     318    else
     319    {
     320        /* quote the arguments in emx / cmd.exe fashion. */
     321        for (i = 1; i < np->arg_count; ++i)
    258322        {
    259             if (pszSrc[0] == '@' && pszSrc[1] != 0)
     323            if (i > 1)
     324            {
     325                ADD(1);
     326                *pszArg++ = ' ';
     327            }
     328            ++pszSrc;                    /* skip flags byte */
     329            BOOL fQuote = FALSE;
     330            if (*pszSrc == 0)
    260331                fQuote = TRUE;
    261             else
     332            else if (ulMode & P_QUOTE)
     333            {
     334                if (pszSrc[0] == '@' && pszSrc[1] != 0)
     335                    fQuote = TRUE;
     336                else
     337                    for (psz = (char *)pszSrc; *psz != 0; ++psz)
     338                        if (*psz == '?' || *psz == '*')
     339                        {
     340                            fQuote = TRUE;
     341                            break;
     342                        }
     343            }
     344            if (!fQuote)
     345            {
    262346                for (psz = (char *)pszSrc; *psz != 0; ++psz)
    263                     if (*psz == '?' || *psz == '*')
     347                    if (*psz == ' ' || *psz == '\t' || (*psz == '"' && enmMethod == args_cmd))
    264348                    {
    265349                        fQuote = TRUE;
    266350                        break;
    267351                    }
    268         }
    269         if (!fQuote)
    270         {
    271             for (psz = (char *)pszSrc; *psz != 0; ++psz)
    272                 if (*psz == ' ' || *psz == '\t' || (*psz == '"' && method == 1))
     352            }
     353            if (fQuote)
     354            {
     355                ADD(1);
     356                *pszArg++ = '"';
     357            }
     358            size_t bs = 0;
     359            while (*pszSrc != 0)
     360            {
     361                if (*pszSrc == '"' && enmMethod == args_standard)
    273362                {
    274                     fQuote = TRUE;
    275                     break;
     363                    ++bs;
     364                    ADD(bs);
     365                    memset(pszArg, '\\', bs); pszArg += bs;
     366                    bs = 0;
    276367                }
    277         }
    278         if (fQuote)
    279         {
    280             ADD(1);
    281             *pszArg++ = '"';
    282         }
    283         size_t bs = 0;
    284         while (*pszSrc != 0)
    285         {
    286             if (*pszSrc == '"' && method == 0)
    287             {
    288                 ++bs;
    289                 ADD(bs);
     368                else if (*pszSrc == '\\' && enmMethod == args_standard)
     369                    ++bs;
     370                else
     371                    bs = 0;
     372                ADD(1);
     373                *pszArg++ = *pszSrc;
     374                ++pszSrc;
     375            }
     376            if (fQuote)
     377            {
     378                ADD(1+bs);
    290379                memset(pszArg, '\\', bs); pszArg += bs;
    291                 bs = 0;
    292             }
    293             else if (*pszSrc == '\\' && method == 0)
    294                 ++bs;
    295             else
    296                 bs = 0;
    297             ADD(1);
    298             *pszArg++ = *pszSrc;
     380                *pszArg++ = '"';
     381            }
    299382            ++pszSrc;
    300383        }
    301         if (fQuote)
    302         {
    303             ADD(1+bs);
    304             memset(pszArg, '\\', bs); pszArg += bs;
    305             *pszArg++ = '"';
    306         }
    307         ++pszSrc;
     384        /* The arguments are an array of zero terminated strings, ending with an empty string. */
     385        ADD(2);
     386        *pszArg++ = '\0';
     387        *pszArg++ = '\0';
    308388    }
    309     /* The arguments are an array of zero terminated strings, ending with an empty string. */
    310     ADD(2);
    311     *pszArg++ = '\0';
    312     *pszArg++ = '\0';
    313389
    314390
     
    345421                 * requires inspection of the first line of the file.
    346422                 */
    347                 char szLineBuf[256];
    348423                const char *pszInterpreter = NULL;
    349424                const char *pszInterpreterArgs = NULL;
Note: See TracChangeset for help on using the changeset viewer.