Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
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);
362: strcpy(job->text, *commandPtr);
363: } else {
364: /*Оставляем любые хвостовые пробелы, хотя и получится это несколько небрежно*/
365:
366: count = returnCommand - *commandPtr;
367: job->text = malloc(count + 1);
368: strncpy(job->text, *commandPtr, count);
369: job->text[count] = '\0';
370: }
371:
372: *commandPtr = returnCommand;
373:
374: return 0;
375: }
376:
377: int setupRedirections(struct childProgram * prog) {
378: int i;
379: int openfd;
380: int mode;
381: struct redirectionSpecifier * redir = prog->redirections;
382:
383: for (i = 0; i < prog->numRedirections; i++, redir++) {
384: switch (redir->type) {
385: case REDIRECT_INPUT:
386: mode = O_RDONLY;
387: break;
388: case REDIRECT_OVERWRITE:
389: mode = O_RDWR | O_CREAT | O_TRUNC;
390: break;
391: case REDIRECT_APPEND:
392: mode = O_RDWR | O_CREAT | O_APPEND;
393: break;
394: }
395:
396: openfd = open(redir->filename, mode, 0666);
397: if (openfd < 0) {
398: /* мы могли потерять это в случае переадресации stderr,
399: хотя bash и ash тоже потеряют его (а вот
400: zsh - нет!) */
401: fprintf(stderr, "ошибка при открытии %s: %s\n",
402: redir->filename, strerror(errno));
403: return 1;
404: }
405:
406: if (openfd != redir->fd) {
407: dup2(openfd, redir->fd);
408: close(openfd);
409: }
410: }
411:
412: return 0;
413: }
414:
415: int runCommand(struct job newJob, struct jobSet * jobList,
416: int inBg) {
417: struct job * job;
418: char * newdir, * buf;
419: int i, len;
420: int nextin, nextout;
421: int pipefds[2]; /* pipefd[0] предназначен для чтения */
422: char * statusString;
423: int jobNum;
424: int controlfds[2] ;/*канал для возможности приостановки работы дочернего процесса*/
425:
426: /* здесь производится обработка встраиваемых модулей — мы не используем fork(),
427: поэтому, чтобы поместить процесс в фон, придется потрудиться */
428: if (!strcmp(newJob.progs[0].argv[0], "exit")) {
Интервал:
Закладка: