Florian Lohoff <flo@rfc822.org>
D.J. Barrow <djbarrow@de.ibm.com>
Topi Miettinen <Topi.Miettinen@nic.fi>
- Gaël Roualland <gael.roualland@dial.oleane.com>
+ Gaël Roualland <gael.roualland@iname.com>
* file.c: rename dirent64 struct to kernel_dirent64 so things compile
again with newer libcs
* test/clone.c: improve our testcase a bit
+ * Merge another patch from Gäel Roualland with FreeBSD updates
2000-09-01 Wichert Akkerman <wakkerma@debian.org>
#define PIOCWSTOP PIOCWAIT
#define PR_WHY why
#define PR_WHAT val
-#define PR_FLAGS flags
+#define PR_FLAGS state
/* from /usr/src/sys/miscfs/procfs/procfs_vnops.c,
status.state = 0 for running, 1 for stopped */
+#define PR_ASLEEP 1
#define PR_SYSENTRY S_SCE
#define PR_SYSEXIT S_SCX
#define PR_SIGNALLED S_SIG
else
tprintf("[%u, %u]", fds[0], fds[1]);
}
-#elif defined(SPARC) || defined(SVR4)
+#elif defined(SPARC) || defined(SVR4) || defined(FREEBSD)
if (exiting(tcp))
tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
#endif
else
tprintf(", [%u, %u]", fds[0], fds[1]);
#endif /* LINUX */
-#ifdef SUNOS4
+#if defined(SUNOS4) || defined(SVR4) || defined(FREEBSD)
tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
-#endif /* SUNOS4 */
-#ifdef SVR4
- tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
-#endif /* SVR4 */
+#endif /* SUNOS4 || SVR4 || FREEBSD */
}
return 0;
}
fprintf(stderr, "sys_fork: tcb table full\n");
return 0;
}
- if (proc_open(tcpchild, 1) < 0)
+ if (proc_open(tcpchild, 2) < 0)
droptcb(tcpchild);
}
return 0;
perror("strace: PIOCSTATUS");
return -1;
}
-#ifndef FREEBSD
if (tcp->status.PR_FLAGS & PR_ASLEEP)
-#else
- if (tcp->status.state == 1)
-#endif
break;
}
}
}
#else /* FREEBSD */
} else {
- /* little hack to show the current syscall */
- IOCTL_STATUS(tcp);
- tcp->flags &= ~TCB_INSYSCALL;
- tcp->status.why = PR_SYSENTRY;
- trace_syscall(tcp);
+ if (attaching < 2) {
+ /* We are attaching to an already running process.
+ * Try to figure out the state of the process in syscalls,
+ * to handle the first event well.
+ * This is done by having a look at the "wchan" property of the
+ * process, which tells where it is stopped (if it is). */
+ FILE * status;
+ char wchan[20]; /* should be enough */
+
+ sprintf(proc, "/proc/%d/status", tcp->pid);
+ status = fopen(proc, "r");
+ if (status &&
+ (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d"
+ "%*d,%*d %*d,%*d %19s", wchan) == 1) &&
+ strcmp(wchan, "nochan") && strcmp(wchan, "spread") &&
+ strcmp(wchan, "stopevent")) {
+ /* The process is asleep in the middle of a syscall.
+ Fake the syscall entry event */
+ tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP);
+ tcp->status.PR_WHY = PR_SYSENTRY;
+ trace_syscall(tcp);
+ }
+ if (status)
+ fclose(status);
+ } /* otherwise it's a fork being followed */
}
#endif /* FREEBSD */
#ifndef HAVE_POLLABLE_PROCFS
}
}
+#ifdef FREEBSD
+ if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) {
+ /* discard first event for a syscall we never entered */
+ IOCTL (tcp->pfd, PIOCRUN, 0);
+ continue;
+ }
+#endif
+
/* clear the just started flag */
tcp->flags &= ~TCB_STARTUP;
#ifndef FREEBSD
struct termio tio;
#else
- struct termios tio;
+ #define TCGETS TIOCGETA
+ #define TCSETS TIOCSETA
+ #define TCSETSW TIOCSETAW
+ #define TCSETSF TIOCSETAF
#endif
struct winsize ws;
#ifdef TIOCGSIZE
return 0;
if (abbrev(tcp)) {
tprintf(", {");
+#ifndef FREEBSD
printxval(baud_options, tios.c_cflag & CBAUD, "B???");
+#else
+ printxval(baud_options, tios.c_ispeed, "B???");
+ if (tios.c_ispeed != tios.c_ospeed) {
+ tprintf(" (in)");
+ printxval(baud_options, tios.c_ospeed, "B???");
+ tprintf(" (out)");
+ }
+#endif
tprintf(" %sopost %sisig %sicanon %secho ...}",
(tios.c_oflag & OPOST) ? "" : "-",
(tios.c_lflag & ISIG) ? "" : "-",
(long) tios.c_iflag, (long) tios.c_oflag);
tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
(long) tios.c_cflag, (long) tios.c_lflag);
-#ifndef SVR4
+#if !defined(SVR4) && !defined(FREEBSD)
tprintf("c_line=%u, ", tios.c_line);
#endif
if (!(tios.c_lflag & ICANON))