Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Богатырев А. Весь текст 1009.15 Kb

Хрестоматия по программированию на Си в Unix

Предыдущая страница Следующая страница
1 ... 74 75 76 77 78 79 80  81 82 83 84 85 86 87
                  * программа должна обладать правами суперпользователя.
                  */
                    return FAILED;
                }
                unlink( src );
                return OK;

        default:   /* dst - не существует или обычный файл */
                printf( "move %s --> %s\n", src, dst );
                unlinkd( dst, typeto );
                /* зачищаем место, т.к. link()
                 * отказывается выполняться, если
                 * файл dst уже существует (errno==EEXIST).
                 */
                if( link( src, dst ) < 0 ) return FAILED;
                unlinkd( src, typefrom );  /* удаляем старый файл */
                return OK;
        }
}
/* Если не получилось связать файл при помощи link() - следует
 * скопировать файл в указанное место, а затем уничтожить старый файл.
 */
int mcopy(char *src, char *dst, unsigned typefrom, unsigned typeto)
{
        if( typefrom == S_IFDIR )
                return FAILED;
        /* каталог не копируем, поскольку непосредственная запись
         * в каталог (как целевой файл) разрешена только ядру ОС.
         */
        return docopy( src, dst, typefrom, typeto );
}
/* Переименование файла */
int domove(char *src, char *dst, unsigned typefrom, unsigned typeto)
{
        switch( typefrom ){
        default:
           if( ! mlink( src, dst, typefrom, typeto)){
                 if( ! mcopy( src, dst, typefrom, typeto)){
                       printf( "Can't move %s\n", src );
                       return FAILED;
                 } else unlinkd( src, typefrom ); /* стереть старый */
           }
           break;

        case S_IFDIR: /* каталог переименовываем в каталог */
           if( ! strcmp( ".", basename(src))){
                 printf( "impossible to move directory \".\"\n" );
                 return FAILED;
           }
           if( ! mlink( src, dst, typefrom, typeto )){
                 if( errno == EXDEV )
                     printf( "No cross device directory links\n" );
                 return FAILED;
           }
           break;

        case ECANTSTAT:
           printf( "%s does not exist\n", src );
           return FAILED;
        }
        return OK;    /* okay */
}
int docpmv( char *src,   /* файл-источник   */
            char *dst,   /* файл-получатель */
            struct ftype typeto, /* тип файла-получателя              */
            int cp,      /* 0 - переименование, 1 - копирование       */
            int *confirm /* запрашивать подтверждение на перезапись ? */
){
        struct ftype typefrom;  /* тип источника       */
        char namebuf[BUFSIZ];   /* новое имя получателя (если надо)   */

        typefrom = filetype(src);
        if(typefrom.type == ECANTSTAT){ /* не существует */
           printf("%s does not exist.\n", src);
           return FAILED;
        }
        if( typefrom.type != S_IFDIR && typeto.type == S_IFDIR ){
                /* файл в каталоге dst */
                sprintf(namebuf, "%s/%s", dst, basename(src));
                typeto = filetype(dst = namebuf);
        }
        if(typefrom.dev == typeto.dev && typefrom.ino == typeto.ino){
        /* Нельзя копировать файл сам в себя */
           printf("%s and %s are identical.\n", src, dst);
           return OK;  /* так как файл уже есть - считаем это удачей */
        }
        /* если получатель уже существует, то
         * запросить подтверждение на перезапись */
        if(*confirm && typeto.type == S_IFREG){
           char answer[40];
           printf("%s already exists. Overwrite (y/n/all) ? ", dst);
           fflush(stdout);
           switch( *gets(answer)){
           case 'n': default:  return OK; /* ничего не делать */
           case 'y':           break;
           case 'a': *confirm = NO; /* дальше - без запросов */
                     break;
           }
        }
        return cp ? docopy(src, dst, typefrom.type, typeto.type) :
                    domove(src, dst, typefrom.type, typeto.type) ;
}
void main(int argc, char *argv[]) {
        char *cmd; int cp, i, err, confirm = YES;
        struct ftype typeto;  /* тип файла-получателя */

        if( argc < 3 ) {
                printf( "Usage: %s source... destination\n", argv[0] );
                exit(1);
                /* ненулевой код возврата сигнализирует об ошибке */
        }
        /* выделяем базовое имя программы. */
        cmd = basename( argv[0] );

        if     ( !strcmp( cmd, CP )) cp = 1;
        else if( !strcmp( cmd, MV )) cp = 0;
        else{
                printf( "%s - wrong program name.\n", cmd );
                exit(2);
        }
        typeto = filetype( argv[argc-1] );
        if(cp && typeto.type != S_IFDIR && typeto.type != S_IFBLK
              && typeto.type != S_IFCHR && argc > 3){
                printf("Group of files can be copied "
                       "to the directory or device only.\n"); exit(3);
        }
        if(!cp && typeto.type != S_IFDIR && argc > 3){
                printf("Group of files can be moved "
                       "to the directory only.\n");           exit(4);
        }
        for(err=0, i=1; i < argc-1; i++)
                err += ! docpmv(argv[i], argv[argc-1], typeto,
                                cp, &confirm);
        exit(err);  /* 0, если не было ошибок */
}

        /*      Пример 13          */

/* Обход дерева каталогов в MS DOS при помощи смены текущего каталога.
 * Аналог ls -R в UNIX. По аналогичному алгоритму работает программа
 * find . -print  (напишите команду find, используя match())
 */
#define STYLE2
#include 
#include 
#include 
#include 
#include       /* для malloc() */
#include      /* strchr(), strrchr(), strcpy(), ... */

                /* прототипы */
char *strend(char *s); char *strdup(const char *s);
void action(int, char **); void main(int, char **);
int listdir(char *); void printdir(int n);
#ifdef STYLE2
void lookdir(char *s, int ac, char **av, register int level);
#else
void lookdir(char *s, int ac, char **av);
#endif

char root[256]; /* имя стартового каталога */
char cwd[256];  /* полное имя текущего каталога */

char *strend(register char *s){ while(*s)s++; return s; }
char *strdup(const char *s){ /* прототип malloc в  */
   char *p = (char *) malloc(strlen(s) + 1);
   if(p) strcpy(p, s); return p;
}

stop(){  /* Реакция на control/break */
   chdir( root );
   /* Это необходимо потому, что MS DOS имеет (в отличие от UNIX)
      понятие "текущий каталог" как глобальное для всей системы.
      Если мы прервем программу, то окажемся не в том каталоге,
      откуда начинали. */
   printf( "\nInterrupted by ctrl-break\n");
   return 0;  /* exit */
}

void main(int argc, char **argv){
    /* получить имя текущего каталога */
    (void) getcwd(root, sizeof root);
    ctrlbrk( stop );  /* установить реакцию на ctrl/break */
#ifndef STYLE2
    lookdir( "." /* корень дерева */, argc, argv );
#else
    /* для примера: дерево от "\\" а не от "." */
    lookdir( "\\", argc, argv, 0 /* начальный уровень */ );
#endif /*STYLE2*/
    chdir(root); /* вернуться в исх. каталог */
}

# ifndef STYLE2
  void lookdir(char *s, int ac, char **av){
       static int level = 0;   /* уровень рекурсии */
# else
  void lookdir(char *s, int ac, char **av, register int level){
# endif /*STYLE2*/
   struct ffblk dblk, *psd = &dblk;
   register done;

   if( chdir(s) < 0 ){ /* войти в каталог */
       printf( "Cannot cd %s\n", s ); return;
   } else if (level == 0){ /* верхний уровень */
       (void) getcwd(cwd, sizeof cwd);
       /* получить полное имя корня поддерева */
   }
   action(ac, av);

   /* искать имена каталогов, удовлетворяющие шаблону "*" */
   /* (не в алфавитном порядке !)                         */
   done = findfirst("*.", psd, FA_DIREC);
   while( !done ){
     if((psd->ff_attrib & FA_DIREC) && psd->ff_name[0] != '.' ){
        /* Видим каталог: войти в него! */
        char *tail =  strend(cwd); char *addplace;
        if( tail[-1] == '\\' ){
            addplace = tail;
        }else{
            *tail = '\\'; addplace = tail+1;
        }
        strcpy(addplace, psd->ff_name);
#ifndef STYLE2
        level++; lookdir( psd->ff_name, ac, av ); level--;
#else
                 lookdir( psd->ff_name, ac, av,   level+1 );
#endif
        *tail = '\0';
     }
     /* Искать следующее имя. Информация о точке, где был
      * прерван поиск, хранится в dblk */
     done = findnext(psd);
   }
   if( level ) chdir( ".." );  /* выйти вверх */
}

/* Выполнить действия в каталоге */
void action(int ac, char **av){
   extern int busy;
   busy = 0;
   if( ac == 1 ) listdir( "*.*" );
   else{
       av++;
       while( *av ) listdir( *av++ );
   }
   printdir( busy );
}

#define MAXF 400
struct fst{
    char *name; long size; short attr;
} files[MAXF];
int busy;       /* сколько имен собрано */

/* Собрать имена, удовлетворяющие шаблону. */
int listdir( char *picture ){
    int done, n; struct ffblk dentry;

    for(n=0, done=findfirst(picture, &dentry,0xFF /* все типы */);
         busy < MAXF && !done ;
         done = findnext( &dentry )){
            files[busy].name = strdup(dentry.ff_name);
            files[busy].size = dentry.ff_fsize;
            files[busy].attr = dentry.ff_attrib;
            n++; busy++;
    }
    return n;
}

/* int cmp(struct fst *a, struct fst *b)       */
/* новые веяния в Си требуют такого прототипа: */
int cmp(const void *a, const void *b){
    return strcmp(((struct fst *) a) -> name,
                  ((struct fst *) b) -> name );
}

/* отсортировать и напечатать */
void printdir(int n){
    register i;
    struct fst *f;

    qsort( files, n, sizeof files[0], cmp );
    printf( "Directory %s\n", cwd );
    for( i=0, f = files; i < n; i++, f++ )
      printf("\t%-16s\t%10ld\t%c%c%c%c%c%c\n",
           f->name, f->size,
           f->attr & FA_DIREC  ? 'd':'-',  /* directory */
           f->attr & FA_RDONLY ? 'r':'-',  /* read only */
           f->attr & FA_HIDDEN ? 'h':'-',  /* hidden */
           f->attr & FA_SYSTEM ? 's':'-',  /* system */
           f->attr & FA_LABEL  ? 'l':'-',  /* volume label */
           f->attr & FA_ARCH   ? 'a':'-'   /* archive */
      ), free(f->name);
    putchar('\n');
}

        /*      Пример 14      */
/* Демонстрация работы с longjmp/setjmp и сигналами */
/* По мотивам книги М.Дансмура и Г.Дейвиса.         */
#include 
#include 
#include 
#include 
/*#define IGN*/         /* потом откомментируйте эту строку */

jmp_buf cs_stack;       /* control point */
int in_cs;              /* флаг, что мы в критической секции */
int sig_recd;           /* флаг signal received */

/* активная задержка */
Delay(){
        int i; for( i=0; i < 10000; i++ ){ i += 200; i -= 200; }
}

interrupt( code ){
        fprintf( stderr, "\n\n***\n" );
        fprintf( stderr, "*** Обрабатываем сигнал (%s)\n",
                              code == 1 ? "разрешенный" : "отложенный" );
        fprintf( stderr, "***\n\n" );
}

/* аргумент реакции на сигнал - номер сигнала (подставляется системой) */
void mexit( nsig ){
  fprintf( stderr, "\nУбили сигналом #%d...\n\n", nsig ); exit(0);
}

void main(){
    extern void sig_vec(); int code; int killable = 1;

    signal( SIGINT,  mexit );
    signal( SIGQUIT, mexit );
 fprintf( stderr, "Данная программа перезапускается по сигналу INTR\n" );
 fprintf( stderr, "Выход из программы по сигналу QUIT\n\n\n" );
 fprintf( stderr, "Сейчас вы еще можете успеть убить эту программу...\n\n" );
    Delay(); Delay(); Delay();

    for(;;){
        if( code = setjmp( cs_stack )){
                /* Возвращает не 0, если возврат в эту точку произошел
Предыдущая страница Следующая страница
1 ... 74 75 76 77 78 79 80  81 82 83 84 85 86 87
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама