;
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() ,
.