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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX β€” ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ срСда программирования». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 95

Автор ΠšΠ΅Ρ€Π½ΠΈΠ³Π°Π½ Π‘Ρ€Π°ΠΉΠ°Π½ Уилсон

7.4 ΠŸΡ€ΠΎΡ†Π΅ΡΡΡ‹

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ Π²Π°ΠΌ, ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Π²Ρ‹Π·Π²Π°Π² Π΅Π΅ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠΉ. Π‘Π°ΠΌΡ‹ΠΉ Π»Π΅Π³ΠΊΠΈΠΉ ΠΏΡƒΡ‚ΡŒ β€” ΠΏΡ€ΠΈΠ²Π»Π΅Ρ‡ΡŒ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ

system
, ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚ΡƒΡŽ, Π½ΠΎ Π·Π°Π±Ρ€Π°ΠΊΠΎΠ²Π°Π½Π½ΡƒΡŽ Π² Π³Π». 6. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°
system
ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠ΄ΠΈΠ½ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Β β€” ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡƒΡŽ строку Π² Ρ‚ΠΎΠΌ Π²ΠΈΠ΄Π΅, Π² ΠΊΠ°ΠΊΠΎΠΌ ΠΎΠ½Π° вводится с Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° (Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ символа ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки), ΠΈ выполняСт Π΅Π΅ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹ΠΌ
shell
. Если командная строка Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ создана ΠΈΠ· кусочков, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ±Π΅Π³Π½ΡƒΡ‚ΡŒ ΠΊ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ памяти ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ
sprintf
. Π’ ΠΊΠΎΠ½Ρ†Π΅ Ρ€Π°Π·Π΄Π΅Π»Π° ΠΌΡ‹ рассмотрим Π±ΠΎΠ»Π΅Π΅ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ
system
для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ, Π½ΠΎ ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π² Ρ†Π΅Π»ΠΎΠΌ, обсудим структуры, ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½Π° составляСтся.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ процСсса Π½ΠΈΠ·ΠΊΠΎΠ³ΠΎ уровня:
execlp
ΠΈ
execvp

Бамая ваТная опСрация - Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±Π΅Π· Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ систСмного Π²Ρ‹Π·ΠΎΠ²Π°

execlp
. НапримСр, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΏΠ΅Ρ‡Π°Ρ‚Π°Ρ‚ΡŒ Π΄Π°Ρ‚Ρƒ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΌ самым послСднСС дСйствиС Π·Π°ΠΏΡƒΡ‰Π΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚

execlp("date", "date", (char*)0);

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚

execlp
Π΅ΡΡ‚ΡŒ имя Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹;
execlp
Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ ΠΏΡƒΡ‚ΡŒ поиска (Ρ‚.Π΅.
$PATH
) ΠΈΠ· вашСго окруТСния ΠΈ выполняСт Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ поиск, ΠΊΠ°ΠΊ
shell
. Π’Ρ‚ΠΎΡ€ΠΎΠΉ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ β€” это ΠΈΠΌΠ΅Π½Π° ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄; для Π½ΠΎΠ²ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΎΠ½ΠΈ становятся массивом
argv
. ΠšΠΎΠ½Π΅Ρ† списка ΠΎΡ‚ΠΌΠ΅Ρ‡Π΅Π½ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ 0. (Π‘ΠΌ. справочноС руководство ΠΏΠΎ
exec(2)
, ΠΈ Π²Ρ‹ ΠΏΠΎΠΉΠΌΠ΅Ρ‚Π΅ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ
execlp
.)

Π’Ρ‹Π·ΠΎΠ²

execlp
ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½ΠΎΠ²ΠΎΠΉ, запускаСт Π΅Π΅ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ. ΠŸΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠ³Π΄Π° Ρ„Π°ΠΉΠ» Π½Π΅ удаСтся Π½Π°ΠΉΡ‚ΠΈ ΠΈΠ»ΠΈ ΠΎΠ½ являСтся Π½Π΅Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠΌΡ‹ΠΌ:

execlp("date", "date", (char*)0);

fprintf(stderr, "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ 'date'\n");

exit(1);

Если число Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π²Π°ΠΌ Π·Π°Ρ€Π°Π½Π΅Π΅ Π½Π΅ извСстно, ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ

execvp
(Π²Π°Ρ€ΠΈΠ°Π½Ρ‚
execlp
). Π’Ρ‹Π·ΠΎΠ² выглядит Ρ‚Π°ΠΊ:

execvp(filename, argp);

Π³Π΄Π΅

argp
ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ массив ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΊ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌ (Ρ‚Π°ΠΊΠΈΠΌ, ΠΊΠ°ΠΊ
argv
). ПослСдним Π² массивС Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ
NULL
, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ
execvp
ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Π΅Ρ† списка. Как ΠΈ для
execlp
,
filename
β€” это Ρ„Π°ΠΉΠ», Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ находится ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°,
argp
β€” массив
argv
для Π½ΠΎΠ²ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, a
argp[0]
β€” имя ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Ни ΠΎΠ΄Π½Π° ΠΈΠ· пСрСчислСнных Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π½Π΅ обСспСчиваСт Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Π² спискС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² мСтасимволов Ρ‚ΠΈΠΏΠ°

<
,
>
,
*
, ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ ΠΈ Ρ‚.ΠΏ. Если ΠΎΠ½ΠΈ Π²Π°ΠΌ Π½ΡƒΠΆΠ½Ρ‹, Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ
execlp
ΠΈ Π²Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅
/bin/sh
ΠΈΠ·
shell
, которая Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ эту Ρ€Π°Π±ΠΎΡ‚Ρƒ. БконструируйтС строку
commandline
, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ ΠΏΠΎΠ»Π½ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ, ΠΊΠ°ΠΊ Ссли Π±Ρ‹ ΠΎΠ½Π° Π±Ρ‹Π»Π° Π½Π°ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π½Π° Π½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

execlp("/bin/sh/", "sh", "-с", commandline, (char*)0);

АргумСнт

-с
прСдписываСт Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΊΠ°ΠΊ Ρ†Π΅Π»ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡƒΡŽ строку.

Π’ качСствС ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ

exec
рассмотрим ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ
waitfile
. Команда

$ waitfile filename [command]

пСриодичСски провСряСт ΠΏΠΎΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ». Если ΠΎΠ½ Π½Π΅ мСнялся послС послСднСй ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, выполняСтся

command
. Π’ Ρ‚ΠΎΠΌ случаС, ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½Π°, Ρ„Π°ΠΉΠ» копируСтся Π² стандартный Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
waitfile
ΠΌΡ‹ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Ρƒ
troff
, ΠΊΠ°ΠΊ Π²

$ waitfile troff .out echo troff done &

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°

waitfile
ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚
fstat
, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ врСмя послСднСго измСнСния Ρ„Π°ΠΉΠ»Π°.

/* waitfile: wait until file stops changing */

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

char *progname;

main(argc, argv)

Β int argc;

Β char *argv[];

{

Β int fd;

Β struct stat stbuf;

Β time_t old_time = 0;

Β progname = argv[0];

Β if (argc < 2)

Β  error("Usage: %s filename [cmd]", progname);

Β if ((fd = open(argv[1], 0)) == -1)

Β  error("can't open %s", argv[1]);

Β fstat(fd, &stbuf);

Β while(stbuf.st_mtime != old_time) {

Β  old_time = stbuf.st_mtime;

Β  sleep(60);

Β  fstat(fd, &stbuf);

Β }

Β if (argc == 2) { /* copy file */

Β  execlp("cat", "cat", argv[1], (char*)0);

Β  error("can't execute cat %s", argv[1]);

Β } else { /* run process */

Β  execvp(argv[2], &argv[2]);

Β  error("can't execute %s", argv[2]);

Β }

Β exit(0);

}

ΠœΡ‹ рассмотрСли ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΠ°ΠΊ

execlp
, Ρ‚Π°ΠΊ ΠΈ
execvp
. Π­Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π²Ρ‹Π±Ρ€Π°Π½Π° Π² качСствС ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½Π° вСсьма ΠΏΠΎΠ»Π΅Π·Π½Π°, Π½ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹. Π’Π°ΠΊ,
waitfile
ΠΌΠΎΠ³Π»Π° Π±Ρ‹ просто Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒΡΡ ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠΈ измСнСния Ρ„Π°ΠΉΠ»Π°.