Informix Error -10
-10 No children.
An operating-system error code with the meaning shown was unexpectedly returned to the database server. Look for other operating-system error messages that might give more information. If the error recurs, note all circumstances and contact IBM Informix Technical Support.
Oninit® Troubleshooting Guidance
This is an operating-system error number, not an Informix diagnosis.
The same errno is returned by many different operations, so on its own it says what the operating system refused, not what Informix was trying to do. Informix will usually have reported a more specific error alongside it — in the message log, in the SQL or ISAM error pair, or in the accompanying assert failure — and that error normally defines the real cause far more precisely than the errno does. Find it before diagnosing from this number alone.
This matters less than it used to. Later versions of the engine trap many of these conditions and report them as specific Informix errors naming the operation, the object and the context, so a bare errno in this range is increasingly a sign of an older version, an unusual code path, or a failure early in startup before the better reporting is available. If you are seeing one on a current version, the more specific error is worth looking for even harder.
Operating-System Meaning
errno 10 is ECHILD — No child processes. A wait(), waitpid() or equivalent was called and there was no child left to wait for.
The important consequence:
ECHILDusually means the child ran and finished normally. Someone else collected it first.
Unlike most errors in this range, -10 rarely means the work failed. It means the reporting failed. A program forked a child, the child did its job and exited, something reaped it, and the program's own wait() then found nothing and returned an error. The caller concludes the command failed. It did not.
That inversion — a failure code for a successful operation — is what makes this error expensive. Scripts retry work that already happened, backups get re-run, and in the worst cases a "failed" step is repeated against data it already processed.
There are two ways the child disappears before the caller can reap it:
SIGCHLDis set toSIG_IGN. The kernel then reaps children automatically and they never become zombies, so there is nothing forwait()to find. This is explicit behaviour, not a race.- Something else reaped it first — typically a
SIGCHLDhandler installed elsewhere in the program, competing with await()in the main flow.
What This Means in Informix
The case that matters is SYSTEM in SPL, RUN in 4GL, and system() or popen() in ESQL/C — that is, in client programs.
Not in a C UDR.
system(),popen()andfork()are unsafe inside a user-defined routine and should not appear there at all. A UDR runs inside a virtual processor, sharing the server's address space, shared-memory attachments and file descriptors; forking duplicates all of that, and a blocking call stalls every thread scheduled on that VP — not just the calling session. AnECHILDis the least of the problems such code will cause. Where a UDR genuinely needs to trigger external work, hand the work to something outside the server rather than spawning it from inside, and review the VP class the routine runs under before doing anything that can block.
In client programs, all of these fork a child, run a command, and wait for it. If the surrounding application has set SIGCHLD to SIG_IGN, or installed a handler that reaps, then:
- the command runs correctly and completes;
- the
wait()insidesystem()returnsECHILD; system()returns -1;- the application concludes the command failed.
In 4GL this surfaces as RUN … RETURNING status reporting a non-zero status for a program that plainly did its work — the file was written, the report printed, the script completed. The status is wrong, not the command.
Other origins:
- Shell wrappers calling
waitwith no outstanding background jobs - Backup wrappers around
ontapeoronbarthat fork a child and also install a reaper ALARMPROGRAMand event scripts whose parent handlesSIGCHLD- Storage-manager integrations spawning helper processes
- Double reaping in any long-running daemon that both handles
SIGCHLDand callswait()directly
Common Causes
SIGCHLDset toSIG_IGNanywhere in a program that also usessystem(),popen()orRUN.- A
SIGCHLDhandler competing with an explicitwait()elsewhere in the same program. wait()called when nothing was forked — a script path where the background job was skipped or already collected.- The child was reaped by an outer process in a nested wrapper arrangement.
Diagnostic Checks
First establish whether the work actually happened. This comes before anything technical — if the command succeeded, you are chasing a reporting defect, not a failure:
ls -l /path/to/expected/output # did the file appear?
tail -50 /path/to/command.log # did the command log success?
onstat -m # did the backup/archive register?
For a backup in particular, confirm against the engine rather than the wrapper's exit code:
onstat -g arc
tail -100 "$BAR_ACT_LOG"
onstat -g arc reports archive status per dbspace — the level of the last archive, when it was performed, and the log position at the time. That is the engine's own record, and it settles the question a wrapper's exit code cannot: whether the archive actually happened.
Then confirm the mechanism. strace shows the wait4 returning ECHILD and, just above it, the child exiting normally:
strace -f -e trace=clone,execve,wait4,exit_group -p "$pid" 2>&1 | tail -40
# look for: wait4(-1, ...) = -1 ECHILD (No child processes)
# Solaris / AIX
truss -f -p "$pid" 2>&1 | grep -E 'wait|ECHILD'
Check the SIGCHLD disposition of the running process — SIG_IGN here is the answer:
grep -E 'SigIgn|SigCgt|SigBlk' /proc/"$pid"/status
# SIGCHLD is signal 17 on Linux; bit 17 of the mask (0x0000000000010000)
Search the application for both patterns:
grep -rn -E 'SIGCHLD|SIGCLD' /path/to/src
grep -rn -E 'signal\s*\(\s*SIGCHLD\s*,\s*SIG_IGN' /path/to/src
grep -rn -E 'SA_NOCLDWAIT' /path/to/src
grep -rn -E '\bwait\s*\(|\bwaitpid\s*\(|\bsystem\s*\(|\bpopen\s*\(' /path/to/src
Both a SIG_IGN (or SA_NOCLDWAIT) and a system()/popen() in the same program is the diagnosis.
In shell wrappers, look for wait on a path where nothing was backgrounded:
grep -n -E '^\s*wait\b|&\s*$' /path/to/wrapper.sh
Solutions / Resolution
- Verify the work before treating this as a failure. Most -10 occurrences are a successful command reported badly, and re-running is the wrong response — particularly for backups and for anything that mutates data.
- Do not set
SIGCHLDtoSIG_IGNin a program that usessystem(),popen()orRUN. The two are incompatible by design. - Save and restore the disposition around the call where a program genuinely needs to ignore
SIGCHLDelsewhere:struct sigaction old, act; act.sa_handler = SIG_DFL; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, &old); rc = system(cmd); /* now reapable */ sigaction(SIGCHLD, &old, NULL); - Have exactly one reaper. If a handler collects children, the main flow must not also call
wait(); if the main flow waits, the handler must not reap. - Use
waitpid()with a specific PID rather thanwait(-1)where several things are being managed, so one consumer cannot take another's child. - Judge success by effect, not by exit status, in the affected code path — check that the output file exists, the archive registered, the rows landed.
- In shell wrappers, guard the
wait:if jobs %% >/dev/null 2>&1; then wait; fi
Examples
A 4GL RUN that worked but reported failure
RUN "/informix/scripts/export_daily.sh" RETURNING status
IF status != 0 THEN
CALL errorlog("export failed")
END IF
$ ls -l /informix/export/daily_20260909.unl
-rw-rw---- 1 ifxprod ifxprod 48211904 Sep 9 02:14 daily_20260909.unl
The export ran and produced 48 MB of output. status is non-zero because the wait() inside RUN found no child to collect — something in the program's startup set SIGCHLD to be ignored. The error handling then logs a failure and, in many implementations, re-runs the export.
SIG_IGN and system() in the same program
$ grep -rn SIGCHLD src/
src/init.c:88: signal(SIGCHLD, SIG_IGN);
$ grep -rn 'system(' src/
src/report.c:214: rc = system(cmd);
Those two lines are the whole fault. init.c asks the kernel to reap children automatically; report.c then expects to reap one itself. Every system() call in this program returns -1 regardless of what the command did.
$ strace -f -e trace=wait4 -p 7712 2>&1 | tail -2
[pid 7712] wait4(-1, 0x7ffd4a1c, 0, NULL) = -1 ECHILD (No child processes)
A wrapper that waits with nothing running
#!/bin/bash
if [ "$FULL_BACKUP" = "Y" ]; then
ontape -s -L 0 &
fi
wait # -10 when FULL_BACKUP is not Y
echo "backup step complete rc=$?"
On the branch where nothing was backgrounded, wait has no children and reports an error, which the script then propagates as a backup failure. Guarding the wait — or structuring the branch so the wait only runs where a job was started — removes it.
Platform Note
errno 10 is ECHILD on Linux, AIX, Solaris, HP-UX and the BSD-derived systems — stable, so the number is reliable.
The SIGCHLD/SIG_IGN behaviour is specified by POSIX and consistent in effect across these platforms, but the older SIGCLD name and its System V semantics differ historically, and code carried from an old System V base can behave differently after a port. Where a program sets the disposition, prefer sigaction() with explicit flags over signal(), and check for SA_NOCLDWAIT as well as SIG_IGN — it produces the same result by a different route and is easy to miss when reading the source.
Related Errors / Related Topics
- -4 — Interrupted system call. The other error that points at a program's signal handling rather than at its SQL, and frequently found in the same code.
- -3 — No such process, the equivalent condition for signalling rather than waiting: the target is already gone.
- -9 — Bad file descriptor, also typically an application lifecycle defect rather than an environmental one.
If -10 appears in an estate, the code path that reports it is worth auditing for what it does next. A successful operation reported as a failure is harmless until something retries it, and a repeated backup is a great deal more forgiving than a repeated data load.