Lift the current argument limit (see BUGS section) and simplify the
parsing logic by turning `xidle -program "/bin/prog args"' into
`xidle prog args' where normal argv is used instead of an strsep(3)
routine.

Search PATH with execvp(3), drop unused status parameter from wait(2)
while here.

Merge `fopts' and `opts' since there is no need to split `-display'
parsing from the rest, so XrmParseCommand(3) is called once still
handling display setup first.


Users would have to adjust their xidle invocations but the change is
trivial and introduces nice improvements, so that's reasonble; I'd put
a note into current.html.

Feedback? Objections? OK?

PS: This diff applies cleanly against -CURRENT and is independent from
my earlier ones and but will conflict diff-wise.

Index: xidle.1
===================================================================
RCS file: /cvs/xenocara/app/xidle/xidle.1,v
retrieving revision 1.5
diff -u -p -r1.5 xidle.1
--- xidle.1     6 Sep 2018 07:21:34 -0000       1.5
+++ xidle.1     4 Nov 2018 01:43:21 -0000
@@ -23,7 +23,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 20, 2005
+.Dd $Mdocdate: November 4 2018 $
 .Dt XIDLE 1
 .Os
 .Sh NAME
@@ -36,8 +36,8 @@
 .Op Fl delay Ar secs
 .Op Fl display Ar display
 .Op Fl no | nw | ne | sw | se
-.Op Fl program Ar path
 .Op Fl timeout Ar secs
+.Op Ar program Op Ar args
 .Ek
 .Sh DESCRIPTION
 .Nm
@@ -45,6 +45,8 @@ uses the
 .Xr XScreenSaver 3
 extension to receive inactivity events when a timeout is specified, running
 a specific program after the elapsed time.
+The default is
+.Xr xlock 1 .
 .Nm
 will also run the program if it is sent a
 .Dv SIGUSR1
@@ -71,14 +73,6 @@ Set the position to one of none, northwe
 respectively.
 If no position is specified,
 the default is northwest.
-.It Fl program Ar path
-Specify the full pathname of the program to run on any of the
-aforementioned events.
-Arguments to the program may also be specified, separated by whitespace.
-If
-.Fl program
-is not specified, the default is
-.Xr xlock 1 .
 .It Fl timeout Ar secs
 Set the timeout to the specified number of seconds.
 If
@@ -129,8 +123,7 @@ Run
 using the flying bats mode if no activity is detected in 300 seconds or the
 pointer sits in the southwest corner for more than 5 seconds:
 .Bd -literal -offset indent
-$ xidle -delay 5 -sw -program "/usr/X11R6/bin/xlock -mode bat" \e
-       -timeout 300
+$ xidle -delay 5 -sw xlock -mode bat -timeout 300
 .Ed
 .Sh SEE ALSO
 .Xr xlock 1 ,
@@ -142,7 +135,3 @@ The
 program was written by
 .An Federico Schwindt Aq Mt fg...@openbsd.org
 as an xautolock replacement.
-.Sh BUGS
-The maximum number of arguments for
-.Fl program ,
-including the executable file, is currently set to 9.
Index: xidle.c
===================================================================
RCS file: /cvs/xenocara/app/xidle/xidle.c,v
retrieving revision 1.6
diff -u -p -r1.6 xidle.c
--- xidle.c     6 Sep 2018 07:21:34 -0000       1.6
+++ xidle.c     4 Nov 2018 02:46:19 -0000
@@ -75,14 +75,10 @@ struct xinfo {
 
 struct xinfo x;
 
-static XrmOptionDescRec fopts[] = {
-       { "-display",   ".display",     XrmoptionSepArg,        (caddr_t)NULL },
-};
-
 static XrmOptionDescRec opts[] = {
        { "-area",      ".area",        XrmoptionSepArg,        (caddr_t)NULL },
        { "-delay",     ".delay",       XrmoptionSepArg,        (caddr_t)NULL },
-       { "-program",   ".program",     XrmoptionSepArg,        (caddr_t)NULL },
+       { "-display",   ".display",     XrmoptionSepArg,        (caddr_t)NULL },
        { "-timeout",   ".timeout",     XrmoptionSepArg,        (caddr_t)NULL },
 
        { "-no",        ".position",    XrmoptionNoArg,         (caddr_t)"no" },
@@ -94,13 +90,12 @@ static XrmOptionDescRec opts[] = {
 
 extern char *__progname;
 
-void   action(struct xinfo *, char **);
+void   action(struct xinfo *, char *const []);
 void   close_x(struct xinfo *);
 Bool   getres(XrmValue *, const XrmDatabase, const char *, const char *);
 void    init_x(struct xinfo *, int, int, int);
 void   handler(int);
-void   parse_opts(int, char **, Display **, int *, int *, int *, int *,
-           char **);
+void   parse_opts(int, char **[], Display **, int *, int *, int *, int *);
 int    str2pos(const char *);
 __dead void    usage(void);
 
@@ -108,9 +103,10 @@ __dead void        usage(void);
 __dead void
 usage()
 {
-       fprintf(stderr, "Usage:\n%s %s\n", __progname,
-           "[-area pixels] [-delay secs] [-display host:dpy] "
-           "[-no | -ne | -nw | -se | -sw]\n      [-program path] [-timeout 
secs]");
+       fprintf(stderr,
+           "usage:\t%s [-area pixels] [-delay secs] [-display host:dpy]\n"
+           "\t      [-no | -ne | -nw | -se | -sw] [-timeout secs] "
+           "[program [args]]\n", __progname);
        exit(1);
 }
 
@@ -180,10 +176,8 @@ close_x(struct xinfo *xi)
 
 
 void
-action(struct xinfo *xi, char **args)
+action(struct xinfo *xi, char *const args[])
 {
-       int dumb;
-
        switch (fork()) {
        case -1:
                err(1, "fork");
@@ -191,12 +185,12 @@ action(struct xinfo *xi, char **args)
 
        case 0:
                setsid();
-               execv(*args, args);
+               execvp(*args, args);
                exit(1);
                /* NOTREACHED */
 
        default:
-               wait(&dumb);
+               wait(NULL);
                XSync(xi->dpy, True);
                break;
        }
@@ -256,19 +250,24 @@ getres(XrmValue *value, const XrmDatabas
 
 
 void
-parse_opts(int argc, char **argv, Display **dpy, int *area, int *delay,
-    int *timeout, int *position, char **args)
+parse_opts(int argc, char **argvp[], Display **dpy, int *area, int *delay,
+    int *timeout, int *position)
 {
-       char **ap, *program = PATH_PROG;
        char *display, *p;
        XrmDatabase tdb, rdb = NULL;
        XrmValue value;
 
        XrmInitialize();
 
-       /* Get display to open. */
-       XrmParseCommand(&rdb, fopts, sizeof(fopts) / sizeof(fopts[0]),
-           __progname, &argc, argv);
+       /* Get command line values. */
+       XrmParseCommand(&rdb, opts, sizeof(opts) / sizeof(opts[0]),
+           __progname, &argc, *argvp);
+       if (argc > 1) {
+               (*argvp)++;
+               if ((*argvp)[0][0] == '-')
+                       usage();
+       } else
+               (*argvp)[0] = PATH_PROG;
 
        display = (getres(&value, rdb, "display", "Display") == True) ?
            (char *)value.addr : NULL;
@@ -292,15 +291,8 @@ parse_opts(int argc, char **argv, Displa
                XrmMergeDatabases(tdb, &rdb);
        }
 
-       /* Get remaining command line values. */
-       XrmParseCommand(&rdb, opts, sizeof(opts) / sizeof(opts[0]),
-           __progname, &argc, argv);
-       if (argc > 1) {
-               usage();
-               /* NOTREACHED */
-       }
        if (getres(&value, rdb, "area", "Area")) {
-               *area = strtol((char *)value.addr, &p, 10);
+               *area = strtol((char *)value.addr, &p, 9);
                if (*p || *area < 1) {
 fail:                  errx(1, "illegal value -- %s", (char *)value.addr);
                        /* NOTREACHED */
@@ -321,24 +313,12 @@ fail:                     errx(1, "illegal value -- %s", (
                if (*p || *timeout < 0)
                        goto fail;
        }
-       if (getres(&value, rdb, "program", "Program")) {
-               /* Should be the last :) */
-               program = (char *)value.addr;
-       }
-
-       for (ap = args; ap < &args[9] &&
-           (*ap = strsep(&program, " ")) != NULL;) {
-               if (**ap != '\0')
-                       ap++;
-       }
-       *ap = NULL;
 }
 
 
 int
 main(int argc, char **argv)
 {
-       char *args[10];
        int area = 2, delay = 2, timeout = 0;
        int position = north|west;
        int fd;
@@ -346,14 +326,12 @@ main(int argc, char **argv)
 
        bzero(&x, sizeof(struct xinfo));
 
-       
-       parse_opts(argc, argv, &x.dpy, &area, &delay, &timeout,
-           &position, args);
+       parse_opts(argc, &argv, &x.dpy, &area, &delay, &timeout, &position);
 
 #ifdef DEBUG
        printf("Area: %d\nDelay: %d\nPosition: %d\nTimeout: %d\n"
            "Program: \"%s\"\n",
-           area, delay, position, timeout, args[0]);
+           area, delay, position, timeout, argv[0]);
 #endif
 
        init_x(&x, position, area, timeout);
@@ -415,7 +393,7 @@ main(int argc, char **argv)
                                close_x(&x);
                                exit(0);
                        } else if (ev.xclient.message_type == XIDLE_LOCK)
-                               action(&x, args);
+                               action(&x, argv);
                        break;
 
                case EnterNotify:
@@ -433,7 +411,7 @@ main(int argc, char **argv)
                            ev.xcrossing.x_root > x.coord_x + area ||
                            ev.xcrossing.y_root > x.coord_y + area)
                                break;
-                       action(&x, args);
+                       action(&x, argv);
                        break;
 
                default:
@@ -449,7 +427,7 @@ main(int argc, char **argv)
                                 * switching or a locking program?
                                 */
                                if (timeout > 0 && se->forced == False)
-                                       action(&x, args);
+                                       action(&x, argv);
                        }
                        break;
                }
===================================================================
Stats: --- 65 lines 1991 chars
Stats: +++ 32 lines 1156 chars
Stats: -33 lines
Stats: -835 chars

Reply via email to