ape: simplify mkfile (thanks amavect)

ape cp, mv, and cc build with ?c, not pcc
ape cp and mv just ignore one or two extra flags,
instead of providing posix compatibility
it's better to fail then do nothing

remove cp.c and mv.c
move cc.c to /sys/src/ape/9src so it doesn't
need its own mkfile rule
This commit is contained in:
Ori Bernstein 2020-07-16 15:22:42 -07:00
parent 61b1134df9
commit 407cf4ac6e
5 changed files with 1 additions and 450 deletions

View file

@ -4,6 +4,7 @@
TARG=\
stty\
tar\
cc\
BIN=/$objtype/bin/ape
</sys/src/cmd/mkmany

View file

@ -1,179 +0,0 @@
#include <u.h>
#include <libc.h>
#define DEFB (8*1024)
int failed;
int gflag;
int uflag;
int xflag;
void copy(char *from, char *to, int todir);
int copy1(int fdf, int fdt, char *from, char *to);
void
main(int argc, char *argv[])
{
Dir *dirb;
int todir, i;
ARGBEGIN {
case 'g':
gflag++;
break;
case 'u':
uflag++;
gflag++;
break;
case 'x':
xflag++;
break;
case 'p':
break;
default:
goto usage;
} ARGEND
todir=0;
if(argc < 2)
goto usage;
dirb = dirstat(argv[argc-1]);
if(dirb!=nil && (dirb->mode&DMDIR))
todir=1;
if(argc>2 && !todir){
fprint(2, "cp: %s not a directory\n", argv[argc-1]);
exits("bad usage");
}
for(i=0; i<argc-1; i++)
copy(argv[i], argv[argc-1], todir);
if(failed)
exits("errors");
exits(0);
usage:
fprint(2, "usage:\tcp [-gux] fromfile tofile\n");
fprint(2, "\tcp [-x] fromfile ... todir\n");
exits("usage");
}
int
samefile(Dir *a, char *an, char *bn)
{
Dir *b;
int ret;
ret = 0;
b=dirstat(bn);
if(b != nil)
if(b->qid.type==a->qid.type)
if(b->qid.path==a->qid.path)
if(b->qid.vers==a->qid.vers)
if(b->dev==a->dev)
if(b->type==a->type){
fprint(2, "cp: %s and %s are the same file\n", an, bn);
ret = 1;
}
free(b);
return ret;
}
void
copy(char *from, char *to, int todir)
{
Dir *dirb, dirt;
char name[256];
int fdf, fdt, mode;
if(todir){
char *s, *elem;
elem=s=from;
while(*s++)
if(s[-1]=='/')
elem=s;
sprint(name, "%s/%s", to, elem);
to=name;
}
if((dirb=dirstat(from))==nil){
fprint(2,"cp: can't stat %s: %r\n", from);
failed = 1;
return;
}
mode = dirb->mode;
if(mode&DMDIR){
fprint(2, "cp: %s is a directory\n", from);
free(dirb);
failed = 1;
return;
}
if(samefile(dirb, from, to)){
free(dirb);
failed = 1;
return;
}
mode &= 0777;
fdf=open(from, OREAD);
if(fdf<0){
fprint(2, "cp: can't open %s: %r\n", from);
free(dirb);
failed = 1;
return;
}
fdt=create(to, OWRITE, mode);
if(fdt<0){
fprint(2, "cp: can't create %s: %r\n", to);
close(fdf);
free(dirb);
failed = 1;
return;
}
if(copy1(fdf, fdt, from, to)==0 && (xflag || gflag || uflag)){
nulldir(&dirt);
if(xflag){
dirt.mtime = dirb->mtime;
dirt.mode = dirb->mode;
}
if(uflag)
dirt.uid = dirb->uid;
if(gflag)
dirt.gid = dirb->gid;
if(dirfwstat(fdt, &dirt) < 0)
fprint(2, "cp: warning: can't wstat %s: %r\n", to);
}
free(dirb);
close(fdf);
close(fdt);
}
int
copy1(int fdf, int fdt, char *from, char *to)
{
char *buf;
long n, n1, rcount;
int rv;
char err[ERRMAX];
buf = malloc(DEFB);
/* clear any residual error */
err[0] = '\0';
errstr(err, ERRMAX);
rv = 0;
for(rcount=0;; rcount++) {
n = read(fdf, buf, DEFB);
if(n <= 0)
break;
n1 = write(fdt, buf, n);
if(n1 != n) {
fprint(2, "cp: error writing %s: %r\n", to);
failed = 1;
rv = -1;
break;
}
}
if(n < 0) {
fprint(2, "cp: error reading %s: %r\n", from);
failed = 1;
rv = -1;
}
free(buf);
return rv;
}

View file

@ -2,11 +2,8 @@ APE=/sys/src/ape
<$APE/config
TARG=basename\
cc\
cp\
dirname\
kill\
mv\
uname
DIRS=\
@ -46,24 +43,6 @@ $DIRS:V:
mk all
}
cc.$O: cc.c
mk -f /sys/src/cmd/mkfile cc.$O
$O.cc: cc.$O
mk -f /sys/src/cmd/mkfile $O.cc
cp.$O: cp.c
mk -f /sys/src/cmd/mkfile cp.$O
$O.cp: cp.$O
mk -f /sys/src/cmd/mkfile $O.cp
mv.$O: mv.c
mk -f /sys/src/cmd/mkfile mv.$O
$O.mv: mv.$O
mk -f /sys/src/cmd/mkfile $O.mv
$BIN/%: %.rc
cp -x $stem.rc $BIN/$stem

View file

@ -1,250 +0,0 @@
#include <u.h>
#include <libc.h>
int copy1(int fdf, int fdt, char *from, char *to);
void hardremove(char *);
int mv(char *from, char *todir, char *toelem);
int mv1(char *from, Dir *dirb, char *todir, char *toelem);
int samefile(char *, char *);
void split(char *, char **, char **);
void
main(int argc, char *argv[])
{
int i, failed;
Dir *dirto, *dirfrom;
char *todir, *toelem;
if(argc<3){
fprint(2, "usage: mv fromfile tofile\n");
fprint(2, " mv fromfile ... todir\n");
exits("bad usage");
}
/* Skip -f */
if(argv[1][0] == '-' && argv[1][1] == 'f' && argv[1][2] == 0) {
for(i=2; i<argc; i++) {
argv[i-1] = argv[i];
}
argc--;
}
/* prepass to canonicalise names before splitting, etc. */
for(i=1; i < argc; i++)
cleanname(argv[i]);
if((dirto = dirstat(argv[argc-1])) != nil && (dirto->mode&DMDIR)){
dirfrom = nil;
if(argc == 3
&& (dirfrom = dirstat(argv[1])) != nil
&& (dirfrom->mode & DMDIR))
split(argv[argc-1], &todir, &toelem); /* mv dir1 dir2 */
else{ /* mv file... dir */
todir = argv[argc-1];
toelem = nil; /* toelem will be fromelem */
}
free(dirfrom);
}else
split(argv[argc-1], &todir, &toelem); /* mv file1 file2 */
free(dirto);
if(argc>3 && toelem != nil){
fprint(2, "mv: %s not a directory\n", argv[argc-1]);
exits("bad usage");
}
failed = 0;
for(i=1; i < argc-1; i++)
if(mv(argv[i], todir, toelem) < 0)
failed++;
if(failed)
exits("failure");
exits(0);
}
int
mv(char *from, char *todir, char *toelem)
{
int stat;
Dir *dirb;
dirb = dirstat(from);
if(dirb == nil){
fprint(2, "mv: can't stat %s: %r\n", from);
return -1;
}
stat = mv1(from, dirb, todir, toelem);
free(dirb);
return stat;
}
int
mv1(char *from, Dir *dirb, char *todir, char *toelem)
{
int fdf, fdt, i, j, stat;
char toname[4096], fromname[4096];
char *fromdir, *fromelem;
Dir *dirt, null;
i = strlen(from);
if(i >= sizeof(fromname)){
fprint(2, "mv: path too big (max %d): %s\n",
sizeof(fromname), from);
return -1;
}
memmove(fromname, from, i+1);
split(from, &fromdir, &fromelem);
if(toelem == 0)
toelem = fromelem;
i = strlen(toelem);
if(i==0){
fprint(2, "mv: null last name element moving %s\n", fromname);
return -1;
}
j = strlen(todir);
if(i + j + 2 > sizeof toname){
fprint(2, "mv: path too big (max %d): %s/%s\n",
sizeof toname, todir, toelem);
return -1;
}
memmove(toname, todir, j);
toname[j] = '/';
memmove(toname+j+1, toelem, i);
toname[i+j+1] = 0;
if(samefile(fromdir, todir)){
if(samefile(fromname, toname)){
fprint(2, "mv: %s and %s are the same\n",
fromname, toname);
return -1;
}
/* remove target if present */
dirt = dirstat(toname);
if(dirt != nil) {
hardremove(toname);
free(dirt);
}
/* try wstat */
nulldir(&null);
null.name = toelem;
if(dirwstat(fromname, &null) >= 0)
return 0;
if(dirb->mode & DMDIR){
fprint(2, "mv: can't rename directory %s: %r\n",
fromname);
return -1;
}
}
/*
* Renaming won't work --- must copy
*/
if(dirb->mode & DMDIR){
fprint(2, "mv: %s is a directory, not copied to %s\n",
fromname, toname);
return -1;
}
fdf = open(fromname, OREAD);
if(fdf < 0){
fprint(2, "mv: can't open %s: %r\n", fromname);
return -1;
}
dirt = dirstat(toname);
if(dirt != nil && (dirt->mode & DMAPPEND))
hardremove(toname); /* because create() won't truncate file */
free(dirt);
fdt = create(toname, OWRITE, dirb->mode);
if(fdt < 0){
fprint(2, "mv: can't create %s: %r\n", toname);
close(fdf);
return -1;
}
stat = copy1(fdf, fdt, fromname, toname);
close(fdf);
if(stat >= 0){
nulldir(&null);
null.mtime = dirb->mtime;
null.mode = dirb->mode;
dirfwstat(fdt, &null); /* ignore errors; e.g. user none always fails */
if(remove(fromname) < 0){
fprint(2, "mv: can't remove %s: %r\n", fromname);
stat = -1;
}
}
close(fdt);
return stat;
}
int
copy1(int fdf, int fdt, char *from, char *to)
{
char buf[8192];
long n, n1;
while ((n = read(fdf, buf, sizeof buf)) > 0) {
n1 = write(fdt, buf, n);
if(n1 != n){
fprint(2, "mv: error writing %s: %r\n", to);
return -1;
}
}
if(n < 0){
fprint(2, "mv: error reading %s: %r\n", from);
return -1;
}
return 0;
}
void
split(char *name, char **pdir, char **pelem)
{
char *s;
s = utfrrune(name, '/');
if(s){
*s = 0;
*pelem = s+1;
*pdir = name;
}else if(strcmp(name, "..") == 0){
*pdir = "..";
*pelem = ".";
}else{
*pdir = ".";
*pelem = name;
}
}
int
samefile(char *a, char *b)
{
Dir *da, *db;
int ret;
if(strcmp(a, b) == 0)
return 1;
da = dirstat(a);
db = dirstat(b);
ret = (da != nil && db != nil &&
da->qid.type==db->qid.type &&
da->qid.path==db->qid.path &&
da->qid.vers==db->qid.vers &&
da->dev==db->dev &&
da->type==db->type);
free(da);
free(db);
return ret;
}
void
hardremove(char *a)
{
if(remove(a) == -1){
fprint(2, "mv: can't remove %s: %r\n", a);
exits("mv");
}
while(remove(a) != -1)
;
}