route: zap unused sockaddr
No object change. OK? Index: show.c === RCS file: /cvs/src/sbin/route/show.c,v retrieving revision 1.112 diff -u -p -r1.112 show.c --- show.c 1 May 2018 18:13:21 - 1.112 +++ show.c 2 Jun 2018 22:55:26 - @@ -140,7 +140,6 @@ p_rttables(int af, u_int tableid, char p char *buf = NULL, *next, *lim = NULL; size_t needed; int mib[7], mcnt; - struct sockaddr *sa; mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -164,7 +163,6 @@ p_rttables(int af, u_int tableid, char p rtm = (struct rt_msghdr *)next; if (rtm->rtm_version != RTM_VERSION) continue; - sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); p_rtentry(rtm); } }
Re: route: regress: Allow specifying binary via ROUTE
On Sun, Jun 03, 2018 at 12:26:18AM +0200, Klemens Nanni wrote: > With `make ROUTE=/usr/obj/sbin/route/route' I can test my patched > version without having to modify PATH or the regress Makefile. > > pfctl already does it that way. This is the right approach. > OK? I prefer ROUTE ?= /sbin/route, then regress does not depend on the PATH. It is clear in the output which route is used. with that OK bluhm@ > Index: Makefile > === > RCS file: /cvs/src/regress/sbin/route/Makefile,v > retrieving revision 1.29 > diff -u -p -r1.29 Makefile > --- Makefile 20 Feb 2018 12:44:28 - 1.29 > +++ Makefile 2 Jun 2018 22:13:25 - > @@ -1,5 +1,6 @@ > # $OpenBSD: Makefile,v 1.29 2018/02/20 12:44:28 mpi Exp $ > > +ROUTE?= route > RDOMAIN?=5 > > .MAIN: all > @@ -27,7 +28,7 @@ RDOMAIN?= 5 > .endif > .endif > > -RCMD=${SUDO} route -T ${RDOMAIN} -n > +RCMD=${SUDO} ${ROUTE} -T ${RDOMAIN} -n > > netmask: > .for mod in -net -dst
route: regress: Allow specifying binary via ROUTE
With `make ROUTE=/usr/obj/sbin/route/route' I can test my patched version without having to modify PATH or the regress Makefile. pfctl already does it that way. OK? Index: Makefile === RCS file: /cvs/src/regress/sbin/route/Makefile,v retrieving revision 1.29 diff -u -p -r1.29 Makefile --- Makefile20 Feb 2018 12:44:28 - 1.29 +++ Makefile2 Jun 2018 22:13:25 - @@ -1,5 +1,6 @@ # $OpenBSD: Makefile,v 1.29 2018/02/20 12:44:28 mpi Exp $ +ROUTE?=route RDOMAIN?= 5 .MAIN: all @@ -27,7 +28,7 @@ RDOMAIN?= 5 .endif .endif -RCMD= ${SUDO} route -T ${RDOMAIN} -n +RCMD= ${SUDO} ${ROUTE} -T ${RDOMAIN} -n netmask: .for mod in -net -dst
Re: [patch] rc.subr support for pidfile-based daemons
IL Ka wrote: > > > > pid files can easily get out of sync with the expected process (example: > > daemon starts, writes a pid file, later it crashes. at any point between > > the crash and you trying to stop/restart the daemon another process > > could be assigned the same pid, then the wrong process is signalled). > > > > Wow, I've never thought about that) > pidfiles are so common on unicies, and mentioned in docs like "standard" > approach: > For example: http://uwsgi-docs.readthedocs.io/en/latest/Management.html > # using kill to send the signal > kill -HUP `cat /tmp/project-master.pid` > > Is it because other OSes do not randomize pids as OpenBSD does (they use > sequental pids) > so chances for pid reuse are lower there? > > Or do they simply "do not care"? They do not care.
Re: [patch] rc.subr support for pidfile-based daemons
> > pid files can easily get out of sync with the expected process (example: > daemon starts, writes a pid file, later it crashes. at any point between > the crash and you trying to stop/restart the daemon another process > could be assigned the same pid, then the wrong process is signalled). > Wow, I've never thought about that) pidfiles are so common on unicies, and mentioned in docs like "standard" approach: For example: http://uwsgi-docs.readthedocs.io/en/latest/Management.html # using kill to send the signal kill -HUP `cat /tmp/project-master.pid` Is it because other OSes do not randomize pids as OpenBSD does (they use sequental pids) so chances for pid reuse are lower there? Or do they simply "do not care"? Anyway, if this is done intentionally, my approach is not correct. Ilya.
Re: [patch] rc.subr support for pidfile-based daemons
On 2018/06/02 23:07, Il Ka wrote: > rc.subr(8) uses pgrep(1)/pkill(1) to control daemons > using their command lines. This is intentional. pid files can easily get out of sync with the expected process (example: daemon starts, writes a pid file, later it crashes. at any point between the crash and you trying to stop/restart the daemon another process could be assigned the same pid, then the wrong process is signalled). The timescale could be days/weeks/longer. (I believe there is still a possible race with pkill, but there the window is tiny, much less than a second.)
httpd/parse.y : fix line count
Applying otto@'s diff to httpd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/httpd/parse.y,v retrieving revision 1.99 diff -u -p -r1.99 parse.y --- parse.y 23 May 2018 19:11:48 - 1.99 +++ parse.y 2 Jun 2018 18:18:13 - @@ -59,6 +59,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -72,8 +76,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -1288,34 +1293,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -unsigned char *parsebuf; -int parseindex; -unsigned char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -1325,8 +1335,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -1335,28 +1345,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -1364,14 +1385,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to eith
iked/parse.y : fix line count
Applying otto@'s diff to iked. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/sbin/iked/parse.y,v retrieving revision 1.71 diff -u -p -r1.71 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.71 +++ parse.y 27 May 2018 14:41:47 - @@ -59,6 +59,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file; @@ -77,8 +81,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -434,7 +439,7 @@ comma : ',' include: INCLUDE STRING{ struct file *nfile; - if ((nfile = pushfile($2, 0)) == NULL) { + if ((nfile = pushfile($2, 1)) == NULL) { yyerror("failed to include file %s", $2); free($2); YYERROR; @@ -1213,34 +1218,39 @@ lookup(char *s) } } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -unsigned char *parsebuf; -int parseindex; -unsigned char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (popfile() == EOF) @@ -1250,8 +1260,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -1261,27 +1271,38 @@ lgetc(int quotec) } while (c == EOF) { - if (popfile() == EOF) - return (EOF); - c = getc(file->stream); + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index <
snmpd/parse.y : fix line count
Applying otto@'s diff to snmpd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v retrieving revision 1.47 diff -u -p -r1.47 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.47 +++ parse.y 27 May 2018 14:18:32 - @@ -61,6 +61,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -74,8 +78,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -657,34 +662,38 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing quoted string"); if (file == topfile || popfile() == EOF) return (EOF); @@ -693,8 +702,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -711,28 +720,39 @@ lgetc(int quotec) c = ' '; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -740,14 +760,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to either EOF or the first real EOL */ while (1) { -
ypldap/parse.y : fix line count
Applying otto@'s diff to ypldap. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/ypldap/parse.y,v retrieving revision 1.24 diff -u -p -r1.24 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.24 +++ parse.y 27 May 2018 12:58:06 - @@ -56,6 +56,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -69,8 +73,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -130,7 +135,7 @@ optnl : '\n' optnl include: INCLUDE STRING{ struct file *nfile; - if ((nfile = pushfile($2, 0)) == NULL) { + if ((nfile = pushfile($2, 1)) == NULL) { yyerror("failed to include file %s", $2); free($2); YYERROR; @@ -491,34 +496,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -528,8 +538,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -538,28 +548,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) +
relayd/parse.y : fix line count
Applying otto@'s diff to relayd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/relayd/parse.y,v retrieving revision 1.223 diff -u -p -r1.223 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.223 +++ parse.y 2 Jun 2018 18:55:33 - @@ -63,6 +63,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -74,8 +78,9 @@ intyylex(void); int yyerror(const char *, ...); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -2327,34 +2332,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +#define START_EXPAND 1 +#define DONE_EXPAND2 + +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -2364,8 +2374,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -2374,28 +2384,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -2403,14 +2424,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to either EOF or the first real EOL */ while (1) { -
switchd/parse.y : fix line count
Applying otto@'s diff to switchd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/switchd/parse.y,v retrieving revision 1.6 diff -u -p -r1.6 parse.y --- parse.y 28 Aug 2017 06:00:05 - 1.6 +++ parse.y 27 May 2018 13:28:54 - @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -56,8 +61,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); int host(const char *, struct sockaddr *, socklen_t); @@ -294,34 +300,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -331,8 +342,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -349,28 +360,39 @@ lgetc(int quotec) c = ' '; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -378,14 +400,9 @@ findeol(void) { int c; - parsebuf =
ldapd/parse.y : fix line count
Applying otto@'s diff to ldapd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/ldapd/parse.y,v retrieving revision 1.28 diff -u -p -r1.28 parse.y --- parse.y 18 May 2018 12:36:30 - 1.28 +++ parse.y 2 Jun 2018 19:48:01 - @@ -52,6 +52,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -65,8 +69,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); struct listener *host_unix(const char *path); @@ -477,34 +482,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#defineSTART_EXPAND1 +#defineDONE_EXPAND 2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -514,8 +524,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -524,28 +534,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -553,14 +574,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to either EOF or the first real EOL */ while (1) { -
ldpd/parse.y : fix line count
Applying otto@'s diff to ldpd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/ldpd/parse.y,v retrieving revision 1.62 diff -u -p -r1.62 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.62 +++ parse.y 2 Jun 2018 19:51:55 - @@ -43,6 +43,10 @@ struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; }; @@ -76,15 +80,14 @@ typedef struct { int lineno; } YYSTYPE; -#define MAXPUSHBACK128 - static int yyerror(const char *, ...) __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1))); static int kw_cmp(const void *, const void *); static int lookup(char *); +static int igetc(void); static int lgetc(int); -static int lungetc(int); +voidlungetc(int); static int findeol(void); static int yylex(void); static int check_file_secrecy(int, const char *); @@ -127,11 +130,6 @@ static struct config_defaults tnbrdefs; static struct config_defaults pwdefs; static struct config_defaults *defs; -static unsigned char *parsebuf; -static int parseindex; -static unsigned charpushback_buffer[MAXPUSHBACK]; -static int pushback_index; - %} %token INTERFACE TNEIGHBOR ROUTERID FIBUPDATE RDOMAIN EXPNULL @@ -168,7 +166,8 @@ grammar : /* empty */ include: INCLUDE STRING{ struct file *nfile; - if ((nfile = pushfile($2, 1)) == NULL) { + if ((nfile = pushfile($2, + !(global.cmd_opts & LDPD_OPT_NOACTION))) == NULL) { yyerror("failed to include file %s", $2); free($2); YYERROR; @@ -876,27 +875,39 @@ lookup(char *s) return (STRING); } -static int -lgetc(int quotec) +#define START_EXPAND 1 +#define DONE_EXPAND2 + +static int expanding; + +int +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +static int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -906,8 +917,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -916,28 +927,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EO
ospf6d/parse.y : fix line count
Applying otto@'s diff to ospf6d. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v retrieving revision 1.31 diff -u -p -r1.31 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.31 +++ parse.y 2 Jun 2018 20:18:24 - @@ -50,6 +50,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -63,8 +67,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -146,7 +151,8 @@ grammar : /* empty */ include: INCLUDE STRING{ struct file *nfile; - if ((nfile = pushfile($2, 1)) == NULL) { + if ((nfile = pushfile($2, + !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) { yyerror("failed to include file %s", $2); free($2); YYERROR; @@ -591,34 +597,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -628,8 +639,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -638,28 +649,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); +
ospfd/parse.y : fix line count
Applying otto@'s diff to ospfd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/ospfd/parse.y,v retrieving revision 1.87 diff -u -p -r1.87 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.87 +++ parse.y 2 Jun 2018 20:17:10 - @@ -48,6 +48,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -61,8 +65,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -154,7 +159,8 @@ grammar : /* empty */ include: INCLUDE STRING{ struct file *nfile; - if ((nfile = pushfile($2, 1)) == NULL) { + if ((nfile = pushfile($2, + !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) { yyerror("failed to include file %s", $2); free($2); YYERROR; @@ -836,34 +842,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -873,8 +884,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -883,28 +894,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); +
iscsictl/parse.y : fix line count
Applying otto@'s diff to iscsictl. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/iscsictl/parse.y,v retrieving revision 1.11 diff -u -p -r1.11 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.11 +++ parse.y 2 Jun 2018 19:05:26 - @@ -50,6 +50,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -62,8 +66,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); voidclear_config(struct iscsi_config *); @@ -393,34 +398,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -430,8 +440,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -448,20 +458,20 @@ lgetc(int quotec) return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -469,14 +479,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to either EOF or the first real EOL */ while (1) { - if (pushback_index) - c = pushback_buffer[--pushback_index]; - else - c = lgetc(0); + c = lgetc(0); if (c == '\n') { file->lineno++; break; @@ -504,7 +509,7 @@ top: if (c == '#') while ((c = lgetc(0)) != '\n' && c != EOF) ; /* nothing */ - if (c == '$' && parsebuf == NULL) { + if (c == '$' && !expanding) { while (1) { if ((c = lgetc(0)) == EOF) return (0); @@ -526,8 +531,13 @@ top: yyerror("macro '%s' not defined", buf); return (findeol()); } - parsebuf = val; -
vmd/parse.y : fix line count
Applying otto@'s diff to vmd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/vmd/parse.y,v retrieving revision 1.33 diff -u -p -r1.33 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.33 +++ parse.y 2 Jun 2018 20:23:16 - @@ -55,6 +55,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -67,8 +71,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -684,34 +689,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -721,8 +731,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -739,28 +749,39 @@ lgetc(int quotec) c = ' '; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -768,14 +789,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to either EOF or the first real EOL */ while (1) {
smtpd/parse.y : fix line count
Applying otto@'s diff to smtpd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v retrieving revision 1.210 diff -u -p -r1.210 parse.y --- parse.y 1 Jun 2018 20:31:33 - 1.210 +++ parse.y 2 Jun 2018 19:31:08 - @@ -63,6 +63,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -73,8 +77,9 @@ intyyparse(void); int yylex(void); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); int yyerror(const char *, ...) __attribute__((__format__ (printf, 1, 2))) @@ -1663,34 +1668,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -unsigned char *parsebuf; -int parseindex; -unsigned char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -1700,8 +1710,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -1710,28 +1720,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -1739,9 +1760,6 @@ findeol(void) { int c; - parsebuf = NULL; - pushback_index = 0; -
eigrpd/parse.y : fix line count
Applying otto@'s diff to eigrpd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/eigrpd/parse.y,v retrieving revision 1.23 diff -u -p -r1.23 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.23 +++ parse.y 27 May 2018 16:12:49 - @@ -45,6 +45,10 @@ struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; }; @@ -83,15 +87,14 @@ typedef struct { int lineno; } YYSTYPE; -#define MAXPUSHBACK128 - static int yyerror(const char *, ...) __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1))); static int kw_cmp(const void *, const void *); static int lookup(char *); +static int igetc(void); static int lgetc(int); -static int lungetc(int); +voidlungetc(int); static int findeol(void); static int yylex(void); static int check_file_secrecy(int, const char *); @@ -123,11 +126,6 @@ static struct config_defaults asdefs; static struct config_defaults ifacedefs; static struct config_defaults *defs; -static unsigned char *parsebuf; -static int parseindex; -static unsigned charpushback_buffer[MAXPUSHBACK]; -static int pushback_index; - %} %token ROUTERID AS FIBUPDATE RDOMAIN REDISTRIBUTE METRIC DFLTMETRIC @@ -159,7 +157,8 @@ grammar : /* empty */ include: INCLUDE STRING { struct file *nfile; - if ((nfile = pushfile($2, 1)) == NULL) { + if ((nfile = pushfile($2, + !(global.cmd_opts & EIGRPD_OPT_NOACTION))) == NULL) { yyerror("failed to include file %s", $2); free($2); YYERROR; @@ -653,27 +652,39 @@ lookup(char *s) return (STRING); } -static int -lgetc(int quotec) +#define START_EXPAND 1 +#define DONE_EXPAND2 + +static int expanding; + +int +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +static int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -683,8 +694,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -693,28 +704,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == E
hostapd/parse.y : fix line count
Applying otto@'s diff to hostapd. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/hostapd/parse.y,v retrieving revision 1.55 diff -u -p -r1.55 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.55 +++ parse.y 27 May 2018 16:16:52 - @@ -62,6 +62,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -75,8 +79,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -190,8 +195,7 @@ include : INCLUDE STRING { struct file *nfile; - if ((nfile = - pushfile($2, 1)) == NULL) { + if ((nfile = pushfile($2, 1)) == NULL) { yyerror("failed to include file %s", $2); free($2); YYERROR; @@ -1336,34 +1340,39 @@ lookup(char *token) return (p == NULL ? STRING : p->k_val); } -#define MAXPUSHBACK128 +#defineSTART_EXPAND1 +#defineDONE_EXPAND 2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -1373,8 +1382,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -1383,28 +1392,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); - } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + retur
acme-client/parse.y : fix line count
Applying otto@'s diff to acme-client. Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/acme-client/parse.y,v retrieving revision 1.21 diff -u -p -r1.21 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.21 +++ parse.y 27 May 2018 15:47:33 - @@ -43,6 +43,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -55,8 +59,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); struct authority_c *conf_new_authority(struct acme_conf *, char *); @@ -432,34 +437,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#defineSTART_EXPAND1 +#defineDONE_EXPAND 2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -469,8 +479,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -479,28 +489,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -508,14 +529,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to either EOF or the
bgpd/parse.y : fix line count
Applying otto@'s diff to bgpd Fixes an off-by-one line count when using include statements. Ok ? Index: parse.y === RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v retrieving revision 1.320 diff -u -p -r1.320 parse.y --- parse.y 26 Apr 2018 14:12:19 - 1.320 +++ parse.y 27 May 2018 13:14:27 - @@ -53,6 +53,10 @@ static struct file { TAILQ_ENTRY(file)entry; FILE*stream; char*name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; int lineno; int errors; } *file, *topfile; @@ -66,8 +70,9 @@ intyyerror(const char *, ...) __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); +int igetc(void); int lgetc(int); -int lungetc(int); +voidlungetc(int); int findeol(void); TAILQ_HEAD(symhead, sym)symhead = TAILQ_HEAD_INITIALIZER(symhead); @@ -2566,34 +2571,39 @@ lookup(char *s) return (STRING); } -#define MAXPUSHBACK128 +#define START_EXPAND 1 +#define DONE_EXPAND2 -u_char *parsebuf; -int parseindex; -u_char pushback_buffer[MAXPUSHBACK]; -int pushback_index = 0; +static int expanding; int -lgetc(int quotec) +igetc(void) { - int c, next; + int c; - if (parsebuf) { - /* Read character from the parsebuffer instead of input. */ - if (parseindex >= 0) { - c = parsebuf[parseindex++]; - if (c != '\0') - return (c); - parsebuf = NULL; - } else - parseindex++; + while (1) { + if (file->ungetpos > 0) + c = file->ungetbuf[--file->ungetpos]; + else + c = getc(file->stream); + + if (c == START_EXPAND) + expanding = 1; + else if (c == DONE_EXPAND) + expanding = 0; + else + break; } + return (c); +} - if (pushback_index) - return (pushback_buffer[--pushback_index]); +int +lgetc(int quotec) +{ + int c, next; if (quotec) { - if ((c = getc(file->stream)) == EOF) { + if ((c = igetc()) == EOF) { yyerror("reached end of file while parsing " "quoted string"); if (file == topfile || popfile() == EOF) @@ -2603,8 +2613,8 @@ lgetc(int quotec) return (c); } - while ((c = getc(file->stream)) == '\\') { - next = getc(file->stream); + while ((c = igetc()) == '\\') { + next = igetc(); if (next != '\n') { c = next; break; @@ -2613,28 +2623,39 @@ lgetc(int quotec) file->lineno++; } - while (c == EOF) { - if (file == topfile || popfile() == EOF) - return (EOF); - c = getc(file->stream); + if (c == EOF) { + /* +* Fake EOL when hit EOF for the first time. This gets line +* count right if last line in included file is syntactically +* invalid and has no newline. +*/ + if (file->eof_reached == 0) { + file->eof_reached = 1; + return ('\n'); + } + while (c == EOF) { + if (file == topfile || popfile() == EOF) + return (EOF); + c = igetc(); + } } return (c); } -int +void lungetc(int c) { if (c == EOF) - return (EOF); - if (parsebuf) { - parseindex--; - if (parseindex >= 0) - return (c); + return; + + if (file->ungetpos >= file->ungetsize) { + void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); + if (p == NULL) + err(1, "lungetc"); + file->ungetbuf = p; + file->ungetsize *= 2; } - if (pushback_index < MAXPUSHBACK-1) - return (pushback_buffer[pushback_index++] = c); - else - return (EOF); + file->ungetbuf[file->ungetpos++] = c; } int @@ -2642,14 +2663,9 @@ findeol(void) { int c; - parsebuf = NULL; - /* skip to either EOF or the first real EOL *
[patch] rc.subr support for pidfile-based daemons
Hello, rc.subr(8) uses pgrep(1)/pkill(1) to control daemons using their command lines. But in some cases it is more convenient to use pidfiles. Many services do so, inluding apache and postgresql. But not all services do have special tool for that. I run gunicorn (python wsgi server) that is able to produce pidfile, but lacks of tool to control it. So, I added ``daemon_pidfile`` variable to rc.subr(8). If this variable is not set then everything works as usual. But if you set it then system uses it to check (ps -p), stop and reload (kill) daemon. I then simply tell gunicorn to write its pidfile and everything works. I believe this approach may be used by other rc scripts also. Diff below does not have man yet, and I am ready to write it if everyone would agree with my changes. Ilya. Index: etc/rc.d/rc.subr === RCS file: /cvs/src/etc/rc.d/rc.subr,v retrieving revision 1.127 diff -u -p -u -r1.127 rc.subr --- etc/rc.d/rc.subr5 Jun 2017 18:31:23 - 1.127 +++ etc/rc.d/rc.subr2 Jun 2018 19:33:29 - @@ -49,6 +49,7 @@ _rc_write_runfile() { cat >${_RC_RUNFILE}
Re: Allow disks to be specifid by duid in install.sub
On Fri, May 18, 2018 at 12:14:36PM +0200, Theo Buehler wrote: > On Thu, May 17, 2018 at 06:42:15PM -0600, Aaron Bieber wrote: > > On Thu, May 17, 2018 at 06:37:56PM -0600, Aaron Bieber wrote: > > > On Fri, Mar 02, 2018 at 07:32:04AM -0700, Aaron Bieber wrote: > > > > Hi, > > > > > > > > Currently disks can only be entered in the [sw]d[0-9][0-9] format at the > > > > "Which disk is the root disk?" prompt. This is great for humans, but > > > > things get tricky when doing an autoinstall upgrade on systems where > > > > connected disks change frequently. > > > > > > > > This diff lets you put the DUID in the response file. > > > > > > > > If anyone has a better way to determine the disk from the duid, I am all > > > > ears :D > > > > > > > > Cheers, > > > > Aaron > > > > > > > > > > Thanks to tb@, kn@, Philipp Buehler and phy1729 on #metabug! I tested a > > > bsd.rd with an auto-upgrade response file. Once with a duid and once > > > with a disk name. Both worked. > > > > > > I have an OK from tb@ unless anyone objects. > > > > > > The diff has been distilled down to this: > > > > > > > Paste fail, here is the latest diff: > > Sleeping over it once more, I must say I'm still not terribly fond of > this hack and would like to retract my ok for these two reasons: > > * we clobber 'resp' which may then leave a confusing error message. > It's only in the $AUTO case, but still. Theo is right here. The orginal input should be preserved and used in the error messages and should be written to the autoinstall logfile. > * In the is_duid case we walk the hw.disknames output twice even though > we know that we already have a good device. This is a bit stupid. The get_rootinfo() function is not very "efficient" anyway because it is meant to kind of dynamically detect just connected disks. That's why get_dkdev() is already called multiple times and this even on every iteration of the while-loop. Which also means walking through the hw.disknames output multiple times. It's more about reusing an existing function (get_dkdev_name) that uses hw.disknames to extract the corresponding disk device name. > I do think this is going in the right direction, but I'd really like to > see these two points resolved before it goes in. It's probably not too > difficult, but I've got too many things on my hand, so I won't be able > to do it myself anytime soon. My suggestion is to not special case autoinstall, but to always use get_dkdev_name() to translate a possible supplied DUID to a disk device name. If the input $resp was already a disk device name, get_dkdev_name() just returns this disk device name. So in both cases, $_dkdev holds the disk device name. $_dkdev can then be used where a disk device name is required. $resp can still be used for the error messages and the ai.log. This would be the resulting diff, which looks more complex but the change is actually simpler then the previous diff. I've tested it sucessfully with DUIDs and disk dev names, both interactivly and with autoinstall. Index: install.sub === RCS file: /cvs/src/distrib/miniroot/install.sub,v retrieving revision 1.1068 diff -u -p -p -u -r1.1068 install.sub --- install.sub 29 May 2018 20:37:22 - 1.1068 +++ install.sub 2 Jun 2018 19:27:03 - @@ -,7 +,7 @@ is_rootdisk() { # Get global root information. ie. ROOTDISK, ROOTDEV and SWAPDEV. get_rootinfo() { - local _default=$(get_dkdevs) + local _default=$(get_dkdevs) _dkdev local _q="Which disk is the root disk? ('?' for details)" while :; do @@ -2231,11 +2231,14 @@ get_rootinfo() { case $resp in "?")diskinfo $(get_dkdevs);; '') ;; - *) if isin "$resp" $(get_dkdevs); then + *) # Translate $resp to disk dev name in case it is a DUID. + # get_dkdev_name bounces back the disk dev name if not. + _dkdev=$(get_dkdev_name "$resp") + if isin "$_dkdev" $(get_dkdevs); then [[ $MODE == install ]] && break - is_rootdisk "$resp" && break + is_rootdisk "$_dkdev" && break echo "$resp is not a valid root disk." - _default="$(rmel "$resp" $_default) $resp" + _default="$(rmel "$_dkdev" $_default) $_dkdev" else echo "no such disk" fi @@ -2245,9 +2248,9 @@ get_rootinfo() { done log_answers "$_q" "$resp" - make_dev $resp || exit + make_dev $_dkdev || exit - ROOTDISK=$resp + ROOTDISK=$_dkdev ROOTDEV=${ROOTDISK}a SWAPDEV=${ROOTDISK}b } === Stats: --- 6 lines 191 ch
witness report
Happens while booting my AMD desktop w/ radeon. lock order reversal: 1st 0xff01d4b2be30 vmmaplk (&map->lock) @ /home/brynet/Projects/current/src/sys/uvm/uvm_map.c:4433 2nd 0xff01d415a0a0 inode (&ip->i_lock) @ /home/brynet/Projects/current/src/sys/ufs/ufs/ufs_vnops.c:1559 lock order "&ip->i_lock"(rrwlock) -> "&map->lock"(rwlock) first seen at: #0 witness_checkorder+0x494 #1 _rw_enter+0x56 #2 vm_map_lock_ln+0xac #3 uvm_map+0x191 #4 km_alloc+0x15a #5 pool_multi_alloc_ni+0xae #6 pool_p_alloc+0x49 #7 pool_do_get+0xd7 #8 pool_get+0xa2 #9 ufsdirhash_build+0x311 #10 ufs_lookup+0x18a #11 VOP_LOOKUP+0x42 #12 vfs_lookup+0x27e #13 namei+0x205 #14 loadfirmware+0xef #15 r600_init_microcode+0x382 #16 r600_init+0x4d5 #17 radeon_device_init+0xa90 #18 radeondrm_attachhook+0x34 lock order "&map->lock"(rwlock) -> "&ip->i_lock"(rrwlock) first seen at: #0 witness_checkorder+0x494 #1 _rw_enter+0x56 #2 _rrw_enter+0x32 #3 VOP_LOCK+0x30 #4 vn_lock+0x24 #5 uvn_io+0x1a5 #6 uvm_pager_put+0xf9 #7 uvn_flush+0x414 #8 uvm_map_clean+0x3c7 #9 syscall+0x31d #10 Xsyscall_untramp+0xc0
witness during regress
Hi, Apart from the traces already reported, my amd64 machine finds this one while running regress. acquiring duplicate lock of same type: "&mp->mnt_lock" 1st vfslock @ /usr/src/sys/kern/vfs_subr.c:191 2nd vfslock @ /usr/src/sys/kern/vfs_subr.c:191 Starting stack trace... witness_checkorder(9,81ac7b98,bf,806c7c40,21) at witness_checkorder+0x63d _rw_enter(0,806c7c40,806c7c00,8) at _rw_enter+0x56 vfs_busy(8000ffa57460,806c9800) at vfs_busy+0x66 dounmount(8000ffa57460,8000ffa77790,1) at dounmount+0x8a sys_unmount(160,8000ffa77790,16) at sys_unmount+0xba syscall(7f7f2450) at syscall+0x31d Xsyscall_untramp(6,0,0,0,0,16) at Xsyscall_untramp+0xc0 end of kernel end trace frame: 0x7f7f2890, count: 250 End of stack trace. Full dmesg is here: http://bluhm.genua.de/regress/results/2018-06-02T06:17:01Z/dmesg-ot6.txt bluhm
Re: Remove unused C3 values (VIA)
On Sat, Jun 02, 2018 at 11:30:15AM +, Visa Hankala wrote: > On Sat, Jun 02, 2018 at 01:00:05PM +0200, Frederic Cambus wrote: > > Hi tech@, > > > > Here is a diff to remove unused C3 values. > > > > Comments? OK? > > I would keep the definitions because they can at least serve as a weak > form of documentation about the hardware. For example, > C3_CRYPT_CWLO_ALG_M indicates what bits specify the algorithm, which > in turn helps one to understand the value of C3_CRYPT_CWLO_ALG_AES. Agreed. That makes sense indeed, sorry for the noise.
Re: Process-shared futexes
> Date: Sat, 2 Jun 2018 12:42:14 +0200 (CEST) > From: Mark Kettenis > > > Date: Sat, 2 Jun 2018 12:04:16 +0200 > > From: Martin Pieuchot > > > > On 01/06/18(Fri) 19:13, Mark Kettenis wrote: > > > The diff below changes our futex implementation to allow futexes that > > > are shared between processes. Such futexes are a little bit tricky > > > since there is no guarantee that a futex is mapped at the same address > > > in each process. To solve tis issue I adopted the strategy chosen by > > > FreeBSD. Shared memory objects have a uvm object associated with > > > them. So instead of using the virtual address I can use the offset > > > into that object. Together with the a pointer to the object itself > > > that should form a unique ID for the futex. > > > > Nice. > > > > > In order to establish that we're dealing with shared memory we need to > > > lookup the mapping corresponding to the userspace address of the > > > futex. That involves locking the map. If we are worried about the > > > additional overhead we could introduce shared versions of the futex > > > operations and skip the lookup for non-shared (process-private) futexes. > > > > > > These futexes could be used to implement support for the POSIX Thread > > > Process-Shared Synchronization option, i.e. the PTHREAD_PROCESS_SHARED > > > attribute for mutexes. But I need these to make libxshmfence work on > > > OpenBSD, which is in turn needed to get DRI3 support working. > > > > > > Making DRI3 support work is somewhat important. We're currently using > > > DRI2 but Linux has moved to DRI3 and some of the DRI2-specific > > > codepaths in X are starting to rot. DRI3 is also supposed to be more > > > secure than DRI2. With DRI2, applications that can guess a 32-bit > > > handle can in principle access graphiucs buffers from other > > > applications. With DRI3 graphics buffers are shared using file > > > descriptor passing which means that only processes that were passed > > > the file descriptor can access the graphics buffer. > > > > > > Another feature of DRI3 is that graphics buffers can be shared between > > > graphics devices. The idea there is that a GPU can render into a > > > buffer which is then shared with the Intel CPU graphics which can then > > > display it on the screen. But my initial implementation won't support > > > that. > > > > > > Thoughts? Especially on whether we want to distinguish between > > > process-shared and process-private futexes! > > > > I'd prefer if we could do the distinction. Would it be enough to pass > > a flag to futex_get()? > > More or less. The question is what what we should do if someone asks > for a process-shared futex in memory that isn't shared. Should we > automatically create a process-private futex? Or should this result > in an error? > > I suspect that people expect PTHREAD_PROCESS_SHARED mutexes to work > even if they're not created in shared memory. So a failure to create > a process-shared futex should probably fall through into the > process-private case. > > Turns out Linux already has a FUTEX_PRIVATE_FLAG and > FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE and FUTEX_REQUEUE_PRIVATE > operations. So I'll just stick to that API. So here is an implementation of that APU. After this gets committed we can change libc to use the _PRIVATE versions of the mutex operations. I already verified that that works. ok? Index: kern/sys_futex.c === RCS file: /cvs/src/sys/kern/sys_futex.c,v retrieving revision 1.7 diff -u -p -r1.7 sys_futex.c --- kern/sys_futex.c24 Apr 2018 17:19:35 - 1.7 +++ kern/sys_futex.c2 Jun 2018 16:36:31 - @@ -31,6 +31,8 @@ #include #endif +#include + /* * Atomicity is only needed on MULTIPROCESSOR kernels. Fall back on * copyin(9) until non-MULTIPROCESSOR architectures have a copyin32(9) @@ -46,21 +48,23 @@ struct futex { LIST_ENTRY(futex)ft_list; /* list of all futexes */ TAILQ_HEAD(, proc) ft_threads;/* sleeping queue */ - uint32_t*ft_uaddr; /* userspace address */ + struct uvm_object *ft_obj;/* UVM object */ + voff_t ft_off;/* UVM offset */ pid_tft_pid;/* process identifier */ unsigned int ft_refcnt; /* # of references */ }; /* Syscall helpers. */ -int futex_wait(uint32_t *, uint32_t, const struct timespec *); -int futex_wake(uint32_t *, uint32_t); -int futex_requeue(uint32_t *, uint32_t, uint32_t *, uint32_t); +int futex_wait(uint32_t *, uint32_t, const struct timespec *, int); +int futex_wake(uint32_t *, uint32_t, int); +int futex_requeue(uint32_t *, uint32_t, uint32_t *, uint32_t, int); /* Flags for futex_get(). */ #define FT_CREATE 0x1 /* Create a futex if it doesn't exist. */ +#define FT_PRIVATE 0x2 /*
Re: Remove BACKWARDS flag from get_shell_command in ed(1)
anyone? On 05/24/18 09:40, Martijn van Duren wrote: > Since we accept "!" as a full command to system(3), I decided to do even > more trimming than when BACKWARDS is not defined. This way we trim even > more LoC and have one less error case. > > Note that running "!!" without a prior command adds an extra empty line > if suppress diagnostics is not active, because substitution prints the > replaced line, which would be empty. But this would be identical to > first running "!" followed by a "!!" with BACKWARDS disabled. > > If people do care about this error message I suggest that we also add > another case for when the command is completely empty, because right > now this would work as well: > $ ed -p'>' >> ! > ! >> a > foo > . >> w ! > 4 > > OK? > > martijn@ > > Index: main.c > === > RCS file: /cvs/src/bin/ed/main.c,v > retrieving revision 1.62 > diff -u -p -r1.62 main.c > --- main.c24 May 2018 06:24:29 - 1.62 > +++ main.c24 May 2018 07:35:08 - > @@ -1012,20 +1012,13 @@ get_shell_command(void) > REALLOC(buf, n, i + 1, ERR); > buf[i++] = *ibufp++; > } > -#ifdef BACKWARDS > - else if (shcmd == NULL || *(shcmd + 1) == '\0') > -#else > - else if (shcmd == NULL) > -#endif > - { > - seterrmsg("no previous command"); > - return ERR; > - } else { > + if (shcmd != NULL) { > REALLOC(buf, n, i + shcmdi, ERR); > for (s = shcmd + 1; s < shcmd + shcmdi;) > buf[i++] = *s++; > - s = ibufp++; > + s = ibufp; > } > + ibufp++; > break; > case '%': > if (*old_filename == '\0') { >
ed remove BACKWARDS from GET_THIRD_ADDR
Hello tech@, The following patch removes the non-backwards case for GET_THIRD_ADDR. POSIX states nothing about making it optional, and since it is our and NetBSD's current behaviour, just leave it as is. I can see how for interactive use making the 3rd argument default to the current address could make life easier, but if people use that behaviour in scripts it makes them less non-portable, so lets just discourage it altogether. OK? martijn@ Index: main.c === RCS file: /cvs/src/bin/ed/main.c,v retrieving revision 1.62 diff -u -p -r1.62 main.c --- main.c 24 May 2018 06:24:29 - 1.62 +++ main.c 2 Jun 2018 13:50:06 - @@ -404,7 +404,6 @@ next_addr(void) } -#ifdef BACKWARDS /* GET_THIRD_ADDR: get a legal address from the command buffer */ #define GET_THIRD_ADDR(addr) \ do { \ @@ -425,26 +424,6 @@ next_addr(void) first_addr = ol1; \ second_addr = ol2; \ } while (0) - -#else /* BACKWARDS */ -/* GET_THIRD_ADDR: get a legal address from the command buffer */ -#define GET_THIRD_ADDR(addr) \ - do { \ - int ol1, ol2; \ - \ - ol1 = first_addr; \ - ol2 = second_addr; \ - if (extract_addr_range() < 0) \ - return ERR; \ - if (second_addr < 0 || addr_last < second_addr) { \ - seterrmsg("invalid address"); \ - return ERR; \ - } \ - addr = second_addr; \ - first_addr = ol1; \ - second_addr = ol2; \ - } while (0) -#endif /* GET_COMMAND_SUFFIX: verify the command suffix in the command buffer */
Locking problem with open(2)
The open(2) system call uses a problematic locking pattern that can cause problems when the process has more than one thread. The system call keeps the file descriptor table locked when calling vn_open(9). If vn_open(9) blocks, the other threads get blocked too if they try to modify the descriptor table. The issue is explained by art@ on the following page (mpi@ brought this to my attention): https://stackoverflow.com/questions/23440216/race-condition-when-using-dup2/24012015#24012015 The following patch makes open(2) use a locking pattern similar to accept(2). The descriptor table lock is released immediately after allocating a file descriptor, so other threads are not directly affected if vn_open(9) blocks. Once vn_open(9) has finished and the code is done with the vnode, the descriptor table lock is reacquired for inserting the file descriptor. The change of the locking pattern has an effect on dup2(2). If vn_open(9) has blocked and another thread tries to dup2() to the already allocated but not yet inserted file descriptor, dup2() fails with error EBUSY. accept(2) already has that behaviour. OK? Tests are welcome too. Index: lib/libc/sys/dup.2 === RCS file: src/lib/libc/sys/dup.2,v retrieving revision 1.19 diff -u -p -r1.19 dup.2 --- lib/libc/sys/dup.2 28 May 2018 08:55:11 - 1.19 +++ lib/libc/sys/dup.2 2 Jun 2018 10:51:48 - @@ -160,6 +160,8 @@ limit. .It Bq Er EBUSY A race condition with .Xr accept 2 +or +.Xr open 2 has been detected. .It Bq Er EINTR An interrupt was received. Index: sys/kern/vfs_syscalls.c === RCS file: src/sys/kern/vfs_syscalls.c,v retrieving revision 1.284 diff -u -p -r1.284 vfs_syscalls.c --- sys/kern/vfs_syscalls.c 2 Jun 2018 10:27:43 - 1.284 +++ sys/kern/vfs_syscalls.c 2 Jun 2018 10:51:48 - @@ -916,6 +916,8 @@ doopenat(struct proc *p, int fd, const c fdplock(fdp); if ((error = falloc(p, &fp, &indx)) != 0) goto out; + fdpunlock(fdp); + flags = FFLAGS(oflags); if (flags & FREAD) ni_pledge |= PLEDGE_RPATH; @@ -935,6 +937,7 @@ doopenat(struct proc *p, int fd, const c flags &= ~O_TRUNC; /* Must do truncate ourselves */ } if ((error = vn_open(&nd, flags, cmode)) != 0) { + fdplock(fdp); if (error == ENODEV && p->p_dupfd >= 0 && /* XXX from fdopen */ (error = @@ -969,6 +972,7 @@ doopenat(struct proc *p, int fd, const c VOP_UNLOCK(vp); error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type); if (error) { + fdplock(fdp); /* closef will vn_close the file for us. */ fdremove(fdp, indx); closef(fp, p); @@ -991,6 +995,7 @@ doopenat(struct proc *p, int fd, const c } if (error) { VOP_UNLOCK(vp); + fdplock(fdp); /* closef will close the file for us. */ fdremove(fdp, indx); closef(fp, p); @@ -999,6 +1004,7 @@ doopenat(struct proc *p, int fd, const c } VOP_UNLOCK(vp); *retval = indx; + fdplock(fdp); fdinsert(fdp, indx, cloexec, fp); FRELE(fp, p); out:
armv7 lld fix
Diff below works around a crash provoked by the /DISCARD/ : { *(.ARM.exidx) } fragment in the kernel linker script. It seems this issue is already fixed upstream in a different way. But backporting that fix isn't trivial. ok? Index: gnu/llvm/tools/lld/ELF/SyntheticSections.cpp === RCS file: /cvs/src/gnu/llvm/tools/lld/ELF/SyntheticSections.cpp,v retrieving revision 1.7 diff -u -p -r1.7 SyntheticSections.cpp --- gnu/llvm/tools/lld/ELF/SyntheticSections.cpp6 Apr 2018 14:38:28 - 1.7 +++ gnu/llvm/tools/lld/ELF/SyntheticSections.cpp2 Jun 2018 12:16:06 - @@ -2571,6 +2571,9 @@ void ARMExidxSentinelSection::writeTo(ui // The sentinel has to be removed if there are no other .ARM.exidx entries. bool ARMExidxSentinelSection::empty() const { OutputSection *OS = getParent(); + if (!OS) +return false; + for (auto *B : OS->SectionCommands) if (auto *ISD = dyn_cast(B)) for (auto *S : ISD->Sections)
Re: Remove unused C3 values (VIA)
> Date: Sat, 2 Jun 2018 11:30:15 + > From: Visa Hankala > > On Sat, Jun 02, 2018 at 01:00:05PM +0200, Frederic Cambus wrote: > > Hi tech@, > > > > Here is a diff to remove unused C3 values. > > > > Comments? OK? > > I would keep the definitions because they can at least serve as a weak > form of documentation about the hardware. For example, > C3_CRYPT_CWLO_ALG_M indicates what bits specify the algorithm, which > in turn helps one to understand the value of C3_CRYPT_CWLO_ALG_AES. +1
Re: Remove unused C3 values (VIA)
On Sat, Jun 02, 2018 at 01:00:05PM +0200, Frederic Cambus wrote: > Hi tech@, > > Here is a diff to remove unused C3 values. > > Comments? OK? I would keep the definitions because they can at least serve as a weak form of documentation about the hardware. For example, C3_CRYPT_CWLO_ALG_M indicates what bits specify the algorithm, which in turn helps one to understand the value of C3_CRYPT_CWLO_ALG_AES. > Index: sys/arch/amd64/include/specialreg.h > === > RCS file: /cvs/src/sys/arch/amd64/include/specialreg.h,v > retrieving revision 1.72 > diff -u -p -r1.72 specialreg.h > --- sys/arch/amd64/include/specialreg.h 23 May 2018 05:37:01 - > 1.72 > +++ sys/arch/amd64/include/specialreg.h 2 Jun 2018 09:14:32 - > @@ -873,14 +873,9 @@ > #define C3_CPUID_DO_PMM 0x002000 > > /* VIA C3 xcrypt-* instruction context control options */ > -#define C3_CRYPT_CWLO_ROUND_M 0x000f > -#define C3_CRYPT_CWLO_ALG_M 0x0070 > #define C3_CRYPT_CWLO_ALG_AES 0x > -#define C3_CRYPT_CWLO_KEYGEN_M 0x0080 > -#define C3_CRYPT_CWLO_KEYGEN_HW 0x > #define C3_CRYPT_CWLO_KEYGEN_SW 0x0080 > #define C3_CRYPT_CWLO_NORMAL0x > -#define C3_CRYPT_CWLO_INTERMEDIATE 0x0100 > #define C3_CRYPT_CWLO_ENCRYPT 0x > #define C3_CRYPT_CWLO_DECRYPT 0x0200 > #define C3_CRYPT_CWLO_KEY1280x000a /* 128bit, 10 > rds */ > Index: sys/arch/i386/include/specialreg.h > === > RCS file: /cvs/src/sys/arch/i386/include/specialreg.h,v > retrieving revision 1.66 > diff -u -p -r1.66 specialreg.h > --- sys/arch/i386/include/specialreg.h28 May 2018 20:52:44 - > 1.66 > +++ sys/arch/i386/include/specialreg.h2 Jun 2018 09:14:32 - > @@ -724,14 +724,9 @@ > #define C3_CPUID_DO_PMM 0x002000 > > /* VIA C3 xcrypt-* instruction context control options */ > -#define C3_CRYPT_CWLO_ROUND_M 0x000f > -#define C3_CRYPT_CWLO_ALG_M 0x0070 > #define C3_CRYPT_CWLO_ALG_AES 0x > -#define C3_CRYPT_CWLO_KEYGEN_M 0x0080 > -#define C3_CRYPT_CWLO_KEYGEN_HW 0x > #define C3_CRYPT_CWLO_KEYGEN_SW 0x0080 > #define C3_CRYPT_CWLO_NORMAL0x > -#define C3_CRYPT_CWLO_INTERMEDIATE 0x0100 > #define C3_CRYPT_CWLO_ENCRYPT 0x > #define C3_CRYPT_CWLO_DECRYPT 0x0200 > #define C3_CRYPT_CWLO_KEY1280x000a /* 128bit, 10 > rds */ >
Remove unused C3 values (VIA)
Hi tech@, Here is a diff to remove unused C3 values. Comments? OK? Index: sys/arch/amd64/include/specialreg.h === RCS file: /cvs/src/sys/arch/amd64/include/specialreg.h,v retrieving revision 1.72 diff -u -p -r1.72 specialreg.h --- sys/arch/amd64/include/specialreg.h 23 May 2018 05:37:01 - 1.72 +++ sys/arch/amd64/include/specialreg.h 2 Jun 2018 09:14:32 - @@ -873,14 +873,9 @@ #define C3_CPUID_DO_PMM0x002000 /* VIA C3 xcrypt-* instruction context control options */ -#defineC3_CRYPT_CWLO_ROUND_M 0x000f -#defineC3_CRYPT_CWLO_ALG_M 0x0070 #defineC3_CRYPT_CWLO_ALG_AES 0x -#defineC3_CRYPT_CWLO_KEYGEN_M 0x0080 -#defineC3_CRYPT_CWLO_KEYGEN_HW 0x #defineC3_CRYPT_CWLO_KEYGEN_SW 0x0080 #defineC3_CRYPT_CWLO_NORMAL0x -#defineC3_CRYPT_CWLO_INTERMEDIATE 0x0100 #defineC3_CRYPT_CWLO_ENCRYPT 0x #defineC3_CRYPT_CWLO_DECRYPT 0x0200 #defineC3_CRYPT_CWLO_KEY1280x000a /* 128bit, 10 rds */ Index: sys/arch/i386/include/specialreg.h === RCS file: /cvs/src/sys/arch/i386/include/specialreg.h,v retrieving revision 1.66 diff -u -p -r1.66 specialreg.h --- sys/arch/i386/include/specialreg.h 28 May 2018 20:52:44 - 1.66 +++ sys/arch/i386/include/specialreg.h 2 Jun 2018 09:14:32 - @@ -724,14 +724,9 @@ #define C3_CPUID_DO_PMM0x002000 /* VIA C3 xcrypt-* instruction context control options */ -#defineC3_CRYPT_CWLO_ROUND_M 0x000f -#defineC3_CRYPT_CWLO_ALG_M 0x0070 #defineC3_CRYPT_CWLO_ALG_AES 0x -#defineC3_CRYPT_CWLO_KEYGEN_M 0x0080 -#defineC3_CRYPT_CWLO_KEYGEN_HW 0x #defineC3_CRYPT_CWLO_KEYGEN_SW 0x0080 #defineC3_CRYPT_CWLO_NORMAL0x -#defineC3_CRYPT_CWLO_INTERMEDIATE 0x0100 #defineC3_CRYPT_CWLO_ENCRYPT 0x #defineC3_CRYPT_CWLO_DECRYPT 0x0200 #defineC3_CRYPT_CWLO_KEY1280x000a /* 128bit, 10 rds */
Re: Process-shared futexes
> Date: Sat, 2 Jun 2018 12:04:16 +0200 > From: Martin Pieuchot > > On 01/06/18(Fri) 19:13, Mark Kettenis wrote: > > The diff below changes our futex implementation to allow futexes that > > are shared between processes. Such futexes are a little bit tricky > > since there is no guarantee that a futex is mapped at the same address > > in each process. To solve tis issue I adopted the strategy chosen by > > FreeBSD. Shared memory objects have a uvm object associated with > > them. So instead of using the virtual address I can use the offset > > into that object. Together with the a pointer to the object itself > > that should form a unique ID for the futex. > > Nice. > > > In order to establish that we're dealing with shared memory we need to > > lookup the mapping corresponding to the userspace address of the > > futex. That involves locking the map. If we are worried about the > > additional overhead we could introduce shared versions of the futex > > operations and skip the lookup for non-shared (process-private) futexes. > > > > These futexes could be used to implement support for the POSIX Thread > > Process-Shared Synchronization option, i.e. the PTHREAD_PROCESS_SHARED > > attribute for mutexes. But I need these to make libxshmfence work on > > OpenBSD, which is in turn needed to get DRI3 support working. > > > > Making DRI3 support work is somewhat important. We're currently using > > DRI2 but Linux has moved to DRI3 and some of the DRI2-specific > > codepaths in X are starting to rot. DRI3 is also supposed to be more > > secure than DRI2. With DRI2, applications that can guess a 32-bit > > handle can in principle access graphiucs buffers from other > > applications. With DRI3 graphics buffers are shared using file > > descriptor passing which means that only processes that were passed > > the file descriptor can access the graphics buffer. > > > > Another feature of DRI3 is that graphics buffers can be shared between > > graphics devices. The idea there is that a GPU can render into a > > buffer which is then shared with the Intel CPU graphics which can then > > display it on the screen. But my initial implementation won't support > > that. > > > > Thoughts? Especially on whether we want to distinguish between > > process-shared and process-private futexes! > > I'd prefer if we could do the distinction. Would it be enough to pass > a flag to futex_get()? More or less. The question is what what we should do if someone asks for a process-shared futex in memory that isn't shared. Should we automatically create a process-private futex? Or should this result in an error? I suspect that people expect PTHREAD_PROCESS_SHARED mutexes to work even if they're not created in shared memory. So a failure to create a process-shared futex should probably fall through into the process-private case. Turns out Linux already has a FUTEX_PRIVATE_FLAG and FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE and FUTEX_REQUEUE_PRIVATE operations. So I'll just stick to that API. > > Index: kern/sys_futex.c > > === > > RCS file: /cvs/src/sys/kern/sys_futex.c,v > > retrieving revision 1.7 > > diff -u -p -r1.7 sys_futex.c > > --- kern/sys_futex.c24 Apr 2018 17:19:35 - 1.7 > > +++ kern/sys_futex.c1 Jun 2018 15:50:17 - > > @@ -31,6 +31,8 @@ > > #include > > #endif > > > > +#include > > + > > /* > > * Atomicity is only needed on MULTIPROCESSOR kernels. Fall back on > > * copyin(9) until non-MULTIPROCESSOR architectures have a copyin32(9) > > @@ -46,6 +48,8 @@ > > struct futex { > > LIST_ENTRY(futex)ft_list; /* list of all futexes */ > > TAILQ_HEAD(, proc) ft_threads;/* sleeping queue */ > > + struct uvm_object *ft_obj; > > + voff_t ft_offset; > > uint32_t*ft_uaddr; /* userspace address */ > > pid_tft_pid;/* process identifier */ > > unsigned int ft_refcnt; /* # of references */ > > @@ -130,8 +134,22 @@ struct futex * > > futex_get(uint32_t *uaddr, int flag) > > { > > struct proc *p = curproc; > > + vm_map_t map = &p->p_vmspace->vm_map; > > + vm_map_entry_t entry; > > + struct uvm_object *obj = NULL; > > + voff_t offset = 0; > > struct futex *f; > > > > + vm_map_lock_read(map); > > + if (uvm_map_lookup_entry(map, (vaddr_t)uaddr, &entry)) { > > + if (entry->object.uvm_obj && > > + entry->inheritance == MAP_INHERIT_SHARE) { > > + obj = entry->object.uvm_obj; > > + offset = entry->offset + ((vaddr_t)uaddr - > > entry->start); > > + } > > + } > > + vm_map_unlock_read(map); > > + > > rw_assert_wrlock(&ftlock); > > > > LIST_FOREACH(f, &ftlist, ft_list) { > > @@ -139,6 +157,10 @@ futex_get(uint32_t *uaddr, int flag) > > f->ft_refcnt++; > >
Re: Process-shared futexes
On 01/06/18(Fri) 19:13, Mark Kettenis wrote: > The diff below changes our futex implementation to allow futexes that > are shared between processes. Such futexes are a little bit tricky > since there is no guarantee that a futex is mapped at the same address > in each process. To solve tis issue I adopted the strategy chosen by > FreeBSD. Shared memory objects have a uvm object associated with > them. So instead of using the virtual address I can use the offset > into that object. Together with the a pointer to the object itself > that should form a unique ID for the futex. Nice. > In order to establish that we're dealing with shared memory we need to > lookup the mapping corresponding to the userspace address of the > futex. That involves locking the map. If we are worried about the > additional overhead we could introduce shared versions of the futex > operations and skip the lookup for non-shared (process-private) futexes. > > These futexes could be used to implement support for the POSIX Thread > Process-Shared Synchronization option, i.e. the PTHREAD_PROCESS_SHARED > attribute for mutexes. But I need these to make libxshmfence work on > OpenBSD, which is in turn needed to get DRI3 support working. > > Making DRI3 support work is somewhat important. We're currently using > DRI2 but Linux has moved to DRI3 and some of the DRI2-specific > codepaths in X are starting to rot. DRI3 is also supposed to be more > secure than DRI2. With DRI2, applications that can guess a 32-bit > handle can in principle access graphiucs buffers from other > applications. With DRI3 graphics buffers are shared using file > descriptor passing which means that only processes that were passed > the file descriptor can access the graphics buffer. > > Another feature of DRI3 is that graphics buffers can be shared between > graphics devices. The idea there is that a GPU can render into a > buffer which is then shared with the Intel CPU graphics which can then > display it on the screen. But my initial implementation won't support > that. > > Thoughts? Especially on whether we want to distinguish between > process-shared and process-private futexes! I'd prefer if we could do the distinction. Would it be enough to pass a flag to futex_get()? > Index: kern/sys_futex.c > === > RCS file: /cvs/src/sys/kern/sys_futex.c,v > retrieving revision 1.7 > diff -u -p -r1.7 sys_futex.c > --- kern/sys_futex.c 24 Apr 2018 17:19:35 - 1.7 > +++ kern/sys_futex.c 1 Jun 2018 15:50:17 - > @@ -31,6 +31,8 @@ > #include > #endif > > +#include > + > /* > * Atomicity is only needed on MULTIPROCESSOR kernels. Fall back on > * copyin(9) until non-MULTIPROCESSOR architectures have a copyin32(9) > @@ -46,6 +48,8 @@ > struct futex { > LIST_ENTRY(futex)ft_list; /* list of all futexes */ > TAILQ_HEAD(, proc) ft_threads;/* sleeping queue */ > + struct uvm_object *ft_obj; > + voff_t ft_offset; > uint32_t*ft_uaddr; /* userspace address */ > pid_tft_pid;/* process identifier */ > unsigned int ft_refcnt; /* # of references */ > @@ -130,8 +134,22 @@ struct futex * > futex_get(uint32_t *uaddr, int flag) > { > struct proc *p = curproc; > + vm_map_t map = &p->p_vmspace->vm_map; > + vm_map_entry_t entry; > + struct uvm_object *obj = NULL; > + voff_t offset = 0; > struct futex *f; > > + vm_map_lock_read(map); > + if (uvm_map_lookup_entry(map, (vaddr_t)uaddr, &entry)) { > + if (entry->object.uvm_obj && > + entry->inheritance == MAP_INHERIT_SHARE) { > + obj = entry->object.uvm_obj; > + offset = entry->offset + ((vaddr_t)uaddr - > entry->start); > + } > + } > + vm_map_unlock_read(map); > + > rw_assert_wrlock(&ftlock); > > LIST_FOREACH(f, &ftlist, ft_list) { > @@ -139,6 +157,10 @@ futex_get(uint32_t *uaddr, int flag) > f->ft_refcnt++; > break; > } > + if (f->ft_obj == obj && f->ft_offset == offset) { > + f->ft_refcnt++; > + break; > + } > } > > if ((f == NULL) && (flag & FT_CREATE)) { > @@ -146,10 +168,15 @@ futex_get(uint32_t *uaddr, int flag) >* We rely on the rwlock to ensure that no other thread >* create the same futex. >*/ > - f = pool_get(&ftpool, PR_WAITOK); > + f = pool_get(&ftpool, PR_WAITOK | PR_ZERO); > TAILQ_INIT(&f->ft_threads); > - f->ft_uaddr = uaddr; > - f->ft_pid = p->p_p->ps_pid; > + if (obj) { > + f->ft_obj = obj; > + f->ft_offset = offset; > + } else { > +