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

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

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

 70:    ΠΎΠ΄Π½ΠΎΠ³ΠΎ задания, ассоциированного с Π½Π΅ΠΉ) ΠΈΠ»ΠΈ NULL, Ссли

 71:    большС Π½Π΅Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄.*/

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

 73:  char *command;

 74:  char *returnCommand = NULL;

 75:  char *src, *buf;

 76:  int argc = 0;

 77:  int done = 0;

 78:  int argvAlloced;

 79:  char quote = '\0';

 80:  int count;

 81:  struct childProgram *prog;

 82:

 83:  /* ΠŸΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π²Π΅Π΄ΡƒΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹ */

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

 85:

 86:  /* здСсь ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ пустыС строки ΠΈ Π²Π΅Π΄ΡƒΡ‰ΠΈΠ΅ символы '#' */

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

 88:   job->numProgs = 0;

 89:   *commandPtr = NULL;

 90:   return 0;

 91:  }

 92:

 93:  *isBg = 0;

 94:  job->numProgs = 1;

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

 96:

 97:  /* ΠœΡ‹ устанавливаСм элСмСнты argv Π² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ строки.

 98:     ΠŸΠ°ΠΌΡΡ‚ΡŒ освобоТдаСтся freeJob().

 99:

100:     ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ чистой памяти позволяСт Π΄Π°Π»Π΅Π΅ ΠΈΠΌΠ΅Ρ‚ΡŒ Π΄Π΅Π»ΠΎ с

101:     NULL-Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΌΠΈΡΡ Π²Π΅Ρ‰Π°ΠΌΠΈ ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ всС ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠ΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ

102:     яснСС (ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅, это добавляСт эффСктивности) */

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

104:  job->text = NULL;

105:

106:  prog = job->progs;

107:

108:  argvAlloced = 5;

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

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

111:

112:  buf = command;

113:  src = *commandPtr;

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

115:   if (quote==*src) {

116:    quote='\0';

117:   } else if (quote) {

118:    if (*src == '\\') {

119:     src++;

120:     if (!*src) {

121:      fprintf(stderr,

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

123:      freeJob(job);

124:      return 1;

125:     }

126:

127:     /* Π² ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ΅, "\'" Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΠΎΡ€ΠΎΠ΄ΠΈΡ‚ΡŒ \' */

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

129:    }

130:    *buf++ = *src;

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

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

133:     buf++, argc++;

134:     /* +1 здСсь оставляСт мСсто для NULL,

135:        ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ argv */

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

137:      argvAlloced += 5;

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

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

140:     }

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

142:    }

143:   } else switch(*src) {

144:   case '"':

145:   case '\'':

146:    quote = *src;

147:    break;

148:

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

150:    done=1;

151:    break;

152:

153:   case '&': /* Ρ„ΠΎΠ½ΠΎΠ²Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ */

154:    *isBg = 1;

155:   case ';': /* мноТСствСнныС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ */

156:    done=1;

157:    return Command = *commandPtr + (src - *commandPtr) + 1;

158:    break;

159:

160:   case '\\' :

161:    src++;

162:    if (!*src) {

163:     freeJob(job);

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

165:     return 1;

166:    }

167:    /* Π΄Π²ΠΈΠ³Π°Ρ‚ΡŒΡΡ дальшС */

168:   default:

169:    *buf++=*src;

170:   }

171:

172:   src++;

173:  }

174:

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

176:   argc++;

177:  }

178:  if (!argc) {

179:   freeJob(job);

180:   return 0;

181:  }

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

183:

184:  if (!returnCommand) {

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

186:   strcpy(job->text,*commandPtr);

187:  } else {

188:   /* Π­Ρ‚ΠΎ оставляСт хвостовыС ΠΏΡ€ΠΎΠ±Π΅Π»Ρ‹, Ρ‡Ρ‚ΠΎ нСсколько излишнС */

189:

190:   count = returnCommand - *commandPtr;

191:   job->text = malloc(count + 1);

192:   strncpy(job->text,*commandPtr,count);

193:   job->text[count] = '\0';

194:  }

195:

196:  *commandPtr = returnCommand;

197:

198:  return 0;

199: }

200:

201: int runCommand(struct jobnewJob, struct jobSet *jobList,

202:  intinBg) {

203:  struct job *job;

204:

205:  /* ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡƒΡ‚ΡŒ "Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ" - ΠΌΡ‹ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ fork(),

206:     поэтому Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π»Π΅Π³ΠΊΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΠΎΠ½ΠΎΠ²Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ */

207:  if (!strcmp(newJob.progs[0].argv[0], "exit")) {

208:   /* это Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° */

209:   exit(0);

210:  } else if(!strcmp(newJob.progs[0].argv[0], "jobs")) {

211:   for (job = jobList->head; job; job = job->next)

212:    printf(JOB_STATUS_FORMAT, job->jobId, "Π Π°Π±ΠΎΡ‚Π°ΡŽ",

213:     job->text);

214:   return 0;

215:  }

216:

217:  /* Ρƒ нас ΠΏΠΎΠΊΠ° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π° Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π΅ Π·Π°Π΄Π°Π½ΠΈΠ΅,

218:     ΠΏΠΎΡ‚ΠΎΠΌΡƒ это просто */

219:  if (!(newJob.progs[0].pid = fork())) {

220:   execvp(newJob.progs[0].argv[0],newJob.progs[0].argv);

221:   fprintf(stderr, "exec() для %s ΠΏΠΎΡ‚Π΅Ρ€ΠΏΠ΅Π»Π° Π½Π΅ΡƒΠ΄Π°Ρ‡Ρƒ: %s\n",

222:    newJob.progs[0].argv[0],

223:   strerror(errno));

224:   exit(1);

225:  }

226:

227:  /* ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π΄ΠΎΡ‡Π΅Ρ€Π½ΡŽΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Π³Ρ€ΡƒΠΏΠΏΡƒ процСссов */

228:  setpgid(newJob.progs[0].pid,newJob.progs[0].pid);

229:

230:  newJob.pgrp = newJob.progs[0].pid;

231:

232:  /* Π½Π°ΠΉΡ‚ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ для задания */

233:  newJob.jobld = 1;

234:  for (job = jobList->head; job; job = job->next)

235:   if (job->jobId >= newJob.jobId)

236:    newJob.jobId = job->jobId+1;

237:

238:  /* Π·Π°Π΄Π°Π½ΠΈΠ΅ для списка Π·Π°Π΄Π°Π½ΠΈΠΉ */

239:  if (!jobList->head) {

240:   job = jobList->head = malloc(sizeof(*job));

241:  } else {

242:   for (job = jobList->head; job->next; job = job->next);

243:   job->next = malloc(sizeof(*job));

244:   job = job->next;

245:  }

246:

247:  *job = newJob;

248:  job->next = NULL;

249:  job->runningProgs = job->numProgs;

250:

251:  if (inBg) {

252:   /* ΠΌΡ‹ Π½Π΅ ΠΆΠ΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ„ΠΎΠ½ΠΎΠ²Ρ‹Ρ… Π·Π°Π΄Π°Π½ΠΈΠΉ - Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

253:      Π² список Ρ„ΠΎΠ½ΠΎΠ²Ρ‹Ρ… Π·Π°Π΄Π°Π½ΠΈΠΉ ΠΈ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² ΠΏΠΎΠΊΠΎΠ΅ */

254:

255:   printf("[%d]%d\n", job->jobId,

256:    newJob.progs[newJob.numProgs-1].pid);

257:  } else {

258:   jobList->fg=job;

259:

260:   /* ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ Π³Ρ€ΡƒΠΏΠΏΡƒ процСссов Π½Π° ΠΏΠ΅Ρ€Π΅Π΄Π½ΠΈΠΉ ΠΏΠ»Π°Π½ */

261:

262:   if (tcsetpgrp(0,newJob.pgrp))

263:    perror("tcsetpgrp");

264:  }

265:

266:  return 0;

267: }

268:

269: void removeJob(struct jobSet *jobList, struct job *job) {

270:  struct job *prevJob;

271:

272:  freeJob(job);

273:  if (job == jobList->head) {

274:   jobList->head=job->next;

275:  } else {

276:   prevJob = jobList->head;

277:   while (prevJob->next != job) prevJob = prevJob->next;

278:   prevJob->next=job->next;

279:  }

280:

281:  free(job);

282: }

283:

284: /* ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΡΡ Π»ΠΈ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ ΠΈΠ· Ρ„ΠΎΠ½ΠΎΠ²Ρ‹Ρ… процСссов -

285:    Ссли Π΄Π°, Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΠΎΡΡŒ Π»ΠΈ Π·Π°Π΄Π°Π½ΠΈΠ΅ */

286: void checkJobs(struct jobSet *jobList) {

287:  struct job *job;

288:  pid_t childpid;

289:  int status;

290:  int progNum;

291:

292:  while ((childpid = waitpid(-1, &status, WNOHANG))>0) {

293:   for (job = jobList->head;job;job = job->next) {

294:    progNum = 0;

295:    while (progNum<job->numProgs &&

296:     job->progs[progNum].pid != childpid)

297:     progNum++;

298:    if (progNum<job->numProgs) break;

299:   }

300:

301:   job->runningProgs--;

302:   job->progs[progNum].pid = 0;

303:

304:   if (!job->runningProgs) {

305:    printf(JOB_STATUS_FORMAT,job->jobId,"Π“ΠΎΡ‚ΠΎΠ²ΠΎ",

306:     job->text);

307:    removeJob(jobList, job);

308:   }

309:  }

310:

311:  if (childpid == -1 && errno!= ECHILD)

312:   perror("waitpid");

313:  }

314:

315:  int main(int argc, const char **argv) {

316:   char command [MAX_COMMAND_LEN + 1];

317:   char *nextCommand = NULL;

318:   struct jobSetjobList = {NULL, NULL};

319:   struct jobnewJob;

320:   FILE *input = stdin;

321:   int i;

322:   int status;

323:   int inBg;

324:

325:   if (argc>2) {

326:    fprintf(stderr,"НСпрСдвидСнныС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹; использованиС: ladsh1 "

327:     "<ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹>\n");

328:    exit(1);