Чтение онлайн

ЖАНРЫ

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

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: /* найти идентификатор для задания */

Поделиться с друзьями: