follow OpenBSD and add mknod as mksh builtin (mknod <file> p acts as mkfifo)

but write a good chunk of that code myself (better structured, better error
handling, more gotos, less function calls, int -> bool)

passes all tests on mirbsd; this will become mksh R25 once tested on other
supported OSes
This commit is contained in:
tg 2005-10-21 12:41:56 +00:00
parent 4e37f85975
commit 2f9687c58a
5 changed files with 192 additions and 66 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.32 2005/10/08 19:30:58 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.33 2005/10/21 12:41:54 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -3712,5 +3712,5 @@ category: pdksh
stdin:
echo $KSH_VERSION
expected-stdout:
@(#)MIRBSD KSH R24 2005/10/08
@(#)MIRBSD KSH R24 2005/10/21
---

91
funcs.c
View File

@ -1,6 +1,6 @@
/** $MirOS: src/bin/mksh/funcs.c,v 1.20 2005/10/21 11:44:25 tg Exp $ */
/** $MirOS: src/bin/mksh/funcs.c,v 1.21 2005/10/21 12:41:55 tg Exp $ */
/* $OpenBSD: c_ksh.c,v 1.27 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: c_sh.c,v 1.29 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: c_sh.c,v 1.31 2005/10/08 18:07:31 otto Exp $ */
/* $OpenBSD: c_test.c,v 1.17 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: c_ulimit.c,v 1.14 2005/03/30 17:16:37 deraadt Exp $ */
@ -13,7 +13,7 @@
#include <ulimit.h>
#endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.20 2005/10/21 11:44:25 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.21 2005/10/21 12:41:55 tg Exp $");
int
c_cd(char **wp)
@ -2192,6 +2192,90 @@ c_exec(char **wp __attribute__((unused)))
return 0;
}
static int
c_mknod(char **wp)
{
int argc, optc, rv = 0;
bool ismkfifo = false;
char **argv;
void *set = NULL;
mode_t mode = 0, oldmode = 0;
while ((optc = ksh_getopt(wp, &builtin_opt, "m:")) != EOF) {
switch (optc) {
case 'm':
set = setmode(builtin_opt.optarg);
if (set == NULL) {
bi_errorf("invalid file mode");
return (1);
}
mode = getmode(set, DEFFILEMODE);
free(set);
break;
default:
goto c_mknod_usage;
}
}
argv = &wp[builtin_opt.optind];
if (argv[0] == '\0')
goto c_mknod_usage;
for (argc = 0; argv[argc]; argc++)
;
if (argc == 2 && argv[1][0] == 'p')
ismkfifo = true;
else if (argc != 4 || (argv[1][0] != 'b' && argv[1][0] != 'c'))
goto c_mknod_usage;
if (set != NULL)
oldmode = umask(0);
else
mode = DEFFILEMODE;
mode |= (argv[1][0] == 'b') ? S_IFBLK :
(argv[1][0] == 'c') ? S_IFCHR : 0;
if (!ismkfifo) {
unsigned long major, minor;
dev_t dv;
char *c;
major = strtoul(argv[2], &c, 0);
if ((c == argv[2]) || (*c != '\0')) {
bi_errorf("non-numeric device major '%s'", argv[2]);
goto c_mknod_err;
}
minor = strtoul(argv[3], &c, 0);
if ((c == argv[3]) || (*c != '\0')) {
bi_errorf("non-numeric device minor '%s'", argv[3]);
goto c_mknod_err;
}
dv = makedev(major, minor);
if ((unsigned long)major(dv) != major) {
bi_errorf("device major too large: %ld", major);
goto c_mknod_err;
}
if ((unsigned long)minor(dv) != minor) {
bi_errorf("device minor too large: %ld", minor);
goto c_mknod_err;
}
if (mknod(argv[0], mode, dv))
goto c_mknod_failed;
} else if (mkfifo(argv[0], mode)) {
c_mknod_failed:
bi_errorf("%s: %s", *wp, strerror(errno));
c_mknod_err:
rv = 1;
}
if (set)
umask(oldmode);
return (rv);
c_mknod_usage:
bi_errorf("usage: mknod [-m mode] name [b | c] major minor");
bi_errorf("usage: mknod [-m mode] name p");
return (1);
}
/* dummy function, special case in comexec() */
int
c_builtin(char **wp __attribute__((unused)))
@ -2227,6 +2311,7 @@ const struct builtin shbuiltins [] = {
{"ulimit", c_ulimit},
{"+umask", c_umask},
{"*=unset", c_unset},
{"mknod", c_mknod},
{NULL, NULL}
};

6
main.c
View File

@ -1,4 +1,4 @@
/** $MirOS: src/bin/mksh/main.c,v 1.27 2005/10/08 18:53:10 tg Exp $ */
/** $MirOS: src/bin/mksh/main.c,v 1.28 2005/10/21 12:41:55 tg Exp $ */
/* $OpenBSD: main.c,v 1.38 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: tty.c,v 1.8 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: io.c,v 1.21 2005/03/30 17:16:37 deraadt Exp $ */
@ -13,9 +13,9 @@
#include <time.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.27 2005/10/08 18:53:10 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.28 2005/10/21 12:41:55 tg Exp $");
#define MKSH_VERSION "@(#)MIRBSD KSH R24 2005/10/08"
#define MKSH_VERSION "@(#)MIRBSD KSH R24 2005/10/21"
extern char **environ;

51
mksh.1
View File

@ -1,5 +1,5 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.22 2005/10/08 19:34:39 tg Exp $
.\" $OpenBSD: ksh.1,v 1.101 2005/08/01 19:29:57 jmc Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.23 2005/10/21 12:41:55 tg Exp $
.\" $OpenBSD: ksh.1,v 1.106 2005/10/12 19:52:56 bernd Exp $
.\" $OpenBSD: sh.1tbl,v 1.53 2004/12/10 01:56:56 jaredy Exp $
.\"
.Dd May 22, 2005
@ -2299,8 +2299,9 @@ Additional
.Nm
regular commands
.Pp
.Ic \&[ , echo , let , print ,
.Ic pwd , test , ulimit , whence
.Ic \&[ , echo , let , mknod ,
.Ic print , pwd , test , ulimit ,
.Ic whence
.Pp
In the future, the additional
.Nm
@ -2890,6 +2891,43 @@ is syntactic sugar for
.No let \&" Ns Ar expr Ns \&" .
.Pp
.It Xo
.Ic mknod
.Op Fl m Ar mode
.Ar name
.Op Cm c | Cm b
.Ar major minor
.Xc
.It Xo
.Ic mknod
.Op Fl m Ar mode
.Ar name
.Cm p
.Xc
Create a device special file.
The file type may be
.Cm b
(block type device),
.Cm c
(character type device),
or
.Cm p
(named pipe).
The file created may be modified according to its
.Ar mode
(via the
.Fl m
option),
.Ar major
(major device number),
and
.Ar minor
(minor device number).
.Pp
See
.Xr mknod 8
for further information.
.Pp
.It Xo
.Ic print
.Oo Fl nprsu Ns Oo Ar n Oc \*(Ba
.Fl R Op Fl en Oc
@ -5068,6 +5106,8 @@ Shell database.
.Xr execve 2 ,
.Xr getgid 2 ,
.Xr getuid 2 ,
.Xr mknod 2 ,
.Xr mkfifo 2 ,
.Xr open 2 ,
.Xr pipe 2 ,
.Xr wait 2 ,
@ -5079,7 +5119,8 @@ Shell database.
.Xr tty 4 ,
.Xr shells 5 ,
.Xr environ 7 ,
.Xr script 7
.Xr script 7 ,
.Xr mknod 8
.Pp
.Pa http://docsrv.sco.com:507/en/man/html.C/sh.C.html
.Rs

106
sh.h
View File

@ -1,11 +1,11 @@
/** $MirOS: src/bin/mksh/sh.h,v 1.18 2005/10/08 19:31:00 tg Exp $ */
/* $OpenBSD: sh.h,v 1.27 2005/03/28 21:33:04 deraadt Exp $ */
/** $MirOS: src/bin/mksh/sh.h,v 1.19 2005/10/21 12:41:56 tg Exp $ */
/* $OpenBSD: sh.h,v 1.28 2005/10/04 20:35:11 otto Exp $ */
/* $OpenBSD: shf.h,v 1.5 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: table.h,v 1.6 2004/12/18 20:55:52 millert Exp $ */
/* $OpenBSD: tree.h,v 1.10 2005/03/28 21:28:22 deraadt Exp $ */
/* $OpenBSD: expand.h,v 1.6 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: lex.h,v 1.9 2004/12/18 21:04:52 millert Exp $ */
/* $OpenBSD: proto.h,v 1.26 2005/03/28 21:28:22 deraadt Exp $ */
/* $OpenBSD: proto.h,v 1.27 2005/10/06 06:39:36 otto Exp $ */
/* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */
/* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */
@ -453,28 +453,6 @@ struct shf {
extern struct shf shf_iob[];
struct shf *shf_open(const char *, int, int, int);
struct shf *shf_fdopen(int, int, struct shf *);
struct shf *shf_reopen(int, int, struct shf *);
struct shf *shf_sopen(char *, int, int, struct shf *);
int shf_close(struct shf *);
int shf_fdclose(struct shf *);
char *shf_sclose(struct shf *);
int shf_finish(struct shf *);
int shf_flush(struct shf *);
int shf_seek(struct shf *, off_t, int);
int shf_read(char *, int, struct shf *);
char *shf_getse(char *, int, struct shf *);
int shf_getchar(struct shf *s);
int shf_ungetc(int, struct shf *);
int shf_putchar(int, struct shf *);
int shf_puts(const char *, struct shf *);
int shf_write(const char *, int, struct shf *);
int shf_fprintf(struct shf *, const char *, ...);
int shf_snprintf(char *, int, const char *, ...);
char *shf_smprintf(const char *, ...);
int shf_vfprintf(struct shf *, const char *, va_list);
struct table {
Area *areap; /* area to allocate entries */
short size, nfree; /* hash size (always 2^^n), free entries */
@ -984,7 +962,34 @@ void afreeall(Area *);
void * alloc(size_t, Area *);
void * aresize(void *, size_t, Area *);
void afree(void *, Area *);
/* c_funcs.c */
/* edit.c */
void x_init(void);
int x_read(char *, size_t);
int x_bind(const char *, const char *, int, int);
/* eval.c */
char * substitute(const char *, int);
char ** eval(char **, int);
char * evalstr(char *cp, int);
char * evalonestr(char *cp, int);
char *debunk(char *, const char *, size_t);
void expand(char *, XPtrV *, int);
int glob_str(char *, XPtrV *, int);
/* exec.c */
int execute(struct op * volatile, volatile int);
int shcomexec(char **);
struct tbl * findfunc(const char *, unsigned int, int);
int define(const char *, struct op *);
void builtin(const char *, int (*)(char **));
struct tbl * findcom(const char *, int);
void flushcom(int);
char * search(const char *, const char *, int, int *);
int search_access(const char *, int, int *);
int pr_menu(char *const *);
int pr_list(char *const *);
/* expr.c */
int evaluate(const char *, long *, int, bool);
int v_evaluate(struct tbl *, const char *, volatile int, bool);
/* funcs.c */
int c_hash(char **);
int c_cd(char **);
int c_pwd(char **);
@ -1020,33 +1025,6 @@ void timex_hook(struct op *, char ** volatile *);
int c_exec(char **);
int c_builtin(char **);
int c_test(char **);
/* edit.c */
void x_init(void);
int x_read(char *, size_t);
int x_bind(const char *, const char *, int, int);
/* eval.c */
char * substitute(const char *, int);
char ** eval(char **, int);
char * evalstr(char *cp, int);
char * evalonestr(char *cp, int);
char *debunk(char *, const char *, size_t);
void expand(char *, XPtrV *, int);
int glob_str(char *, XPtrV *, int);
/* exec.c */
int execute(struct op * volatile, volatile int);
int shcomexec(char **);
struct tbl * findfunc(const char *, unsigned int, int);
int define(const char *, struct op *);
void builtin(const char *, int (*)(char **));
struct tbl * findcom(const char *, int);
void flushcom(int);
char * search(const char *, const char *, int, int *);
int search_access(const char *, int, int *);
int pr_menu(char *const *);
int pr_list(char *const *);
/* expr.c */
int evaluate(const char *, long *, int, bool);
int v_evaluate(struct tbl *, const char *, volatile int, bool);
/* histrap.c */
void init_histvec(void);
void hist_init(Source *);
@ -1176,6 +1154,28 @@ int make_path(const char *, const char *, char **, XString *, int *);
void simplify_path(char *);
char *get_phys_path(const char *);
void set_current_wd(char *);
/* shf.c */
struct shf *shf_open(const char *, int, int, int);
struct shf *shf_fdopen(int, int, struct shf *);
struct shf *shf_reopen(int, int, struct shf *);
struct shf *shf_sopen(char *, int, int, struct shf *);
int shf_close(struct shf *);
int shf_fdclose(struct shf *);
char * shf_sclose(struct shf *);
int shf_finish(struct shf *);
int shf_flush(struct shf *);
int shf_seek(struct shf *, off_t, int);
int shf_read(char *, int, struct shf *);
char * shf_getse(char *, int, struct shf *);
int shf_getchar(struct shf *s);
int shf_ungetc(int, struct shf *);
int shf_putchar(int, struct shf *);
int shf_puts(const char *, struct shf *);
int shf_write(const char *, int, struct shf *);
int shf_fprintf(struct shf *, const char *, ...);
int shf_snprintf(char *, int, const char *, ...);
char * shf_smprintf(const char *, ...);
int shf_vfprintf(struct shf *, const char *, va_list);
/* syn.c */
void initkeywords(void);
struct op * compile(Source *);