; close (0); /* 0 - */ fcntl (fd, F_DUPFD, 0 ); /* 0 - */ close (fd); $ a.out < _ . 0 1, stdin stdout, open creat, "r" "w". dup2 |-: new = open("1",...); dup2(new, old); close(new); ...## ## new----##---> 1 new---##---> 1 ## ## old----##---> 2 old---## 2 ## ## 0: 1: old 2 dup2() ( old, ) ## ## new----##--*--> 1 new ## *----> 1 ## | ## | old----##--* old--##--* ## ## 2: old 1 3: close(new); dup2 . new . 1 2 - " " , - ( /). dup2 new old R/W- . , new old : dup2(new, old); write(new, "a", 1); write(old, "b", 1); write(new, "c", 1); 1 "abc". ____________________ |- int system(char *); , , - /bin/sh -c "" . , 1992-95 - 159 - UNIX int fd; printf( "Hi there\n"); fd = creat( "newout", 0640 ); dup2(fd, 1); close(fd); printf( "Hey, You!\n"); , - newout, printf stdout, 1. 4.33. , , . argc - . . 4.34. , , - . #include <stdio.h> char buf[512], word[] = "#"; main(){ char *s; int len = strlen(word); while((s=fgets(buf, sizeof buf, stdin)) && strncmp(s, word, len)); fputs(s? s: " .\n", stdout); } 4.35. , ߔ , >>>ߔ : #include <stdio.h> char line[512]; main(){ FILE *fp = fopen("00", "w"); while(gets(line) != NULL) if( !strncmp(line, ">>>", 3)){ if( freopen(line+3, "a", fp) == NULL){ fprintf(stderr, "Can't write to '%s'\n", line+3); fp = fopen("00", "a"); } } else fprintf(fp, "%s\n", line); } 4.36. stdio , . - read write: fread ( ) : ____________________ . popen (pipe open) , (pipe). fp, .. - . ____________________ |- dup2 "dup to", "to" 2, "to" "two" : "". "From me 2 You". 4 "for". . , 1992-95 - 160 - UNIX int fread(addr, size, count, fp) register char *addr; unsigned size, count; FILE *fp; { register c; unsigned ndone=0, sz; if(size) for( ; ndone < count ; ndone++){ sz = size; do{ if((c = getc(fp)) >= 0 ) *addr++ = c; else return ndone; }while( --sz ); } return ndone; } , count - ( read), size . . fwrite . : #include <stdio.h> #define MAXPTS 200 #define N 127 char filename[] = "pts.dat"; struct point { int x,y; } pts[MAXPTS], pp= { -1, -2}; main(){ int n, i; FILE *fp = fopen(filename, "w"); for(i=0; i < N; i++) /* */ pts[i].x = i, pts[i].y = i * i; /* N */ fwrite((char *)pts, sizeof(struct point), N, fp); fwrite((char *)&pp, sizeof pp, 1, fp); fp = freopen(filename, "r", fp); /* fclose(fp); fp=fopen(filename, "r"); */ /* */ n = fread(pts, sizeof pts[0], MAXPTS, fp); for(i=0; i < n; i++) printf(" #%d(%d,%d)\n",i,pts[i].x,pts[i].y); } , fwrite, , - ,  , . -  , "" . - : fprintf, fscanf, fputs, fgets. , , : - . ! lseek fseek: fseek(fp, offset, whence); lseek, . /! - long ftell(fp); fp. fseek " ", feof(fp); . , 1992-95 - 161 - UNIX 4.37. ( "- " - ): #include <stdio.h> #include <sys/types.h> #include <sys/dir.h> main(){ FILE *fp; struct direct d; char buf[DIRSIZ+1]; buf[DIRSIZ] = '\0'; fp = fopen( '/', "r" ); while( fread( &d, sizeof d, 1, fp) == 1 ){ if( !d.d_ino ) continue; /* */ strncpy( buf, d.d_name, DIRSIZ); printf( "%s\n", buf ); } fclose(fp); } : fopen(). ! '/' "/" - ( !). , main ( - "."). 4.38. fputs( , fp); printf( , ...); fprintf(fp, , ...); , '\0', - . , , - . ? . fp 4 "\033e\0\5". : putc('\033',fp); putc('e', fp); putc('\000',fp); putc('\005',fp); ( ), : fprintf( fp, "\033e%c\5", '\0'); write ( fileno(fp), "\033e\0\5", 4 ); fwrite ( "\033e\0\5", sizeof(char), 4, fp); 4 - . 4.39. " " . : ( ) long (, off_t), fgets() ftell(). n- fseek() fgets(). #include <stdio.h> #define MAXLINES 2000 /* . */ FILE *fp; /* */ int nlines; /* */ long offsets[MAXLINES];/* */ extern long ftell();/* */ . , 1992-95 - 162 - UNIX char buffer[256]; /* */ /* */ void getSeeks(){ int c; offsets[0] =0L; while((c = getc(fp)) != EOF) if(c =='\n') /* - */ offsets[++nlines] = ftell(fp); /* \n , */ /* , */ if(ftell(fp) != offsets[nlines]) nlines++; printf( "%d \n", nlines); } char *getLine(n){ /* n */ fseek(fp, offsets[n], 0); return fgets(buffer, sizeof buffer, fp); } void main(){ /* - */ int i; fp = fopen("INPUT", "r"); getSeeks(); for( i=nlines-1; i>=0; --i) printf( "%3d:%s", i, getLine(i)); } 4.40. ? #include <stdio.h> main(){ printf( "Hello, " ); printf( "sunny " ); write( 1, "world", 5 ); } : , "Hello, sunny world", printf stdout, 1, 1 - . , ! "worldHello, sunny ". , printf , write - . printf stdout, write , . , write() stdout: fflush( stdout ); - stdout: printf setbuf(stdout, NULL); , stderr , . : . . , 1992-95 - 163 - UNIX , - , '\n' (" "). stdout : printf("Hello\n"); (.. printf stdout '\n'). : setlinebuf(fp); setvbuf(fp, NULL, _IOLBF, BUFSIZ); , - ! 4.41. , . - '\7' ('\a' ANSI). , . (, printf() putchar() , ( ) fflush() ). : 1: register i; for(i=0; i<3; i++){ putchar( '\7' ); fflush(stdout); sleep(1); /* 1 . */ } 2: register i; for(i=0; i<3; i++){ write(1, "\7", 1 ); sleep(1); } 4.42. ? printf( "..."); sleep ( 5 ); /* 5 . */ printf( "\n" ); : - stdout. , , . "" 5 . ! printf() , sleep() fflush(stdout) . : stderr , : fprintf( stderr, "..." ); 4.43. . EOF? #include <stdio.h> FILE *fwr, *frd; char b[40], *s; int n = 1917; main(){ fwr = fopen( "aFile", "w" ); . , 1992-95 - 164 - UNIX frd = fopen( "aFile", "r" ); fprintf( fwr, "%d: Hello, dude!", n); s = fgets( b, sizeof b, frd ); printf( "%s\n", s ? s : "EOF" ); } : fwr : ! fflush(fwr); fprintf(). : FILE *fp = fopen("users", "w"); ... fprintf(fp, ...); ... system("sort users | uniq > 00; mv 00 users"); fp (, ) . fclose(fp) system, fflush(fp); 4.44. UNIX ( !) . - , ( ). - . - - , read, write, lseek - . , , ioctl (input/output control): ioctl(fd, _, );  , , _ - , ( -   ). _ . TCGETA, (. " "). , ( ), - ( ): #include <termio.h> int isatty(fd){ struct termio tt; return ioctl(fd, TCGETA, &tt) < 0 ? 0 : 1; } main(){ printf("%s\n", isatty(0 /* STDIN */)? "term":"no"); } isatty |-. "", - , , .  (. ). - : /dev/null , " ". : read(...)==0; (). , , , - ( , ), . /dev/null: . , 1992-95 - 165 - UNIX $ a.out > /dev/null & : $ cp /dev/hd00 /dev/null " ". , - . , . /dev/tty  , ; - |=. , - , , : #include <stdio.h> void message(char *s){ FILE *fptty = fopen("/dev/tty", "w"); fprintf(fptty, "%s\n", s); fclose (fptty); } main(){ message("Tear down the wall!"); } ( ) ( ). O_TRUNC - . - ( - /dev/tty) fd=creat("/dev/tty", 0644); - mknod, unlink-. - " UNIX". 4.45. STDIO, 4.2 BSD. #include <fcntl.h> #define BUFSIZ 512 /* */ #define _NFILE 20 #define EOF (-1) /* */ #define NULL ((char *) 0) #define IOREAD 0x0001 /* */ #define IOWRT 0x0002 /* */ #define IORW 0x0004 /* */ #define IONBF 0x0008 /* */ #define IOTTY 0x0010 /* */ #define IOALLOC 0x0020 /* malloc- */ #define IOEOF 0x0040 /* */ #define IOERR 0x0080 /* / */ ____________________ |- , fd , extern char *ttyname(); char *tname = ttyname(fd); , "/dev/tty01". fd - . , 1992-95 - 166 - UNIX extern char *malloc(); extern long lseek(); typedef unsigned char uchar; uchar sibuf[BUFSIZ], sobuf[BUFSIZ]; typedef struct _iobuf { int cnt; /* */ uchar *ptr, *base; /* */ int bufsiz, flag, file; /* , , */ } FILE; FILE iob[_NFILE] = { { 0, NULL, NULL, 0, IOREAD, 0 }, { 0, NULL, NULL, 0, IOWRT|IOTTY, 1 }, { 0, NULL, NULL, 0, IOWRT|IONBF, 2 }, }; #define stdin (&iob[0]) #define stdout (&iob[1]) #define stderr (&iob[2]) #define putchar(c) putc((c), stdout) #define getchar() getc(stdin) #define fileno(fp) ((fp)->file) #define feof(fp) (((fp)->flag & IOEOF) != 0) #define ferror(fp) (((fp)->flag & IOERR) != 0) #define clearerr(fp) ((void) ((fp)->flag &= ~(IOERR | IOEOF))) #define getc(fp) (--(fp)->cnt < 0 ? \ filbuf(fp) : (int) *(fp)->ptr++) #define putc(x, fp) (--(fp)->cnt < 0 ? \ flsbuf((uchar) (x), (fp)) : \ (int) (*(fp)->ptr++ = (uchar) (x))) int fputc(int c, FILE *fp){ return putc(c, fp); } int fgetc( FILE *fp){ return getc(fp); } ____________________ NULL. ____________________ |= u-area : u_ttyp, u_ttyd,  . /dev/tty, , ..   ! UNIX. . , 1992-95 - 167 - UNIX /* */ FILE *fopen(char *name, char *how){ register FILE *fp; register i, rw; for(fp = iob, i=0; i < _NFILE; i++, fp++) if(fp->flag == 0) goto found; return NULL; /* */ found: rw = how[1] == '+'; if(*how == 'r'){ if((fp->file = open(name, rw ? O_RDWR:O_RDONLY)) < 0) return NULL; fp->flag = IOREAD; } else { if((fp->file = open(name, (rw ? O_RDWR:O_WRONLY)| O_CREAT | (*how == 'a' ? O_APPEND : O_TRUNC), 0666 )) < 0) return NULL; fp->flag = IOWRT; } if(rw) fp->flag = IORW; fp->bufsiz = fp->cnt = 0; fp->base = fp->ptr = NULL; return fp; } /* */ void fflush(FILE *fp){ uchar *base; int full= 0; if((fp->flag & (IONBF|IOWRT)) == IOWRT && (base = fp->base) != NULL && (full=fp->ptr - base) > 0){ fp->ptr = base; fp->cnt = fp->bufsiz; if(write(fileno(fp), base, full) != full) fp->flag |= IOERR; } } /* */ void fclose(FILE *fp){ if((fp->flag & (IOREAD|IOWRT|IORW)) == 0 ) return; fflush(fp); close(fileno(fp)); if(fp->flag & IOALLOC) free(fp->base); fp->base = fp->ptr = NULL; fp->cnt = fp->bufsiz = fp->flag = 0; fp->file = (-1); } /* exit()- */ void _cleanup(){ register i; for(i=0; i < _NFILE; i++) fclose(iob + i); } /* */ void exit(uchar code){ _cleanup(); _exit(code); /* */ } . , 1992-95 - 168 - UNIX /* */ int filbuf(FILE *fp){ static uchar smallbuf[_NFILE]; if(fp->flag & IORW){ if(fp->flag & IOWRT){ fflush(fp); fp->flag &= ~IOWRT; } fp->flag |= IOREAD; /* */ } if((fp->flag & IOREAD) == 0 || feof(fp)) return EOF; while( fp->base == NULL ) /* */ if( fp->flag & IONBF ){ /* */ fp->base = &smallbuf[fileno(fp)]; fp->bufsiz = sizeof(uchar); } else if( fp == stdin ){ /* */ fp->base = sibuf; fp->bufsiz = sizeof(sibuf); } else if((fp->base = malloc(fp->bufsiz = BUFSIZ)) == NULL) fp->flag |= IONBF; /* */ else fp->flag |= IOALLOC; /* */ if( fp == stdin && (stdout->flag & IOTTY)) fflush(stdout); fp->ptr = fp->base; /* */ if((fp->cnt = read(fileno(fp), fp->base, fp->bufsiz)) == 0 ){ fp->flag |= IOEOF; if(fp->flag & IORW) fp->flag &= ~IOREAD; return EOF; } else if( fp->cnt < 0 ){ fp->flag |= IOERR; fp->cnt = 0; return EOF; } return getc(fp); } . , 1992-95 - 169 - UNIX /* */ int flsbuf(int c, FILE *fp){ uchar *base; int full, cret = c; if( fp->flag & IORW ){ fp->flag &= ~(IOEOF|IOREAD); fp->flag |= IOWRT; /* */ } if((fp->flag & IOWRT) == 0) return EOF; tryAgain: if(fp->flag & IONBF){ /* */ if(write(fileno(fp), &c, 1) != 1) { fp->flag |= IOERR; cret=EOF; } fp->cnt = 0; } else { /* */ if((base = fp->base) == NULL){ /* */ if(fp == stdout){ if(isatty(fileno(stdout))) fp->flag |= IOTTY; else fp->flag &= ~IOTTY; fp->base = fp->ptr = sobuf; /* */ fp->bufsiz = sizeof(sobuf); goto tryAgain; } if((base = fp->base = malloc(fp->bufsiz = BUFSIZ))== NULL){ fp->bufsiz = 0; fp->flag |= IONBF; goto tryAgain; } else fp->flag |= IOALLOC; } else if ((full = fp->ptr - base) > 0) if(write(fileno(fp), fp->ptr = base, full) != full) { fp->flag |= IOERR; cret = EOF; } fp->cnt = fp->bufsiz - 1; *base++ = c; fp->ptr = base; } return cret; } /* */ int ungetc(int c, FILE *fp){ if(c == EOF || fp->flag & IONBF || fp->base == NULL) return EOF; if((fp->flag & IOREAD)==0 || fp->ptr <= fp->base) if(fp->ptr == fp->base && fp->cnt == 0) fp->ptr++; else return EOF; fp->cnt++; return(* --fp->ptr = c); } /* */ void setbuffer(FILE *fp, uchar *buf, int size){ fflush(fp); if(fp->base && (fp->flag & IOALLOC)) free(fp->base); fp->flag &= ~(IOALLOC|IONBF); if((fp->base = fp->ptr = buf) == NULL){ fp->flag |= IONBF; fp->bufsiz = 0; } else fp->bufsiz = size; fp->cnt = 0; } . , 1992-95 - 170 - UNIX /* "" */ void rewind(FILE *fp){ fflush(fp); lseek(fileno(fp), 0L, 0); fp->cnt = 0; fp->ptr = fp->base; clearerr(fp); if(fp->flag & IORW) fp->flag &= ~(IOREAD|IOWRT); } /* / */ #ifdef COMMENT base ptr IOREAD | |<----cnt---->| 0L | | | |=======######@@@@@@@@@@@@@@======== file | |<-p->|<-dl-->| |<----pos---->| | | |<----offset(new)-->| | |<----RWptr---------------->| pos = RWptr - cnt; // offset = pos + p = RWptr - cnt + p = lseek(file,0L,1) - cnt + p : ( SEEK_SET) p = offset+cnt-lseek(file,0L,1); ( SEEK_CUR) dl = RWptr - offset = p - cnt lseek(file, dl, 1); , : if( cnt > 0 && p <= cnt && base <= ptr + p ){ ptr += p; cnt -= p; } #endif /*COMMENT*/ . , 1992-95 - 171 - UNIX int fseek(FILE *fp, long offset, int whence){ register resync, c; long p = (-1); clearerr(fp); if( fp->flag & (IOWRT|IORW)){ fflush(fp); if(fp->flag & IORW){ fp->cnt = 0; fp->ptr = fp->base; fp->flag &= ~IOWRT; } p = lseek(fileno(fp), offset, whence); } else if( fp->flag & IOREAD ){ if(whence < 2 && fp->base && !(fp->flag & IONBF)){ c = fp->cnt; p = offset; if(whence == 0) /* SEEK_SET */ p += c - lseek(fileno(fp), 0L, 1); else offset -= c; if(!(fp->flag & IORW) && c > 0 && p <= c && p >= fp->base - fp->ptr ){ fp->ptr += (int) p; fp->cnt -= (int) p; return 0; /* done */ } resync = offset & 01; } else resync = 0; if(fp->flag & IORW){ fp->ptr = fp->base; fp->flag &= ~IOREAD; resync = 0; } p = lseek(fileno(fp), offset-resync, whence); fp->cnt = 0; /* filbuf(); */ if(resync) getc(fp); } return (p== -1 ? -1 : 0); } /* */ long ftell(FILE *fp){ long tres; register adjust; if(fp->cnt < 0) fp->cnt = 0; if(fp->flag & IOREAD) adjust = -(fp->cnt); else if(fp->flag & (IOWRT|IORW)){ adjust = 0; if(fp->flag & IOWRT && fp->base && !(fp->flag & IONBF)) /* */ adjust = fp->ptr - fp->base; } else return (-1L); if((tres = lseek(fileno(fp), 0L, 1)) < 0) return tres; return (tres + adjust); } . , 1992-95 - 172 - UNIX 5. . ("") ( -  ); ,   . struct { int x, y; /* */ char s[10]; /* - */ } s1; : struct XYS { int x, y; /* */ char str[10]; /* - */ }; , ( ). : struct XYS s2, *sptr = &s2; ( , - ): __._ __ -> _ #define 0 struct { int , ; } x; #define 1 x. = 175; int x[2]; x[] = 175; s1.x = 13; strcpy(s2.str, "Finish"); sptr->y = 27;  : struct XYS_Z { struct XYS xys; int z; } a1; a1.xys.x = 71; a1.z = 12;   - . -  ( ).  : struct node { int value; struct node *next; }; : . , 1992-95 - 173 - UNIX struct XYS array[20]; int i = 5, j; array[i].x = 12; j = array[i].x; , {} : extern struct node n2; struct node n1 = { 1, &n2 }, n2 = { 2, &n1 }, n3 = { 3, NULL }; n2 , &n2 n1 . ( - ): struct XYS s1, s2; ... s2 = s1; , : int a[5], b[5]; a = b; /* ! */ : typedef struct _Point { short x, y; /* */ char *s; /* */ } Point; Point p; Point *pptr; short *iptr; struct _Curve { Point points[25]; /* */ int color; /* */ } aLine[10], *linePtr = & aLine[0]; ... pptr = &p; /* p */ p.x = 1; p.y = 2; p.s = "Grue"; linePtr->points[2].x = 54; aLine[5].points[0].y = 17; ---------+------------+------------+-----------+----------- p.x | pptr->x | (*pptr).x | (&p)->x | 1 ---------+------------+------------+-----------+----------- &p->x | -----------+----------------+------------------+----------- iptr= &p.x | iptr= &pptr->x | iptr= &(pptr->x) | -----------+----------------+--------+---------+----------- *pptr->s | *(pptr->s) | *p.s | p.s[0] | 'G' -----------+----------------+--------+---------+----------- pptr->s[1] | (&p)->s[1] | p.s[1] | 'r' -----------+----------------+------------------+----------- &p->s[1] | -----------+----------------+------------------+----------- (*pptr).s | pptr->s | p.s | "Grue" -----------+----------------+------------------+----------- *pptr.s | -----------------------------------------------+----------- . , 1992-95 - 174 - UNIX (&p)->field = p.field pptr->field = (*pptr).field - ,  . struct a{ int x, y; char *s; } A; union b{ int i; char *s; struct a aa; } B; : ________________________ A: | A.x int | ------------------------ . | A.y int | ------------------------ "" . | A.s char * | ------------------------ "", . _______________________________________________________ B: | B.i int | B.s char * | B.aa : B.aa.x int | -----------| | struct a : B.aa.y int | ---------------| : B.aa.s char * | |___________________________| "" , (" ", ), ("/"). , . union  - - . , - short : union lb { char s[2]; short i; } x; unsigned hi, lo; x.i = (02 << 8) | 01; hi = x.s[1]; lo = x.s[0]; printf( "%d %d\n", hi, lo); : #include <stdio.h> union { int i; unsigned char s[sizeof(int)]; } u; void main(){ unsigned char *p; int n; u.i = 0x12345678; for(n=0, p=u.s; n < sizeof(int); n++, p++){ printf("%02X ", *p); } putchar('\n'); } . , 1992-95 - 175 - UNIX long : union xx { long l; struct ab { short a; /* low word */ short b; /* high word */ } ab; } c; main(){ /* IBM PC 80386 00020001 */ c.ab.a = 1; c.ab.b = 2; printf("%08lx\n", c.l ); } 5.1. : structure { int arr[12], char string, int *sum } 5.2. , , - , . . struct month { char name[10]; /* char *name; */ char abbrev[4]; /* char *abbrev; */ int days; int num; }; struct month months[12] = { /* */ {"" , "", 31, 1 }, /* 0 */ {"", "", 28, 2 }, /* 1 */ ... {"", "", 31, 12}, /* 11 */ }, *mptr = & months[0]; /* *mptr = months */ main(){ struct month *mptr; printf( "%s\n", mptr[1].name ); printf( "%s %d\n", mptr->name, mptr->num ); } , months ; , . fprintf fscanf. , name char name[10] char *name? : malloc() strcpy(), .. ( - ). main(). "", - ? : mptr, main()? : " " - ( - - ), , mptr, ! mptr main. . , 1992-95 - 176 - UNIX , printf() , .