if((stf.st_mode & S_IFMT) == S_IFREG){
/* dirname */
struct statvfs fs;
char tmpbuf[MAXPATHLEN+1];
if(dirname == NULL){
/* 'to' - , */
strcpy(tmpbuf, to);
if(s = strrchr(tmpbuf, '/')){
if(*tmpbuf != '/' || s != tmpbuf){
/* "../xxx"
* :
* ,
* "/" "/xxx"
*/
*s = '\0';
}else{
/* "/" "/xxx" */
if(s[1]) s[1] = '\0';
}
dirname = tmpbuf;
} else dirname = ".";
}
if(statvfs(dirname, &fs) >= 0){
size_t size = (geteuid() == 0 ) ?
/* : */
fs.f_frsize * fs.f_bfree :
/* : */
fs.f_frsize * fs.f_bavail;
if(size < stf.st_size){
error("Not enough free space on %s: have %lu, need %lu",
dirname, size, stf.st_size);
close(fdin);
return (-5);
}
}
}
if((fdout = creat(to, stf.st_mode)) < 0){
error("Can't create %s", to);
close(fdin);
return (-6);
} else {
fchmod(fdout, stf.st_mode);
fchown(fdout, stf.st_uid, stf.st_gid);
}
. , 1992-95 - 211 - UNIX
while (n = read (fdin, iobuf, sizeof iobuf)) {
if(n < 0){
error ("read error");
code = (-7);
goto done;
}
if(write (fdout, iobuf, n) != n) {
error ("write error");
code = (-8);
goto done;
}
}
done:
close (fdin);
close (fdout);
/* : */
if(stat(to, &stt) >= 0 && (stt.st_mode & S_IFMT) == S_IFREG){
if(stf.st_size < stt.st_size){
error("File has grown at the time of copying");
} else if(stf.st_size > stt.st_size){
error("File too short, target %s removed", to);
unlink(to);
code = (-9);
}
}
return code;
}
int main(int argc, char *argv[]){
int i, code = 0;
progname = argv[0];
if(argc < 3){
error("Usage: %s from... to", argv[0]);
return 1;
}
for(i=1; i < argc-1; i++)
code |= copyFile(argv[argc-1], argv[i]) < 0 ? 1 : 0;
return code;
}
struct statvfs ( ):
long:
f_frsize
f_blocks
f_bfree ( )
f_bavail ( )
f_files I-nodes
f_ffree I-nodes ( )
f_favail I-nodes ( )
char *
f_basetype : ufs, nfs, ...
. , 1992-95 - 212 - UNIX
, -
(
, ). ufs - UNIX file system
BSD 4.x
6.4. .
UNIX .
.
- . ? ,
: -
(). -, - " ?",
, , .
-, , , -
. .
. -
, .
, . ""
, ; (
). () .
. ,
(
) - . -
gets, ,
. - . -
, (
- : -
( ),
, ...).
- . , -
- . , -
. :
. - , -
, . (
, , ). , -
5- , - 34-. -
, , .
, -
. include-
<signal.h> SIG. 1..NSIG-1,
NSIG . ,
: , .
" ". ,
; - ,
"".
:
- ,
kill(pid, sig);
pid - () -, sig - .
- -
.
- . , -
,
.
.
- -
SIGINT SIGQUIT. ,
. -
.
- - . :
. , 1992-95 - 213 - UNIX
- ( );
- ( ), - ,
;
- ( );
-.
. signal:
#include <signal.h>
void (*signal(int sig, void (*react)() )) ();
react :
SIG_IGN
sig . ( SIGKILL)
.
SIG_DFL
( - ).
_
void fr(gotsig){ ..... } /* */
... signal (sig, fr); ... /* */
sig fr,
, -
gotsig==sig. , ..
:
... signal (sig1, fr); signal(sig2, fr); ...
fr() .
-
SIG_DFL, fr.
, - ,
.
; .
: G - ; D - (k),
(i); C - : core,
adb; F - ; S -
, .
G D C F S
SIGTERM + k - + -
SIGKILL - k - + -
SIGINT + k - + -
SIGQUIT + k + + -
SIGALRM + k - + +
SIGILL + k + - +
SIGBUS + k + + +
SIGSEGV + k + + +
SIGUSR1, USR2 + i - + -
SIGCLD + i - + +
- SIGILL ,
: "" -
""
SIGILL. - -
( ),
. ,
. , 1992-95 - 214 - UNIX
.
- SIGALRM alarm() (. ).
- SIGCLD - -
exit ( ). -
( ) , -
wait (. ). - -
.
- SIG_IGN SIG_DFL , .. -
.
- signal ,
void (*f)(); .
- ()
(), .
UNIX .
, BSD ( -
).
" ",
. "" () ,
"":
|
sighold(sig);
| :
:<--- sig,
: ,
| : "", .
| :
sigrelse(sig);
|<----------- sig
| ,
| .
sig,
.
( ):
mask |= (1 << (sig - 1));
sig, ,
( ).
sighold "" ,
, . sigrelse "-
" ( ) .
sigset(sig, react);
signal, , -
react, sig ; react -
sighold, - sigrelse. ,
, ,
"" , (
sigrelse).
sigpause(sig);
""
sighold(sig);
...
sigpause(sig);
...
sigrelse(sig);
. , 1992-95 - 215 - UNIX
sig.
sig ( sigset),
"" sig.
UNIX POSIX sigaction, sigproc-
mask, sigpending, sigsuspend. !
6.4.1. , /etc/termcap. -
SIGINT, "?". 'y' - -
; 'n' - ; 'r' - :
lseek(fd,0L,0). SIGINT,
.
#include <signal.h>
void onintr(sig){ /* sig - */
signal (sig, onintr); /* */
... ...
}
main(){ signal (SIGINT, onintr); ... }
. :
signal (SIGINT, SIG_IGN);
. , SIG_IGN -
.
6.4.2. , - (read
, wait -, ...),
. "" (-1) errno
EINTR. -
: ,
. alarm(sec),
SIGALRM sec (0 - ):
#include <signal.h>
void (*oldaction)(); int alarmed;
/* */
void onalarm(nsig){ alarmed++; }
...
/* */
oldaction = signal (SIGALRM, onalarm);
/* TIMEOUT . */
alarmed = 0; alarm ( TIMEOUT /* sec */ );
sys_call(...); /* */
// ,
// - onalarm
if(alarmed){
// .
// .. .
}else{
alarm(0); /* */
// ,
// .
}
signal (SIGALRM, oldaction);
, 10 .
- " ", - "".
read, gets ( getchar),
. , 1992-95 - 216 - UNIX
read. ,
fgets (gets) .
/*
* -.
* FIFO-
* .
*
* "" (.. ,
* ).
* :
* -2.2 FIFO-,
* read()
* . open()-
* O_NDELAY, .
*
* : a.out /dev/tty
*
* . ..
*/
#define WAIT_TIME 5 /* 5 */
#define MAX_TRYS 5 /* 5 */
#define BSIZE 256
#define STDIN 0 /* */
#define STDOUT 1 /* */
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
char buffer [ BSIZE ];
extern int errno; /* */
void timeout(nsig){ signal( SIGALRM, timeout ); }
void main(argc, argv) char **argv;{
int fd, n, trys = 0; struct stat stin, stout;
if( argc != 2 ){
fprintf(stderr, ": %s \n", argv[0]); exit(1);
}
if((fd = !strcmp(argv[1],"-")? STDIN : open(argv[1],O_RDONLY)) < 0){
fprintf(stderr, " %s\n", argv[1]); exit(2);
}
/* , ,
* hardcat aFile >> aFile
* , - .
* - (STDIN->STDOUT),
* */
fstat(fd, &stin); fstat(STDOUT, &stout);
if( !isatty(STDOUT) && stin.st_ino == stout.st_ino &&
stin.st_dev == stout.st_dev
){ fprintf(stderr,
"\a == , %s.\n",argv[1]);
exit(33);
}
. , 1992-95 - 217 - UNIX
signal( SIGALRM, timeout );
while( trys < MAX_TRYS ){
alarm( WAIT_TIME ); /* 5 */
/* ... */
n = read( fd, buffer, BSIZE );
alarm(0); /* */
/* (, , ) */
/* : read() ? */
if( n < 0 && errno == EINTR ){
/* SIGALRM,
* EINTR -
* .
*/
fprintf( stderr, "\7timed out (%d )\n", ++trys );
continue;
}
if( n < 0 ){
/* */
fprintf( stderr, "read error.\n" ); exit(4);
}
if( n == 0 ){
/* */
fprintf( stderr, " EOF.\n\n" ); exit(0);
}
/* */
write( STDOUT, buffer, n );
trys = 0;
}
fprintf( stderr, " .\n" ); exit(5);
}
, , :
#include <signal.h>
void (*fsaved)();
...
fsaved = signal (sig, SIG_IGN);
sys_call(...);
signal (sig, fsaved);
:
sighold(sig);
sys_call(...);
sigrelse(sig);
.
6.4.3. sleep(n), n .
alarm(n) () pause(),
. -
, SIGALRM. alarm, -
sleep (alarm , -
). . :
. , 1992-95 - 218 - UNIX
#include <sys/types.h>
#include <stdio.h>
#include <signal.h>
int got; /* */
void onalarm(int sig)
{ printf( "\n" ); got++; } /* */
void sleep(int n){
time_t time(), start = time(NULL);
void (*save)();
int oldalarm, during = n;
if( n <= 0 ) return;
got = 0;
save = signal(SIGALRM, onalarm);
oldalarm = alarm(3600); /* */
if( oldalarm ){
printf( " , %d .\n",
oldalarm );
if(oldalarm > n) oldalarm -= n;
else { during = n = oldalarm; oldalarm = 1; }
}
printf( "n=%d oldalarm=%d\n", n, oldalarm );
while( n > 0 ){
printf( "alarm(%d)\n", n );
alarm(n); /* SIGALRM n */
pause();
if(got) break;
/* pause */
n = during - (time(NULL) - start); /* */
}
printf( "alarm(%d) \n", oldalarm );
alarm(oldalarm); /* alarm(0) - */
signal(SIGALRM, save); /* */
}
void onintr(int nsig){
printf( " SIGINT\n"); signal(SIGINT, onintr);
}
void onOldAlarm(int nsig){
printf( " \n");
}
void main(){
int time1 = 0; /* 5, 10, 20 */
setbuf(stdout, NULL);
signal(SIGINT, onintr);
signal(SIGALRM, onOldAlarm); alarm(time1);
sleep(10);
if(time1) pause();
printf("!\n");
}
. , 1992-95 - 219 - UNIX
6.4.4. "", 3 .
#include <signal.h>
#include <time.h>
#include <stdio.h>
void tick(nsig){
time_t tim; char *s;
signal (SIGALRM, tick);
alarm(3); time(&tim);
s = ctime(&tim);
s[ strlen(s)-1 ] = '\0'; /* '\n' */
fprintf(stderr, "\r%s", s);
}
main(){ tick(0);
for(;;) pause();
}
6.5. .
6.5.1. , -
?
char x[] = "hello";
int y[25];
char *p;
main(){
int z = 12;
int v;
static int w = 25;
static int q;
char s[20];
char *pp;
...
v = w + z; /* #1 */
}
:
x static data/DATA "hello"
y static data/BSS {0, ..., 0}
p static data/BSS NULL
z auto stack 12
v auto stack
w static data/DATA 25
q static data/BSS 0
s auto stack
pp auto stack
main static text/TEXT
, :
DATA - ( -
). ,
( ),
.
BSS (Block Started by Symbol)
- . -
0 (NULL, "", '\0'). -
, .
. , 1992-95 - 220 - UNIX
TEXT - , ().
-
; -
- . ,
, . adb
sdb, ld.
nm ߔ
,
strip ߔ
size ߔ
, (.. ), 3x ,
:
stack
- ( ). -
,
( -
- ,
).
( , ).
.
data - , DATA BSS,
. ,
- sbrk brk. , malloc() -
.
text - , TEXT . #1
.
, :
proc - -
;
user - 4- - (u-area).
, .
2 :
( , I- , -
, I- , ...)
. -
. , -
,
.
, -
- ( "
" - context switch).
- .
:
:
struct proc[]
####---------------> stack 1
#### data 2
text 3
: struct user 4
. , 1992-95 - 221 - UNIX
, p_pid proc|-.
: ( ,
); p_uid - ; p_ppid - -;
p_pri, p_nice - ; p_pgrp - ; p_wchan -
; p_flag p_stat - ; .
proc include- <sys/proc.h>, user - <sys/user.h>.
6.5.2. fork() () : , -
. fork- :
0 - .
pid - .
fork .
:
main(){
while(1)
if( ! fork()) pause();
}
- -
( : ,
, -).
fork 4 -
. text , -
(" ") .
user (.
).
, fork()
- . :
#include <stdio.h>
int pid, i, fd; char c;
main(){
fd = creat( "TEST", 0644);
if( !(pid = fork())){ /* : */
c = 'a';
for(i=0; i < 5; i++){
write(fd, &c, 1); c++; sleep(1);
}
printf(" %d \n", getpid());
exit(0);
}
/* else - */
c = 'A';
for(i=0; i < 5; i++){
write(fd, &c, 1); c++; sleep(1);
}
printf(" %d %d \n",
getpid(), pid );
}
TEST
aABbCcDdEe AaBbcdCDEe
, "" fork() -
. , -
____________________
|- pid=getpid();
. , 1992-95 - 222 - UNIX
.
- !
UNIX:
fork() " -
" - ,
-. , ,
0, 1, 2: ,
.
.
fork();
0 ## ---<---
1 ## --->---
2 ## --->---
... ##
fd ## --->--- TEST
... ##
fork();
- -
0 ## ---<--- --->--- ## 0
1 ## --->--- ---<--- ## 1
2 ## --->--- ---<--- ## 2
... ## ## ...
fd ## --->--- TEST ---<--- ## fd
... ## | ## ...
*--RWptr-->
" "
(. ). ,
, , /
. , "" "" fd,
R/W, .. -
.
pipe.
: (!!!), ,
, , ...
exec() ( , ,
)
( ).
6.5.3. - , , .
, ( a.out).
exec, .
:
char *path;
char *argv[], *envp[], *arg0, ..., *argn;
execle(path, arg0, arg1, ..., argn, NULL, envp);
execve(path, argv, envp);
exec , , ,
path. path
:
/usr/bin/vi a.out ../mybin/xkick
. , 1992-95 - 223 - UNIX
"". ( -
), short int, " "
(A_MAGIC), ( include- <a.out.h>).
ld
. , -
. ,
. , ,
text data ( text
), -
text ().
- arg0, ..., argn - main
. , -
. -
:
char *argv[20];
argv[0]="ls"; argv[1]="-l"; argv[2]="-i"; argv[3]=NULL;
execv( "/bin/ls", argv);
execl( "/bin/ls", "ls","-l","-i", NULL):
( !)
: stack, data, text
; data text, path; -
stack ( - ); user -
( , SIG_DFL
SIG_IGN - SIG_DFL). main
argv:
void main( argc, argv )
int argc; char *argv[]; { ... }
- argc - . NULL -
.
- (
); (pid); -
( ); -
; , , (
SIG_DFL). "" -
. , exec