os_calls changes
- Add g_pipe() - Add g_file_duplicate_on() - Rework struct exit_status to make it easier to parse - Add optional status return to g_waitchild()
This commit is contained in:
+69
-20
@@ -1396,6 +1396,13 @@ g_sleep(int msecs)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_pipe(int fd[2])
|
||||
{
|
||||
return pipe(fd);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_sck_last_error_would_block(int sck)
|
||||
@@ -2344,6 +2351,24 @@ mode_t_to_hex(mode_t mode)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Duplicates a file descriptor onto another one using the semantics
|
||||
* of dup2() */
|
||||
/* return boolean */
|
||||
int
|
||||
g_file_duplicate_on(int fd, int target_fd)
|
||||
{
|
||||
int rv = (dup2(fd, target_fd) >= 0);
|
||||
|
||||
if (rv < 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Can't clone file %d as file %d [%s]",
|
||||
fd, target_fd, g_get_strerror());
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int
|
||||
@@ -3051,9 +3076,11 @@ g_set_allusercontext(int uid)
|
||||
#endif
|
||||
/*****************************************************************************/
|
||||
/* does not work in win32
|
||||
returns pid of process that exits or zero if signal occurred */
|
||||
returns pid of process that exits or zero if signal occurred
|
||||
an exit_status struct can optionally be passed in to get the
|
||||
exit status of the child */
|
||||
int
|
||||
g_waitchild(void)
|
||||
g_waitchild(struct exit_status *e)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return 0;
|
||||
@@ -3061,15 +3088,36 @@ g_waitchild(void)
|
||||
int wstat;
|
||||
int rv;
|
||||
|
||||
struct exit_status dummy;
|
||||
|
||||
if (e == NULL)
|
||||
{
|
||||
e = &dummy; // Set this, then throw it away
|
||||
}
|
||||
|
||||
e->reason = E_XR_UNEXPECTED;
|
||||
e->val = 0;
|
||||
|
||||
rv = waitpid(0, &wstat, WNOHANG);
|
||||
|
||||
if (rv == -1)
|
||||
{
|
||||
if (errno == EINTR) /* signal occurred */
|
||||
if (errno == EINTR)
|
||||
{
|
||||
/* This shouldn't happen as signal handlers use SA_RESTART */
|
||||
rv = 0;
|
||||
}
|
||||
}
|
||||
else if (WIFEXITED(wstat))
|
||||
{
|
||||
e->reason = E_XR_STATUS_CODE;
|
||||
e->val = WEXITSTATUS(wstat);
|
||||
}
|
||||
else if (WIFSIGNALED(wstat))
|
||||
{
|
||||
e->reason = E_XR_SIGNAL;
|
||||
e->val = WTERMSIG(wstat);
|
||||
}
|
||||
|
||||
return rv;
|
||||
#endif
|
||||
@@ -3077,7 +3125,10 @@ g_waitchild(void)
|
||||
|
||||
/*****************************************************************************/
|
||||
/* does not work in win32
|
||||
returns pid of process that exits or <= 0 if no process was found */
|
||||
returns pid of process that exits or <= 0 if no process was found
|
||||
|
||||
Note that signal handlers are established with BSD-style semantics,
|
||||
so this call is NOT interrupted by a signal */
|
||||
int
|
||||
g_waitpid(int pid)
|
||||
{
|
||||
@@ -3101,25 +3152,21 @@ g_waitpid(int pid)
|
||||
|
||||
/*****************************************************************************/
|
||||
/* does not work in win32
|
||||
returns exit status code of child process with pid */
|
||||
returns exit status code of child process with pid
|
||||
|
||||
Note that signal handlers are established with BSD-style semantics,
|
||||
so this call is NOT interrupted by a signal */
|
||||
struct exit_status
|
||||
g_waitpid_status(int pid)
|
||||
{
|
||||
struct exit_status exit_status;
|
||||
|
||||
#if defined(_WIN32)
|
||||
exit_status.exit_code = -1;
|
||||
exit_status.signal_no = 0;
|
||||
return exit_status;
|
||||
#else
|
||||
int rv;
|
||||
int status;
|
||||
|
||||
exit_status.exit_code = -1;
|
||||
exit_status.signal_no = 0;
|
||||
struct exit_status exit_status = {.reason = E_XR_UNEXPECTED, .val = 0};
|
||||
|
||||
#if !defined(_WIN32)
|
||||
if (pid > 0)
|
||||
{
|
||||
int rv;
|
||||
int status;
|
||||
|
||||
LOG(LOG_LEVEL_DEBUG, "waiting for pid %d to exit", pid);
|
||||
rv = waitpid(pid, &status, 0);
|
||||
|
||||
@@ -3127,11 +3174,13 @@ g_waitpid_status(int pid)
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
exit_status.exit_code = WEXITSTATUS(status);
|
||||
exit_status.reason = E_XR_STATUS_CODE;
|
||||
exit_status.val = WEXITSTATUS(status);
|
||||
}
|
||||
if (WIFSIGNALED(status))
|
||||
{
|
||||
exit_status.signal_no = WTERMSIG(status);
|
||||
exit_status.reason = E_XR_SIGNAL;
|
||||
exit_status.val = WTERMSIG(status);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3140,8 +3189,8 @@ g_waitpid_status(int pid)
|
||||
}
|
||||
}
|
||||
|
||||
return exit_status;
|
||||
#endif
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
+13
-6
@@ -23,13 +23,17 @@
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
enum exit_reason
|
||||
{
|
||||
E_XR_STATUS_CODE = 0, ///< 'val' contains exit status
|
||||
E_XR_SIGNAL, ///< 'val' contains a signal number
|
||||
E_XR_UNEXPECTED
|
||||
};
|
||||
|
||||
struct exit_status
|
||||
{
|
||||
/* set to -1 when the process exited via a signal */
|
||||
uint8_t exit_code;
|
||||
|
||||
/* set to 0 when the process exited normally */
|
||||
uint8_t signal_no;
|
||||
enum exit_reason reason;
|
||||
int val;
|
||||
};
|
||||
|
||||
struct list;
|
||||
@@ -178,6 +182,8 @@ const char *
|
||||
g_sck_get_peer_description(int sck,
|
||||
char *desc, unsigned int bytes);
|
||||
void g_sleep(int msecs);
|
||||
int g_pipe(int fd[2]);
|
||||
|
||||
tintptr g_create_wait_obj(const char *name);
|
||||
tintptr g_create_wait_obj_from_socket(tintptr socket, int write);
|
||||
void g_delete_wait_obj_from_socket(tintptr wait_obj);
|
||||
@@ -213,6 +219,7 @@ int g_file_read(int fd, char *ptr, int len);
|
||||
int g_file_write(int fd, const char *ptr, int len);
|
||||
int g_file_seek(int fd, int offset);
|
||||
int g_file_lock(int fd, int start, int len);
|
||||
int g_file_duplicate_on(int fd, int target_fd);
|
||||
int g_chmod_hex(const char *filename, int flags);
|
||||
int g_umask_hex(int flags);
|
||||
int g_chown(const char *name, int uid, int gid);
|
||||
@@ -273,7 +280,7 @@ int g_setlogin(const char *name);
|
||||
*/
|
||||
int g_set_allusercontext(int uid);
|
||||
#endif
|
||||
int g_waitchild(void);
|
||||
int g_waitchild(struct exit_status *e);
|
||||
int g_waitpid(int pid);
|
||||
struct exit_status g_waitpid_status(int pid);
|
||||
void g_clearenv(void);
|
||||
|
||||
Reference in New Issue
Block a user