Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support NetBsd and OpenIndiana #2811

Open
wants to merge 10 commits into
base: devel
Choose a base branch
from
157 changes: 137 additions & 20 deletions common/os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
#include <windows.h>
#include <winsock.h>
#else
/* fix for solaris 10 with gcc 3.3.2 problem */
#if defined(sun) || defined(__sun)
#define ctid_t id_t
#endif
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
Expand All @@ -55,6 +51,7 @@ struct sockaddr_hvs
};
#endif
#endif
#include <limits.h>
#include <poll.h>
#include <sys/un.h>
#include <sys/time.h>
Expand Down Expand Up @@ -111,8 +108,11 @@ extern char **environ;

/* sys/ucred.h needs to be included to use struct xucred
* in FreeBSD and OS X. No need for other BSDs except GNU/kFreeBSD */
/* Solaris uses __sun and needs .h */
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__FreeBSD_kernel__)
#include <sys/ucred.h>
#elif defined(__sun)
#include <ucred.h>
#endif

/* for solaris */
Expand Down Expand Up @@ -164,11 +164,14 @@ g_mk_socket_path(void)
LOG(LOG_LEVEL_ERROR,
"g_mk_socket_path: g_create_path(%s) failed",
XRDP_SOCKET_PATH);

LOG(LOG_LEVEL_TRACE, "g_mk_socket_path() returned 1");
return 1;
}
}
g_chmod_hex(XRDP_SOCKET_PATH, 0x1777);
}

return 0;
}

Expand Down Expand Up @@ -616,6 +619,7 @@ g_sck_vsock_socket(void)
int
g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
{
LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred(%d)", sck);
#if defined(SO_PEERCRED)
socklen_t ucred_length;
struct myucred
Expand All @@ -628,6 +632,7 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
ucred_length = sizeof(credentials);
if (getsockopt(sck, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length))
{
LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 1");
return 1;
}
if (pid != 0)
Expand All @@ -651,6 +656,7 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)

if (getsockopt(sck, SOL_LOCAL, LOCAL_PEERCRED, &xucred, &xucred_length))
{
LOG(LOG_LEVEL_ERROR, "getsockopt() failed: %s", strerror(errno));
return 1;
}
if (pid != 0)
Expand All @@ -665,8 +671,66 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
{
*gid = xucred.cr_gid;
}

LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 0");
return 0;
#elif defined(LOCAL_PEEREID)
/* Net BSD */
#ifndef SOL_LOCAL
#define SOL_LOCAL 0
#endif
struct unpcbid xucred;
unsigned int xucred_length;
xucred_length = sizeof(xucred);
if (getsockopt(sck, SOL_LOCAL, LOCAL_PEEREID, &xucred, &xucred_length))
{
LOG(LOG_LEVEL_ERROR, "getsockopt() failed: %s", strerror(errno));
return 1;
}

if (pid != 0)
{
*pid = xucred.unp_pid;
}
if (uid != 0)
{
*uid = xucred.unp_euid;
}
if (gid != 0)
{
*gid = xucred.unp_egid;
}

LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 0");
return 0;
#elif defined(__sun)
/* Solaris, OpenIndiana */
ucred_t *xucred = NULL;

if (getpeerucred(sck, &xucred))
{
LOG(LOG_LEVEL_ERROR, "getsockopt() failed: %s", strerror(errno));
return 1;
}

if (pid != 0)
{
*pid = ucred_getpid(xucred);
}
if (uid != 0)
{
*uid = ucred_geteuid(xucred);
}
if (gid != 0)
{
*gid = ucred_getegid(xucred);
}

ucred_free(xucred);
LOG_DEVEL(LOG_LEVEL_TRACE, "g_sck_get_peer_cred() returned 0");
return 0;
#else
LOG(LOG_LEVEL_ERROR, "g_sck_get_peer_cred() has no implementation.");
return 1;
#endif
}
Expand Down Expand Up @@ -1404,7 +1468,14 @@ g_sleep(int msecs)
#if defined(_WIN32)
Sleep(msecs);
#else
usleep(msecs * 1000);
struct timespec tv;
tv.tv_sec = msecs / 1000;
tv.tv_nsec = ( msecs % 1000 ) * 1000000;
if ( nanosleep(&tv, NULL) == -1 )
{
LOG(LOG_LEVEL_ERROR, "nanosleep returned error %s", g_get_strerror());
}

#endif
}

Expand Down Expand Up @@ -3009,6 +3080,7 @@ g_set_alarm(void (*func)(int), unsigned int secs)
{
(void)alarm(secs);
}

return rv;
#endif
}
Expand All @@ -3019,6 +3091,7 @@ void
g_signal_child_stop(void (*func)(int))
{
#if defined(_WIN32)
return;
#else
struct sigaction action;

Expand Down Expand Up @@ -3197,6 +3270,7 @@ g_fork(void)
#if defined(_WIN32)
return 0;
#else
LOG_DEVEL(LOG_LEVEL_TRACE, "g_fork()");
int rv;

rv = fork();
Expand All @@ -3208,6 +3282,7 @@ g_fork(void)
g_get_errno(), g_get_strerror());
}

LOG_DEVEL(LOG_LEVEL_TRACE, "g_fork() returned %d", rv);
return rv;
#endif
}
Expand All @@ -3220,7 +3295,10 @@ g_setgid(int pid)
#if defined(_WIN32)
return 0;
#else
return setgid(pid);
LOG_DEVEL(LOG_LEVEL_TRACE, "g_setgid(%d)", pid);
int retval = setgid(pid);
LOG_DEVEL(LOG_LEVEL_TRACE, "--g_setgid()");
return retval;
#endif
}

Expand All @@ -3233,12 +3311,15 @@ g_initgroups(const char *username)
#if defined(_WIN32)
return 0;
#else
LOG_DEVEL(LOG_LEVEL_TRACE, "g_initgroups(%s)", username);
int gid;
int error = g_getuser_info_by_name(username, NULL, &gid, NULL, NULL, NULL);
if (error == 0)
{
error = initgroups(username, gid);
}

LOG_DEVEL(LOG_LEVEL_TRACE, "g_initgroups() returned %d", error);
return error;
#endif
}
Expand Down Expand Up @@ -3364,7 +3445,7 @@ g_waitchild(struct exit_status *e)
e->reason = E_XR_UNEXPECTED;
e->val = 0;

rv = waitpid(-1, &wstat, WNOHANG);
rv = g_waitpid(-1, &wstat, WNOHANG);

if (rv == -1)
{
Expand Down Expand Up @@ -3396,20 +3477,34 @@ g_waitchild(struct exit_status *e)
Note that signal handlers are established with BSD-style semantics,
so this call is NOT interrupted by a signal */
int
g_waitpid(int pid)
g_waitpid(int pid, int *stat_loc, int options)
{
#if defined(_WIN32)
return 0;
#else
int rv = 0;

if (pid < 0)
#if defined(__NetBSD__) || defined(__sun)
again:
#endif
rv = waitpid(pid, stat_loc, options);
#if defined(__NetBSD__) || defined(__sun)
//Retry EINTR for NetBSD and OpenIndiana.
if ( rv == -1 && errno == EINTR )
{
rv = -1;
goto again;
}
else
#endif

if ( rv == -1 )
{
rv = waitpid(pid, 0, 0);
if ( errno == ECHILD )
{
LOG(LOG_LEVEL_INFO, "waitpid returned %s", g_get_strerror());
}
else
{
LOG(LOG_LEVEL_ERROR, "waitpid returned %s", g_get_strerror());
}
}

return rv;
Expand All @@ -3434,7 +3529,7 @@ g_waitpid_status(int pid)
int status;

LOG(LOG_LEVEL_DEBUG, "waiting for pid %d to exit", pid);
rv = waitpid(pid, &status, 0);
rv = g_waitpid(pid, &status, 0);

if (rv != -1)
{
Expand All @@ -3451,7 +3546,7 @@ g_waitpid_status(int pid)
}
else
{
LOG(LOG_LEVEL_WARNING, "wait for pid %d returned unknown result", pid);
LOG(LOG_LEVEL_WARNING, "wait for pid %d returned unknown result %s", pid, g_get_strerror());
}
}

Expand Down Expand Up @@ -3482,14 +3577,16 @@ g_setpgid(int pid, int pgid)
void
g_clearenv(void)
{
LOG_DEVEL(LOG_LEVEL_TRACE, "g_clearenv()");
#if defined(_WIN32)
#else
#if defined(BSD)
#if defined(BSD) || defined(__sun) || defined(__APPLE__)
environ[0] = 0;
#else
environ = 0;
#endif
#endif
LOG_DEVEL(LOG_LEVEL_TRACE, "--g_clearenv()");
}

/*****************************************************************************/
Expand All @@ -3500,7 +3597,10 @@ g_setenv(const char *name, const char *value, int rewrite)
#if defined(_WIN32)
return 0;
#else
return setenv(name, value, rewrite);
LOG_DEVEL(LOG_LEVEL_TRACE, "g_setenv(%s, %s, %d)", name, value, rewrite);
int retval = setenv(name, value, rewrite);
LOG_DEVEL(LOG_LEVEL_TRACE, "g_setenv() returned %d", retval);
return retval;
#endif
}

Expand Down Expand Up @@ -3604,7 +3704,14 @@ g_getuser_info_by_name(const char *username, int *uid, int *gid,

if (gecos != 0)
{
*gecos = g_strdup(pwd_1->pw_gecos);
if ( pwd_1->pw_gecos == NULL )
{
*gecos = g_strdup("");
}
else
{
*gecos = g_strdup(pwd_1->pw_gecos);
}
}
}
}
Expand Down Expand Up @@ -3652,7 +3759,14 @@ g_getuser_info_by_uid(int uid, char **username, int *gid,

if (gecos != 0)
{
*gecos = g_strdup(pwd_1->pw_gecos);
if ( pwd_1->pw_gecos == NULL )
{
*gecos = g_strdup("");
}
else
{
*gecos = g_strdup(pwd_1->pw_gecos);
}
}

return 0;
Expand Down Expand Up @@ -4013,7 +4127,10 @@ g_shmdt(const void *shmaddr)
int
g_gethostname(char *name, int len)
{
return gethostname(name, len);
LOG_DEVEL(LOG_LEVEL_TRACE, "g_gethostname(name, %d)", len);
int retval = gethostname(name, len);
LOG_DEVEL(LOG_LEVEL_TRACE, "g_gethostname(%s, %d) returned %d", name, len, retval);
return retval;
}

static unsigned char g_reverse_byte[0x100] =
Expand Down
2 changes: 1 addition & 1 deletion common/os_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ int g_setlogin(const char *name);
int g_set_allusercontext(int uid);
#endif
int g_waitchild(struct exit_status *e);
int g_waitpid(int pid);
int g_waitpid(int pid, int *stat_loc, int options);
struct exit_status g_waitpid_status(int pid);
/*
* Sets the process group ID of the indicated process to the specified value.
Expand Down
Loading