/* waitpid tarafından döndürülen süreç kimliğinin durumunu
saklayalım. İstenen yapıldıysa 0 yoksa sıfırdan farklı
bir değerle dönelim.. */
int
mark_process_status (pid_t pid, int status)
{
job *j;
process *p;
if (pid > 0)
{
/* Süreç için kaydı güncelleyelim. */
for (j = first_job; j; j = j->next)
for (p = j->first_process; p; p = p->next)
if (p->pid == pid)
{
p->status = status;
if (WIFSTOPPED (status))
p->stopped = 1;
else
{
p->completed = 1;
if (WIFSIGNALED (status))
fprintf (stderr, "%d: %d sinyali ile sonlandırıldı.\n",
(int) pid, WTERMSIG (p->status));
}
return 0;
}
fprintf (stderr, "%d kimlikli bir süreç yok.\n", pid);
return -1;
}
else if (pid == 0 || errno == ECHILD)
/* Rapor verecek süreç yok. */
return -1;
else {
/* Diğer tuhaf hatalar. */
perror ("waitpid");
return -1;
}
}
/* Süreçleri beklemeden durum bilgilerinin varlığını sınayalım. */
void
update_status (void)
{
int status;
pid_t pid;
do
pid = waitpid (WAIT_ANY, &status, WUNTRACED|WNOHANG);
while (!mark_process_status (pid, status));
}
/* Belirtilen işteki tüm süreçleri beklerken
durum bilgilerinin varlığını sınayalım. */
void
wait_for_job (job *j)
{
int status;
pid_t pid;
do
pid = waitpid (WAIT_ANY, &status, WUNTRACED);
while (!mark_process_status (pid, status)
&& !job_is_stopped (j)
&& !job_is_completed (j));
}
/* İş durumu ile ilgili bilgileri kullanıcıya sunmak için biçimleyelim. */
void
format_job_info (job *j, const char *status)
{
fprintf (stderr, "%ld (%s): %s\n", (long)j->pgid, status, j->command);
}
/* Durmuş ya da sonlandılılmış işler hakkında kullanıcıyı uyaralım.
Sonlanmış işleri etkin iş listesinden kaldıralım. */
void
do_job_notification (void)
{
job *j, *jlast, *jnext;
process *p;
/* Alt sürecin durum bilgisini güncelleyelim. */
update_status ();
jlast = NULL;
for (j = first_job; j; j = jnext)
{
jnext = j->next;
/* Tüm süreçler tamamlanmışsa, kullanıcıya işin tamamlandığını
bildirelim ve onu etkin işler listesinden silelim. */
if (job_is_completed (j)) {
format_job_info (j, "iş tamamdır");
if (jlast)
jlast->next = jnext;
else
first_job = jnext;
free_job (j);
}
/* Duran işleri kullanıcıya bildirelim ve
bunu bir daha yapmamak için onları imleyelim. */
else if (job_is_stopped (j) && !j->notified) {
format_job_info (j, "iş durdu");
j->notified = 1;
jlast = j;
}
/* Hala sürmekte olan işler için bir şey söylemek gerekmez. */
else
jlast = j;
}
}