lib_LTLIBRARIES = libminiexpect.la
 
 libminiexpect_la_SOURCES = miniexpect.c miniexpect.h
-libminiexpect_la_CFLAGS = $(PCRE_CFLAGS) -Wall
-libminiexpect_la_LIBADD = $(PCRE_LIBS)
+libminiexpect_la_CFLAGS = $(PCRE2_CFLAGS) -Wall
+libminiexpect_la_LIBADD = $(PCRE2_LIBS)
 libminiexpect_la_LDFLAGS = -version-info 0:0:0
 
 # Examples.
 noinst_PROGRAMS = example-sshpass
 
 example_sshpass_SOURCES = example-sshpass.c
-example_sshpass_CFLAGS = $(PCRE_CFLAGS) -Wall
+example_sshpass_CFLAGS = $(PCRE2_CFLAGS) -Wall
 example_sshpass_LDADD = libminiexpect.la
 
 # Tests.
        test-multi-match
 
 test_spawn_SOURCES = test-spawn.c tests.h miniexpect.h
-test_spawn_CFLAGS = $(PCRE_CFLAGS) -Wall
+test_spawn_CFLAGS = $(PCRE2_CFLAGS) -Wall
 test_spawn_LDADD = libminiexpect.la
 
 test_ls_version_SOURCES = test-ls-version.c tests.h miniexpect.h
-test_ls_version_CFLAGS = $(PCRE_CFLAGS) -Wall
+test_ls_version_CFLAGS = $(PCRE2_CFLAGS) -Wall
 test_ls_version_LDADD = libminiexpect.la
 
 test_multi_match_SOURCES = test-multi-match.c tests.h miniexpect.h
-test_multi_match_CFLAGS = $(PCRE_CFLAGS) -Wall
+test_multi_match_CFLAGS = $(PCRE2_CFLAGS) -Wall
 test_multi_match_LDADD = libminiexpect.la
 
 # parallel-tests breaks the ability to put 'valgrind' into
 
 It has a saner interface than libexpect, and doesn't depend on Tcl.
 It is also thread safe, const-correct and uses modern C standards.
 
-It is standalone, except that it requires the PCRE (Perl Compatible
-Regular Expressions) library from http://www.pcre.org/.  The PCRE
+It is standalone, except that it requires the PCRE2 (Perl Compatible
+Regular Expressions) library from http://www.pcre.org/.  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 partial matches which made this
+PCRE2 has a convenient way to detect partial matches which made this
 library very simple to implement.
 
 License
 
 # miniexpect
-# Copyright (C) 2014 Red Hat Inc.
+# Copyright (C) 2014-2022 Red Hat Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-AC_INIT([miniexpect],[1.0])
+AC_INIT([miniexpect],[1.1])
 
 AM_INIT_AUTOMAKE(foreign) dnl NB: Do not [quote] this parameter.
 
 dnl Check support for 64 bit file offsets.
 AC_SYS_LARGEFILE
 
-dnl The only dependency is libpcre (Perl Compatible Regular Expressions).
-PKG_CHECK_MODULES([PCRE], [libpcre])
+dnl The only dependency is libpcre2 (Perl Compatible Regular Expressions).
+PKG_CHECK_MODULES([PCRE2], [libpcre2-8])
 
 dnl Optional for building the manual page.  This is part of Perl.
 AC_CHECK_PROG([POD2MAN], [pod2man], [pod2man], [no])
 
 /* miniexpect example.
- * Copyright (C) 2014 Red Hat Inc.
+ * Copyright (C) 2014-2022 Red Hat Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 #include <unistd.h>
 #include <assert.h>
 
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 #include "miniexpect.h"
 
-static pcre *compile_re (const char *rex);
+static pcre2_code *compile_re (const char *rex);
 
 static void
 usage (void)
   mexp_h *h;
   const char *password;
   int status;
-  pcre *password_re, *prompt_re, *hello_re;
-  const int ovecsize = 12;
-  int ovector[ovecsize];
+  pcre2_code *password_re, *prompt_re, *hello_re;
+  pcre2_match_data *match_data;
+
+  match_data = pcre2_match_data_create (4, NULL);
 
   while ((opt = getopt (argc, argv, "d")) != -1) {
     switch (opt) {
                          { 100, .re = password_re },
                          { 0 }
                        },
-                       ovector, ovecsize)) {
+                       match_data)) {
   case 100:
     break;
   case MEXP_EOF:
                          { 101, .re = prompt_re },
                          { 0 },
                        },
-                       ovector, ovecsize)) {
+                       match_data)) {
   case 100:                     /* Password. */
     fprintf (stderr, "error: ssh asked for password again, probably the password supplied is wrong\n");
     goto error;
                          { 100, .re = hello_re },
                          { 0 },
                        },
-                       ovector, ovecsize)) {
+                       match_data)) {
   case 100:
     break;
   case MEXP_EOF:
     goto error;
   }
 
-  switch (mexp_expect (h, NULL, NULL, 0)) {
+  switch (mexp_expect (h, NULL, NULL)) {
   case MEXP_EOF:
     /* This is what we're expecting: ssh will close the connection. */
     break;
 
   printf ("test was successful\n");
 
+  pcre2_match_data_free (match_data);
   exit (EXIT_SUCCESS);
 
  error:
 }
 
 /* Helper function to compile a PCRE regexp. */
-static pcre *
+static pcre2_code *
 compile_re (const char *rex)
 {
-  const char *errptr;
-  int erroffset;
-  pcre *ret;
+  int errorcode;
+  PCRE2_SIZE erroroffset;
+  char errormsg[256];
+  pcre2_code *ret;
 
-  ret = pcre_compile (rex, 0, &errptr, &erroffset, NULL);
+  ret = pcre2_compile ((PCRE2_SPTR) rex, PCRE2_ZERO_TERMINATED,
+                       0, &errorcode, &erroroffset, NULL);
   if (ret == NULL) {
-    fprintf (stderr, "error: failed to compile regular expression '%s': %s at offset %d\n",
-             rex, errptr, erroffset);
+    pcre2_get_error_message (errorcode,
+                             (PCRE2_UCHAR *) errormsg, sizeof errormsg);
+    fprintf (stderr, "error: "
+             "failed to compile regular expression '%s': "
+             "%s at offset %zu\n",
+             rex, errormsg, erroroffset);
     exit (EXIT_FAILURE);
   }
   return ret;
 
 #include <sys/wait.h>
 #include <sys/time.h>
 
-#include <pcre.h>
-
-/* RHEL 6 pcre did not define PCRE_PARTIAL_SOFT.  However PCRE_PARTIAL
- * is a synonym so use that.
- */
-#ifndef PCRE_PARTIAL_SOFT
-#define PCRE_PARTIAL_SOFT PCRE_PARTIAL
-#endif
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 #include "miniexpect.h"
 
 }
 
 enum mexp_status
-mexp_expect (mexp_h *h, const mexp_regexp *regexps, int *ovector, int ovecsize)
+mexp_expect (mexp_h *h, const mexp_regexp *regexps,
+             pcre2_match_data *match_data)
 {
   time_t start_t, now_t;
   int timeout;
       assert (h->buffer != NULL);
 
       for (i = 0; regexps[i].r > 0; ++i) {
-        const int options = regexps[i].options | PCRE_PARTIAL_SOFT;
+        const int options = regexps[i].options | PCRE2_PARTIAL_SOFT;
 
-        r = pcre_exec (regexps[i].re, regexps[i].extra,
-                       h->buffer, (int)h->len, 0,
-                       options,
-                       ovector, ovecsize);
+        r = pcre2_match (regexps[i].re,
+                         (PCRE2_SPTR) h->buffer, (int)h->len, 0,
+                         options, match_data, NULL);
         h->pcre_error = r;
 
         if (r >= 0) {
           /* A full match. */
-          if (ovector != NULL && ovecsize >= 1 && ovector[1] >= 0)
+          const PCRE2_SIZE *ovector = NULL;
+
+          if (match_data)
+            ovector = pcre2_get_ovector_pointer (match_data);
+
+          if (ovector != NULL && ovector[1] >= 0)
             h->next_match = ovector[1];
           else
             h->next_match = -1;
           return regexps[i].r;
         }
 
-        else if (r == PCRE_ERROR_NOMATCH) {
+        else if (r == PCRE2_ERROR_NOMATCH) {
           /* No match at all. */
           /* (nothing here) */
         }
 
-        else if (r == PCRE_ERROR_PARTIAL) {
+        else if (r == PCRE2_ERROR_PARTIAL) {
           /* Partial match.  Keep the buffer and keep reading. */
           can_clear_buffer = 0;
         }
 
 /* miniexpect
- * Copyright (C) 2014 Red Hat Inc.
+ * Copyright (C) 2014-2022 Red Hat Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 #include <stdio.h>
 #include <unistd.h>
 
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 /* This handle is created per subprocess that is spawned. */
 struct mexp_h {
 /* Expect. */
 struct mexp_regexp {
   int r;
-  const pcre *re;
-  const pcre_extra *extra;
+  const pcre2_code *re;
   int options;
 };
 typedef struct mexp_regexp mexp_regexp;
 };
 
 extern int mexp_expect (mexp_h *h, const mexp_regexp *regexps,
-                        int *ovector, int ovecsize);
+                        pcre2_match_data *match_data);
 
 /* Sending commands, keypresses. */
 extern int mexp_printf (mexp_h *h, const char *fs, ...)
 
 
  #include <errno.h>
  #include <sys/wait.h>
- #include <pcre.h>
+ #define PCRE2_CODE_UNIT_WIDTH 8
+ #include <pcre2.h>
  #include <miniexpect.h>
  
  mexp_h *h;
  h = mexp_spawnl ("ssh", "ssh", "host", NULL);
- switch (mexp_expect (h, regexps, ovector, ovecsize)) {
+ 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
 
 standards.
 
 Miniexpect is a standalone library, except for a single dependency: it
-requires the PCRE (Perl Compatible Regular Expressions) library from
-L<http://www.pcre.org/>.  The PCRE dependency is fundamental because
+requires the PCRE2 (Perl Compatible Regular Expressions) library from
+L<http://www.pcre.org/>.  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
 B<int mexp_get_pcre_error (mexp *h);>
 
 When C<mexp_expect> [see below] calls the PCRE function
-L<pcre_exec(3)>, it stashes the return value in the C<pcre_error>
+L<pcre2_match(3)>, it stashes the return value in the C<pcre_error>
 field in the handle, and that field is returned by this method.
 
-There are two uses for this:
-
-=over 4
-
-=item 1.
-
 If C<mexp_expect> returns C<MEXP_PCRE_ERROR>, then the actual PCRE
-error code returned by L<pcre_exec(3)> is available by calling this
-method.  For a list of PCRE error codes, see L<pcreapi(3)>.
-
-=item 2.
-
-A more unusual use is if you ever need to get the captured substrings
-from your regular expression (calling L<pcre_get_substring(3)>).  The
-third parameter of that function (C<stringcount>) is the value
-returned by L<pcre_exec(3)>, and so you can call it like this:
-
- pcre_get_substring (h->buffer, ovector,
-                     mexp_get_pcre_error (h), 1, &matched);
-
-=back
+error code returned by L<pcre2_match(3)> is available by calling this
+method.  For a list of PCRE error codes, see L<pcre2api(3)>.
 
 B<void mexp_set_debug_file (mexp *h, FILE *fp);>
 
 =head1 EXPECT FUNCTION
 
 Miniexpect contains a powerful regular expression matching function
-based on L<pcre(3)>:
+based on L<pcre2(3)>:
 
 B<int mexp_expect (mexp_h *h, const mexp_regexp *regexps,
-int *ovector, int ovecsize);>
+pcre2_match_data *match_data);>
 
 The output of the subprocess is matched against the list of PCRE
 regular expressions in C<regexps>.  C<regexps> is a list of regular
 
  struct mexp_regexp {
    int r;
-   const pcre *re;
-   const pcre_extra *extra;
+   const pcre2_code *re;
    int options;
  };
  typedef struct mexp_regexp mexp_regexp;
 
 =item *
 
-C<regexps[].re>, C<regexps[].extra>, C<regexps[].options>, C<ovector>
-and C<ovecsize> are passed through to the L<pcre_exec(3)> function.
+C<regexps[].re>, C<regexps[].options> and C<match_data> are passed
+through to the L<pcre2_match(3)> function.
 
 =item *
 
  mexp_h *h;
  char *errptr;
  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);
                         { 100, .re = password_re },
                         { 101, .re = prompt_re },
                         { 0 },
-                      }, ovector, ovecsize)) {
+                      }, match_data)) {
   case 100:
     /* here you would send a password */
     break;
 
 =head1 SEE ALSO
 
-L<pcre(3)>,
-L<pcre_exec(3)>,
-L<pcreapi(3)>,
+L<pcre2(3)>,
+L<pcre2_match(3)>,
+L<pcre2api(3)>,
 L<waitpid(2)>,
 L<system(3)>.
 
 
 =head1 COPYRIGHT
 
-Copyright (C) 2014 Red Hat Inc.
+Copyright (C) 2014-2022 Red Hat Inc.
 
 #include <unistd.h>
 #include <assert.h>
 
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 #include "miniexpect.h"
 #include "tests.h"
 {
   mexp_h *h;
   int status, r;
-  pcre *ls_coreutils_re;
-  pcre *ls_busybox_re;
-  const int ovecsize = 12;
-  int ovector[ovecsize];
-  const char *version;
+  pcre2_code *ls_coreutils_re;
+  pcre2_code *ls_busybox_re;
+  pcre2_match_data *match_data = pcre2_match_data_create (4, NULL);
+  PCRE2_UCHAR *version;
+  PCRE2_SIZE verlen;
 
   ls_coreutils_re = test_compile_re ("^ls.* ([.\\d]+)");
   /* Busybox doesn't actually recognize the --version option, but
                          { 100, ls_coreutils_re },
                          { 101, ls_busybox_re },
                          { 0 },
-                       }, ovector, ovecsize)) {
+                       }, match_data)) {
   case 100:
   case 101:
     /* Get the matched version number. */
-    r = pcre_get_substring (h->buffer, ovector,
-                            mexp_get_pcre_error (h), 1, &version);
+    r = pcre2_substring_get_bynumber (match_data, 1, &version, &verlen);
     if (r < 0) {
       fprintf (stderr, "error: PCRE error reading version substring: %d\n",
                r);
       exit (EXIT_FAILURE);
     }
-    printf ("ls version = %s\n", version);
-    pcre_free_substring (version);
+    printf ("ls version = %s\n", (char *) version);
+    pcre2_substring_free (version);
     break;
   case MEXP_EOF:
     fprintf (stderr, "error: EOF before matching version string\n");
     exit (EXIT_FAILURE);
   }
 
-  pcre_free (ls_coreutils_re);
-  pcre_free (ls_busybox_re);
+  pcre2_code_free (ls_coreutils_re);
+  pcre2_code_free (ls_busybox_re);
+  pcre2_match_data_free (match_data);
 
   exit (EXIT_SUCCESS);
 }
 
   int r;
   int rv[5];
   size_t i;
-  pcre *multi_re = test_compile_re ("multi");
-  pcre *match_re = test_compile_re ("match");
-  pcre *ing_re = test_compile_re ("ing");
-  pcre *str_re = test_compile_re ("str");
-  pcre *s_re = test_compile_re ("s");
-  const int ovecsize = 12;
-  int ovector[ovecsize];
+  pcre2_code *multi_re = test_compile_re ("multi");
+  pcre2_code *match_re = test_compile_re ("match");
+  pcre2_code *ing_re = test_compile_re ("ing");
+  pcre2_code *str_re = test_compile_re ("str");
+  pcre2_code *s_re = test_compile_re ("s");
+  pcre2_match_data *match_data = pcre2_match_data_create (4, NULL);
 
   /* If the subprocess prints multiple things, we should be able to
    * repeatedly call mexp_expect to match on each one.  This didn't
                        { 103, str_re },
                        { 104, s_re },
                        { 0 },
-                     }, ovector, ovecsize);
+                     }, match_data);
     switch (r) {
     case 100: case 101: case 102: case 103: case 104:
       printf ("iteration %zu: matched %d\n", i, r);
 
 /* miniexpect test suite
- * Copyright (C) 2014 Red Hat Inc.
+ * Copyright (C) 2014-2022 Red Hat Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
     fprintf (stderr, "stopped by signal %d", WSTOPSIG (status));
 }
 
-static pcre *
+__attribute__((__unused__))
+static pcre2_code *
 test_compile_re (const char *rex)
 {
-  const char *errptr;
-  int erroffset;
-  pcre *ret;
+  int errorcode;
+  PCRE2_SIZE erroroffset;
+  char errormsg[256];
+  pcre2_code *ret;
 
-  ret = pcre_compile (rex, 0, &errptr, &erroffset, NULL);
+  ret = pcre2_compile ((PCRE2_SPTR) rex, PCRE2_ZERO_TERMINATED,
+                       0, &errorcode, &erroroffset, NULL);
   if (ret == NULL) {
-    fprintf (stderr, "error: failed to compile regular expression '%s': %s at offset %d\n",
-             rex, errptr, erroffset);
+    pcre2_get_error_message (errorcode,
+                             (PCRE2_UCHAR *) errormsg, sizeof errormsg);
+    fprintf (stderr, "error: "
+             "failed to compile regular expression '%s': "
+             "%s at offset %zu\n",
+             rex, errormsg, erroroffset);
     exit (EXIT_FAILURE);
   }
   return ret;