-
,
fd = open( , O_RDWR | O_SYNC);
, write -
. , .
creat,
. mknod:
#include <sys/sysmacros.h>
dev_t dev = makedev(major, minor);
/* (major << 8) | minor */
mknod( ߔ, |, dev);
dev - (,) ; -
(0777)|=; - S_IFIFO, S_IFCHR, S_IFBLK include-
<sys/stat.h>.
mknod (
S_IFIFO). , , -
, ,
.
/ ,
( ).
____________________
|= () -
, "" ( -
) -
.
. , 1992-95 - 251 - UNIX
ENODEV.
stat() ,
. dev_t st_dev; -
( ),
dev_t st_rdev; , ,
:
#include <sys/types.h>
#include <sys/stat.h>
void main(ac, av) char *av[]; {
struct stat st1, st2; int eq;
if(ac != 3) exit(13);
stat(av[1], &st1); stat(av[2], &st2);
if(eq =
(st1.st_ino == st2.st_ino && /* I- */
st1.st_dev == st2.st_dev)) /* */
printf("%s %s - \n",av[1],av[2]);
exit( !eq );
}
, :
ino=2
*------
/ \ /\ /dev/hd0
/ /\ /\
\
*-/mnt/hd1
:
* ino=2 FS /dev/hd1
/ \ (removable FS)
/\ \
, ,
/dev/hd1, /mnt/hd1 "" ,
mount("/dev/hd1", "/mnt/hd1", 0);
umount("/dev/hd1");
(, , , -
). /mnt/hd1 ,
/mnt/hd1 () -
/dev/hd1. mount point
, "." ".." :
struct stat st1, st2;
stat("/mnt/hd1/.", &st1); stat("/mnt/hd1/..", &st2);
if( st1.st_dev != st2.st_dev) ... ; /*mount point*/
st1 st_dev /dev/hd1, st2 - , -
.
.
- I-.
stat
<sys/ino.h> <sys/inode.h> <sys/stat.h>
. , 1992-95 - 252 - UNIX
struct dinode struct inode struct stat
//
ushort di_mode i_mode st_mode
//
short di_nlink i_nlink st_nlink
// I-
ushort --- i_number st_ino
//
ushort di_uid i_uid st_uid
//
ushort di_gid i_gid st_gid
//
off_t di_size i_size st_size
//
time_t di_ctime i_ctime st_ctime
// (write)
time_t di_mtime i_mtime st_mtime
// (read/write)
time_t di_atime i_atime st_atime
// ,
dev_t --- i_dev st_dev
// , .
dev_t --- i_rdev st_rdev
//
char di_addr[39] i_addr[]
//
cnt_t i_count
// -
, , . -
UNIX .
6.10.1. pwd, .
#define U42 , -
(14 ).
. , 1992-95 - 253 - UNIX
/* pwd.
* getwd() .
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#define ediag(e,r) (e)
/*
* getwd() .
* NULL, pathname
* .
*/
#ifndef MAXPATHLEN
#define MAXPATHLEN 128
#endif
#define CURDIR "." /* */
#define PARENTDIR ".." /* */
#define PATHSEP "/" /* */
#define ROOTDIR "/" /* */
#define GETWDERR(s) strcpy(pathname, (s));
#define CP(to,from) strncpy(to,from.d_name,DIRSIZ),to[DIRSIZ]='\0'
char *strcpy(char *, char *); char *strncpy(char *, char *, int);
char *getwd(char *pathname);
static char *prepend(char *dirname, char *pathname);
static int pathsize; /* */
#ifndef U42
char *getwd(char *pathname)
{
char pathbuf[MAXPATHLEN]; /* temporary pathname buffer */
char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
dev_t rdev; /* root device number */
int fil = (-1); /* directory file descriptor */
ino_t rino; /* root inode number */
struct direct dir; /* directory entry struct */
struct stat d ,dd; /* file status struct */
/* d - "." dd - ".." | dname */
char dname[DIRSIZ+1]; /* an directory entry */
pathsize = 0;
*pnptr = '\0';
if (stat(ROOTDIR, &d) < 0) {
GETWDERR(ediag("getwd: can't stat /",
"getwd: stat /"));
return (NULL);
}
rdev = d.st_dev; /* , */
rino = d.st_ino; /* I-, */
. , 1992-95 - 254 - UNIX
for (;;) {
if (stat(CURDIR, &d) < 0) {
CantStat:
GETWDERR(ediag("getwd: can't stat .",
"getwd: stat ."));
goto fail;
}
if (d.st_ino == rino && d.st_dev == rdev)
break; /* */
if ((fil = open(PARENTDIR, O_RDONLY)) < 0) {
GETWDERR(ediag("getwd: can't open ..",
"getwd: .."));
goto fail;
}
if (chdir(PARENTDIR) < 0) {
GETWDERR(ediag("getwd: can't chdir to ..",
"getwd: .."));
goto fail;
}
if (fstat(fil, &dd) < 0)
goto CantStat;
if (d.st_dev == dd.st_dev) { /* */
if (d.st_ino == dd.st_ino) {
/* ".." == "." */
close(fil); break;
}
do {
if (read(fil, (char *) &dir,
sizeof(dir)) < sizeof(dir)
){
ReadErr:
close(fil);
GETWDERR(ediag("getwd: read error in ..",
"getwd: .."));
goto fail;
}
} while (dir.d_ino != d.st_ino);
CP(dname,dir);
} else /* ".." : mount point */
do {
if (read(fil, (char *) &dir,
sizeof(dir)) < sizeof(dir))
goto ReadErr;
if( dir.d_ino == 0 ) /* */
continue;
CP(dname,dir);
if (stat(dname, &dd) < 0) {
sprintf (pathname, "getwd: %s %s",
ediag ("can't stat",
" stat"), dname);
goto fail;
}
} while(dd.st_ino != d.st_ino ||
dd.st_dev != d.st_dev);
close(fil);
pnptr = prepend(PATHSEP, prepend(dname, pnptr));
}
. , 1992-95 - 255 - UNIX
if (*pnptr == '\0') /* == */
strcpy(pathname, ROOTDIR);
else {
strcpy(pathname, pnptr);
if (chdir(pnptr) < 0) {
GETWDERR(ediag("getwd: can't change back to .",
"getwd: ."));
return (NULL);
}
}
return (pathname);
fail:
close(fil);
chdir(prepend(CURDIR, pnptr));
return (NULL);
}
#else /* U42 */
extern char *strcpy ();
extern DIR *opendir();
char *getwd (char *pathname)
{
char pathbuf[MAXPATHLEN];/* temporary pathname buffer */
char *pnptr = &pathbuf[(sizeof pathbuf) - 1];/* pathname pointer */
char *prepend (); /* prepend dirname to pathname */
dev_t rdev; /* root device number */
DIR * dirp; /* directory stream */
ino_t rino; /* root inode number */
struct dirent *dir; /* directory entry struct */
struct stat d,
dd; /* file status struct */
pathsize = 0;
*pnptr = '\0';
stat (ROOTDIR, &d);
rdev = d.st_dev;
rino = d.st_ino;
for (;;) {
stat (CURDIR, &d);
if (d.st_ino == rino && d.st_dev == rdev)
break; /* reached root directory */
if ((dirp = opendir (PARENTDIR)) == NULL) {
GETWDERR ("getwd: can't open ..");
goto fail;
}
if (chdir (PARENTDIR) < 0) {
closedir (dirp);
GETWDERR ("getwd: can't chdir to ..");
goto fail;
}
. , 1992-95 - 256 - UNIX
fstat (dirp -> dd_fd, &dd);
if (d.st_dev == dd.st_dev) {
if (d.st_ino == dd.st_ino) {
/* reached root directory */
closedir (dirp);
break;
}
do {
if ((dir = readdir (dirp)) == NULL) {
closedir (dirp);
GETWDERR ("getwd: read error in ..");
goto fail;
}
} while (dir -> d_ino != d.st_ino);
}
else
do {
if ((dir = readdir (dirp)) == NULL) {
closedir (dirp);
GETWDERR ("getwd: read error in ..");
goto fail;
}
stat (dir -> d_name, &dd);
} while (dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
closedir (dirp);
pnptr = prepend (PATHSEP, prepend (dir -> d_name, pnptr));
}
if (*pnptr == '\0') /* current dir == root dir */
strcpy (pathname, ROOTDIR);
else {
strcpy (pathname, pnptr);
if (chdir (pnptr) < 0) {
GETWDERR ("getwd: can't change back to .");
return (NULL);
}
}
return (pathname);
fail:
chdir (prepend (CURDIR, pnptr));
return (NULL);
}
#endif
. , 1992-95 - 257 - UNIX
/*
* prepend() tacks a directory name onto the front of a pathname.
*/
static char *prepend (
register char *dirname, /* */
register char *pathname /* */
) {
register int i; /* */
for (i = 0; *dirname != '\0'; i++, dirname++)
continue;
if ((pathsize += i) < MAXPATHLEN)
while (i-- > 0)
*--pathname = *--dirname;
return (pathname);
}
#ifndef CWDONLY
void main(){
char buffer[MAXPATHLEN+1];
char *cwd = getwd(buffer);
printf( "%s%s\n", cwd ? "": "ERROR:", buffer);
}
#endif
6.10.2. canon(), , ..
( ), "." "..", -
'/'. , , /usr/abs/C-
book.
. -> /usr/abs/C-book
.. -> /usr/abs
../.. -> /usr
////.. -> /
/aa -> /aa
/aa/../bb -> /bb
cc//dd/../ee -> /usr/abs/C-book/cc/ee
../a/b/./d -> /usr/abs/a/b/d
:
#include <stdio.h>
/* , */
#define SLASH '/'
extern char *strchr (char *, char),
*strrchr(char *, char);
struct savech{ char *s, c; };
#define SAVE(sv, str) (sv).s = (str); (sv).c = *(str)
#define RESTORE(sv) if((sv).s) *(sv).s = (sv).c
/* :
void main(){
char *d = "hello"; struct savech ss;
SAVE(ss, d+3); *(d+3) = '\0'; printf("%s\n", d);
RESTORE(ss); printf("%s\n", d);
}
*/
/* */
struct savech parentdir(char *path){
char *last = strrchr( path, SLASH );
. , 1992-95 - 258 - UNIX
char *first = strchr ( path, SLASH );
struct savech sp; sp.s = NULL; sp.c = '\0';
if( last == NULL ) return sp; /* */
if( last[1] == '\0' ) return sp; /* */
if( last == first ) /* : /DIR */
last++;
sp.s = last; sp.c = *last; *last = '\0';
return sp;
}
#define isfullpath(s) (*s == SLASH)
/* */
void canon(
char *where, /* */
char *cwd, /* */
char *path /* */
){ char *s, *slash;
/* - */
if( isfullpath(path)){
s = strchr(path, SLASH); /* @ */
strncpy(where, path, s - path + 1);
where[s - path + 1] = '\0';
/* strcpy(where, "/"); */
path = s+1; /* '/' */
} else strcpy(where, cwd);
/* */
do{ if(slash = strchr(path, SLASH)) *slash = '\0';
/* path */
if(*path == '\0' || !strcmp(path, ".")) ;
/* "." "///" */
else if( !strcmp(path, ".."))
(void) parentdir(where);
else{ int len = strlen(where);
/* */
if( where[len-1] != SLASH ){
where[len] = SLASH;
where[len+1] = '\0';
}
strcat( where+len, path );
/* +len
* strcat(); */
}
if(slash){ *slash = SLASH; /* */
path = slash + 1;
}
} while (slash != NULL);
}
char cwd[256], input[256], output[256];
void main(){
/* .
* getcwd() - ,
* popen() pwd ( ).
*/
getcwd(cwd, sizeof cwd);
while( gets(input)){
canon(output, cwd, input);
printf("%-20s -> %s\n", input, output);
}
}
. , 1992-95 - 259 - UNIX
( MS DOS) "" ,
/*@*/. , DOS isfullpath -
C:\aaa\bbb, .
6.11. -.
select, , , -
. : -
( )
- .
, .
6.11.1.
/* select()
* .
* .
* : tty01 tty02
* sleep 30000
* tty00 select /dev/tty01 /dev/tty02
* - tty01 tty02
* : cc select.c -o select -lsocket
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h> /* fd_set, FD_SET, e.t.c. */
#include <sys/param.h> /* NOFILE */
#include <sys/select.h>
#include <sys/time.h>
#include <sys/filio.h> /* FIONREAD */
#define max(a,b) ((a) > (b) ? (a) : (b))
char buf[512]; /* */
int fdin, fdout; /* stdin, stdout */
int nready; /* */
int nopen; /* */
int maxfd = 0; /* */
int nfds; /* */
int f; /* */
fd_set set, rset; /* */
/* */
struct _fds {
int fd; /* */
char name[30]; /* */
} fds[ NOFILE ] = { /* NOFILE - . */
{ 0, "stdin" }, { 1, "stdout" }, { 2, "stderr" }
/* - */
};
struct timeval timeout, rtimeout;
/* */
char *N( int fd ){
register i;
for(i=0; i < NOFILE; i++)
if(fds[i].fd == fd ) return fds[i].name;
return "???";
}
. , 1992-95 - 260 - UNIX
void main( int ac, char **av ){
nopen = 3; /* stdin, stdout, stderr */
for( f = 3; f < NOFILE; f++ ) fds[f].fd = (-1);
fdin = fileno(stdin); fdout = fileno(stdout);
setbuf(stdout, NULL); /* */
FD_ZERO(&set); /* */
for(f=1; f < ac; f++ )
if((fds[nopen].fd = open(av[f], O_RDONLY)) < 0 ){
fprintf(stderr, "Can't read %s\n", av[f] );
continue;
} else {
FD_SET(fds[nopen].fd, &set ); /* */
maxfd = max(maxfd, fds[nopen].fd );
strncpy(fds[nopen].name, av[f], sizeof(fds[0].name) - 1);
nopen++;
}
if( nopen == 3 ){
fprintf(stderr, "Nothing is opened\n");
exit(1);
}
FD_SET(fdin, &set); /* stdin */
maxfd = max(maxfd, fdin );
nopen -= 2; /* stdout stderr select */
timeout.tv_sec = 10; /* */
timeout.tv_usec = 0; /* */
/* nfds - ,
* .
* nfds = NOFILE; (- )
* nfds = maxfd+1; (- = +1)
* ( +1 .. fd 0, - 1).
*/
nfds = maxfd + 1;
while( nopen ){
rset = set; rtimeout = timeout; /* , .. */
/* FIFO-, , pty, socket-, stream- */
nready = select( nfds, &rset, NULL, NULL, &rtimeout );
/* &rtimeout NULL,
* ( )
*/
if( nready <= 0 ){ /* */
fprintf(stderr, "Timed out, nopen=%d\n", nopen);
continue;
}
. , 1992-95 - 261 - UNIX
/* */
for(f=0; f < nfds; f++ )
if( FD_ISSET(f, &rset)){ /* f */
int n;
/* FIONREAD
*
* .
*/
if(ioctl(f, FIONREAD, &n) < 0)
perror("FIONREAD");
else printf("%s have %d bytes.\n", N(f), n);
if((n = read(f, buf, sizeof buf)) <= 0 ){
eof:
FD_CLR(f, &set); /* */
close(f); nopen--;
fprintf(stderr, "EOF in %s\n", N(f));
} else {
fprintf(stderr, "\n%d bytes from %s:\n", n, N(f));
write(fdout, buf, n);
if( n == 4 && !strncmp(buf, "end\n", 4))
/* ncmp, .. buf \0 */
goto eof;
}
}
}
exit(0);
}
6.11.2. ,
. .
. , 1992-95 - 262 - UNIX
/*
* script.c
* .
*
* / select() ( ttyp+ptyp).
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/param.h> /* NOFILE */
#include <sys/times.h>
#include <sys/wait.h>
#include <errno.h>
#ifdef TERMIOS
# include <termios.h>
# define TERMIO struct termios
# define GTTY(fd, tadr) tcgetattr(fd, tadr)
# define STTY(fd, tadr) tcsetattr(fd, TCSADRAIN, tadr)
#else
# include <termio.h>
# define TERMIO struct termio
# define GTTY(fd, tadr) ioctl(fd, TCGETA, tadr)
# define STTY(fd, tadr) ioctl(fd, TCSETAW, tadr)
#endif
. , 1992-95 - 263 - UNIX
#ifdef __SVR4
# include <stropts.h> /* STREAMS i/o */
extern char *ptsname();
#endif
#if defined(ISC2_2)
# include <sys/bsdtypes.h>
#else
# include <sys/select.h>
#endif
#ifndef BSIZE
# define BSIZE 512
#endif
#define LOGFILE "/usr/spool/scriptlog"
#define max(a,b) ((a) > (b) ? (a) : (b))
extern int errno;
TERMIO told, tnew, ttypmodes;
FILE *fpscript = NULL; /* ( ) */
int go = 0;
int scriptflg = 0;
int halfflag = 0; /* HALF DUPLEX */
int autoecho = 0;
char *protocol = "typescript";
#define STDIN 0 /* fileno(stdin) */
#define STDOUT 1 /* fileno(stdout) */
#define STDERR 2 /* fileno(stderr) */
/* ? */
int tty_stdin, tty_stdout, tty_stderr;
int TTYFD;
void wm_checkttys(){
TERMIO t;
tty_stdin = ( GTTY(STDIN, &t) >= 0 );
tty_stdout = ( GTTY(STDOUT, &t) >= 0 );
tty_stderr = ( GTTY(STDERR, &t) >= 0 );
if ( tty_stdin ) TTYFD = STDIN;
else if( tty_stdout ) TTYFD = STDOUT;
else if( tty_stderr ) TTYFD = STDERR;
else {
fprintf(stderr, "Cannot access tty\n");
exit(7);
}
}
. , 1992-95 - 264 - UNIX
/* */
struct ptypair {
char line[25]; /* : /dev/ttyp? */
int pfd; /* master pty */
long in_bytes; /* */
long out_bytes; /* */
int pid; /* */
time_t t_start, t_stop; /* */
char *command; /* */
} PP;
/* -
* SIGCLD
*/
char Reason[128];
void ondeath(sig){
int pid;
extern void wm_done();
int status;
int fd;
/* */
while((pid = wait(&status)) > 0 ){
if( WIFEXITED(status))
sprintf( Reason, "Pid %d died with retcode %d",
pid, WEXITSTATUS(status));
else if( WIFSIGNALED(status)) {
sprintf( Reason, "Pid %d killed by signal #%d",
pid, WTERMSIG(status));
#ifdef WCOREDUMP
if(WCOREDUMP(status)) strcat( Reason, " Core dumped" );
#endif
} else if( WIFSTOPPED(status))
sprintf( Reason, "Pid %d suspended by signal #%d",
pid, WSTOPSIG(status));
}
wm_done(0);
}
void wm_init(){
wm_checkttys();
GTTY(TTYFD, &told);
/* "" __ */
tnew = told;
tnew.c_cc[VINTR] = '\0';
tnew.c_cc[VQUIT] = '\0';
tnew.c_cc[VERASE] = '\0';
tnew.c_cc[VKILL] = '\0';
#ifdef VSUSP
tnew.c_cc[VSUSP] = '\0';
#endif
. , 1992-95 - 265 - UNIX
/* CBREAK */
tnew.c_cc[VMIN] = 1;
tnew.c_cc[VTIME] = 0;
tnew.c_cflag &= ~(PARENB|CSIZE);
tnew.c_cflag |= CS8;
tnew.c_iflag &= ~(ISTRIP|ICRNL);
tnew.c_lflag &= ~(ICANON|ECHO|ECHOK|ECHOE|XCASE);
tnew.c_oflag &= ~OLCUC;
/* c_oflag ONLCR TAB3, */
/* */
ttypmodes = told;
/* :
* ONLCR: \n --> \r\n
* TAB3: \t -->
*/
ttypmodes.c_oflag &= ~(ONLCR|TAB3);
(void) signal(SIGCLD, ondeath);
}
void wm_fixtty(){
STTY(TTYFD, &tnew);
}
void wm_resettty(){
STTY(TTYFD, &told);
}
/* */
struct ptypair wm_ptypair(){
struct ptypair p;
#ifdef __SVR4
p.pfd = (-1); p.pid = 0;
p.in_bytes = p.out_bytes = 0;
/* master side pty ( slave) */
if((p.pfd = open( "/dev/ptmx", O_RDWR)) < 0 ){
/* STREAMS driver.
* ,
* , master-
* !
*/
perror( "Open /dev/ptmx" );
goto err;
}
. , 1992-95 - 266 - UNIX
# ifdef notdef
/* slave- . */
if( grantpt (p.pfd) < 0 ){
perror( "grantpt");
exit(errno);
}
# endif
/* slave- :
open() */
if( unlockpt(p.pfd) < 0 ){
perror( "unlockpt");
exit(errno);
}
/* slave--. */
strcpy( p.line, ptsname(p.pfd));
#else
register i;
char c;
struct stat st;
p.pfd = (-1); p.pid = 0;
p.in_bytes = p.out_bytes = 0;
strcpy( p.line, "/dev/ptyXX" );
for( c = 'p'; c <= 's'; c++ ){
p.line[ strlen("/dev/pty") ] = c;
p.line[ strlen("/dev/ptyp")] = '0';
if( stat(p.line, &st) < 0 )
goto err;
for(i=0; i < 16; i++){
p.line[ strlen("/dev/ptyp") ] =
"0123456789abcdef" [i] ;
if((p.pfd = open( p.line, O_RDWR )) >= 0 ){
p.line[ strlen("/dev/") ] = 't';
return p;
}
}
}
#endif
err: return p;
}
. , 1992-95 - 267 - UNIX
/* script */
void write_stat( in_bytes, out_bytes, time_here , name, line, at )
long in_bytes, out_bytes;
time_t time_here;
char *name;
char *line;
char *at;
{
FILE *fplog;
struct flock lock;
if((fplog = fopen( LOGFILE, "a" )) == NULL )
return;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0; /* */
fcntl ( fileno(fplog), F_SETLKW, &lock );
fprintf( fplog, "%s (%s) %ld bytes_in %ld bytes_out %ld secs %s %s %s",
PP.command, Reason, in_bytes, out_bytes,
time_here, name, line, at );
fflush ( fplog );
lock.l_type = F_UNLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0; /* */
fcntl ( fileno(fplog), F_SETLK, &lock );
fclose ( fplog );
}
void wm_done(sig){
char *getlogin(), *getenv(), *logname = getlogin();
time( &PP.t_stop ); /* */
wm_resettty(); /* */
if( fpscript )
fclose(fpscript);
if( PP.pid > 0 ) kill( SIGHUP, PP.pid ); /* " " */
if( go ) write_stat( PP.in_bytes, PP.out_bytes,
PP.t_stop - PP.t_start,
logname ? logname : getenv("LOGNAME"),
PP.line, ctime(&PP.t_stop) );
printf( "\n" );
exit(0);
}
. , 1992-95 - 268 - UNIX
/* */
void wm_startshell (ac, av)
char **av;
{
int child, fd, sig;
if( ac == 0 ){
static char *avshell[] = { "/bin/sh", "-i", NULL };
av = avshell;
}
if((child = fork()) < 0 ){
perror("fork");
wm_done(errno);
}
if( child == 0 ){ /* SON */
if( tty_stdin )
setpgrp(); /* */
/* */
if((fd = open( PP.line, O_RDWR )) < 0 ){
exit(errno);
}
/* */
if( fpscript )
fclose(fpscript);
close( PP.pfd );
#ifdef __SVR4
/* Push pty compatibility modules onto stream */
ioctl(fd, I_PUSH, "ptem"); /* pseudo tty module */
ioctl(fd, I_PUSH, "ldterm"); /* line discipline module */
ioctl(fd, I_PUSH, "ttcompat"); /* BSD ioctls module */
#endif
/* , */
if( fd != STDIN && tty_stdin ) dup2(fd, STDIN);
if( fd != STDOUT && tty_stdout ) dup2(fd, STDOUT);
if( fd != STDERR && tty_stderr ) dup2(fd, STDERR);
if( fd > STDERR )
(void) close(fd);
/* */
STTY(TTYFD, &ttypmodes);
/* */
for(sig=1; sig < NSIG; sig++)
signal( sig, SIG_DFL );
execvp(av[0], av);
system( "echo OBLOM > HELP.ME");
perror("execl");
exit(errno);
. , 1992-95 - 269 - UNIX
} else { /* FATHER */
PP.pid = child;
PP.command = av[0];
time( &PP.t_start ); PP.t_stop = PP.t_start;
signal( SIGHUP, wm_done );
signal( SIGINT, wm_done );
signal( SIGQUIT, wm_done );
signal( SIGTERM, wm_done );
signal( SIGILL, wm_done );
signal( SIGBUS, wm_done );
signal( SIGSEGV, wm_done );
}
}
char buf[ BSIZE ]; /* */
/* /dev/pty? /dev/ttyp?
*--------* *--------*
/||| | | PP.pfd | |
|||||<-STDOUT--| |<---------| |<-STDOUT---|
\||| || ||<-STDERR---|
|() | | |
------- | | STDIN | | |
|.....|-STDIN--> |----------> |--STDIN--->|
|_____| | | | |
*--------* *--------*
master slave
*/
/* */
void wm_select(){
int nready;
int nfds;
int maxfd;
int nopen; /* */
register f;
fd_set s