Add debugging capability at runtime.
[miniexpect.git] / miniexpect.h
index ba3607a..14d8236 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/* ** NOTE ** All API documentation is in the manual page.
+ *
+ * To read the manual page from the source directory, do:
+ *    man ./miniexpect.3
+ * If you have installed miniexpect, do:
+ *    man 3 miniexpect
+ *
+ * The source for the manual page is miniexpect.pod.
+ */
+
 #ifndef MINIEXPECT_H_
 #define MINIEXPECT_H_
 
+#include <stdio.h>
 #include <unistd.h>
 
 #include <pcre.h>
 
 /* This handle is created per subprocess that is spawned. */
 struct mexp_h {
-  int fd;                       /* File descriptor pointing to pty. */
-  pid_t pid;                    /* Subprocess PID. */
-
-  /* Timeout (milliseconds, 1/1000th seconds).  The caller may set
-   * this before calling mexp_expect.  Set it to -1 to mean no
-   * timeout.  The default is 60000 (= 60 seconds).
-   */
+  int fd;
+  pid_t pid;
   int timeout;
-
-  /* The read buffer is allocated by the library when mexp_expect is
-   * called.  It is available so you can examine the buffer to see
-   * what part of the regexp matched.  Note this buffer does not
-   * contain the full input from the process, but it will contain at
-   * least the part matched by the regular expression (and maybe some
-   * more).
-   */
-  char *buffer;                 /* Read buffer. */
-  size_t len;                   /* Length of data in the buffer. */
-  size_t alloc;                 /* Allocated size of the buffer. */
-
-  /* The caller may set this to set the size (in bytes) for reads from
-   * the subprocess.  The default is 1024.
-   */
+  char *buffer;
+  size_t len;
+  size_t alloc;
+  ssize_t next_match;
   size_t read_size;
-
-  /* If mexp_expect returns MEXP_PCRE_ERROR, then the actual PCRE
-   * error code is returned here.  See pcre_exec(3) for details.
-   */
   int pcre_error;
-
-  /* Opaque pointers for use of the caller.  The library will not
-   * touch these.
-   */
+  FILE *debug_fp;
   void *user1;
   void *user2;
   void *user3;
 };
 typedef struct mexp_h mexp_h;
 
-/* Spawn a subprocess.
- *
- * If successful it returns a handle.  If it fails, it returns NULL
- * and sets errno.
- */
-extern mexp_h *mexp_spawnv (const char *file, char **argv);
-
-/* Same as mexp_spawnv, but it uses a NULL-terminated variable length
- * list of arguments.
- */
-extern mexp_h *mexp_spawnl (const char *file, const char *arg, ...);
-
-/* Close the handle and clean up the subprocess.
- *
- * This returns:
- *   0:   successful close, subprocess exited cleanly.
- *   -1:  error in system call, see errno.
- *   > 0: exit status of subprocess if it didn't exit cleanly.  Use
- *        WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG etc macros to
- *        examine this.
- *
- * Notes:
- *
- * - Even in the error cases, the handle is always closed and
- *   freed by this call.
- *
- * - It is normal for the kernel to send SIGHUP to the subprocess.
- *   If the subprocess doesn't catch the SIGHUP, then it will die
- *   (WIFSIGNALED (status) && WTERMSIG (status) == SIGHUP).  This
- *   case should not necessarily be considered an error.
+/* Methods to access (some) fields in the handle. */
+#define mexp_get_fd(h) ((h)->fd)
+#define mexp_get_pid(h) ((h)->pid)
+#define mexp_get_timeout_ms(h) ((h)->timeout)
+#define mexp_set_timeout_ms(h, ms) ((h)->timeout = (ms))
+/* If secs == -1, then this sets h->timeout to -1000, but the main
+ * code handles this since it only checks for h->timeout < 0.
  */
+#define mexp_set_timeout(h, secs) ((h)->timeout = 1000 * (secs))
+#define mexp_get_read_size(h) ((h)->read_size)
+#define mexp_set_read_size(h, size) ((h)->read_size = (size))
+#define mexp_get_pcre_error(h) ((h)->pcre_error)
+#define mexp_set_debug_file(h, fp) ((h)->debug_fp = (fp))
+#define mexp_get_debug_file(h) ((h)->debug_fp)
+
+/* Spawn a subprocess. */
+extern mexp_h *mexp_spawnvf (unsigned flags, const char *file, char **argv);
+extern mexp_h *mexp_spawnlf (unsigned flags, const char *file, const char *arg, ...);
+#define mexp_spawnv(file,argv) mexp_spawnvf (0, (file), (argv))
+#define mexp_spawnl(file,...) mexp_spawnlf (0, (file), __VA_ARGS__)
+
+#define MEXP_SPAWN_KEEP_SIGNALS 1
+#define MEXP_SPAWN_KEEP_FDS     2
+#define MEXP_SPAWN_COOKED_MODE  4
+#define MEXP_SPAWN_RAW_MODE     0
+
+/* Close the handle. */
 extern int mexp_close (mexp_h *h);
 
-/* The list of regular expressions passed to mexp_expect. */
+/* Expect. */
 struct mexp_regexp {
-  int r;                        /* The returned value from mexp_expect
-                                 * if this regular expression matches.
-                                 * MUST be > 0.
-                                 */
-  const pcre *re;               /* The compiled regular expression. */
-  const pcre_extra *extra;      /* See pcre_exec. */
-  int options;                  /* See pcre_exec. */
+  int r;
+  const pcre *re;
+  const pcre_extra *extra;
+  int options;
 };
 typedef struct mexp_regexp mexp_regexp;
 
 enum mexp_status {
   MEXP_EOF        = 0,
-  MEXP_TIMEOUT    = -1,
-  MEXP_ERROR      = -2,
-  MEXP_PCRE_ERROR = -3,
+  MEXP_ERROR      = -1,
+  MEXP_PCRE_ERROR = -2,
+  MEXP_TIMEOUT    = -3,
 };
 
-/* Expect some output from the subprocess.  Match the output against
- * the PCRE regular expression(s) in the list, and return which one
- * matched.
- *
- * See example-sshpass.c for an example of how to pass in regular
- * expressions.
- *
- * This can return:
- *
- *   MEXP_TIMEOUT:
- *     No input matched before the timeout (mexp_h->timeout) was reached.
- *   MEXP_EOF:
- *     The subprocess closed the connection.
- *   MEXP_ERROR:
- *     There was a system call error (eg. from the read call).  See errno.
- *   MEXP_PCRE_ERROR
- *     There was a pcre_exec error.  h->pcre_error is set to the error code
- *     (see pcreapi(3) for a list of PCRE_* error codes and what they mean).
- *
- * Notes:
- *
- * - 'regexps' may be NULL or an empty list, which means we don't
- *   match against a regular expression.  This is useful if you just
- *   want to wait for EOF or timeout.
- *
- * - 'regexps[].re', 'regexps[].extra', 'regexps[].options', 'ovector'
- *   and 'ovecsize' are passed through to the pcre_exec function.
- */
 extern int mexp_expect (mexp_h *h, const mexp_regexp *regexps,
                         int *ovector, int ovecsize);
 
-/* This is a convenience function for writing something (eg. a
- * password or command) to the subprocess.  You could do this by
- * writing directly to 'h->fd', but this function does all the error
- * checking for you.
- *
- * Returns the number of bytes if the whole message was written OK
- * (partial writes are not possible with this function), or -1 if
- * there was an error (check errno).
- */
+/* Sending commands, keypresses. */
 extern int mexp_printf (mexp_h *h, const char *fs, ...)
   __attribute__((format(printf,2,3)));
+extern int mexp_printf_password (mexp_h *h, const char *fs, ...)
+  __attribute__((format(printf,2,3)));
+extern int mexp_send_interrupt (mexp_h *h);
 
 #endif /* MINIEXPECT_H_ */