[pty] Split chfunc
into functions in steps
- start a new session - obtain the new controlling terminal - drop privileges - finally, `exec`
This commit is contained in:
parent
88355da673
commit
0bc71828b5
@ -92,9 +92,13 @@ struct pty_info {
|
|||||||
|
|
||||||
static void getDevice(int*, int*, char [DEVICELEN], int);
|
static void getDevice(int*, int*, char [DEVICELEN], int);
|
||||||
|
|
||||||
|
static int start_new_session(char *errbuf, size_t errbuf_len);
|
||||||
|
static int obtain_ctty(int master, int slave, const char *slavename, char *errbuf, size_t errbuf_len);
|
||||||
|
static int drop_privilige(char *errbuf, size_t errbuf_len);
|
||||||
|
|
||||||
struct child_info {
|
struct child_info {
|
||||||
int master, slave;
|
int master, slave;
|
||||||
char *slavename;
|
const char *slavename;
|
||||||
VALUE execarg_obj;
|
VALUE execarg_obj;
|
||||||
struct rb_execarg *eargp;
|
struct rb_execarg *eargp;
|
||||||
};
|
};
|
||||||
@ -102,18 +106,34 @@ struct child_info {
|
|||||||
static int
|
static int
|
||||||
chfunc(void *data, char *errbuf, size_t errbuf_len)
|
chfunc(void *data, char *errbuf, size_t errbuf_len)
|
||||||
{
|
{
|
||||||
struct child_info *carg = data;
|
const struct child_info *carg = data;
|
||||||
int master = carg->master;
|
int master = carg->master;
|
||||||
int slave = carg->slave;
|
int slave = carg->slave;
|
||||||
|
const char *slavename = carg->slavename;
|
||||||
|
|
||||||
|
if (start_new_session(errbuf, errbuf_len))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (obtain_ctty(master, slave, slavename, errbuf, errbuf_len))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (drop_privilige(errbuf, errbuf_len))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return rb_exec_async_signal_safe(carg->eargp, errbuf, errbuf_len);
|
||||||
|
}
|
||||||
|
|
||||||
#define ERROR_EXIT(str) do { \
|
#define ERROR_EXIT(str) do { \
|
||||||
strlcpy(errbuf, (str), errbuf_len); \
|
strlcpy(errbuf, (str), errbuf_len); \
|
||||||
return -1; \
|
return -1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set free from process group and controlling terminal
|
* Set free from process group and controlling terminal
|
||||||
*/
|
*/
|
||||||
|
static int
|
||||||
|
start_new_session(char *errbuf, size_t errbuf_len)
|
||||||
|
{
|
||||||
#ifdef HAVE_SETSID
|
#ifdef HAVE_SETSID
|
||||||
(void) setsid();
|
(void) setsid();
|
||||||
#else /* HAS_SETSID */
|
#else /* HAS_SETSID */
|
||||||
@ -135,17 +155,22 @@ chfunc(void *data, char *errbuf, size_t errbuf_len)
|
|||||||
# endif /* SETPGRP_VOID */
|
# endif /* SETPGRP_VOID */
|
||||||
# endif /* HAVE_SETPGRP */
|
# endif /* HAVE_SETPGRP */
|
||||||
#endif /* HAS_SETSID */
|
#endif /* HAS_SETSID */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* obtain new controlling terminal
|
* obtain new controlling terminal
|
||||||
*/
|
*/
|
||||||
|
static int
|
||||||
|
obtain_ctty(int master, int slave, const char *slavename, char *errbuf, size_t errbuf_len)
|
||||||
|
{
|
||||||
#if defined(TIOCSCTTY)
|
#if defined(TIOCSCTTY)
|
||||||
close(master);
|
close(master);
|
||||||
(void) ioctl(slave, TIOCSCTTY, (char *)0);
|
(void) ioctl(slave, TIOCSCTTY, (char *)0);
|
||||||
/* errors ignored for sun */
|
/* errors ignored for sun */
|
||||||
#else
|
#else
|
||||||
close(slave);
|
close(slave);
|
||||||
slave = rb_cloexec_open(carg->slavename, O_RDWR, 0);
|
slave = rb_cloexec_open(slavename, O_RDWR, 0);
|
||||||
if (slave < 0) {
|
if (slave < 0) {
|
||||||
ERROR_EXIT("open: pty slave");
|
ERROR_EXIT("open: pty slave");
|
||||||
}
|
}
|
||||||
@ -156,14 +181,20 @@ chfunc(void *data, char *errbuf, size_t errbuf_len)
|
|||||||
dup2(slave,1);
|
dup2(slave,1);
|
||||||
dup2(slave,2);
|
dup2(slave,2);
|
||||||
if (slave < 0 || slave > 2) (void)!close(slave);
|
if (slave < 0 || slave > 2) (void)!close(slave);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
drop_privilige(char *errbuf, size_t errbuf_len)
|
||||||
|
{
|
||||||
#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID)
|
#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID)
|
||||||
if (seteuid(getuid())) ERROR_EXIT("seteuid()");
|
if (seteuid(getuid())) ERROR_EXIT("seteuid()");
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
return rb_exec_async_signal_safe(carg->eargp, errbuf, sizeof(errbuf_len));
|
|
||||||
#undef ERROR_EXIT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef ERROR_EXIT
|
||||||
|
|
||||||
static void
|
static void
|
||||||
establishShell(int argc, VALUE *argv, struct pty_info *info,
|
establishShell(int argc, VALUE *argv, struct pty_info *info,
|
||||||
char SlaveName[DEVICELEN])
|
char SlaveName[DEVICELEN])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user