summary |
tags |
clone url |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
7c4e25e)
SCCS-vsn: bin/pax/ar_subs.c 1.4
SCCS-vsn: bin/pax/ar_io.c 1.4
-static char sccsid[] = "@(#)ar_io.c 1.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)ar_io.c 1.4 (Berkeley) %G%";
#endif /* not lint */
#include <sys/types.h>
#endif /* not lint */
#include <sys/types.h>
#define STDO "<STDOUT>" /* psuedo name for stdout */
#define STDN "<STDIN>" /* psuedo name for stdin */
static int arfd = -1; /* archive file descriptor */
#define STDO "<STDOUT>" /* psuedo name for stdout */
#define STDN "<STDIN>" /* psuedo name for stdin */
static int arfd = -1; /* archive file descriptor */
-static int artyp; /* archive type: file/FIFO/tape */
+static int artyp = ISREG; /* archive type: file/FIFO/tape */
static int arvol = 1; /* archive volume number */
static int lstrval = -1; /* return value from last i/o */
static int io_ok; /* i/o worked on volume after resync */
static int arvol = 1; /* archive volume number */
static int lstrval = -1; /* return value from last i/o */
static int io_ok; /* i/o worked on volume after resync */
static int invld_rec; /* tape has out of spec record size */
static int phyblk; /* size of physical block on TAPE */
static int wr_trail = 1; /* trailer was rewritten in append */
static int invld_rec; /* tape has out of spec record size */
static int phyblk; /* size of physical block on TAPE */
static int wr_trail = 1; /* trailer was rewritten in append */
+static int can_unlnk = 0; /* do we unlink null archives? */
char *arcname; /* printable name of archive */
static int get_phys __P((void));
char *arcname; /* printable name of archive */
static int get_phys __P((void));
if (arfd != -1)
(void)close(arfd);
arfd = -1;
if (arfd != -1)
(void)close(arfd);
arfd = -1;
- phyblk = did_io = io_ok = invld_rec = 0;
+ can_unlnk = phyblk = did_io = io_ok = invld_rec = 0;
+ artyp = ISREG;
arcname = STDO;
} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
syswarn(0, errno, "Failed open to write on %s", name);
arcname = STDO;
} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
syswarn(0, errno, "Failed open to write on %s", name);
break;
case APPND:
if (name == NULL) {
break;
case APPND:
if (name == NULL) {
*/
if (fstat(arfd, &arsb) < 0) {
syswarn(0, errno, "Failed stat on %s", arcname);
*/
if (fstat(arfd, &arsb) < 0) {
syswarn(0, errno, "Failed stat on %s", arcname);
+ (void)close(arfd);
+ arfd = -1;
+ can_unlnk = 0;
return(-1);
}
if (S_ISDIR(arsb.st_mode)) {
warn(0, "Cannot write an archive on top of a directory %s",
arcname);
return(-1);
}
if (S_ISDIR(arsb.st_mode)) {
warn(0, "Cannot write an archive on top of a directory %s",
arcname);
+ (void)close(arfd);
+ arfd = -1;
+ can_unlnk = 0;
if (S_ISCHR(arsb.st_mode))
artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
else if (S_ISBLK(arsb.st_mode))
if (S_ISCHR(arsb.st_mode))
artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
else if (S_ISBLK(arsb.st_mode))
+ /*
+ * make sure we beyond any doubt that we only can unlink regular files
+ * we created
+ */
+ if (artyp != ISREG)
+ can_unlnk = 0;
/*
* if we are writing, we are done
*/
/*
* if we are writing, we are done
*/
+ /*
+ * if nothing was written to the archive (and we created it), we remove
+ * it
+ */
+ if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
+ (arsb.st_size == 0)) {
+ (void)unlink(arcname);
+ can_unlnk = 0;
+ }
+
(void)close(arfd);
if (vflag && (artyp == ISTAPE)) {
(void)close(arfd);
if (vflag && (artyp == ISTAPE)) {
-static char sccsid[] = "@(#)ar_subs.c 1.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)ar_subs.c 1.4 (Berkeley) %G%";
#endif /* not lint */
#include <sys/types.h>
#endif /* not lint */
#include <sys/types.h>
#include "pax.h"
#include "extern.h"
#include "pax.h"
#include "extern.h"
-static void wr_archive __P((register ARCHD *));
+static void wr_archive __P((register ARCHD *, int is_app));
static int get_arc __P((void));
static int next_head __P((register ARCHD *));
extern sigset_t s_mask;
static int get_arc __P((void));
static int next_head __P((register ARCHD *));
extern sigset_t s_mask;
-wr_archive(register ARCHD *arcn)
+wr_archive(register ARCHD *arcn, int is_app)
+wr_archive(arcn, is_app)
#endif
{
register int res;
register int hlk;
#endif
{
register int res;
register int hlk;
off_t cnt;
int (*wrf)();
int fd = -1;
off_t cnt;
int (*wrf)();
int fd = -1;
if (iflag && (name_start() < 0))
return;
if (iflag && (name_start() < 0))
return;
+ /*
+ * if this not append, and there are no files, we do no write a trailer
+ */
+ wr_one = is_app;
+
/*
* while there are files to archive, process them one at at time
*/
/*
* while there are files to archive, process them one at at time
*/
rdfile_close(arcn, &fd);
break;
}
rdfile_close(arcn, &fd);
break;
}
if (res > 0) {
/*
* format write says no file data needs to be stored
if (res > 0) {
/*
* format write says no file data needs to be stored
* were matched. block off signals to avoid chance for multiple entry
* into the cleanup code
*/
* were matched. block off signals to avoid chance for multiple entry
* into the cleanup code
*/
- (*frmt->end_wr)();
- wr_fin();
+ if (wr_one) {
+ (*frmt->end_wr)();
+ wr_fin();
+ }
(void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);
ar_close();
if (tflag)
(void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);
ar_close();
if (tflag)
/*
* go to the writing phase to add the new members
*/
/*
* go to the writing phase to add the new members
*/
if ((*frmt->options)() < 0)
return;
if ((*frmt->options)() < 0)
return;