рд╕реНрд░реЛрдд рдХреЛрдб, рд╕реНрддрд░ 1, рд╢реЗрд▓
рдЪреВрдВрдХрд┐ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдкреНрд░рд▓реЗрдЦрди рд╕реНрд░реЛрдд рдХреЛрдб рд╣реИ, рд╣рдо рдЗрд╕реЗ рдЪрд╛рд▓реВ рдХрд░реЗрдВрдЧреЗред рдмреИрд╢ рдЗрдирдкреБрдЯ рдХрдорд╛рдВрдбреНрд╕ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Yacc рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ 'рдХрдорд╛рдВрдб_рдХрдиреЗрдХреНрдЯ ()' рд░рд┐рдЯрд░реНрди рджреЗрддрд╛ рд╣реИ рдЬрдм рдпрд╣ рдХреИрд░реЗрдХреНрдЯрд░ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддрд╛ рд╣реИред
parse.y :
1242 pipeline: pipeline '|' newline_list pipeline 1243 { $$ = command_connect ($1, $4, '|'); } 1244 | pipeline BAR_AND newline_list pipeline 1245 { 1246 1247 COMMAND *tc; 1248 REDIRECTEE rd, sd; 1249 REDIRECT *r; 1250 1251 tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1; 1252 sd.dest = 2; 1253 rd.dest = 1; 1254 r = make_redirection (sd, r_duplicating_output, rd, 0); 1255 if (tc->redirects) 1256 { 1257 register REDIRECT *t; 1258 for (t = tc->redirects; t->next; t = t->next) 1259 ; 1260 t->next = r; 1261 } 1262 else 1263 tc->redirects = r; 1264 1265 $$ = command_connect ($1, $4, '|'); 1266 } 1267 | command 1268 { $$ = $1; } 1269 ;
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдпрд╣рд╛рдВ '' | & '' рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рдЬреЛ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ stdout рдФрд░ stderr рджреЛрдиреЛрдВ рдХреЛ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж, command_connect ():
make_cmd.c рдХреА рдУрд░ рдореБрдбрд╝реЗрдВ :
194 COMMAND * 195 command_connect (com1, com2, connector) 196 COMMAND *com1, *com2; 197 int connector; 198 { 199 CONNECTION *temp; 200 201 temp = (CONNECTION *)xmalloc (sizeof (CONNECTION)); 202 temp->connector = connector; 203 temp->first = com1; 204 temp->second = com2; 205 return (make_command (cm_connection, (SIMPLE_COM *)temp)); 206 }
рдЬрд╣рд╛рдВ рдХрдиреЗрдХреНрдЯрд░ рдЪрд░рд┐рддреНрд░ рд╣реИ '|' рдЗрдВрдЯ рдХреА рддрд░рд╣ред рдЖрджреЗрд╢реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╕рдордп ('&', '|', ';', рдЗрддреНрдпрд╛рджрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ), execute_connection () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ:
execute_cmd.c :
2325 case '|': ... 2331 exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
PIPE_IN рдФрд░ PIPE_OUT рдлрд╝рд╛рдЗрд▓ рд╡рд┐рд╡рд░рдг рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╣реИред рд╡реЗ рдорд╛рди NO_PIPE рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ I / O рд╕реНрдЯрдб / рд╕реНрдЯрдбрдЖрдЙрдЯ рд╣реИред
execute_pipeline () рдПрдХ рдмрдбрд╝рд╛ рдХрд╛рдо рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдХреНрд░рд┐рдпрд╛рдиреНрд╡рдпрди
execute_cmd.c рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИред рд╣рдо рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣рд┐рд╕реНрд╕реЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред
execute_cmd.c :
2112 prev = pipe_in; 2113 cmd = command; 2114 2115 while (cmd && cmd->type == cm_connection && 2116 cmd->value.Connection && cmd->value.Connection->connector == '|') 2117 { 2118 2119 if (pipe (fildes) < 0) 2120 { } ....... 2178 execute_command_internal (cmd->value.Connection->first, asynchronous, 2179 prev, fildes[1], fd_bitmap); 2180 2181 if (prev >= 0) 2182 close (prev); 2183 2184 prev = fildes[0]; 2185 close (fildes[1]); ....... 2190 cmd = cmd->value.Connection->second; 2191 }
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдмреИрд╢ рдкрд╛рдЗрдк () рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рдкреНрд░рддреНрдпреЗрдХ '' | '' рд╡рд░реНрдг рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдХреЗ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдкреНрд░рддреАрдХ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рдФрд░ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреБрдХреНрдд рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХрдорд╛рдВрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИред
рд╕реНрд░реЛрдд рдХреЛрдб, рд╕реНрддрд░ 2, рдХрд░реНрдиреЗрд▓
рд╣рдо рдХрд░реНрдиреЗрд▓ рдХреЛрдб рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдкрд╛рдЗрдк () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВред рдпрд╣ рдЖрд▓реЗрдЦ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг 3.10.10 рд╕реНрдерд┐рд░ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рддрд╛ рд╣реИред
fs / pip.c (рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдкрд▓рдмреНрдз рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ):
35 unsigned int pipe_max_size = 1048576; 40 unsigned int pipe_min_size = PAGE_SIZE; 869 int create_pipe_files(struct file **res, int flags) 870 { 871 int err; 872 struct inode *inode = get_pipe_inode(); 873 struct file *f; 874 struct path path; 875 static struct qstr name = {. name = тАЬтАЭ }; 881 path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name); 889 f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops); 893 f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); 896 res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops); 902 res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK); 903 res[1] = f; 904 return 0; 917 } 918 919 static int __do_pipe_flags(int *fd, struct file **files, int flags) 920 { 921 int error; 922 int fdw, fdr; 927 error = create_pipe_files(files, flags); 931 fdr = get_unused_fd_flags(flags); 936 fdw = get_unused_fd_flags(flags); 941 audit_fd_pair(fdr, fdw); 942 fd[0] = fdr; 943 fd[1] = fdw; 944 return 0; 952 } 969 SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags) 970 { 971 struct file *files[2]; 972 int fd[2]; 975 __do_pipe_flags(fd, files, flags); 977 copy_to_user(fildes, fd, sizeof(fd)); 984 fd_install(fd[0], files[0]); 985 fd_install(fd[1], files[1]); 989 } 991 SYSCALL_DEFINE1(pipe, int __user *, fildes) 992 { 993 return sys_pipe2(fildes, 0); 994 }
рдпрджрд┐ рдЖрдкрдиреЗ рджреЗрдЦрд╛, рддреЛ рдХреЛрдб O_NONBLOCK рдзреНрд╡рдЬ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░ рд░рд╣рд╛ рд╣реИред рдЗрд╕реЗ fcntl рдореЗрдВ F_SETFL рдСрдкрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╡рд╣ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ I / O рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд┐рдП рдмрд┐рдирд╛ рдореЛрдб рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдЗрд╕ рдореЛрдб рдореЗрдВ, рд▓реЙрдХ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рд╕реНрдЯреНрд░реАрдо рдХреЛ рдкрдврд╝рдиреЗ / рд▓рд┐рдЦрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЧрд▓рдд рдХреЛрдб EAGAIN рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧреАред
рдкрд╛рдЗрдк рдХреЛ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рдХрд╛ рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ рд╣рд╛рде рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА (4K) рдХрд╛ рдПрдХ рдкреГрд╖реНрда рд╣реИ:
рдореЗрд╣рд░рд╛рдм / рдмрд╛рдВрд╣ / рд╢рд╛рдорд┐рд▓ / asm / limit.h :
8 #define PIPE_BUF PAGE_SIZE
рдЧреБрдард▓реА рдХреЗ рд▓рд┐рдП> = 2.6.35, рдЖрдк рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдмрдлрд░ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ:
fcntl(fd, F_SETPIPE_SZ, <size>)
рдЕрдзрд┐рдХрддрдо рдЕрдиреБрдордд рдмрдлрд░ рдЖрдХрд╛рд░, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдКрдкрд░ рджреЗрдЦрд╛, рдлрд╝рд╛рдЗрд▓ / proc / sys / fs / рдкрд╛рдЗрдк-рдЕрдзрд┐рдХрддрдо-рдЖрдХрд╛рд░ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИред