void rs_reportMsgReport ( rs_reportMsg reportMsg) { char buf[MAX_REPORT_SIZE]; int written; assert (reportMsg); written = snprintf (buf, MAX_REPORT_SIZE, "### Report Message ###\n" "Type : %s\n" "Context : %s\n" "File : %s\n" "Line : %d\n" "Code : %d\n" "Description : %s\n" "Domain : %s\n" "Node : %s\n" "Process : %s\n" "Thread : %s\n" "Timestamp : %d.%9.9d\n", reportTypeText[reportMsg->reportType], reportMsg->reportContext, reportMsg->fileName, reportMsg->lineNo, reportMsg->reportCode, reportMsg->description, reportMsg->domain, reportMsg->node, reportMsg->process, reportMsg->thread, reportMsg->dateTime.seconds, reportMsg->dateTime.nanoseconds); os_write(fileno(stdout), buf, written); }
_WCRTLINK int write( int handle, const void *buffer, unsigned len ) #endif /**********************************************************************/ { unsigned iomode_flags; char *buf; unsigned buf_size; unsigned len_written, i, j; #if defined(__NT__) HANDLE h; LONG cur_ptr_low; LONG cur_ptr_high; DWORD rc1; #else tiny_ret_t rc1; #endif int rc2; __handle_check( handle, -1 ); iomode_flags = __GetIOMode( handle ); if( iomode_flags == 0 ) { #if defined(__WINDOWS__) || defined(__WINDOWS_386__) // How can we write to the handle if we never opened it? JBS return( _lwrite( handle, buffer, len ) ); #else __set_errno( EBADF ); return( -1 ); #endif } if( !(iomode_flags & _WRITE) ) { __set_errno( EACCES ); /* changed from EBADF to EACCES 23-feb-89 */ return( -1 ); } #if defined(__NT__) h = __getOSHandle( handle ); #endif // put a semaphore around our writes _AccessFileH( handle ); if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) ) { #if defined(__NT__) if( GetFileType( h ) == FILE_TYPE_DISK ) { cur_ptr_low = 0; cur_ptr_high = 0; rc1 = SetFilePointer( h, cur_ptr_low, &cur_ptr_high, FILE_END ); if( rc1 == INVALID_SET_FILE_POINTER ) { // this might be OK so if( GetLastError() != NO_ERROR ) { _ReleaseFileH( handle ); return( __set_errno_nt() ); } } } #elif defined(__OS2__) { unsigned long dummy; rc1 = DosChgFilePtr( handle, 0L, SEEK_END, &dummy ); // should we explicitly ignore ERROR_SEEK_ON_DEVICE here? } #else rc1 = TinySeek( handle, 0L, SEEK_END ); #endif #if !defined(__NT__) if( TINY_ERROR( rc1 ) ) { _ReleaseFileH( handle ); return( __set_errno_dos( TINY_INFO( rc1 ) ) ); } #endif } len_written = 0; rc2 = 0; // Pad the file with zeros if necessary if( iomode_flags & _FILEEXT ) { // turn off file extended flag __SetIOMode_nogrow( handle, iomode_flags&(~_FILEEXT) ); // It is not required to pad a file with zeroes on an NTFS file system; // unfortunately it is required on FAT (and probably FAT32). (JBS) rc2 = zero_pad( handle ); } if( rc2 == 0 ) { if( iomode_flags & _BINARY ) { /* if binary mode */ rc2 = os_write( handle, buffer, len, &len_written ); /* end of binary mode part */ } else { /* text mode */ i = stackavail(); if( i < 0x00b0 ) { __STKOVERFLOW(); /* not enough stack space */ } buf_size = 512; if( i < (512 + 48) ) { buf_size = 128; } #if defined(__AXP__) || defined(__PPC__) buf = alloca( buf_size ); #else buf = __alloca( buf_size ); #endif j = 0; for( i = 0; i < len; ) { if( ((const char*)buffer)[i] == '\n' ) { buf[j] = '\r'; ++j; if( j == buf_size ) { rc2 = os_write( handle, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } buf[j] = ((const char*)buffer)[i]; ++i; ++j; if( j == buf_size ) { rc2 = os_write( handle, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } if( j ) { rc2 = os_write( handle, buf, j, &i ); if( rc2 == ENOSPC ) { len_written += i; } else { len_written = len; } } /* end of text mode part */ } } _ReleaseFileH( handle ); if( rc2 == -1 ) { return( rc2 ); } else { return( len_written ); } }
int sandbox_write_state(struct sandbox_state *state, const char *fname) { struct sandbox_state_io *io; bool got_err; int size; int ret; int fd; /* Create a state FDT if we don't have one */ if (!state->state_fdt) { size = 0x4000; state->state_fdt = os_malloc(size); if (!state->state_fdt) { puts("No memory to create FDT\n"); return -ENOMEM; } ret = fdt_create_empty_tree(state->state_fdt, size); if (ret < 0) { printf("Cannot create empty state FDT: %s\n", fdt_strerror(ret)); ret = -EIO; goto err_create; } } /* Call all the state write funtcions */ got_err = false; io = ll_entry_start(struct sandbox_state_io, state_io); ret = 0; for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { ret = sandbox_write_state_node(state, io); if (ret == -EIO) break; else if (ret) got_err = true; } if (ret == -EIO) { printf("Could not write sandbox state\n"); goto err_create; } ret = fdt_pack(state->state_fdt); if (ret < 0) { printf("Cannot pack state FDT: %s\n", fdt_strerror(ret)); ret = -EINVAL; goto err_create; } size = fdt_totalsize(state->state_fdt); fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT); if (fd < 0) { printf("Cannot open sandbox state file '%s'\n", fname); ret = -EIO; goto err_create; } if (os_write(fd, state->state_fdt, size) != size) { printf("Cannot write sandbox state file '%s'\n", fname); ret = -EIO; goto err_write; } os_close(fd); debug("Wrote sandbox state to '%s'%s\n", fname, got_err ? " (with errors)" : ""); return 0; err_write: os_close(fd); err_create: os_free(state->state_fdt); return ret; }
static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, const void *rxp, void *txp, unsigned long flags) { struct sandbox_spi_flash *sbsf = dev_get_priv(dev); const uint8_t *rx = rxp; uint8_t *tx = txp; uint cnt, pos = 0; int bytes = bitlen / 8; int ret; debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state, sandbox_sf_state_name(sbsf->state), bytes); if ((flags & SPI_XFER_BEGIN)) sandbox_sf_cs_activate(dev); if (sbsf->state == SF_CMD) { /* Figure out the initial state */ ret = sandbox_sf_process_cmd(sbsf, rx, tx); if (ret) return ret; ++pos; } /* Process the remaining data */ while (pos < bytes) { switch (sbsf->state) { case SF_ID: { u8 id; debug(" id: off:%u tx:", sbsf->off); if (sbsf->off < IDCODE_LEN) { /* Extract correct byte from ID 0x00aabbcc */ id = sbsf->data->jedec >> (8 * (IDCODE_LEN - 1 - sbsf->off)); } else { id = 0; } debug("%d %02x\n", sbsf->off, id); tx[pos++] = id; ++sbsf->off; break; } case SF_ADDR: debug(" addr: bytes:%u rx:%02x ", sbsf->addr_bytes, rx[pos]); if (sbsf->addr_bytes++ < SF_ADDR_LEN) sbsf->off = (sbsf->off << 8) | rx[pos]; debug("addr:%06x\n", sbsf->off); if (tx) sandbox_spi_tristate(&tx[pos], 1); pos++; /* See if we're done processing */ if (sbsf->addr_bytes < SF_ADDR_LEN + sbsf->pad_addr_bytes) break; /* Next state! */ if (os_lseek(sbsf->fd, sbsf->off, OS_SEEK_SET) < 0) { puts("sandbox_sf: os_lseek() failed"); return -EIO; } switch (sbsf->cmd) { case CMD_READ_ARRAY_FAST: case CMD_READ_ARRAY_SLOW: sbsf->state = SF_READ; break; case CMD_PAGE_PROGRAM: sbsf->state = SF_WRITE; break; default: /* assume erase state ... */ sbsf->state = SF_ERASE; goto case_sf_erase; } debug(" cmd: transition to %s state\n", sandbox_sf_state_name(sbsf->state)); break; case SF_READ: /* * XXX: need to handle exotic behavior: * - reading past end of device */ cnt = bytes - pos; debug(" tx: read(%u)\n", cnt); assert(tx); ret = os_read(sbsf->fd, tx + pos, cnt); if (ret < 0) { puts("sandbox_sf: os_read() failed\n"); return -EIO; } pos += ret; break; case SF_READ_STATUS: debug(" read status: %#x\n", sbsf->status); cnt = bytes - pos; memset(tx + pos, sbsf->status, cnt); pos += cnt; break; case SF_READ_STATUS1: debug(" read status: %#x\n", sbsf->status); cnt = bytes - pos; memset(tx + pos, sbsf->status >> 8, cnt); pos += cnt; break; case SF_WRITE_STATUS: debug(" write status: %#x (ignored)\n", rx[pos]); pos = bytes; break; case SF_WRITE: /* * XXX: need to handle exotic behavior: * - unaligned addresses * - more than a page (256) worth of data * - reading past end of device */ if (!(sbsf->status & STAT_WEL)) { puts("sandbox_sf: write enable not set before write\n"); goto done; } cnt = bytes - pos; debug(" rx: write(%u)\n", cnt); if (tx) sandbox_spi_tristate(&tx[pos], cnt); ret = os_write(sbsf->fd, rx + pos, cnt); if (ret < 0) { puts("sandbox_spi: os_write() failed\n"); return -EIO; } pos += ret; sbsf->status &= ~STAT_WEL; break; case SF_ERASE: case_sf_erase: { if (!(sbsf->status & STAT_WEL)) { puts("sandbox_sf: write enable not set before erase\n"); goto done; } /* verify address is aligned */ if (sbsf->off & (sbsf->erase_size - 1)) { debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n", sbsf->cmd, sbsf->erase_size, sbsf->off); sbsf->status &= ~STAT_WEL; goto done; } debug(" sector erase addr: %u, size: %u\n", sbsf->off, sbsf->erase_size); cnt = bytes - pos; if (tx) sandbox_spi_tristate(&tx[pos], cnt); pos += cnt; /* * TODO([email protected]): latch WIP in status, and * delay before clearing it ? */ ret = sandbox_erase_part(sbsf, sbsf->erase_size); sbsf->status &= ~STAT_WEL; if (ret) { debug("sandbox_sf: Erase failed\n"); goto done; } goto done; } default: debug(" ??? no idea what to do ???\n"); goto done; }
s32 FFS_Write(s32 fd, void *s, s32 len) { return os_write(fd, s, len); }
static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx, uint bytes) { struct sandbox_spi_flash *sbsf = priv; uint cnt, pos = 0; int ret; debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state, sandbox_sf_state_name(sbsf->state), bytes); if (sbsf->state == SF_CMD) { /* Figure out the initial state */ if (sandbox_sf_process_cmd(sbsf, rx, tx)) return 1; ++pos; } /* Process the remaining data */ while (pos < bytes) { switch (sbsf->state) { case SF_ID: { u8 id; debug(" id: off:%u tx:", sbsf->off); if (sbsf->off < IDCODE_LEN) id = sbsf->data->idcode[sbsf->off]; else id = 0; debug("%02x\n", id); tx[pos++] = id; ++sbsf->off; break; } case SF_ADDR: debug(" addr: bytes:%u rx:%02x ", sbsf->addr_bytes, rx[pos]); if (sbsf->addr_bytes++ < SF_ADDR_LEN) sbsf->off = (sbsf->off << 8) | rx[pos]; debug("addr:%06x\n", sbsf->off); sandbox_spi_tristate(&tx[pos++], 1); /* See if we're done processing */ if (sbsf->addr_bytes < SF_ADDR_LEN + sbsf->pad_addr_bytes) break; /* Next state! */ if (os_lseek(sbsf->fd, sbsf->off, OS_SEEK_SET) < 0) { puts("sandbox_sf: os_lseek() failed"); return 1; } switch (sbsf->cmd) { case CMD_READ_ARRAY_FAST: case CMD_READ_ARRAY_SLOW: sbsf->state = SF_READ; break; case CMD_PAGE_PROGRAM: sbsf->state = SF_WRITE; break; default: /* assume erase state ... */ sbsf->state = SF_ERASE; goto case_sf_erase; } debug(" cmd: transition to %s state\n", sandbox_sf_state_name(sbsf->state)); break; case SF_READ: /* * XXX: need to handle exotic behavior: * - reading past end of device */ cnt = bytes - pos; debug(" tx: read(%u)\n", cnt); ret = os_read(sbsf->fd, tx + pos, cnt); if (ret < 0) { puts("sandbox_spi: os_read() failed\n"); return 1; } pos += ret; break; case SF_READ_STATUS: debug(" read status: %#x\n", sbsf->status); cnt = bytes - pos; memset(tx + pos, sbsf->status, cnt); pos += cnt; break; case SF_READ_STATUS1: debug(" read status: %#x\n", sbsf->status); cnt = bytes - pos; memset(tx + pos, sbsf->status >> 8, cnt); pos += cnt; break; case SF_WRITE: /* * XXX: need to handle exotic behavior: * - unaligned addresses * - more than a page (256) worth of data * - reading past end of device */ if (!(sbsf->status & STAT_WEL)) { puts("sandbox_sf: write enable not set before write\n"); goto done; } cnt = bytes - pos; debug(" rx: write(%u)\n", cnt); sandbox_spi_tristate(&tx[pos], cnt); ret = os_write(sbsf->fd, rx + pos, cnt); if (ret < 0) { puts("sandbox_spi: os_write() failed\n"); return 1; } pos += ret; sbsf->status &= ~STAT_WEL; break; case SF_ERASE: case_sf_erase: { const struct sandbox_spi_flash_erase_commands * erase_cmd = sbsf->cmd_data; if (!(sbsf->status & STAT_WEL)) { puts("sandbox_sf: write enable not set before erase\n"); goto done; } /* verify address is aligned */ if (sbsf->off & (erase_cmd->size - 1)) { debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n", erase_cmd->cmd, erase_cmd->size, sbsf->off); sbsf->status &= ~STAT_WEL; goto done; } debug(" sector erase addr: %u\n", sbsf->off); cnt = bytes - pos; sandbox_spi_tristate(&tx[pos], cnt); pos += cnt; /* * TODO([email protected]): latch WIP in status, and * delay before clearing it ? */ ret = sandbox_erase_part(sbsf, erase_cmd->size); sbsf->status &= ~STAT_WEL; if (ret) { debug("sandbox_sf: Erase failed\n"); goto done; } goto done; } default: debug(" ??? no idea what to do ???\n"); goto done; } } done: return pos == bytes ? 0 : 1; }
void serial_puts(const char *str) { os_write(1, str, strlen(str)); }
void serial_putc(const char ch) { os_write(1, &ch, 1); }
/* * write -- write bytes to the serial port. Ignore fd, since * stdout and stderr are the same. Since we have no filesystem, * open will only return an error. */ ssize_t write(int fd, const void *buffer, size_t cnt) { _ssize_t ret; unsigned int iomode_flags; unsigned len_written, i, j; int rc2; char *buf; __io_handle *ioh; if( (fd < 0) || (fd >=64) ) { errno = EBADF; return -1; }; ioh = &__io_tab[fd]; iomode_flags = ioh->mode; if( iomode_flags == 0 ) { errno = EBADF; return( -1 ); } if( !(iomode_flags & _WRITE) ) { errno = EACCES ; return( -1 ); } if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) ) { ioh->offset = lseek(fd, 0L, SEEK_END ); /* end of data offset */ } len_written = 0; rc2 = 0; // Pad the file with zeros if necessary if( iomode_flags & _FILEEXT ) { // turn off file extended flag ioh->mode = iomode_flags & (~_FILEEXT); // It is not required to pad a file with zeroes on an NTFS file system; // unfortunately it is required on FAT (and probably FAT32). (JBS) // rc2 = zero_pad( ptr, fd ); } if( rc2 == 0 ) { if( iomode_flags & _BINARY ) { /* if binary mode */ rc2 = os_write(fd, buffer, cnt, &len_written ); /* end of binary mode part */ } else { /* text mode */ int buf_size = 512; buf = (char*)alloca( buf_size ); j = 0; for( i = 0; i < cnt; ) { if( ((const char*)buffer)[i] == '\n' ) { buf[j] = '\r'; ++j; if( j == buf_size ) { rc2 = os_write(fd, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } buf[j] = ((const char*)buffer)[i]; ++i; ++j; if( j == buf_size ) { rc2 = os_write(fd, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } if( j ) { rc2 = os_write(fd, buf, j, &i ); if( rc2 == ENOSPC ) { len_written += i; } else { len_written = cnt; } } /* end of text mode part */ } } if( rc2 == -1 ) { return( rc2 ); } else { return( len_written ); } return 0; }
void dr_terminate(const char* reason) { os_write(1 /* stdout */, reason, strlen(reason)); os_terminate(NULL, 0); }
void os_write(std::ostream& s, const V& v, fas::type_list<H, L> ) { os_write(s, v, L() ); }
int main(int argc, char *argv[]) { int listenfd; int connfd; int on = 1; struct sockaddr_in serv_addr, cli_addr; socklen_t cli_len; int client_fd[FD_SETSIZE];/* each for every client */ fd_set allset; /* save interested descriptors */ fd_set rdset; /* select on this set */ int maxfd; int max_indx; /* max index in client_fd[] array */ int i, n; int nready; char buf[MAXLINE]; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "socket error: %s\n", strerror(errno)); exit(1); } os_setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); if (bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { fprintf(stderr, "bind error: %s\n", strerror(errno)); exit(1); } if (listen(listenfd, LISTEN_QUEUE) < 0) { fprintf(stderr, "listern error: %s\n", strerror(errno)); exit(1); } for (i=0; i < FD_SETSIZE; i++) client_fd[i] = -1; FD_ZERO(&allset); FD_SET(listenfd, &allset); maxfd = listenfd; max_indx = 0; for (; ;) { rdset = allset; nready = os_select(maxfd + 1, &rdset, NULL, NULL, NULL); /* select will modify rdset once return */ /* task 1: listen... accept new connection */ if(FD_ISSET(listenfd, &rdset)) { cli_len = sizeof(cli_addr); connfd = os_accept(listenfd, (struct sockaddr *)&cli_addr, &cli_len); for (i=0; i < FD_SETSIZE; i++) { /* a new client coming, select a useable fd */ if (client_fd[i] == -1) { client_fd[i] = connfd; maxfd = (connfd > maxfd) ? connfd : maxfd; break; } } FD_SET(connfd, &allset); if (i > max_indx) max_indx = i; if (--nready <= 0) continue; /* no more readable descriptors */ } /* task 2: deal with all clients' data */ for (i=0; i < maxfd; i++) { if (client_fd[i] == -1) continue; if (FD_ISSET(client_fd[i], &rdset)) { if ((n = os_read(client_fd[i], buf, MAXLINE)) == 0) { close(client_fd[i]); FD_CLR(client_fd[i], &allset); client_fd[i] = -1; } else { #ifdef DEBUG os_write(fileno(stdout), buf, n); #endif os_write(client_fd[i], buf, n); } } if (--nready <= 0) break; /* no more readable descriptors */ } #if 0 cli_len = sizeof(cli_addr); if ((connfd = accept(listenfd, (struct sockaddr *)&cli_addr, &cli_len)) < 0) { if (errno == EINTR) continue; else os_err_sys("accept error"); } if ((childpid = fork()) == 0) { close(listenfd); echo_string(connfd); exit(1); } close(connfd); #endif } return 0; }
void stackdump(void) { int pid, core_pid; /* get name now -- will be same for children */ char *exec_name = get_application_name(); char core_name[128]; char tmp_name[128]; snprintf(tmp_name, 128, "%s.%d", TEMPORARY_FILENAME, get_process_id()); #ifdef VMX86_SERVER if (os_in_vmkernel_userworld()) { return; /* no local gdb, no multithreaded fork */ } #endif #if VERBOSE SYSLOG_INTERNAL_ERROR("about to fork parent %d to dump core", get_process_id()); #endif /* Fork a child to dump core */ pid = fork_syscall(); if (pid == 0) { /* child */ #if VERBOSE SYSLOG_INTERNAL_ERROR("about to dump core in process %d parent %d thread " TIDFMT "", get_process_id(), get_parent_id(), get_thread_id()); #endif /* We used to use abort here, but that had lots of complications with * pthreads and libc, so now we just dereference NULL. */ if (!set_default_signal_action(SIGSEGV)) { SYSLOG_INTERNAL_ERROR("ERROR in setting handler"); exit_process_syscall(1); } *(volatile int *)NULL = 0; #if VERBOSE SYSLOG_INTERNAL_ERROR("about to exit process %d", get_process_id()); #endif exit_process_syscall(0); } else if (pid == -1) { SYSLOG_INTERNAL_ERROR("ERROR: could not fork to dump core"); exit_process_syscall(1); } #if VERBOSE SYSLOG_INTERNAL_ERROR("parent %d %d waiting for child %d", get_process_id(), get_thread_id(), pid); #endif /* Parent continues */ core_pid = pid; while (wait_syscall(NULL) != pid) { /* wait for core to be dumped */ } #if VERBOSE SYSLOG_INTERNAL_ERROR("about to fork 2nd child to run gdb"); #endif /* Fork a 2nd child to run gdb */ pid = fork_syscall(); if (pid == 0) { /* child */ file_t fp; int fd; const char *argv[16]; int i; int execve_errno; /* Open a temporary file for the input: the "where" command */ fp = os_open(tmp_name, OS_OPEN_REQUIRE_NEW | OS_OPEN_WRITE); os_write(fp, DEBUGGER_COMMAND, strlen(DEBUGGER_COMMAND)); os_close(fp); fd = open_syscall(tmp_name, O_RDONLY, 0); if (fd < 0) { SYSLOG_INTERNAL_ERROR("ERROR: open failed on temporary file"); exit_process_syscall(1); } #if !BATCH_MODE /* Redirect stdin from the temporary file */ close_syscall(0); /* close stdin */ dup_syscall(fd); /* replace file descriptor 0 with reference to temp file */ #endif close_syscall(fd); /* close the other reference to temporary file */ /* Find the core file */ strncpy(core_name, CORE_NAME, 127); core_name[127] = '\0'; /* if max no null */ fd = open_syscall(core_name, O_RDONLY, 0); if (fd < 0) { snprintf(core_name, 128, "%s.%d", CORE_NAME, core_pid); SYSLOG_INTERNAL_ERROR("core not found, trying %s", core_name); fd = open_syscall(core_name, O_RDONLY, 0); if (fd < 0) { SYSLOG_INTERNAL_ERROR("ERROR: no core file found!"); exit_process_syscall(1); } } close_syscall(fd); /* avoid running the debugger under us! * FIXME: just remove our libraries, instead of entire env var? */ unsetenv("LD_PRELOAD"); SYSLOG_INTERNAL_ERROR("-------------------------------------------"); SYSLOG_INTERNAL_ERROR("stackdump: --- now running the debugger ---"); SYSLOG_INTERNAL_ERROR("%s %s %s %s", DEBUGGER, QUIET_MODE, exec_name, core_name); SYSLOG_INTERNAL_ERROR("-------------------------------------------"); i = 0; /* We rely on /usr/bin/env to do the PATH search for gdb on our behalf. */ argv[i++] = "/usr/bin/env"; argv[i++] = DEBUGGER; argv[i++] = QUIET_MODE; #if BATCH_MODE argv[i++] = "-x"; argv[i++] = tmp_name; argv[i++] = "-batch"; #endif argv[i++] = exec_name; argv[i++] = core_name; argv[i++] = NULL; execve_errno = execve_syscall("/usr/bin/env", argv, our_environ); SYSLOG_INTERNAL_ERROR("ERROR: execve failed for debugger: %d", -execve_errno); exit_process_syscall(1); } else if (pid == -1) { SYSLOG_INTERNAL_ERROR("ERROR: could not fork to run debugger"); exit_process_syscall(1); } /* Parent continues */ /* while(wait(NULL)>0) waits for all children, and could hang, so: */ while (wait_syscall(NULL) != pid) { /* empty loop */ } /* Wait for these children to complete before returning */ while (wait_syscall(NULL) > 0) { /* empty loop */ } os_delete_file(tmp_name); /* clean up the temporary file */ SYSLOG_INTERNAL_ERROR("-------------------------------------------"); }