Chương trình ngắn dưới đây nhằm lặp qua argv truyền từ dòng lệnh và thực hiện từng đối số. Đây không phải là bài tập về nhà của tôi, mà đúng hơn là tôi đang chuẩn bị làm bài tập ở nhà.Tôi có hiểu cách các trình mô tả tập tin Unix hoạt động trong C không?
Đối số đầu tiên được nhập từ STDIN và STDOUT và ghi vào một đường ống. Vào cuối mỗi lần lặp (ngoại trừ lần cuối), các bộ mô tả tập tin được hoán đổi, sao cho đường dẫn được viết bởi lệnh cuối cùng sẽ được đọc từ lần kế tiếp. Theo cách này, tôi có ý định, ví dụ: đối với
./a.out /bin/pwd /usr/bin/wc
để chỉ in chiều dài của thư mục làm việc. Mã sau
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
main(int argc, char * argv[]) {
int i;
int left[2], right[2], nbytes; /* arrays for file descriptors */
/* pointers for swapping */
int (* temp);
int (* leftPipe) = left;
int (* rightPipe) = right;
pid_t childpid;
char readbuffer[80];
/* for the first iteration, leftPipe is STDIN */
leftPipe[0] = STDIN_FILENO;
leftPipe[1] = STDOUT_FILENO;
for (i = 1; i < argc; i++) {
/* reopen the right pipe (is this necessary?) */
pipe(rightPipe);
fprintf(stderr, "%d: %s\n", i, argv[i]);
fprintf(stderr, "%d %d %d %d\n", leftPipe[0], leftPipe[1], rightPipe[0], rightPipe[1]);
if ((childpid = fork()) == -1) {
perror("fork");
exit(1);
}
if (childpid == 0) {
/* read input from the left */
close(leftPipe[1]); /* close output */
dup2(leftPipe[0], STDIN_FILENO);
close(leftPipe[0]); /* is this necessary? A tutorial seemed to be doing this */
/* write output to the right */
close(rightPipe[0]); /* close input */
dup2(rightPipe[1], STDOUT_FILENO);
close(rightPipe[1]);
execl(argv[i], argv[i], NULL);
exit(0);
}
wait();
/* on all but the last iteration, swap the pipes */
if (i + 1 < argc) {
/* swap the pipes */
fprintf(stderr, "%d %d %d %d\n", leftPipe[0], leftPipe[1], rightPipe[0], rightPipe[1]);
temp = leftPipe;
leftPipe = rightPipe;
rightPipe = temp;
fprintf(stderr, "%d %d %d %d\n", leftPipe[0], leftPipe[1], rightPipe[0], rightPipe[1]);
}
}
/* read what was last written to the right pipe */
close(rightPipe[1]); /* the receiving process closes 1 */
nbytes = read(rightPipe[0], readbuffer, sizeof(readbuffer));
readbuffer[nbytes] = 0;
fprintf(stderr, "Received string: %s\n", readbuffer);
return 0;
}
CẬP NHẬT: trong tất cả các trường hợp thử nghiệm dưới đây Ban đầu tôi đã sử dụng/bin/wc nhưng mà WC reveiled rằng closet nước không phải là ở tất cả các nơi mà tôi nghĩ. Tôi đang trong quá trình sửa đổi kết quả.
Sản lượng trong một vụ án tầm thường (./a.out/bin/pwd) là như mong đợi:
1: /bin/pwd
Received string: /home/zeigfreid/Works/programmatical/Langara/spring_2012/OS/labs/lab02/play
Kết quả chạy chương trình này với ví dụ đầu tiên (./a.out/bin/pwd/usr/bin/wc):
1: /bin/pwd
0 1 3 4
3 4 0 1
2: /bin/wc
Tại thời điểm đó, thiết bị đầu cuối bị treo (có thể đang chờ nhập).
Như bạn thấy, chuỗi không được nhận. Điều tôi tưởng tượng là tôi đã làm điều gì đó sai ở trên, hoặc khi hoán đổi con trỏ, hoặc tôi không hiểu các mô tả tập tin unix. Nhiệm vụ của tôi, cuối cùng, sẽ là để giải thích các đường ống dài tùy tiện, và đây là một trong những ý tưởng tôi có để giải quyết vấn đề. Tôi đang gặp khó khăn khi đánh giá liệu tôi có đang đi đúng hướng để sủa cây không. Tôi có hiểu các mô tả tập tin unix không?
UPDATE:
Chạy nó với/bin/ls như là đối số thứ hai, tôi nhận được kết quả như sau (các con số là file descriptor tại các điểm khác nhau):
1: /bin/pwd
0 1 3 4
0 1 3 4
3 4 0 1
2: /bin/ls
3 4 5 6
Received string: a.out
log
pipe2.c
play.c
@
Có vẫn còn một số rác cuối cùng ở đó, nhưng bây giờ tôi quan tâm nhiều hơn là tôi không hiểu con trỏ! Hai lệnh này độc lập với nhau mặc dù chúng không thực sự sử dụng đường ống.
CẬP NHẬT: ký tự rác từ không đóng chuỗi. Bây giờ tôi đóng nó, và không có rác.
tôi muốn đề nghị thay đổi tất cả 'printf của bạn (...) 'gọi vào' fprintf (stderr , ...) '. Trộn chuẩn IO ('printf (3)') với các thường trình mức thấp hơn ('pipe (2)', 'dup2 (2)', 'close (2)') là rắc rối nhiều hơn giá trị. – sarnold
Lưu ý đúng! Tôi tưởng tượng nẹp sẽ đồng ý. – Ziggy
Bạn không chấm dứt chuỗi trước khi in, điều này giải thích rác. Hãy thử 'readbytes [nbytes] = 0' sau' read'. –