📄 open.c
字号:
/* * open.c * * Copyright (C) 1993 Alain Knaff */#define _LARGEFILE64_SOURCE#define _GNU_SOURCE#include "sysincludes.h"static char *zlib_compressor[]= { COMPR, 0 };#ifdef HAVE___LIBC_OPEN#define open __libc_open/*ALIASF2(open, __libc_open, int, mode_t);*/#endifALIASF2(open, __open, int, mode_t);int open(__const char *name, int flags, mode_t mode){ int fd; int zfd; int pid; int filetype; int zflags; int do_append; int do_uncompress; int do_create; int have_filetype; int tmp; int stat_result; int status; struct stat buf;#ifdef SYS_UTIME struct utimbuf buf2;#else# ifdef SYS_UTIMES struct timeval buf2[2];# endif#endif int pipeout[2]; char newname[MAXPATHLEN + MAXEXTLEN + 1]; char _pname[MAXPATHLEN + MAXEXTLEN + 1]; __const char *pname; filetype=have_filetype=do_append=do_uncompress=do_create=0; zflags = flags; if (flags & O_CREAT){ zlib_initialise(); have_filetype=1; if ( ! (zlib_mode & CM_DISAB )){ filetype = zlib_getfiletype(name,-1); if ((flags & O_ACCMODE) == O_WRONLY && (flags & (O_TRUNC | O_EXCL)) && (filetype & PM_CREATE_COMPR)) do_create = 1; else if ((flags & O_ACCMODE) == O_WRONLY && (flags & O_APPEND) && (filetype & PM_APPEND_COMPR)) do_append=1; else if ((flags & O_ACCMODE ) != O_RDONLY && (filetype & PM_UNCOMPR_BEFORE_WRITE)) do_uncompress=1; if (do_create | do_append | do_uncompress) zflags &= ~O_CREAT; } } fd = zlib_real_open(name,zflags,mode);#ifdef DEBUG fprintf(stderr,"file opened *: %s %d %x %x %d\n", name,fd, flags, zflags, errno);#endif /* success to open uncompressed file */ if ( fd >= 0 || errno != ENOENT ) return fd; if (!have_filetype) zlib_initialise(); if ( zlib_mode & CM_DISAB ) return fd; if (!have_filetype) filetype = zlib_getfiletype(name,-1); if ( zlib_mode & CM_VERBOSE ) fprintf(stderr,"opening %s %o\n", name,flags); strncpy(newname,name,MAXPATHLEN); strcat(newname,zlib_ext); /* open compressed file */ zflags = flags; if ((flags & O_ACCMODE) == O_WRONLY && (flags & O_TRUNC) && (filetype & PM_CREATE_COMPR)) do_create = 1; else if ((flags & O_ACCMODE) == O_WRONLY && (flags & O_APPEND) && (filetype & PM_APPEND_COMPR)) do_append=1; else if ((flags & O_ACCMODE ) != O_RDONLY && (filetype & PM_UNCOMPR_BEFORE_WRITE)){ zflags = O_RDONLY; do_uncompress=1; } else if ((flags & O_ACCMODE) != O_RDONLY) return fd; zfd = zlib_real_open(newname,zflags,mode); if ( zfd < 0 ){ if ( flags & O_CREAT ) return zlib_real_open(name,flags,mode); if ( errno == EINVAL ) /* don't want to replace perm errors */ errno = ENOENT; return zfd; } if (do_append || do_create){ /* make a pipe */ if(pipe(pipeout) < 0 ) return -1; /* double fork */ switch(pid=fork()){ case 0: /* son */ switch(fork()){ case 0: /* son of son */ if (zfd == 0){ /* shit happens ... */ tmp = dup(zfd); close(zfd); zfd = tmp; } if (pipeout[0] != 0){ close(0); dup(pipeout[0]); } if ( zfd != 1 ){ close(1); dup(zfd); /* compressed file, input */ } close(pipeout[0]); close(pipeout[1]); if(! (zlib_mode & CM_VERBOSE)) close(2); execvp (zlib_compressor[0], zlib_compressor); if ( zlib_mode & CM_VERBOSE ){ perror("exec compressor"); exit(1); } case -1: /* error */ if ( zlib_mode & CM_VERBOSE ) perror("fork error"); exit(1); default: /* father */ exit(0); /* son of son will be taken over by init */ } case -1: /* error */ errno = ENOENT; return -1; } close(pipeout[0]); /* close read end of pipe */ close(zfd); /* close raw compressed file */ fd=dup(pipeout[1]); close(pipeout[1]); /*wait4(pid,&status,0,0); wait for son */ wait(&status); return fd; } if (!do_uncompress && (filetype & PM_READ_MASK) >= PM_HIDE_PIPE ){ /* make a pipe */ if(pipe(pipeout) < 0 ) return -1; /* double fork */ switch(pid=fork()){ case 0: /* son */ switch(fork()){ case 0: /* son of son */ if ( zfd != 0 ){ close(0); dup(zfd); /* compressed file, input */ } if ( pipeout[1] != 1 ){ close(1); dup(pipeout[1]); } close(pipeout[0]); close(pipeout[1]); if(! (zlib_mode & CM_VERBOSE)) close(2); execvp ( zlib_uncompressor[0], zlib_uncompressor ); if ( zlib_mode & CM_VERBOSE ){ perror("exec uncompressor"); exit(1); } case -1: /* error */ if ( zlib_mode & CM_VERBOSE ) perror("fork error"); exit(1); default: /* father */ exit(0); /* son of son will be taken over by init */ } case -1: /* error */ errno = ENOENT; return -1; } close(pipeout[1]); /* close write end of pipe */ close(zfd); /* close raw compressed file */ fd=dup(pipeout[0]); close(pipeout[0]); wait(&status); } else { stat_result=fstat(zfd, &buf); mode = 0400; if ( !do_uncompress){ sprintf(_pname,"%s/pipe.%d",zlib_tmp,(int)getpid()); pname = _pname; } else { mode = 0; pname = name; } zlib_real_unlink(pname); pipeout[0]=zlib_real_open(pname, O_RDWR | O_CREAT | O_EXCL, mode); /* temporary output file */ if ( pipeout[0] < 0 ){ if ( zlib_mode & CM_VERBOSE ) perror("could not create uncompressed file"); errno = ENOENT; return -1; } switch(pid=fork()){ case 0: /* son */ if ( zfd != 0 ){ close(0); dup(zfd); /* compressed file, input */ } if ( pipeout[0] != 1 ){ close(1); dup(pipeout[0]); } if(! (zlib_mode & CM_VERBOSE)) close(2); execvp ( zlib_uncompressor[0], zlib_uncompressor ) ; if ( zlib_mode & CM_VERBOSE ) perror("exec uncompressor"); exit(1); case -1: /* error */ errno = ENOENT; return -1; } wait(&status); /* touch it */ close(pipeout[0]); if(do_uncompress){ /* restore the original mode */ if ( stat_result >= 0) mode = buf.st_mode; else mode = 0600; zlib_real_chmod(pname, mode); } if ( stat_result >= 0 ){#ifdef SYS_UTIME buf2.actime = buf.st_atime; buf2.modtime = buf.st_mtime; zlib_real_utime(pname, &buf2);#else# ifdef SYS_UTIMES buf2[0].tv_sec = buf.st_atime; buf2[0].tv_usec = 0; buf2[1].tv_sec = buf.st_mtime; buf2[1].tv_usec = 0; zlib_real_utimes(pname, buf2);# endif#endif } close(zfd); /* close raw compressed file */ /* re-open it */ fd=zlib_real_open(pname, flags, mode); if ( !do_uncompress) zlib_real_unlink(pname); else { if ( fd>=0 && WIFEXITED(status) && WEXITSTATUS(status)==0 ) /* only erase the original file if nothing looks fishy... */ zlib_real_unlink(newname); } } return fd;}#undef creatint creat(__const char *name, mode_t mode){ return open(name, O_CREAT | O_WRONLY | O_TRUNC, mode);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -