Типовые задачи прака (не с комиссии, но стоит уметь их решать) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 Написать программу tail , печатающую n последних строк файла. Число n и Имя файла задается с помощью аргументов командной стоки. Обращение вида tail n filename, печатает n последних строк файла с именем filename. Если строк в файле меньше n, тогда печатаются все строки файла. #include main(int argc, char **argv) { int n=10; int fd1; char e; FILE *f; if( argc!=2 ) { printf( "\n\nUsage: tail1 " ); return 1; } if( (fd1=open( argv[1], _F_READ ))==-1 ) { printf( "Error opening '%s' for reading.\n", argv[1] ); return 2; } lseek( fd1, 0, SEEK_END ); while( n && lseek( fd1, 0, SEEK_CUR ) ) { read(fd1, &e, 1 ); if( e=='\n' ) n--; lseek( fd1, -2, SEEK_CUR ); } if( e=='\n' ) lseek( fd1, +2, SEEK_CUR ); while( (read(fd1, &e, 1)==1 ) printf( "%c", e ); close( fd1 ); return 0; } 2 Написать программу head, печатающую n первых строк файла. Число n и имя файла задается с помощью аргументов командной стоки. Обращение вида head n filename, печатает n первых строк файла с именем filename. Если строк в файле меньше n, тогда печатаются все строки файла. # include # include char name[50]; char e; main () { sscanf( "%s", name ); f=open( name, O_RDONLY ); for( i=0; i<10; ) { if( !read( f, &e, 1 ) ) break; if( e=='\n' ) i++; printf( "%c", e ); } } 3 Написать программу, реализующую следующую схему: процесс 2 считывает строку с клавиатуры и посылает ее через канал процессу 4, который выводит строку на экран. // task with a sophisticated process hierarchy #include #include char s; int fd[2]; main() { pipe( fd ); if( !fork() ) while( (s=getchar())!='\n' ) write( fd[1], &s, 1 ); if( !fork() ) if( !fork() ) while( (read( fd[0], &s, 1 )==1 ) printf( "%c", s ); return 0; } 4 Написать ф-ю strindex(s,t), кот. Выдает позицию самого правого вхождения t в s или 1, если вхождение не обнаружено. # include # include int strindex (char*s, char t) { int i, len=-1; for (i=1,i #include main() { char mas[50],c; int fd, sh=o,max=0; scanf ("%s",mas); fd=open(mas,O_RONLY); while (read(fd,&c,1)!=0) { if (c!=',') sh++; else { if (max # include int strend (char*s, char *t) { int i; char *d; d=t+strlen(t); s=s+strlen(s); for (i=0, i # include void replace(char *s1,char *s2) { int i, flag=0; for (i=0,i main( int argc, int **argv ) { int fd[2]; if( argc<3 ){ printf( "Go and learn C!! \n" ); return 1; } pipe(fd); if( !fork() ) { dup2( fd[1], 1 ); execvp( argv[1], argv[1], 0 ); printf( "%s not found\n", argv[1] ); return 1; } if( !fork() ) { dup2( fd[0], 0 ); execvp( argv[2], argv[2], 0 ); printf( "%s not found\n", argv[2]); return 1; } return 0; } 1.2 Написать на Си прогу, обрабатывающую каждое четное возникновение сигнала SIGTRAP форматированием двух сыновьих процессов, связанных каналом. /* Предполагается: в условии задачи имеется в виду, что при каждом четном получении сигнала SIGTRAP отец ФОРМИРУЕТ НОВУЮ пару сыновей, связанных каналом. */ #include #include int fd[2]; // флаг четности поступившего сигнала int flg; void hand( int sig ) { // восстановим перехват сигнала signal( SIGTRAP, hand ); if( flg ) { pipe(fd); flg=0; if( !fork() ) { .... // здесь работает первый сын } if( !fork() ) { .... // здесь работает второй сын } } else flg=1; } main() { flg=1; signal( SIGTRAP, hand ); while( 1 ); return 0; } 2.1 Дан текстовый файл с именем Name. Написать прогу, инвертирующую (запись наоборот) данный файл без использования доп. рабочих файлов.. #include #include int fd1, fd2; char a, b; long int p1, p2; char *Name; main() { .... // будем считать, что здесь Name некоторым образом задается fd1=open( Name, O_RDWR ); p1=0; fd2=open( Name, O_RDWR ); p2=lseek( fd2, 0, SEEK_END ); while( p2-p1>0 ) { read( fd1, &a, 1 ); read( fd2, &b, 1 ); lseek( fd1, -1, SEEK_CUR ); lseek( fd2, -1, SEEK_CUR ); write( fd1, &b, 1 ); write( fd2, &a, 1 ); lseek( fd2, -2, SEEK_CUR ); } close( f1 ); close( f2 ); } 2.2 Написать прогу, которая свяжет каналом процесс-внук с правнуком, при этом, процесс-внук имеет доступ к файлу Name2. Процесс внук должен передать через канал процессу правнуку содержание файла Name2. Правнук должен изменить (создать) файл Name3, чтобы тот содержал инвертированную копию Name2. Рабочие файлы не использовать. #include #include int pp[2]; int fd1, fd2; int p; if( !fork() ) if( !fork() ) { pipe(pp); if( !fork() ) { fd2=open( Name3, O_WRONLY ); // we also suppose here all's o.k. while( read( pp[0], &c, 1 )==1 ) { write( fd2, &c, 1 ); return 0; } fd1=open( Name2, O_RDONLY ); // we suppose that everything's ok with Name2 lseek( fd1, 0, SEEK_END ); if( read( fd1, &c, 1 ) ) { write( pp[1], &c, 1); // move 1 byte away from end of file lseek( fd1, -1, SEEK_CUR ); do { write( pp[1], &c, 1 ); p=lseek( fd1, -2, SEEK_CUR ); read( fd1, &c, 1 ); } while( p ); write( pp[1], &c, 1 ); } // don't make other process wait for nothing, close pipe close(pp); return 0; }