Mstdlib-1.24.0
Process Open (popen)

Typedefs

typedef struct M_popen_handle M_popen_handle_t
 

Enumerations

enum  M_popen_fd_t {
  M_POPEN_FD_READ = 0 ,
  M_POPEN_FD_WRITE ,
  M_POPEN_FD_ERR
}
 
enum  M_popen_err_t {
  M_POPEN_ERR_NONE = 0 ,
  M_POPEN_ERR_INVALIDUSE ,
  M_POPEN_ERR_CMDNOTFOUND ,
  M_POPEN_ERR_PERM ,
  M_POPEN_ERR_NOEXEC ,
  M_POPEN_ERR_KILLSIGNAL ,
  M_POPEN_ERR_PIPE ,
  M_POPEN_ERR_WAIT ,
  M_POPEN_ERR_SPAWN
}
 
enum  M_popen_status_t {
  M_POPEN_STATUS_RUNNING = 0 ,
  M_POPEN_STATUS_ERROR ,
  M_POPEN_STATUS_DONE
}
 

Functions

M_popen_handle_tM_popen (const char *cmd, M_popen_err_t *errorid)
 
ssize_t M_popen_read (M_popen_handle_t *mp, M_popen_fd_t fd, char *out, size_t out_len, M_uint64 timeout_ms)
 
ssize_t M_popen_write (M_popen_handle_t *mp, M_popen_fd_t fd, const char *in, size_t in_len)
 
int M_popen_closefd (M_popen_handle_t *mp, M_popen_fd_t fd)
 
M_popen_status_t M_popen_check (M_popen_handle_t *mp)
 
int M_popen_close_ex (M_popen_handle_t *mp, char **stdout_buf, size_t *stdout_buf_len, char **stderr_buf, size_t *stderr_buf_len, M_popen_err_t *errorid, M_uint64 timeout)
 
int M_popen_close (M_popen_handle_t *mp, M_popen_err_t *errorid)
 
const char * M_popen_strerror (M_popen_err_t err)
 

Detailed Description

Open and interact with a process.

Note
On Unix SIGCHLD cannot be set to SIG_IGN. ECHILD could be generated and M_popen_check may return M_POPEN_ERR_WAIT when the process exits. See M_backtrace_set_ignore_signal for explantion.

Example:

const char *data = "<x><t>data</t></x>"
int retval;
char *stdout_buf = NULL;
size_t stdout_buf_len = 0;
char *stderr_buf = NULL;
size_t stderr_buf_len = 0;
mp = M_popen("curl <url>", &mperr);
if (mp == NULL) {
printf("m_popen failed: %s\n", M_popen_strerror(mperr));
return M_FALSE;
}
M_printf("Process spawned....\n");
retval = M_popen_write(mp, M_POPEN_FD_WRITE, data, M_str_len(data));
if (retval <= 0) {
M_printf("M_popen_write failed, retval = %d\n", retval);
M_popen_close(mp, &mperr);
return M_FALSE;
}
/ * Close file descriptor to let process know we're done * /
if (!M_popen_closefd(mp, M_POPEN_FD_WRITE)) {
M_printf("M_popen_closefd() failed\n");
M_popen_close(mp, &mperr);
return M_FALSE;
}
M_printf("Wrote process stream....\n");
while ((status=M_popen_check(mp)) == M_POPEN_STATUS_RUNNING) {
M_thread_sleep(50000);
}
if (status == M_POPEN_STATUS_ERROR) {
retval = M_popen_close(mp, &mperr);
printf("Error during M_popen_check(): %d: %s\n", retval, M_popen_strerror(mperr));
return M_FALSE;
}
M_printf("Process done...\n");
retval = M_popen_close_ex(mp, &stdout_buf, &stdout_buf_len, &stderr_buf, &stderr_buf_len, &mperr, 0);
if (retval < 0) {
M_printf("error: %s\n", M_popen_strerror(mperr));
return M_FALSE;
}
M_printf("stdout: %d:\n%s\n", (int)stdout_buf_len, stdout_buf);
M_printf("stderr: %d:\n%s\n", (int)stderr_buf_len, stderr_buf);
M_free(stdout_buf);
M_free(stderr_buf);
M_printf("return code: %d\n", retval);
ssize_t M_printf(const char *fmt,...)
const char * M_popen_strerror(M_popen_err_t err)
int M_popen_close(M_popen_handle_t *mp, M_popen_err_t *errorid)
M_popen_err_t
Definition: m_popen.h:126
M_popen_handle_t * M_popen(const char *cmd, M_popen_err_t *errorid)
ssize_t M_popen_write(M_popen_handle_t *mp, M_popen_fd_t fd, const char *in, size_t in_len)
struct M_popen_handle M_popen_handle_t
Definition: m_popen.h:115
M_popen_status_t
Definition: m_popen.h:139
@ M_POPEN_FD_WRITE
Definition: m_popen.h:121
size_t M_str_len(const char *s) M_WARN_UNUSED_RESULT

Typedef Documentation

◆ M_popen_handle_t

typedef struct M_popen_handle M_popen_handle_t

Enumeration Type Documentation

◆ M_popen_fd_t

Types of file descriptors that can be retrieved and used

Enumerator
M_POPEN_FD_READ 
M_POPEN_FD_WRITE 
M_POPEN_FD_ERR 

◆ M_popen_err_t

Possible error reason codes

Enumerator
M_POPEN_ERR_NONE 
M_POPEN_ERR_INVALIDUSE 

invalid API usage

M_POPEN_ERR_CMDNOTFOUND 

command not found

M_POPEN_ERR_PERM 

permission denied

M_POPEN_ERR_NOEXEC 

file not executable

M_POPEN_ERR_KILLSIGNAL 

killed by signal

M_POPEN_ERR_PIPE 

pipe creation failed

M_POPEN_ERR_WAIT 

attempting to check process status failed

M_POPEN_ERR_SPAWN 

fork failed

◆ M_popen_status_t

Status codes for command being executed

Enumerator
M_POPEN_STATUS_RUNNING 
M_POPEN_STATUS_ERROR 
M_POPEN_STATUS_DONE 

Function Documentation

◆ M_popen()

M_popen_handle_t * M_popen ( const char *  cmd,
M_popen_err_t errorid 
)

Start the specified command and open stdin (write), stdout (read), and stderr (read) file descriptors for communication.

Must call M_popen_close() to clean up the returned handle.

Parameters
[in]cmdCommand to execute.
[out]erroridPointer to store error id if an error occurs.
Returns
NULL on failure, M_popen_handle_t on success.

◆ M_popen_read()

ssize_t M_popen_read ( M_popen_handle_t mp,
M_popen_fd_t  fd,
char *  out,
size_t  out_len,
M_uint64  timeout_ms 
)

Read from a file descriptor

Parameters
[in]mpOpen M_popen_t object.
[in]fdWhich FD to read from.
[out]outBuffer to hold read data.
[in]out_lenLength of out buffer.
[in]timeout_msTime in ms to wait for data. M_TIMEOUT_INF will cause this to block. Note: Windows only has 15 ms resolution.
Returns
-1 on error, -2 if fd was closed, 0 if a timeout occurred and no bytes were read, otherwise number of bytes read.

◆ M_popen_write()

ssize_t M_popen_write ( M_popen_handle_t mp,
M_popen_fd_t  fd,
const char *  in,
size_t  in_len 
)

Write to a file descriptor

Parameters
[in,out]mpOpen M_popen_t object.
[in]fdWhich FD to write to.
[in]inBuffer to holding data to be written.
[in]in_lenLength of data to be written.
Returns
-1 on error, otherwise number of bytes written.

◆ M_popen_closefd()

int M_popen_closefd ( M_popen_handle_t mp,
M_popen_fd_t  fd 
)

Close the provided file descriptor.

This is used mainly to close the stdin stream to signal to the command being executed that there is no more data left to be read. Any open file descriptors are automatically closed by M_popen_close().

Parameters
[in,out]mpOpen M_popen_t object.
[in]fdWhich FD to close.
Returns
1 on success, 0 on error.

◆ M_popen_check()

M_popen_status_t M_popen_check ( M_popen_handle_t mp)

Checks the current state of the command being executed and returns a code identifying the state.

Even if the state returns DONE or ERROR, M_popen_close() must be called.

Parameters
[in]mpOpen M_popen_t object.
Returns
M_popen_status_t code.

◆ M_popen_close_ex()

int M_popen_close_ex ( M_popen_handle_t mp,
char **  stdout_buf,
size_t *  stdout_buf_len,
char **  stderr_buf,
size_t *  stderr_buf_len,
M_popen_err_t errorid,
M_uint64  timeout 
)

Close the M_popen_t object.

This will perform a blocking wait for the process to exit before returning control to the caller.

Parameters
[in]mpM_popen_t object
[out]stdout_bufOptional parameter. Will return allocated buffer containing the contents of the process's stdout. If specified, must also specify stdout_buf_len.
[out]stdout_buf_lenOptional parameter. Will return the length of stdout_buf.
[out]stderr_bufOptional parameter. Will return allocated buffer containing the contents of the process's stderr. If specified, must also specify stderr_buf_len.
[out]stderr_buf_lenOptional parameter. Will return the length of stderr_buf.
[out]erroridif an error has occurred, will populate with a reason code.
[in]timeoutTime in ms to wait for the processes to exit. If the process has not finished after the timeout expires it will be killed. M_TIMEOUT_INF will cause this to block until the process exits. Note: the time out only has 15 ms resolution.
Returns
-1 on error, -2 on timeout, otherwise the exit code from the process.

◆ M_popen_close()

int M_popen_close ( M_popen_handle_t mp,
M_popen_err_t errorid 
)

Close the M_popen_t object.

This is a simplified wrapper around M_popen_close_ex(). This command blocks forever until the child process is done. If you need to force-kill the process after a given timeout, use M_popen_close_ex() instead of this function.

Parameters
[in]mpM_popen_t object
[out]erroridif an error has occurred, will populate with a reason code.
See also
M_popen_close_ex
Returns
-1 on error, otherwise the exit code from the process.

◆ M_popen_strerror()

const char * M_popen_strerror ( M_popen_err_t  err)

Output human-readable error string.

Parameters
[in]errError as returned by M_popen() or M_popen_close().
Returns
string error message.