+/* Script handling: */
+
+static void device_script_cfgfunc(const char *section,const char *key,const char *value)
+{
+ setenv(key,value,1/*overwrite*/); /* errors ignored */
+}
+
+static int device_script(int fd, const char *section)
+{
+pid_t pid;
+const char *scriptname = CFG_Get(CFG_Info, "global", section);
+
+ if (!scriptname)
+ return(0);
+
+ errno=0;
+ switch ((pid=fork())) {
+ case -1:
+ fprintf(stderr,_("device_script(\"%s\"): fork() failure: %s!\n"),scriptname,strerror(errno));
+ return(-1);
+
+ default: { /* parent */
+int status;
+ if (pid==waitpid(pid,&status,0/*options*/) && WIFEXITED(status) && !WEXITSTATUS(status))
+ return(0);
+ fprintf(stderr,_("device_script(\"%s\"): child script failure: %s, exit code=%d\n"),scriptname,
+ (WIFEXITED(status) ? _("normal exit") : _("abnormal exit")),
+ (WIFEXITED(status) ? WEXITSTATUS(status) : -1));
+ errno=EIO;
+ return(-1);
+ }
+
+ case 0: { /* child */
+ CFG_GetForeach(CFG_Info,section,device_script_cfgfunc);
+ errno=0;
+ if (0!=dup2(fd,0) || 1!=dup2(fd,1) || close(fd)) {
+ fprintf(stderr,_("device_script(\"%s\"): file descriptor prepare: %s\n"),scriptname,strerror(errno));
+ _exit(-1);
+ }
+ /* FIXME: close all open descriptors - how to track them?
+ */
+ execl("/bin/sh","sh","-c",scriptname,NULL);
+ fprintf(stderr,_("device_script(\"%s\"): execute script: %s\n"),scriptname,strerror(errno));
+ _exit(-1);
+ /* NOTREACHED */
+ }
+ }
+ /* NOTREACHED */
+}
+
+int serial_close_all_openfds[0x10]; /* -1 when entry not used, fd otherwise */
+int serial_close(int __fd);
+
+static void serial_close_all(void)
+{
+ int i;
+
+ dprintf("serial_close_all() executed\n");
+ for (i=0;i<ARRAY_LEN(serial_close_all_openfds);i++)
+ if (serial_close_all_openfds[i]!=-1)
+ serial_close(serial_close_all_openfds[i]);
+}
+
+static void unixserial_interrupted(int signo)
+{
+ exit(EXIT_FAILURE);
+ /* NOTREACHED */
+}
+