Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² срСдС Linux. Π’Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 141

Автор Майкл ДТонсон

104:   i = 0;

105:  }

106:

107:  rc = glob(prog->argv[argc - 1], flags, NULL, &prog->globResult);

108:  if (rc == GLOB_NOSPACE) {

109:   fprintf(stderr, "нСдостаточно пространства для унивСрсализации\n");

110:   return;

111:  } else if (rc == GLOB_NOMATCH ||

112:   (!rc && (prog->globResult.gl_pathc - i) == 1 &&

113:   !strcmp(prog->argv[argc - 1],

114:   prog->globResult.gl_pathv[i]))) {

115:   /* Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ всС, Ρ‡Ρ‚ΠΎ Π΄ΠΎ сих ΠΏΠΎΡ€ Π±Ρ‹Π»ΠΎ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ \ */

116:   src = dst = prog->argv[argc - 1];

117:   while (*src) {

118:    if (*src != '\\') *dst++ = *src;

119:    src++;

120:   }

121:   *dst = '\0';

122:  } else if (!rc) {

123:   argcAlloced += (prog->globResult.gl_pathc - i);

124:   prog->argv = realloc(prog->argv,

125:   argcAlloced * sizeof(*prog->argv));

126:   memcpy(prog->argv + (argc - 1),

127:   prog->globResult.gl_pathv + i,

128:   sizeof(*(prog->argv)) *

129:    (prog->globResult.gl_pathc - i));

130:   argc += (prog->globResult.gl_pathc - i - 1);

131:  }

132:

133:  *argcAllocedPtr = argcAlloced;

134:  *argcPtr = argc;

135: }

136:

137: /* Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ cmd->numProgs ΠΊΠ°ΠΊ 0, Ссли Π½Π΅ прСдставлСно Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹

138:    (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, пустая строка). Если Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π° допустимая ΠΊΠΎΠΌΠ°Π½Π΄Π°,

139:    commandPtr Π±ΡƒΠ΄Π΅Ρ‚ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° Π½Π°Ρ‡Π°Π»ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ (Ссли исходная

140:    ΠΊΠΎΠΌΠ°Π½Π΄Π° Π±Ρ‹Π»Π° связана с нСсколькими заданиями) ΠΈΠ»ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΠΎ NULL,

141:    Ссли большС Π½Π΅ прСдставлСно Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹. */

142: int parseCommand(char ** commandPtr, struct job * job, int * isBg) {

143:  char * command;

144:  char * returnCommand = NULL;

145:  char * src, * buf, * chptr;

146:  int argc = 0;

147:  int done = 0;

148:  int argvAlloced;

149:  int i;

150:  char quote = '\0';

151:  int count;

152:  struct childProgram * prog;

153:

154:  /* пропускаСм ΠΏΠ΅Ρ€Π²ΠΎΠ΅ свободноС мСсто (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΎΠ±Π΅Π») */

155:  while (**commandPtr && isspace(**commandPtr)) (*commandPtr)++;

156:

157:  /* ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ пустыС строки ΠΈ ΠΏΠ΅Ρ€Π²Ρ‹Π΅ символы '#' */

158:  if (!**commandPtr || (**commandPtr=='#')) {

159:   job->numProgs = 0;

160:   *commandPtr = NULL;

161:   return 0;

162:  }

163:

164:  *isBg = 0;

165:  job->numProgs = 1;

166:  job->progs = malloc(sizeof(*job->progs));

167:

168:  /* ΠœΡ‹ Π·Π°Π΄Π°Π΅ΠΌ элСмСнты массива argv для ссылки Π²Π½ΡƒΡ‚Ρ€ΠΈ строки.

169:     ОсвобоТдСниС памяти осущСствляСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ freeJob().

170:

171:     ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ² Π½Π΅Π·Π°Π½ΡΡ‚ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠ΅

172:     значСния NULL, поэтому ΠΎΡΡ‚Π°Π²ΡˆΠ°ΡΡΡ Ρ‡Π°ΡΡ‚ΡŒ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½Π΅Π΅

173:     (хотя, чСстно говоря, ΠΌΠ΅Π½Π΅Π΅ эффСктивно). */

174:  job->cmdBuf = command = calloc(1, strlen(*commandPtr) + 1);

175:  job->text = NULL;

176:

177:  prog = job->progs;

178:  prog->numRedirections = 0;

179:  prog->redirections = NULL;

180:  prog->freeGlob = 0;

181:  prog->isStopped = 0;

182:

183:  argvAlloced = 5;

184:  prog->argv = malloc(sizeof(*prog->argv) * argvAlloced);

185:  prog->argv[0] = job->cmdBuf;

186:

187:  buf = command;

188:  src = *commandPtr;

189:  while (*src && !done) {

190:   if (quote == *src) {

191:    quote = '\0';

192:   } else if (quote) {

193:    if (*src ==0 '\\') {

194:     src++;

195:     if (!*src) {

196:      fprintf(stderr,

197:       "послС \\ оТидался символ\n");

198:      freeJob(job);

199:      return 1;

200:     }

201:

202:     /* Π² ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ΅ сочСтаниС "\'" Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π΄Π°Ρ‚ΡŒ */

203:     if (*src != quote) *buf++ = '\\';

204:    } else if (*src == '*' | | *src == ' ?' | | *src == '[' ||

205:     *src == ']')

206:     *buf++ = '\\';

207:    *buf++ = *src;

208:   } else if (isspace(*src)) {

209:    if (*prog->argv[argc]) {

210:     buf++, argc++;

211:     /* +1 здСсь оставляСт мСсто для NULL, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅

212:        Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ массив argv */

213:     if ((argc + 1) == argvAlloced) {

214:      argvAlloced += 5;

215:      prog->argv = realloc(prog->argv,

216:       sizeof(*prog->argv) * argvAlloced);

217:     }

218:     prog->argv[argc] = buf;

219:

220:     globLastArgument(prog, &argc, &argvAlloced);

221:    }

222:   } else switch (*src) {

223:   case '"':

224:   case '\'':

225:    quote = *src;

226:    break;

227:

228:   case '#': /* ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ */

229:    done = 1;

230:    break;

231:

232:   case '>': /* пСрСадрСсации */

233:   case '<':

234:    i = prog->numRedirections++;

235:    prog->redirections = realloc(prog->redirections,

236:    sizeof(*prog->redirections) * (i+1));

237:

238:    prog->redirections[i].fd= -1;

239:    if (buf != prog->argv[argc]) {

240:     /* ΠΏΠ΅Ρ€Π΅Π΄ этим символом ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Π½ Π½ΠΎΠΌΠ΅Ρ€

241:        пСрСадрСсовываСмого Ρ„Π°ΠΉΠ»Π° */

242:     prog->redirections[i].fd =

243:      strtol(prog->argv[argc], &chptr, 10);

244:

245:     if (*chptr && *prog->argv[argc]) {

246:      buf++, argc++;

247:      globLastArgument(prog, &argc, &argvAlloced);

248:     }

249:    }

250:

251:    if (prog->redirections[i].fd == -1) {

252:     if (*src == '>')

253:      prog->redirections[i].fd = 1;

254:     else

255:      prog->redirections[i].fd = 0;

256:    }

257:

258:    if (*src++ == '>') {

259:     if (*src == '>') {

260:      prog->redirections[i].type = REDIRECT_APPEND;

261:      src++;

262:     } else {

263:      prog->redirections[i].type = REDIRECT_OVERWRIΠ’Π•;

264:     }

265:    } else {

266:     prog->redirections[i].type = REDIRECT_INPUT;

267:    }

268:

269:    /* Π­Ρ‚ΠΎ Π½Π΅ соотвСтствуСт стандарту sh POSIX. Ну ΠΈ Π»Π°Π΄Π½ΠΎ. */

270:    chptr = src;

271:    while (isspace(*chptr)) chptr++;

272:

273:    if (!*chptr) {

274:     fprintf(stderr, "послС %c оТидалось имя Ρ„Π°ΠΉΠ»Π°\n",

275:      *src);

276:     freeJob(job);

277:     return 1;

278:    }

279:

280:    prog->redirections[i].filename = buf;

281:    while (*chptr && !isspace(*chptr))

282:     *buf++ = *chptr++;

283:

284:    src = chptr - 1; /* src++ Π±ΡƒΠ΄Π΅Ρ‚ сдСлано ΠΏΠΎΠ·ΠΆΠ΅ */

285:    prog->argv[argc] = ++buf;

286:    break;

287:

288:   case '|': /* ΠΊΠ°Π½Π°Π» */

289:    /* Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ этой ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ */

290:    if (*prog->argv[argc]) argc++;

291:    if (large) {

292:     fprintf(stderr, "пустая ΠΊΠΎΠΌΠ°Π½Π΄Π° Π² ΠΊΠ°Π½Π°Π»Π΅\n");

293:     freeJob(job);

294:     return 1;

295:    }

296:    prog->argv[argc] = NULL;

297:

298:    /* ΠΈ Π½Π°Ρ‡Π°Π»ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ */

299:    job->numProgs++;

300:    job->progs = realloc(job->progs,

301:     sizeof (*job->progs) *

302:      job->numProgs);

303:    prog = job->progs + (job->numProgs - 1);

304:    prog->numRedirections = 0;

305:    prog->redirections = NULL;

306:    prog->freeGlob = 0;

307:    argc = 0;

308:

309:    argvAlloced = 5;

310:    prog->argv = malloc(sizeof(*prog->argv) *

311:     argvAlloced);

312:    prog->argv[0] = ++buf;

313:

314:    src++;

315:    while (*src && isspace(*src)) src++;

316:

317:    if (!*src) {

318:     fprintf(stderr, "пустая ΠΊΠΎΠΌΠ°Π½Π΄Π° Π² ΠΊΠ°Π½Π°Π»Π΅\n");

319:     return 1;

320:    }

321:    src--; /* ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ ++ ΠΌΡ‹ сдСлаСм Π² ΠΊΠΎΠ½Ρ†Π΅ Ρ†ΠΈΠΊΠ»Π° */

322:

323:    break;

324:

325:   case '&': /* Ρ„ΠΎΠ½ */

326:    *isBg = 1;

327:   case ';': /* Ρ€Π°Π·Π½ΠΎΠΎΠ±Ρ€Π°Π·Π½Ρ‹Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ */

328:    done = 1;

329:    returnCommand = *commandPtr + (src - * commandPtr) + 1;

330:    break;

331:

332:   case '\\':

333:    src++;

334:    if (!*src) {

335:     freeJob(job);

336:     fprintf(stderr, "послС \\ оТидался символ\n");

337:     return 1;

338:    }

339:    if (*src == '*' | | *src == '[' || *src == '] '

340:     || *src == '?')

341:     *buf++ = '\\';

342:    /* Π½Π΅ΡƒΠ΄Π°Ρ‡Π° */

343:   default:

344:    *buf++ = *src;

345:   }

346:

347:   src++;

348:  }

349:

350:  if (*prog->argv[argc]) {

351:   argc++;

352:   globLastArgument(prog, &argc, &argvAlloced);

353:  }

354:  if (!argc) {

355:   freeJob(job);

356:   return 0;

357:  }

358:  prog->argv[argc] = NULL;

359:

360:  if (!returnCommand) {

361:   job->text = malloc(strlen(*commandPtr) + 1);