Changeset 3040 in kBuild for trunk/src/kmk/kmkbuiltin.c
- Timestamp:
- May 10, 2017 1:07:10 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin.c
r3034 r3040 43 43 #endif 44 44 45 45 46 int kmk_builtin_command(const char *pszCmd, struct child *pChild, char ***ppapszArgvToSpawn, pid_t *pPidSpawned) 46 47 { … … 48 49 char **argv; 49 50 int rc; 51 char *pszzCmd; 52 char *pszDst; 53 int fOldStyle = 0; 50 54 51 55 /* … … 54 58 if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1)) 55 59 { 56 printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);60 fprintf(stderr, "kmk_builtin: Invalid command prefix '%s'!\n", pszCmd); 57 61 return 1; 58 62 } … … 61 65 * Parse arguments. 62 66 */ 63 argc = 0; 64 argv = NULL; 65 while (*pszCmd) 66 { 67 const char *pszEnd; 68 const char *pszNext; 69 int fEscaped = 0; 70 size_t cch; 67 rc = 0; 68 argc = 0; 69 argv = NULL; 70 pszzCmd = pszDst = (char *)strdup(pszCmd); 71 if (!pszDst) 72 { 73 fprintf(stderr, "kmk_builtin: out of memory. argc=%d\n", argc); 74 return 1; 75 } 76 do 77 { 78 const char * const pszSrcStart = pszCmd; 79 char ch; 80 char chQuote; 71 81 72 82 /* 73 * Find start and end of the current command. 74 */ 75 if (*pszCmd == '"' || *pszCmd == '\'') 76 { 77 pszEnd = pszCmd; 78 for (;;) 79 { 80 pszEnd = strchr(pszEnd + 1, *pszCmd); 81 if (!pszEnd) 82 { 83 printf("kmk_builtin: Unbalanced quote in argument %d: %s\n", argc + 1, pszCmd); 84 while (argc--) 85 free(argv[argc]); 86 free(argv); 87 return 1; 88 } 89 /* two quotes -> escaped quote. */ 90 if (pszEnd[0] != pszEnd[1]) 91 break; 92 fEscaped = 1; 93 } 94 pszNext = pszEnd + 1; 95 pszCmd++; 96 } 97 else 98 { 99 pszEnd = pszCmd; 100 while (!isspace(*pszEnd) && *pszEnd) 101 pszEnd++; 102 pszNext = pszEnd; 103 } 104 105 /* 106 * Make argument. 83 * Start new argument. 107 84 */ 108 85 if (!(argc % 16)) … … 111 88 if (!pv) 112 89 { 113 printf("kmk_builtin: out of memory. argc=%d\n", argc); 90 fprintf(stderr, "kmk_builtin: out of memory. argc=%d\n", argc); 91 rc = 1; 114 92 break; 115 93 } 116 94 argv = (char **)pv; 117 95 } 118 cch = pszEnd - pszCmd; 119 argv[argc] = malloc(cch + 1); 120 if (!argv[argc]) 96 argv[argc++] = pszDst; 97 argv[argc] = NULL; 98 99 if (!fOldStyle) 121 100 { 122 printf("kmk_builtin: out of memory. argc=%d len=%d\n", argc, (int)(pszEnd - pszCmd + 1)); 101 /* 102 * Process the next argument, bourne style. 103 */ 104 chQuote = 0; 105 ch = *pszCmd++; 106 do 107 { 108 /* Unquoted mode? */ 109 if (chQuote == 0) 110 { 111 if (ch != '\'' && ch != '"') 112 { 113 if (!isspace(ch)) 114 { 115 if (ch != '\\') 116 *pszDst++ = ch; 117 else 118 { 119 ch = *pszCmd++; 120 if (ch) 121 *pszDst++ = ch; 122 else 123 { 124 fprintf(stderr, "kmk_builtin: Incomplete escape sequence in argument %d: %s\n", 125 argc, pszSrcStart); 126 rc = 1; 127 break; 128 } 129 } 130 } 131 else 132 break; 133 } 134 else 135 chQuote = ch; 136 } 137 /* Quoted mode */ 138 else if (ch != chQuote) 139 { 140 if ( ch != '\\' 141 || chQuote == '\'') 142 *pszDst++ = ch; 143 else 144 { 145 ch = *pszCmd++; 146 if (ch) 147 { 148 if ( ch != '\\' 149 && ch != '"' 150 && ch != '`' 151 && ch != '$' 152 && ch != '\n') 153 *pszDst++ = '\\'; 154 *pszDst++ = ch; 155 } 156 else 157 { 158 fprintf(stderr, "kmk_builtin: Unbalanced quote in argument %d: %s\n", argc, pszSrcStart); 159 rc = 1; 160 break; 161 } 162 } 163 } 164 else 165 chQuote = 0; 166 } while ((ch = *pszCmd++) != '\0'); 167 } 168 else 169 { 170 /* 171 * Old style in case we ever need it. 172 */ 173 ch = *pszCmd++; 174 if (ch != '"' && ch != '\'') 175 { 176 do 177 *pszDst++ = ch; 178 while ((ch = *pszCmd++) != '\0' && !isspace(ch)); 179 } 180 else 181 { 182 chQuote = ch; 183 for (;;) 184 { 185 char *pszEnd = strchr(pszCmd, chQuote); 186 if (pszEnd) 187 { 188 fprintf(stderr, "kmk_builtin: Unbalanced quote in argument %d: %s\n", argc, pszSrcStart); 189 rc = 1; 190 break; 191 } 192 memcpy(pszDst, pszCmd, pszEnd - pszCmd); 193 pszDst += pszEnd - pszCmd; 194 if (pszEnd[1] != chQuote) 195 break; 196 *pszDst++ = chQuote; 197 } 198 } 199 } 200 *pszDst++ = '\0'; 201 202 /* 203 * Skip argument separators (IFS=space() for now). Check for EOS. 204 */ 205 if (ch != 0) 206 while ((ch = *pszCmd) && isspace(ch)) 207 pszCmd++; 208 if (ch == 0) 123 209 break; 124 } 125 memcpy(argv[argc], pszCmd, cch); 126 argv[argc][cch] = '\0'; 127 128 /* unescape quotes? */ 129 if (fEscaped) 130 { 131 char ch = pszCmd[-1]; 132 char *pszW = argv[argc]; 133 char *pszR = argv[argc]; 134 while (*pszR) 135 { 136 if (*pszR == ch) 137 pszR++; 138 *pszW++ = *pszR++; 139 } 140 *pszW = '\0'; 141 } 142 /* commit it */ 143 argv[++argc] = NULL; 144 145 /* 146 * Next 147 */ 148 pszCmd = pszNext; 149 while (isspace(*pszCmd) && *pszCmd) 150 pszCmd++; 151 } 210 } while (rc == 0); 152 211 153 212 /* 154 213 * Execute the command if parsing was successful. 155 214 */ 156 if ( !*pszCmd)215 if (rc == 0) 157 216 rc = kmk_builtin_command_parsed(argc, argv, pChild, ppapszArgvToSpawn, pPidSpawned); 158 else159 rc = 1;160 217 161 218 /* clean up and return. */ 162 while (argc--)163 free(argv[argc]);164 219 free(argv); 220 free(pszzCmd); 165 221 return rc; 166 222 } … … 178 234 if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1)) 179 235 { 180 printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);236 fprintf(stderr, "kmk_builtin: Invalid command prefix '%s'!\n", pszCmd); 181 237 return 1; 182 238 } … … 241 297 else 242 298 { 243 printf("kmk_builtin: Unknown command '%s'!\n", pszCmd);299 fprintf(stderr, "kmk_builtin: Unknown command '%s'!\n", pszCmd); 244 300 return 1; 245 301 }
Note:
See TracChangeset
for help on using the changeset viewer.