X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=miniexpect.pod;h=74538599342012b577d6370bfbb165d4566e9482;hb=45a7c4d5ed0afd47e0df2f444d33683e17ae53b9;hp=827a26829cee6a10d4b8fb4d937f120e3a34f51d;hpb=e475bd56d61fed83f59d6299525ddb69c50b6ab4;p=miniexpect.git diff --git a/miniexpect.pod b/miniexpect.pod index 827a268..7453859 100644 --- a/miniexpect.pod +++ b/miniexpect.pod @@ -2,23 +2,24 @@ =head1 NAME -miniexpect - A very simple expect library for C. +miniexpect - A very simple expect library =head1 SYNOPSIS #include #include - #include + #define PCRE2_CODE_UNIT_WIDTH 8 + #include #include mexp_h *h; - h = mexp_spawnl ("ssh", "ssh", "host"); - switch (mexp_expect (h, regexps, ovector, ovecsize)) { + h = mexp_spawnl ("ssh", "ssh", "host", NULL); + switch (mexp_expect (h, regexps, match_data)) { ... } mexp_close (h); - cc prog.c -o prog -lminiexpect -lpcre + cc prog.c -o prog -lminiexpect -lpcre2-8 =head1 DESCRIPTION @@ -30,10 +31,10 @@ Tcl. It is also thread safe, const-correct and uses modern C standards. Miniexpect is a standalone library, except for a single dependency: it -requires the PCRE (Perl Compatible Regular Expressions) library from -L. The PCRE dependency is fundamental because +requires the PCRE2 (Perl Compatible Regular Expressions) library from +L. The PCRE2 dependency is fundamental because we want to offer the most powerful regular expression syntax to match -on, but more importantly because PCRE has a convenient way to detect +on, but more importantly because PCRE2 has a convenient way to detect partial matches which made this library very simple to implement. This manual page documents the API. Examples of how to use the API @@ -54,14 +55,15 @@ You can control multiple programs at the same time. =head1 SPAWNING THE SUBPROCESS -There are two calls for creating a subprocess: +There are four calls for creating a subprocess: B This creates a subprocess running the external program C (the current C<$PATH> is searched unless you give an absolute path). -C are the arguments to the program. Usually the first -argument should be the name of the program. +C are the arguments to the program. You should terminate +the list of arguments with C. Usually the first argument should +be the name of the program. The return value is a handle (see next section). @@ -70,11 +72,11 @@ the error is available in C. For example, to run an ssh subprocess you could do: - h = mexp_spawnl ("ssh", "ssh", "-l", "root", "host"); + h = mexp_spawnl ("ssh", "ssh", "-l", "root", "host", NULL); or to run a particular ssh binary: - h = mexp_spawnl ("/usr/local/bin/ssh", "ssh", "-l", "root", "host"); + h = mexp_spawnl ("/usr/local/bin/ssh", "ssh", "-l", "root", "host", NULL); An alternative to C is: @@ -83,30 +85,99 @@ B This is the same as C except that you pass the arguments in a NULL-terminated array. +There are also two versions of the above calls which take flags: + +B + +B + +The flags may contain the following values, logically ORed together: + +=over 4 + +=item B + +Do not reset signal handlers to C in the subprocess. + +=item B + +Do not close file descriptors E 3 in the subprocess. + +=item B or B + +Configure the pty in cooked mode or raw mode. Raw mode is the +default. + +=back + =head1 HANDLES -After spawning a subprocess, you get back a handle. There are various -fields in this handle which you can read or write: +After spawning a subprocess, you get back a handle which is a pointer +to a struct: + + struct mexp_h; + typedef struct mexp_h mexp_h; + +Various methods can be used on the handle: + +B + +Return the file descriptor of the pty of the subprocess. You can read +and write to this if you want, although convenience functions are also +provided (see below). + +B + +Return the process ID of the subprocess. You can send it signals if +you want. + +B + +B + +B + +Get or set the timeout used by C [see below]. The +resolution is milliseconds (1/1000th of a second). Set this before +calling C. Passing -1 to either of the C methods +means no timeout. The default setting is 60000 milliseconds (60 +seconds). - struct mexp_h { - int fd; - pid_t pid; +B -C is the pty of the subprocess. You can read and write to this if -you want, although convenience functions are also provided (see -below). C is the process ID of the subprocess. You can send it -signals if you want. +B - int timeout; +Get or set the natural size (in bytes) for reads from the subprocess. +The default is 1024. Most callers will not need to change this. -C is the timeout in milliseconds (1/1000th of a second) used -by C (see below). You can set this before calling -C if you want. Setting it to -1 means no timeout. The -default setting is 60000 (60 seconds). +B - char *buffer; - size_t len; - size_t alloc; +When C [see below] calls the PCRE function +L, it stashes the return value in the C +field in the handle, and that field is returned by this method. + +If C returns C, then the actual PCRE +error code returned by L is available by calling this +method. For a list of PCRE error codes, see L. + +B + +B + +Set or get the debug file of the handle. To enable debugging, pass a +non-C file handle, eg. C. To disable debugging, pass +C. Debugging messages are printed on the file handle. + +Note that all output and input gets printed, including passwords. To +prevent passwords from being printed, modify your code to call +C instead of C. + +The following fields in the handle do not have methods, but can be +accessed directly instead: + + char *buffer; + size_t len; + size_t alloc; If C returns a match then these variables contain the read buffer. Note this buffer does not contain the full input from @@ -114,7 +185,7 @@ the process, but it will contain at least the part matched by the regular expression (and maybe some more). C is the read buffer and C is the number of bytes of data in the buffer. - ssize_t next_match; + ssize_t next_match; If C returns a match, then C points to the first byte in the buffer I the fully matched expression. (It @@ -127,29 +198,13 @@ C<-1> in order to ignore the remainder of the buffer. In most cases callers can ignore this field, and C will just do the right thing when called repeatedly. - size_t read_size; - -Callers may set this to the natural size (in bytes) for reads from the -subprocess. The default is 1024. Most callers will not need to -change this. - - int pcre_error; - -If C returns C, then the actual PCRE -error code returned by L is available here. For a list -of PCRE error codes, see L. - - void *user1; - void *user2; - void *user3; + void *user1; + void *user2; + void *user3; Opaque pointers for use by the caller. The library will not touch these. - }; - - typedef struct mexp_h mexp_h; - =head1 CLOSING THE HANDLE To close the handle and clean up the subprocess, call: @@ -206,10 +261,10 @@ This is how code should check for and print errors from C: =head1 EXPECT FUNCTION Miniexpect contains a powerful regular expression matching function -based on L: +based on L: B +pcre2_match_data *match_data);> The output of the subprocess is matched against the list of PCRE regular expressions in C. C is a list of regular @@ -217,8 +272,7 @@ expression structures: struct mexp_regexp { int r; - const pcre *re; - const pcre_extra *extra; + const pcre2_code *re; int options; }; typedef struct mexp_regexp mexp_regexp; @@ -248,7 +302,7 @@ returned in C. =item C -There was a C error. Cpcre_error> is set to the +There was a C error. Cpcre_error> is set to the error code. See L for a list of the C error codes and what they mean. @@ -271,8 +325,8 @@ for EOF or timeout. =item * -C, C, C, C -and C are passed through to the L function. +C, C and C are passed +through to the L function. =item * @@ -313,26 +367,29 @@ literal" and is available in C99. If you need to use an older compiler, you can just use a local variable instead. mexp_h *h; - char *errptr; + int errcode; int offset; - pcre *password_re, *prompt_re; - const int ovecsize = 12; - int ovector[ovecsize]; + pcre2_code *password_re, *prompt_re; + pcre2_match_data *match_data = pcre2_match_data_create (4, NULL); - password_re = pcre_compile ("assword", 0, &errptr, &offset, NULL); - prompt_re = pcre_compile ("[$#] ", 0, &errptr, &offset, NULL); + password_re = pcre2_compile ("assword", PCRE2_ZERO_TERMINATED, + 0, &errcode, &offset, NULL); + prompt_re = pcre2_compile ("[$#] ", PCRE2_ZERO_TERMINATED, + 0, &errcode, &offset, NULL); switch (mexp_expect (h, (mexp_regexp[]) { { 100, .re = password_re }, { 101, .re = prompt_re }, { 0 }, - }, ovector, ovecsize)) { + }, match_data)) { case 100: - /* here you would send a password */ + /* server printed a password prompt, so send a password */ + mexp_printf_password (h, "%s", password); break; case 101: - /* here you would send a command */ + /* server sent a shell prompt, send a command */ + mexp_printf (h, "ls\n"); break; case MEXP_EOF: fprintf (stderr, "error: ssh closed the connection unexpectedly\n"); @@ -355,6 +412,8 @@ However we also provide a convenience function: B +B + This returns the number of bytes, if the whole message was written OK. If there was an error, -1 is returned and the error is available in C. @@ -375,8 +434,26 @@ send a command followed by a newline you have to do something like: mexp_printf (h, "exit\n"); +=item * + +C works identically to C except +that the output is I sent to the debugging file if debugging is +enabled. As the name suggests, use this for passwords so that they +don't appear in debugging output. + =back +B + +Send the interrupt character (C<^C>, Ctrl-C, C<\003>). This is like +pressing C<^C> - the subprocess (or remote process, if using C) +is gracefully killed. + +Note this only works if the pty is in cooked mode +(ie. C was passed to C or +C). In raw mode, all characters are passed through +without any special interpretation. + =head1 SOURCE Source is available from: @@ -384,9 +461,9 @@ L =head1 SEE ALSO -L, -L, -L, +L, +L, +L, L, L. @@ -401,4 +478,4 @@ your option any later version. =head1 COPYRIGHT -Copyright (C) 2014 Red Hat Inc. +Copyright (C) 2014-2022 Red Hat Inc.