Skip to content

Commit e0634b4

Browse files
committed
Take up openkal 0.11's unit: a handle the caller holds, not a flag
The identity is established at the first start --- the first member forms the group and its identifier is reported --- so nothing has to be remembered and no registry appears. `kal_process_terminate' is one program again; the unit has its own operations.
1 parent 8d09318 commit e0634b4

1 file changed

Lines changed: 32 additions & 20 deletions

File tree

src/process.cpp

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ struct vector {
5656
};
5757

5858
constexpr okm_long nr_fchdir = 13;
59-
// openkal 0.11: a started program that forms a job of its own.
59+
// openkal 0.11: the unit a started program joins.
6060
constexpr okm_long nr_setpgid = 82;
61-
constexpr okm_long nr_getpgid = 151;
61+
6262

6363
} // namespace
6464

@@ -100,8 +100,7 @@ int kal_process_spawn(const kal_spawn* how,
100100
// outright, and what this system offers instead is a WATCH, which needs a
101101
// live context to notice. Composing it would move the defect from "refused"
102102
// to "works except when it matters".
103-
constexpr kal_uintptr can = KAL_SPAWN_OWN_JOB;
104-
if (how->flags & ~can) return kal_err_not_supported;
103+
if (how->flags != 0) return kal_err_not_supported;
105104

106105
okm::terminated p(path, path_len);
107106
if (!p.ok) return kal_err_invalid;
@@ -143,7 +142,11 @@ int kal_process_spawn(const kal_spawn* how,
143142
const okm_long ou = streams ? static_cast<okm_long>(streams->out.h) : 0;
144143
const okm_long er = streams ? static_cast<okm_long>(streams->err.h) : 0;
145144

146-
const bool job = (how->flags & KAL_SPAWN_OWN_JOB) != 0;
145+
// ⭐ The unit, named here by a process group --- which is to say by whichever
146+
// program formed it first. Zero for the first member; a later one is given
147+
// the number to join.
148+
const okm_long join = how->job ? static_cast<okm_long>(how->job->h) : 0;
149+
const bool unit = how->job != nullptr;
147150

148151
bool is_duplicate = false;
149152
const okm_long child = okm::duplicate(is_duplicate);
@@ -167,14 +170,18 @@ int kal_process_spawn(const kal_spawn* how,
167170
// is named from, so this no longer has to serve both.
168171
okm::sys(nr_fchdir, w);
169172

170-
if (job) okm::sys(nr_setpgid, 0, 0);
173+
if (unit) okm::sys(nr_setpgid, 0, join);
171174

172175
okm::sys(okm::nr_execve, reinterpret_cast<okm_long>(whole),
173176
reinterpret_cast<okm_long>(args.slots),
174177
reinterpret_cast<okm_long>(envs.slots));
175178
for (;;) okm::sys(okm::nr_exit, 127);
176179
}
177180

181+
// Written only after the start succeeded, and only when the unit was new:
182+
// the first member's identifier IS the group's.
183+
if (unit && join == 0) how->job->h = static_cast<kal_uintptr>(child);
184+
178185
*out = kal_process{ static_cast<kal_uintptr>(child) };
179186
return kal_ok;
180187
}
@@ -221,24 +228,29 @@ void kal_process_channel_close(kal_stream s) {
221228

222229
// Starting a program that receives exactly the directories named.
223230

224-
// ⭐ REACHES THE WHOLE JOB WHEN THERE IS ONE, AND THE HANDLE CARRIES NOTHING TO
225-
// SAY SO. A program started with KAL_SPAWN_OWN_JOB called `setpgid(0, 0)', so its
226-
// group identifier is its own; one started without it inherited this
227-
// implementation's, which is some other process. `getpgid(pid) == pid'
228-
// distinguishes them exactly.
229-
//
230-
// ⚠️ Without this the flag would do nothing a caller could see: forming the job
231-
// matters only because terminating then reaches what the started program itself
232-
// started.
231+
// One program, whatever unit it is in --- the unit has its own operation below,
232+
// so this one's meaning never turns on how the program was started.
233233
int kal_process_terminate(kal_process h) {
234234
if (h.h == 0) return kal_err_invalid;
235-
const okm_long pid = static_cast<okm_long>(h.h);
236-
const okm_long pgid = okm::sys(nr_getpgid, pid);
237-
const okm_long target = (!okm::failed(pgid) && pgid == pid) ? -pid : pid;
238-
const okm_long r = okm::sys(okm::nr_kill, target, 15 /* SIGTERM */);
235+
const okm_long r = okm::sys(okm::nr_kill, static_cast<okm_long>(h.h), 15 /* SIGTERM */);
236+
return okm::failed(r) ? okm::translate(r) : kal_ok;
237+
}
238+
239+
// Every program in the unit, including ones never held as a handle.
240+
//
241+
// ⚠️ A group is named by a process identifier, and those are reused: once the
242+
// program that formed it has ended and the numbers have wrapped, this can reach
243+
// a different group. That is what this system does, and it is recorded rather
244+
// than hidden.
245+
int kal_process_job_terminate(kal_job j) {
246+
if (j.h == 0) return kal_err_invalid;
247+
const okm_long r = okm::sys(okm::nr_kill, -static_cast<okm_long>(j.h), 15 /* SIGTERM */);
239248
return okm::failed(r) ? okm::translate(r) : kal_ok;
240249
}
241250

251+
// A group here is a number and not a resource, so there is nothing to release.
252+
void kal_process_job_close(kal_job) { }
253+
242254
// Releasing the handle does not affect the program. A program that has not been
243255
// waited for continues, and this environment collects it when the caller exits.
244256
void kal_process_close(kal_process) { }
@@ -250,6 +262,6 @@ kal_uintptr kal_process_props(void) { return
250262
KAL_PROCESS_PROP_TERMINATE | KAL_PROCESS_PROP_STREAM_PASSING
251263
| KAL_PROCESS_PROP_EXIT_STATUS
252264
| KAL_PROCESS_PROP_CHANNEL | KAL_PROCESS_PROP_GRANT_DIR
253-
| KAL_PROCESS_PROP_OWN_JOB; }
265+
| KAL_PROCESS_PROP_JOB; }
254266

255267
}

0 commit comments

Comments
 (0)