rakitzis / rc

rc shell -- independent re-implementation for Unix of the Plan 9 shell (from circa 1992)
Other
250 stars 23 forks source link

history mechanism skipping lines in $history when searching; #104

Closed gitboy closed 2 weeks ago

gitboy commented 3 weeks ago

I occasionally come across the following oddness using the history mechanism in rc, where we link ./-, ./--, ./-p, ./--p to the history binary. I have found on occasion that despite matching lines in my $history existing the program refuses to find them when I search.

I've contrived an example to demonstrate;

; cat history.test
A
sh -c 'aws s3 ls s3://flatfiles/ --endpoint-url https://files.polygon.io/'
Z
; echo $history
history.test
; gcc history.c
; ls -ld ./--
lrwxrwxrwx 1 russ russ 5 Aug 19 20:24 ./-- -> a.out*
; ./-- endpoint
command not matched

It seems related to the the getcommand() function; when I comment the following

    /*
     * if the command contains the "me" character at the start of the line
     * or after any of [`{|()@/] then try again
     */

    // for (t = s; *t != '\0'; ++t)
    //      if (*t == me) {
    //              char *u = t - 1;
    //              while (u >= s && (*u == ' ' || *u == '\t'))
    //                      --u;
    //              if (u < s)
    //                      goto again;
    //              switch (*u) {
    //              case '`': case '@':
    //              case '(': case ')':
    //              case '{': case '|':
    //              case '/':
    //                      goto again;
    //              default:
    //                      break;
    //              }
    //      }

I obtain the expected behaviour;

gcc history.c
; ./-- endpoint
./-- endpoint
-
./-- endpoint
-
sh -c 'aws s3 ls s3://flatfiles/ --endpoint-url https://files.polygon.io/'
^echo
echo sh -c 'aws s3 ls s3://flatfiles/ --endpoint-url https://files.polygon.io/'

sh -c aws s3 ls s3://flatfiles/ --endpoint-url https://files.polygon.io/

It seems this is due to the history program trying to avoid including its own invocations when searching back through the shell $history. Can anyone improve this so that we can search shell history with confidence? (please don't suggest readline)

rakitzis commented 3 weeks ago

Discussed offline. The getcommand function uses that switch statement to mitigate infinite recursion caused by inadvertently executing the history program as a result of matching a command. The / is meant to protect full- and relative-pathname expressions of the history command (e.g., ./--) but it goes overboard by applying the rule after whitespace is trimmed. I think there is some room for improvement here, and I'll likely make a fix.

This code shows its age, esp. wrt the lack of unit testing.