os.StartProcess equivalent for exec (without fork)?

1,021 views
Skip to first unread message

Caleb Spare

unread,
Aug 21, 2018, 3:50:23 AM8/21/18
to golang-nuts
I was recently trying to write a Go program that's something like chpst or setpriv: it execs another program with an altered process state by changing the user ID or modifying the ambient capabilities. (My program is Linux-specific.)

In Go, when you want to spawn another process (fork+exec in Posix-land) you have the option of a very high-level API in os/exec or a lower-level API in the form of os.StartProcess. But os.StartProcess still does a lot of work. In my program where I need to exec without forking, I did not have the benefit of either os/exec or os.StartProcess, and I ended up having to copy Linux-specific code from the syscall package here:


If I wanted to fork+exec, then I could've implemented my features easily by using the fields in the platform-specific syscall.SysProcAttr. However, because I wanted to exec only, no easy options were available to me, and my code ended up doing about a dozen raw syscalls, using runtime.LockOSThread, using unsafe, and being generally unpleasant.

My question is: would it make sense to add an API similar to os.StartProcess for exec-without-fork? For now I'm just wondering if there is any showstopper that makes this unreasonable; if there isn't then I'll file a proposal with more details.

Here are two potential problems that I considered:

1. Is exec-without-fork fundamentally at odds with Go and its runtime somehow, like fork-without-exec is? I don't see why that would be the case.
2. Is the concept of exec-without-fork incoherent on non-Posix systems? I mainly worry about Windows; after some brief googling it did seem like you can exec on Windows, though I admit the situation isn't at all clear to me.

So am I missing any reason why an os.StartProcess-like API for exec-ing would be untenable?

Thanks!
Caleb

Manlio Perillo

unread,
Aug 21, 2018, 6:06:15 PM8/21/18
to golang-nuts
On Tuesday, August 21, 2018 at 9:50:23 AM UTC+2, Caleb Spare wrote:
I was recently trying to write a Go program that's something like chpst or setpriv: it execs another program with an altered process state by changing the user ID or modifying the ambient capabilities. (My program is Linux-specific.)

In Go, when you want to spawn another process (fork+exec in Posix-land) you have the option of a very high-level API in os/exec or a lower-level API in the form of os.StartProcess. But os.StartProcess still does a lot of work. In my program where I need to exec without forking, I did not have the benefit of either os/exec or os.StartProcess, and I ended up having to copy Linux-specific code from the syscall package here:


If I wanted to fork+exec, then I could've implemented my features easily by using the fields in the platform-specific syscall.SysProcAttr. However, because I wanted to exec only, no easy options were available to me, and my code ended up doing about a dozen raw syscalls, using runtime.LockOSThread, using unsafe, and being generally unpleasant.

My question is: would it make sense to add an API similar to os.StartProcess for exec-without-fork? For now I'm just wondering if there is any showstopper that makes this unreasonable; if there isn't then I'll file a proposal with more details.

Here are two potential problems that I considered:

1. Is exec-without-fork fundamentally at odds with Go and its runtime somehow, like fork-without-exec is? I don't see why that would be the case.

fork without exec simply does not work with multithreading programs:

Also, fork is not supported on Windows (well, AFAIK it can be implemented but it is an hack).

2. Is the concept of exec-without-fork incoherent on non-Posix systems? I mainly worry about Windows; after some brief googling it did seem like you can exec on Windows, though I admit the situation isn't at all clear to me.


exec is not supported on Windows.
 
 
So am I missing any reason why an os.StartProcess-like API for exec-ing would be untenable?

Thanks!
Caleb


Manlio 

Manlio Perillo

unread,
Aug 21, 2018, 6:09:25 PM8/21/18
to golang-nuts
On Wednesday, August 22, 2018 at 12:06:15 AM UTC+2, Manlio Perillo wrote:
On Tuesday, August 21, 2018 at 9:50:23 AM UTC+2, Caleb Spare wrote:

> [...]
 
 
Here are two potential problems that I considered:

1. Is exec-without-fork fundamentally at odds with Go and its runtime somehow, like fork-without-exec is? I don't see why that would be the case.

fork without exec simply does not work with multithreading programs:

Also, fork is not supported on Windows (well, AFAIK it can be implemented but it is an hack).

2. Is the concept of exec-without-fork incoherent on non-Posix systems? I mainly worry about Windows; after some brief googling it did seem like you can exec on Windows, though I admit the situation isn't at all clear to me.


exec is not supported on Windows.
 

For low level UNIX specific API, see syscall.Exec.

> [...]

Manlio

Ian Lance Taylor

unread,
Aug 21, 2018, 6:15:47 PM8/21/18
to Caleb Spare, golang-nuts
I think that API would be very rarely used. The number of programs
that need to exec-without-fork, and that can not simply use
syscall.Exec, is very small. Those programs tend to be highly
system-specific. I don't think such an API would be appropriate for
the os package.

Ian

Caleb Spare

unread,
Aug 21, 2018, 8:35:53 PM8/21/18
to Manlio Perillo, golang-nuts
On Tue, Aug 21, 2018 at 3:06 PM Manlio Perillo <manlio....@gmail.com> wrote:
On Tuesday, August 21, 2018 at 9:50:23 AM UTC+2, Caleb Spare wrote:
I was recently trying to write a Go program that's something like chpst or setpriv: it execs another program with an altered process state by changing the user ID or modifying the ambient capabilities. (My program is Linux-specific.)

In Go, when you want to spawn another process (fork+exec in Posix-land) you have the option of a very high-level API in os/exec or a lower-level API in the form of os.StartProcess. But os.StartProcess still does a lot of work. In my program where I need to exec without forking, I did not have the benefit of either os/exec or os.StartProcess, and I ended up having to copy Linux-specific code from the syscall package here:


If I wanted to fork+exec, then I could've implemented my features easily by using the fields in the platform-specific syscall.SysProcAttr. However, because I wanted to exec only, no easy options were available to me, and my code ended up doing about a dozen raw syscalls, using runtime.LockOSThread, using unsafe, and being generally unpleasant.

My question is: would it make sense to add an API similar to os.StartProcess for exec-without-fork? For now I'm just wondering if there is any showstopper that makes this unreasonable; if there isn't then I'll file a proposal with more details.

Here are two potential problems that I considered:

1. Is exec-without-fork fundamentally at odds with Go and its runtime somehow, like fork-without-exec is? I don't see why that would be the case.

fork without exec simply does not work with multithreading programs:

I understand that. I was asking if there's a similar problem for exec-without-fork, and it sounds like there's not.

Also, fork is not supported on Windows (well, AFAIK it can be implemented but it is an hack).

2. Is the concept of exec-without-fork incoherent on non-Posix systems? I mainly worry about Windows; after some brief googling it did seem like you can exec on Windows, though I admit the situation isn't at all clear to me.


exec is not supported on Windows.

Yeah, Windows and other less-posix-y platforms seem to be the main problem here.
 
 
So am I missing any reason why an os.StartProcess-like API for exec-ing would be untenable?

Thanks!
Caleb


Manlio 

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Caleb Spare

unread,
Aug 21, 2018, 8:37:18 PM8/21/18
to Manlio Perillo, golang-nuts
Yes, I'm using syscall.Exec (actually, unix.Exec) already. My question was about avoiding all the awful syscall boilerplate that os.StartProcess (really, syscall.StartProcess) takes care of.

> [...]

Manlio

Caleb Spare

unread,
Aug 21, 2018, 9:08:42 PM8/21/18
to Ian Taylor, golang-nuts
I *can* use syscall.Exec (really unix.Exec), and I am right now. The
question was about avoiding all the boilerplate syscalls that go along
with it that {os,syscall}.StartProcess take care of.

Perhaps it would indeed be rarely used. I've wanted it at least twice,
personally.

It seems like the main problem is that exec isn't exactly a
well-defined cross-platform concept. Aram suggested that instead of os
it should be in syscall, though I suppose x/sys/unix is more
appropriate these days.

I'll try implementing this function in my own package first. Thanks
for the feedback.
Reply all
Reply to author
Forward
0 new messages