Главная · Поиск книг · Поступления книг · 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 ... 73 74 75 76 77 78 79  80 81 82 83 84 85 86 87
int MEMcheck_consistency(AllocFrame *ptr){
        MemFileRecord mr_found;
        int nrecords, i, found = 0;
        size_t size;

        MEMopenFd();

        /* Ищем запись в таблице указателей */
        lseek(mem_fd, 0L, SEEK_SET);    /* перемотать в начало */
        for(;;){
                size = read(mem_fd, memrecords, sizeof memrecords);
                nrecords = size / sizeof(memrecords[0]);

                if(nrecords <= 0) break;

                for(i=0; i < nrecords; i++)
                        if(memrecords[i].ptr == ptr){
                        /* Мы ищем последнюю запись про память
                         * с таким адресом, поэтому
                         * вынуждены прочитать ВЕСЬ файл.
                         */
                                mr_found = memrecords[i];
                                found++;
                        }
        }
        if(found) {
                return MEMcheckRecord(&mr_found);
        } else {
                printf("%p -- запись в таблице отсутствует.\n", ptr);
                return NOTHERE;
        }
}

/* Уничтожить все прежние записи про ptr, прописывая их adjsize=0 */
void MEMerasePreviousRecords(AllocFrame *ptr){
        int nrecords, i, found;
        size_t size;

        MEMopenFd();
        lseek(mem_fd, 0L, SEEK_SET);    /* перемотать в начало */
        for(;;){
                found = 0;
                size = read(mem_fd, memrecords, sizeof memrecords);
                nrecords = size / sizeof(memrecords[0]);

                if(nrecords <= 0) break;

                for(i=0; i < nrecords; i++)
                        if(memrecords[i].ptr == ptr){
                                memrecords[i].adjsize = 0;
                                /* memrecords[i].size = 0; */
                                found++;
                        }
                if(found){
                        lseek(mem_fd, -size, SEEK_CUR);    /* шаг назад */
                        write(mem_fd, memrecords, size);   /* перезаписать */
                }
        }
}

void MEMcheckAll(){
#ifdef CHECKALL
        int nrecords, i;
        size_t size;

        printf("Проверка всех указателей -------------\n");
        MEMopenFd();
        lseek(mem_fd, 0L, SEEK_SET);    /* перемотать в начало */
        for(;;){
                size = read(mem_fd, memrecords, sizeof memrecords);
                nrecords = size / sizeof(memrecords[0]);

                if(nrecords <= 0) break;

                for(i=0; i < nrecords; i++)
                        if(memrecords[i].adjsize != 0)
                                MEMcheckRecord(&memrecords[i]);
        }
        printf("Проверка всех указателей завершена ---\n");
#endif
}

/* ============================================================= */
/* Заполнение пограничных зон образцом - "следовой дорожкой" */
void MEMmakeRedZones(char *cptr, size_t size, size_t adjsize){
        register i;

        for(i=0; i < adjsize; i++){
                if(i <  RedZoneTypeSize || i >= RedZoneTypeSize + size ){
                   /* головная погранзона ИЛИ
                    * хвостовая погранзона + дополнение
                    * до целого числа RedZoneType-ов
                    */
                        cptr[i] = red_table[ i % RedZoneTypeSize ];
                }
        }
}
/* ============================================================= */
/* Функция выделения памяти */
void *MEMmalloc(size_t size){
        AllocFrame *retptr;
        int fullRedZoneTypes =
                (size + RedZoneTypeSize - 1) / RedZoneTypeSize;
        size_t adjustedSize =
                sizeof(retptr->red_zone) * 2 + /* две погранзоны */
                fullRedZoneTypes * RedZoneTypeSize;

        retptr  = (AllocFrame *) malloc(adjustedSize);
        if(retptr == NULL) return NULL;

        MEMmakeRedZones ((char *) retptr, size, adjustedSize);
        MEMputTableRecord(retptr, retptr, size, adjustedSize);
        return &retptr->stuff[0];
        /* вернуть указатель на зону данных */
}

void *MEMrealloc(void *ptr, size_t size){
        AllocFrame *retptr;
        char *cptr = (char *)ptr - RedZoneTypeSize;  /* прежний AllocFrame */
        AllocFrame *oldptr = (AllocFrame *) cptr;
        int fullRedZoneTypes =
                (size + RedZoneTypeSize - 1) / RedZoneTypeSize;
        size_t adjustedSize =
                sizeof(retptr->red_zone) * 2 +
                fullRedZoneTypes * RedZoneTypeSize;

        /* Проверить сохранность того, что мы сейчас будем realloc-ить */
        MEMcheck_consistency(oldptr);

        retptr  = (AllocFrame *) realloc((void *)oldptr, adjustedSize);
        if(retptr == NULL) return NULL;

        MEMmakeRedZones ((char *) retptr, size, adjustedSize);
        MEMputTableRecord(retptr, oldptr, size, adjustedSize);
        return &retptr->stuff[0];
}

void *MEMcalloc(size_t n, size_t size){
        size_t newsize = n * size;
        void *ptr = MEMmalloc(newsize);
        memset(ptr, '\0', newsize);
        return ptr;
}

/* Очистка отведенной памяти.
 * ptr - это указатель не на AllocFrame,
 * а на данные - то есть на stuff[0].
 */
void MEMfree(void *ptr){
        char *cptr = (char *)ptr - RedZoneTypeSize;
        int i, code;

        code = MEMcheck_consistency((AllocFrame *) cptr);
        for(i=0; i < RedZoneTypeSize; i++)
                cptr[i] = free_table[i];

        if(code != FREED) free((void *) cptr);

        MEMputTableRecordKilled((AllocFrame *) cptr);
}

/* ============================================================= */
/* Тестовый пример                                               */
/* ============================================================= */
#define MAXPTRS 512
char *testtable[MAXPTRS];

/* Сгенерировать строку случайной длины со случайным содержимым */
char *wildstring(int c){
#define N 1024
        char teststring[N + 1];
        int len, i;
        char *ptr;

        len = rand() % N;
        for(i=0; i < len; i++)
                teststring[i] = c;
        teststring[len] = '\0';

        ptr = (char *) MEMmalloc(len + 1);
        if(ptr){
                strcpy(ptr, teststring);
        } else printf("NULL wildstring()\n");

        return ptr;
}

int main(int ac, char *av[]){
        int ilen, len, n, i;

        srand(time(NULL));

        for(n=0; n < MAXPTRS; n++)
                testtable[n] = wildstring('A');

#define DAMAGE (MAXPTRS/3*2-1)
#ifdef DAMAGE
        /* Навести порчу */
        len = strlen(testtable[DAMAGE]);
        testtable[DAMAGE][len+1] = 'x';
        testtable[DAMAGE][-2]    = 'y';
        printf("ptr=%p len=%d\n", testtable[DAMAGE], len);
#endif
        for(n=0; n < MAXPTRS/2; n++){
                char *p = wildstring('B');
                int length = strlen(p);
                char *ptr;

                i = rand() % MAXPTRS;
                /* Не забыть присвоить возвращенное realloc() значение
                 * обратно в testtable[i] !!!
                 */
                testtable[i] = ptr =
                        (char *) MEMrealloc(testtable[i], length + 1);

                if(ptr == NULL) printf("Не могу сделать realloc()\n");
                else            strcpy(ptr, p);

#ifdef DAMAGE
                /* Порча */
                if(n == MAXPTRS/3){
                        ptr[length+2] = 'z';
                }
#endif
                MEMfree(p);
        }

        for(n=0; n < MAXPTRS; n++){
                if(testtable[n]) MEMfree(testtable[n]);
        }
#ifdef DAMAGE
        MEMfree(testtable[DAMAGE]);
#endif
        return 0;
}

        /*      Пример 12     */

/* Программа, совмещающая команды mv и cp. Иллюстрация работы с файлами.
 * Пример того, как программа может выбирать род работы
 * по своему названию.
 * Компиляция:
 *              cc cpmv.c -o copy ; ln copy move
 * По мотивам книги М.Дансмура и Г.Дейвиса.
 */

#include               /* буферизованный ввод/вывод */
#include           /* системные типы данных */
#include            /* struct stat           */
#include               /* O_RDONLY              */
#include               /* системные коды ошибок */

/* #define strrchr rindex           /* для версии ДЕМОС (BSD)    */
extern char *strrchr(char *, char); /* из библиотеки libc.a      */
extern int   errno;
char    MV[] = "move"; char CP[] = "copy";
#define OK      1       /* success - успех   */
#define FAILED  0       /* failure - неудача */
#define YES     OK
#define NO      0

/* Выделить базовое имя файла:
 *     ../wawa/xxx  -->   xxx
 *     zzz          -->   zzz
 *     /            -->   /
 */
char *basename( char *name ){
        char *s      = strrchr( name , '/' );
        return (s    == NULL) ? name : /* нет слэшей       */
               (s[1] == '\0') ? name : /* корневой каталог */
                                s + 1;
}
#define ECANTSTAT (-1)  /* файл не существует */
struct ftype {
       unsigned type;  /* тип файла */
       dev_t    dev;   /* код устройства, содержащего файл */
       ino_t    ino;   /* индексный узел файла на этом устройстве */
};
/* Получение типа файла */
struct ftype filetype( char *name /* имя файла */   )
{
        struct stat st; struct ftype f;

        if( stat( name, &st ) < 0 ){
                 f.type = ECANTSTAT; f.dev = f.ino = 0;
        } else { f.type = st.st_mode & S_IFMT;
                 f.dev  = st.st_dev; f.ino = st.st_ino;
        }
        return f;
}
/* Удаляет файлы, кроме устройств */
int unlinkd( char *name, unsigned type )
{
        if( type == S_IFBLK || type == S_IFCHR || type == S_IFDIR)
                return 0;
        return unlink( name );
}
/* Функция нижнего уровня: копирование информации большими порциями */
int copyfile( int from, int to )
        /* from - дескриптор откуда */
        /* to   - дескриптор куда   */
{
        char buffer[ BUFSIZ ];
        int n; /* число прочитанных байт */

        while(( n = read( from, buffer, BUFSIZ )) > 0 )
        /* read возвращает число прочитанных байт,
         * 0 в конце файла
         */
                    if( write( to,  buffer, n ) != n ){
                        printf( "Write error.\n" );
                        return FAILED;
                    }
        return OK;
}
/* Копирование файла */
int docopy(char *src, char *dst, unsigned typefrom, unsigned typeto)
{       int retc; int fdin, fdout;
        printf( "copy %s --> %s\n", src, dst );

        if((fdin = open( src, O_RDONLY )) < 0 ){
                printf( "Сan't read %s\n", src );
                return FAILED;
        }
        if((fdout = creat( dst, 0644 )) < 0 ){  /* rw-r--r-- */
                printf( "Can't create %s\n", dst );
                return FAILED;
        }
        retc = copyfile( fdin, fdout );
        close( fdin ); close( fdout );
        return retc;
}
/* Переименование файла. Вернуть OK, если удачно, FAILED - неудачно */
int mlink(char *src, char *dst, unsigned typefrom, unsigned typeto)
{
        switch( typefrom ){
        case S_IFDIR:           /* переименование каталога */
                printf( "rename directory %s --> %s\n", src, dst );

                if( access( dst, 0 ) == 0 ){
                /* 0 - проверить существование файла */
                        printf( "%s exists already\n", dst );
                        /* файл уже существует */
                        return FAILED;
                }
                if( link( src, dst ) < 0 ){
                    printf( "Can't link to directory %s\n", dst );
                    perror( "link" );
                 /* Возможно, что для выполнения link() для каталогов,
Предыдущая страница Следующая страница
1 ... 73 74 75 76 77 78 79  80 81 82 83 84 85 86 87
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама