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:
matt335672
2023-03-10 15:52:07 +00:00
parent b53060e734
commit 8b9f9b40c8
6 changed files with 132 additions and 43 deletions
+69 -20
View File
@@ -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
View File
@@ -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);