diff --git a/check.t b/check.t index 537ad68..9bbf249 100644 --- a/check.t +++ b/check.t @@ -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 --- diff --git a/funcs.c b/funcs.c index 1a9f9cb..d497806 100644 --- a/funcs.c +++ b/funcs.c @@ -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 #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} }; diff --git a/main.c b/main.c index ef3c6db..08a24a3 100644 --- a/main.c +++ b/main.c @@ -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 #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; diff --git a/mksh.1 b/mksh.1 index d7fbe64..ac1bc0a 100644 --- a/mksh.1 +++ b/mksh.1 @@ -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 diff --git a/sh.h b/sh.h index 5a8e4ab..91689c4 100644 --- a/sh.h +++ b/sh.h @@ -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 *);