APUE 책에 IF - ELSE로 구현 된 것을 switch - case로 재구현 한 것. stat 스트럭쳐 의 st_mode 의 내부를 들여다 본 것.

헤더파일과 구현부로 나뉘어 있음.

 
/* Header : myhdr.h */

#include <sys/types.h>
#include <sys/stat.h>
#include "ourhdr.h"

//Defined Values
#define N_IFREG 32768 // 1000 0000 0000 0000
#define N_IFDIR 16384 // 0100 0000 0000 0000   
#define N_IFCHR 8192 // 0010 0000 0000 0000
#define N_IFBLK 24576 // 0110 0000 0000 0000
#define N_IFIFO 4096 // 0001 0000 0000 0000
#define N_IFLNK 40960 // 1010 0000 0000 0000
#define N_IFSOCK 49152 // 1100 0000 0000 0000
#define MASK 61440 // 1111 0000 0000 0000

/* End of myhdr.h */

/* Source : file_mode.c */

#include "myhdr.h"

int main(int argc, char *argv[])
{
    int  i; //for loop
    int   mode ; //mode checker by bits
    struct stat buf;
    char  *ptr;

    for (i = 1; i < argc; i++)
    {
        printf("%s: ", argv[i]);
        if (lstat(argv[i], &buf) < 0)
        {
            err_ret("lstat error");
            continue;
        }

        mode = buf.st_mode & MASK; //Masking

        switch (mode)
        {
            case N_IFREG :
                ptr = "regular";
            break;

            case N_IFDIR :
                ptr = "directory";
            break;

            case N_IFCHR :
                ptr = "character special";
            break;

            case N_IFBLK :
                ptr = "block special";
            break;

            case N_IFIFO :
                ptr = "fifo";
            break;

#ifdef S_IFLNK
            case N_IFLNK :
                ptr = "symbolic link";
            break;
#endif
#ifdef S_IFSOCK
            case N_IFSOCK :
                ptr = "socket";
            break;
#endif
            default :
                ptr = "** unknown mode **";
            break;    
        }//end of switch

        printf("%s\n", ptr);

    }//end of for

    exit(0);
}
/* End of file_mode.c */

'Studies > Advanced Programming in the UNIX Environment' 카테고리의 다른 글

File mode checker  (0) 2008.08.12
myShell  (0) 2008.08.12
myCAT : cat(1)  (0) 2008.08.12
WC : Word Count  (0) 2008.08.10
실행파일 만들기 : Make a .exe file for APUE  (0) 2008.08.10
error.c  (0) 2008.08.10
Posted by 지그프리드 지그프리드
입력받은 커맨드를 실행하고, 그 실행 시간을 측정한다. 유닉스 쉘의 입력 부분만 흉내낸 것

Get command from user, then calculate the command's execute time.
This is a simple UNIX shell. Just make command input part
 

#include <sys/types.h> //for types for time and etc.
#include <sys/wait.h>  //for wait()
#include <signal.h>  //for signal catching
#include "ourhdr.h"  //System Programming Default Header
#include <sys/times.h> //for times()

//functions
static void sig_int(int);  /* our signal-catching function */
static void report(void);  // print report
static void pr_times(clock_t, struct tms *, struct tms *); //time checker

//global variable : to save data
char cmd[80][80];
double rtime[80];
double utime[80];
double stime[80];

int num_of_cmd = -1; // counter

// MAIN  //////////////////////////////////////

int main(void)
{
    char buf[MAXLINE];
    pid_t pid;
    int status;
    struct tms tmsstart, tmsend; //structure for time check
    clock_t start, end;   //variable for time

    if (signal(SIGINT, sig_int) == SIG_ERR) //signal checker
    { err_sys("signal error"); }

    printf("%% "); /* print prompt (printf requires %% to print %) */

    while (fgets(buf, MAXLINE, stdin) != NULL)  //^D를 제외한 입력의 경우 : ^D이면 루프 끝
    {
        buf[strlen(buf) - 1] = 0; /* replace newline with null */
        num_of_cmd++; // Counter ++

        if ( (pid = fork()) < 0)
        { err_sys("fork error"); }
        else if (pid == 0)
        {
            /* child */
            execlp(buf, buf, (char *) 0);  //입력받은 커맨드 실행 후 else if 블록을 빠져나감
            // 커맨드가 실행되지 않는 경우
            err_ret("couldn't execute: %s", buf);
            exit(127);
        }

        strcpy (cmd[num_of_cmd], buf);  //입력 받은 커맨드를 전역변수 배열에 저장

        if ( (start = times(&tmsstart)) == -1) /* starting values */
        { err_sys("times error"); }

        /* parent */
        if ( (pid = waitpid(pid, &status, 0)) < 0)
        { err_sys("waitpid error"); }

        if ( (end = times(&tmsend)) == -1)  /* ending values */
        { err_sys("times error"); }

        pr_times(end-start, &tmsstart, &tmsend); //시간 계산
        printf("%% "); //프롬프트 출력
    }

    report(); //^D 입력시 루프 종료 후 결과 표시

    exit(0);
}

void sig_int(int signo) //시그널 입력 시 출력
{
 //printf("interrupt\n%% ");
}

static void pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend) // 시간 체크
{
    static long clktck = 0;

    if (clktck == 0) /* fetch clock ticks per second first time */
    {
        if ( (clktck = sysconf(_SC_CLK_TCK)) < 0) //시스템 상수를 받아옴
        { err_sys("sysconf error"); }
    }

    // fprintf(stderr, "  real:\t\t%7.2f\n", real / (double) clktck);
    // fprintf(stderr, "  user:\t\t%7.2f\n", (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck);
    // fprintf(stderr, "  system:\t%7.2f\n", (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck);

    rtime[num_of_cmd] = real / (double) clktck; //시간을 계산하여 배열에 저장
    utime[num_of_cmd] = (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck;
    stime[num_of_cmd] = (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck;
}

void report(void)
{
    int loop;

    for (loop = 0; loop <=num_of_cmd; loop++) //전체 시행 시간을 계산, 배열의 마지막에 추가
    {
        strcpy (cmd[num_of_cmd+1], "Total");
        rtime[num_of_cmd+1] += rtime[loop];
        utime[num_of_cmd+1] += utime[loop];
        stime[num_of_cmd+1] += stime[loop];
    }

    // 출력 시작
    printf ("\n\t\tProcess\tSystem time\tUse time\tReal time\n");

    for (loop = 0; loop <=num_of_cmd; loop++)
    {
        if (rtime[loop]==0 && utime[loop]==0 && stime[loop]==0) //커맨드 오류시 모든 시간이 0로 표시됨을 이용, 에러커맨드는 출력하지 않음
        {   /* Do nothing */    }
        else
        {
            fprintf(stderr, "  %s:\t", cmd[loop]);
            fprintf(stderr, "  \t\t%7.2f",rtime[loop]);
            fprintf(stderr, "  \t%7.2f", utime[loop]);
            fprintf(stderr, "  \t%7.2f\n", stime[loop]);
        }
    }

    // total 값 출력
    printf ("-------------------------------------------------------------------\n");
    fprintf(stderr, "  %s:\t", cmd[num_of_cmd+1]);
    fprintf(stderr, "  \t%7.2f",rtime[num_of_cmd+1]);
    fprintf(stderr, "  \t%7.2f", utime[num_of_cmd+1]);
    fprintf(stderr, "  \t%7.2f\n", stime[num_of_cmd+1]);
}

'Studies > Advanced Programming in the UNIX Environment' 카테고리의 다른 글

File mode checker  (0) 2008.08.12
myShell  (0) 2008.08.12
myCAT : cat(1)  (0) 2008.08.12
WC : Word Count  (0) 2008.08.10
실행파일 만들기 : Make a .exe file for APUE  (0) 2008.08.10
error.c  (0) 2008.08.10
Posted by 지그프리드 지그프리드
파일의 내용을 보여주거나, 둘 이상의 파일을 내용을 합쳐서 출력해주는 cat(1)을 직접 구현한 것.

cat는 유닉스에 기본으로 포함되어 있는 명령어이다.

 

#include "ourhdr.h"  //기본 헤더파일 //Common header

int main (int argc, char *argv[])
{
    FILE *file[argc-1];  //파일 포인터 배열 : 입력 받은 파일 명의 수 만큼 파일포인터를 선언
    int loop;    //순환문을 위한 변수
    char buffer;   //Read Buffer

    if (argc <2)   //입력받은 파라메터의 수를 확인
    { err_quit ("Error - One or more parameter is needed."); } //에러 메세지

    for (loop = 0; loop <argc -1; loop++) //출력 루프
    {
        if ( (file[loop] = fopen( argv[loop+1], "r" ) ) ==NULL) //파일 Open이이 실패한 경우
        {
            printf ("cat : %s : No such file or directory\n", argv[loop+1]); //에러메세지
        }
        else           //파일 Open이 성공한 경우
        {
            while ( (buffer = fgetc(file[loop]) )> 0)   //한 바이트씩 읽어서 출력
            {
                printf ("%c",buffer);     //STDOUT 출력
            }     

            if ( (fclose (file[loop])) !=0 )     //출력이 끝나면 파일 Close
            {
                err_sys("%d번째 파일", loop);    //Close 실패 시 에러메세지
            }  
        }
    }

    return 0;
}

'Studies > Advanced Programming in the UNIX Environment' 카테고리의 다른 글

File mode checker  (0) 2008.08.12
myShell  (0) 2008.08.12
myCAT : cat(1)  (0) 2008.08.12
WC : Word Count  (0) 2008.08.10
실행파일 만들기 : Make a .exe file for APUE  (0) 2008.08.10
error.c  (0) 2008.08.10
Posted by 지그프리드 지그프리드
UNIX의 wc(1)의 기능을 구현한 것.

#include "ourhdr.h"  //System Programming Default Header

enum bool {false, true}; //C dosen't support the "boolean" type. So, I defined as enumeration type.


/////////////////////////////////////////
//main function  ////////////
////////////////////////////////////////

int main (int agrc, char *agrv[])
{
    int c = 0;       //get character input
    int lines = 0, words = 0 , bytes = 0; //count lines, words, bytes
    enum bool real_word = false;   //check a byte whether a part of the first word or not

    while ( (c = getchar() )> 0)    //count loop - until EOF (This retuns -1)
    {
        if (c > 33)     //check first character is input or not
            real_word = true;  //character inputed

        if (c=='\n')     //check new-line character
        {
            lines++;     //line count
            words++;     //word count
        }
        else if (c==' ' || c=='\t' || c=='\r' || c=='\v' || c=='\f') //check word seperation conditions
        {
            if (real_word)      //first character inputed
                words++;        //word count
        }

        bytes++;      //byte count
    }

    if (ferror(stdin))     //check stdin error
        err_sys("input error");  //system error massage

    printf ("      %d       %d      %d\n", lines, words, bytes); //print out to stdout

    return 0;
}

'Studies > Advanced Programming in the UNIX Environment' 카테고리의 다른 글

myShell  (0) 2008.08.12
myCAT : cat(1)  (0) 2008.08.12
WC : Word Count  (0) 2008.08.10
실행파일 만들기 : Make a .exe file for APUE  (0) 2008.08.10
error.c  (0) 2008.08.10
ourhdr.h  (0) 2008.08.10
Posted by 지그프리드 지그프리드
역시, Advanced Programming in the UNIX Environment(이하 APUE)의 기본 헤더파일. 다운 받아도 좋고, 직접 긁어 저장해도 좋다.
 

/* Our own header, to be included *after* all standard system headers */

#ifndef __ourhdr_h
#define __ourhdr_h

#include <sys/types.h> /* required for some of our prototypes */
#include <stdio.h>  /* for convenience */
#include <stdlib.h>  /* for convenience */
#include <string.h>  /* for convenience */
#include <unistd.h>  /* for convenience */

#define MAXLINE 4096   /* max line length */

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
     /* default file access permissions for new files */
#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
     /* default permissions for new directories */

typedef void Sigfunc(int); /* for signal handlers */

     /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */
#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((Sigfunc *)-1)
#endif

#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))

     /* prototypes for our own functions */
char *path_alloc(int *);   /* {Prog pathalloc} */
int   open_max(void);   /* {Prog openmax} */
void  clr_fl(int, int);   /* {Prog setfl} */
void  set_fl(int, int);   /* {Prog setfl} */
void  pr_exit(int);    /* {Prog prexit} */
void  pr_mask(const char *);  /* {Prog prmask} */
Sigfunc *signal_intr(int, Sigfunc *);/* {Prog signal_intr_function} */

int   tty_cbreak(int);   /* {Prog raw} */
int   tty_raw(int);    /* {Prog raw} */
int   tty_reset(int);   /* {Prog raw} */
void  tty_atexit(void);   /* {Prog raw} */
#ifdef ECHO /* only if <termios.h> has been included */
struct termios *tty_termios(void); /* {Prog raw} */
#endif

void  sleep_us(unsigned int); /* {Ex sleepus} */
ssize_t  readn(int, void *, size_t);/* {Prog readn} */
ssize_t  writen(int, const void *, size_t);/* {Prog writen} */
int   daemon_init(void);   /* {Prog daemoninit} */

int   s_pipe(int *);    /* {Progs svr4_spipe bsd_spipe} */
int   recv_fd(int, ssize_t (*func)(int, const void *, size_t));
         /* {Progs recvfd_svr4 recvfd_43bsd} */
int   send_fd(int, int);   /* {Progs sendfd_svr4 sendfd_43bsd} */
int   send_err(int, int, const char *);/* {Prog senderr} */
int   serv_listen(const char *); /* {Progs servlisten_svr4 servlisten_44bsd} */
int   serv_accept(int, uid_t *); /* {Progs servaccept_svr4 servaccept_44bsd} */
int   cli_conn(const char *); /* {Progs cliconn_svr4 cliconn_44bsd} */
int   buf_args(char *, int (*func)(int, char **));
         /* {Prog bufargs} */

int   ptym_open(char *);   /* {Progs ptyopen_svr4 ptyopen_44bsd} */
int   ptys_open(int, char *); /* {Progs ptyopen_svr4 ptyopen_44bsd} */
#ifdef TIOCGWINSZ
pid_t  pty_fork(int *, char *, const struct termios *,
      const struct winsize *); /* {Prog ptyfork} */
#endif

int  lock_reg(int, int, int, off_t, int, off_t);
         /* {Prog lockreg} */
#define read_lock(fd, offset, whence, len) \
   lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)
#define readw_lock(fd, offset, whence, len) \
   lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len)
#define write_lock(fd, offset, whence, len) \
   lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)
#define writew_lock(fd, offset, whence, len) \
   lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)
#define un_lock(fd, offset, whence, len) \
   lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)

pid_t lock_test(int, int, off_t, int, off_t);
         /* {Prog locktest} */

#define is_readlock(fd, offset, whence, len) \
   lock_test(fd, F_RDLCK, offset, whence, len)
#define is_writelock(fd, offset, whence, len) \
   lock_test(fd, F_WRLCK, offset, whence, len)

void err_dump(const char *, ...); /* {App misc_source} */
void err_msg(const char *, ...);
void err_quit(const char *, ...);
void err_ret(const char *, ...);
void err_sys(const char *, ...);

void log_msg(const char *, ...);  /* {App misc_source} */
void log_open(const char *, int, int);
void log_quit(const char *, ...);
void log_ret(const char *, ...);
void log_sys(const char *, ...);

void TELL_WAIT(void);  /* parent/child from {Sec race_conditions} */
void TELL_PARENT(pid_t);
void TELL_CHILD(pid_t);
void WAIT_PARENT(void);
void WAIT_CHILD(void);

#endif /* __ourhdr_h */


'Studies > Advanced Programming in the UNIX Environment' 카테고리의 다른 글

myCAT : cat(1)  (0) 2008.08.12
WC : Word Count  (0) 2008.08.10
실행파일 만들기 : Make a .exe file for APUE  (0) 2008.08.10
error.c  (0) 2008.08.10
ourhdr.h  (0) 2008.08.10
Advanced Programming in the UNIX Environment  (0) 2008.08.10
Posted by 지그프리드 지그프리드

http://www.yendor.com/programming/unix/apue/apue.html


Advanced Programming in the


UNIX Environment

by W. Richard Stevens

Addison-Wesley Professional Computing Series
0-201-56317-7 * Hardback * 768 pages * ©1992
Web/HTML/man-page-linking by: Ariel Faigon


위 주소에 가면 이 책의 모든 소스를 구할 수 있다.


정말, 주옥같은 소스코드들이 실려있는 책이다. 아직 본격적으로 본문을 읽지는 않고, 소스코드만 보고 있는데, 그것만으로도 이 책의 진가를 알 수 있다.

'Studies > Advanced Programming in the UNIX Environment' 카테고리의 다른 글

myCAT : cat(1)  (0) 2008.08.12
WC : Word Count  (0) 2008.08.10
실행파일 만들기 : Make a .exe file for APUE  (0) 2008.08.10
error.c  (0) 2008.08.10
ourhdr.h  (0) 2008.08.10
Advanced Programming in the UNIX Environment  (0) 2008.08.10
Posted by 지그프리드 지그프리드

BLOG main image
일상, 프로그래밍, IT 그리고 직장생활, Dive, 여행 by 지그프리드

카테고리

Class List (402)
Studies (30)
Exercise & Quizz (10)
Term Project (0)
ECIM list (Help!) (10)
Issues & News (0)
Gossip about IT & Job (22)
Tools (2)
Think about the Justice (23)
Book Review (170)
조엘 온 소프트웨어(번역) (28)
Diary (87)
Vacations (9)
Clash of clans 클래시 오브.. (11)

글 보관함

달력

«   2019/06   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
Total : 313,389
Today : 12 Yesterday : 11