/** * Attempts to fill the shell buffer from the given file descriptor, however, * the buffer is not further filled before it is completely empty. */ static int read_data(int fd, struct shell_buf *sb) { if (!sb) { return -1; } if (0 == sb->fill && sb->readable) { ssize_t ret; ret = unix_read(fd, sb->buf, sb->size); switch (ret) { case 0: sb->eof = 1; break; case -1: if (!is_temporary_error(errno)) { if (sb->server) { perror("read() from server failed"); } else { perror("read() failed"); } return -1; } break; default: sb->fill = ret; } } return 0; }
static void do_log_file(FileBuff log, const char* procfile) { char buff[1024]; int fd; do_log_uptime(log); /* append file content */ fd = open(procfile,O_RDONLY); if (fd >= 0) { close_on_exec(fd); for (;;) { int ret; ret = unix_read(fd, buff, sizeof(buff)); if (ret <= 0) break; file_buff_write(log, buff, ret); if (ret < (int)sizeof(buff)) break; } close(fd); } do_log_ln(log); }
/*M \emph{Read a RTP packet from filedescriptor.} Reads a RTP packet from the filedescriptor, and unpacks the RTP header into the \verb|rtp_pkt_t| data fields. **/ int rtp_pkt_read(rtp_pkt_t *pkt, int fd) { assert(pkt != NULL); ssize_t len; switch (len = unix_read(fd, pkt->data, RTP_PKT_SIZE)) { case 0: /* EOF */ return 0; case -1: /* error */ return -1; default: break; } /*M Check if the packet is long enough. **/ if (len < RTP_HDR_SIZE) return -1; pkt->length = len; return rtp_pkt_unpack(pkt); }
static int unix_recv(struct socket *sock, void *buff, int len, int nonblock, unsigned flags) { if (flags != 0) return -EINVAL; return unix_read(sock, (char *) buff, len, nonblock); }
int file_read(void * fd, char * buffer, int size) { #ifdef WIN32 return win32_rw(fd, FALSE, buffer, size); #else return unix_read(fd, buffer, size, NULL); #endif }
static int proc_read(const char* filename, char* buff, size_t buffsize) { int len = 0; int fd = open(filename, O_RDONLY); if (fd >= 0) { len = unix_read(fd, buff, buffsize-1); close(fd); } buff[len > 0 ? len : 0] = 0; return len; }
static void do_log_procs(FileBuff log) { DIR* dir = opendir("/proc"); struct dirent* entry; do_log_uptime(log); while ((entry = readdir(dir)) != NULL) { /* only match numeric values */ char* end; int pid = strtol( entry->d_name, &end, 10); if (end != NULL && end > entry->d_name && *end == 0) { char filename[32]; char buff[1024]; char cmdline[1024]; int len; int fd; /* read command line and extract program name */ snprintf(filename,sizeof(filename),"/proc/%d/cmdline",pid); proc_read(filename, cmdline, sizeof(cmdline)); /* read process stat line */ snprintf(filename,sizeof(filename),"/proc/%d/stat",pid); fd = open(filename,O_RDONLY); if (fd >= 0) { len = unix_read(fd, buff, sizeof(buff)-1); close(fd); if (len > 0) { int len2 = strlen(cmdline); if (len2 > 0) { /* we want to substitute the process name with its real name */ const char* p1; const char* p2; buff[len] = 0; p1 = strchr(buff, '('); p2 = strchr(p1, ')'); file_buff_write(log, buff, p1+1-buff); file_buff_write(log, cmdline, strlen(cmdline)); file_buff_write(log, p2, strlen(p2)); } else { /* no substitution */ file_buff_write(log,buff,len); } } } } } closedir(dir); do_log_ln(log); }
static void *stdin_read_thread(void *x) { int fd, fdi; unsigned char buf[1024]; int r, n; int state = 0; int *fds = (int*) x; fd = fds[0]; fdi = fds[1]; free(fds); for(;;) { /* fdi is really the client's stdin, so use read, not adb_read here */ D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi); r = unix_read(fdi, buf, 1024); D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi); if(r == 0) break; if(r < 0) { if(errno == EINTR) continue; break; } for(n = 0; n < r; n++){ switch(buf[n]) { case '\n': state = 1; break; case '\r': state = 1; break; case '~': if(state == 1) state++; break; case '.': if(state == 2) { fprintf(stderr,"\n* disconnect *\n"); #ifdef HAVE_TERMIO_H stdin_raw_restore(fdi); #endif exit(0); } default: state = 0; } } r = adb_write(fd, buf, r); if(r <= 0) { break; } } return 0; }
static void adbd_auth_event(int fd, unsigned events, void*) { if (events & FDE_READ) { char response[2]; int ret = unix_read(fd, response, sizeof(response)); if (ret <= 0) { framework_disconnected(); } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { if (usb_transport) { adbd_auth_verified(usb_transport); } } } }
int get_uptime() { int fd, ret, len; static char buff[65]; int ten_ms=0; fd = open("/proc/uptime",O_RDONLY); if (fd >= 0) { int ret; ret = unix_read(fd, buff, 64); close(fd); buff[64] = 0; if (ret >= 0) { ten_ms = 100*strtod(buff,NULL); } } return ten_ms; }
void log_service(int fd, void *cookie) { /* get the name of the log filepath to read */ char * log_filepath = cookie; /* open the log file. */ int logfd = unix_open(log_filepath, O_RDONLY); if (logfd < 0) { goto done; } // temp buffer to read the entries unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4))); struct logger_entry *entry = (struct logger_entry *) buf; while (1) { int ret; ret = unix_read(logfd, entry, LOGGER_ENTRY_MAX_LEN); if (ret < 0) { if (errno == EINTR || errno == EAGAIN) continue; // perror("logcat read"); goto done; } else if (!ret) { // fprintf(stderr, "read: Unexpected EOF!\n"); goto done; } /* NOTE: driver guarantees we read exactly one full entry */ entry->msg[entry->len] = '\0'; write_log_entry(fd, entry); } done: unix_close(fd); free(log_filepath); }
static void do_log_uptime(FileBuff log) { char buff[65]; int fd, ret, len; fd = open("/proc/uptime",O_RDONLY); if (fd >= 0) { int ret; ret = unix_read(fd, buff, 64); close(fd); buff[64] = 0; if (ret >= 0) { long long jiffies = 100LL*strtod(buff,NULL); int len; snprintf(buff,sizeof(buff),"%lld\n",jiffies); len = strlen(buff); file_buff_write(log, buff, len); } } }
void cdrom_helper(unsigned char *req_buf, unsigned char *transfer_buf, unsigned int dos_transfer_buf) { unsigned int Sector_plus_150,Sector; struct cdrom_msf cdrom_msf; struct cdrom_subchnl cdrom_subchnl; struct cdrom_tochdr cdrom_tochdr; struct cdrom_tocentry cdrom_tocentry; struct cdrom_volctrl cdrom_volctrl; int n, err; cdrom_subchnl.cdsc_format = CDROM_MSF; IndexCd=(int)((HI(ax) & 0xC0)>>6); HI(ax) = HI(ax) & 0x3F; if ((cdu33a) && (cdrom_fd < 0)) { cdrom_fd = open (path_cdrom, O_RDONLY | O_NONBLOCK); if (cdrom_fd < 0) { switch (HI(ax)) { case 0x09: /* media changed request */ LO(bx) = 1; /* media changed */ LO(ax) = 0; return; case 0x0A: /* device status request */ LWORD(ebx) = audio_status.status | 0x800; /* no disc */ LO(ax) = 0; return; } LO(ax) = 1; /* for other requests return with error */ return ; } } switch (HI(ax)) { case 0x01: /* NOTE: you can't see XA data disks if bit 10 of status * is cleared, MSCDEX will test it and skip XA entries! * Actually the entries skipped must have this pattern: * xxxx1xxx xxxxxxxx 0x58 0x41 * and the mscdex 2.25 code is: * test word ptr [bx+1Eh],400h * jz [check for XA] * [return 0 = valid entry] * [check for XA] * ... * cmp word ptr es:[bx+6],4158h 'XA' * jne [return 0] * mov ax,es:[bx+4] * and ax,8 * [return ax] */ audio_status.status = 0x00000710; /* see function 0x0A below */ audio_status.paused_bit = 0; audio_status.media_changed = 0; audio_status.volume0 = 0xFF; audio_status.volume1 = 0xFF; audio_status.volume2 = 0; audio_status.volume3 = 0; audio_status.outchan0 = 0; audio_status.outchan1 = 1; audio_status.outchan2 = 2; audio_status.outchan3 = 3; cdrom_fd = open (path_cdrom, O_RDONLY | O_NONBLOCK); err = errno; if (cdrom_fd < 0) { C_printf("CDROM: cdrom open (%s) failed: %s\n", path_cdrom, strerror(err)); LO(ax) = 0; if ((err == EIO) || (err==ENOMEDIUM)) { /* drive which cannot be opened if no disc is inserted! */ cdu33a = 1; if (! eject_allowed) LO(ax) = 1; /* no disk in drive */ } else LO(ax) = 1; /* no cdrom drive installed */ if (! eject_allowed) LO(ax) = 1; /* no disk in drive */ } else { LO(ax) = 0; if (! eject_allowed) { if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) LO(ax) = 1; } } break; case 0x02: /* read long */ if (eject_allowed && ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl) && errno != ENOTTY) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disc in drive */ LO(ax) = 1; break; } else { /* disc in drive */ } } if (req_buf == NULL && transfer_buf == NULL) { req_buf = SEG_ADR((unsigned char *), es, di); dos_transfer_buf = SEGOFF2LINEAR(REG(ds), LWORD(esi)); } if (*CALC_PTR(req_buf,MSCD_READ_ADRESSING,u_char) == 1) { cdrom_msf.cdmsf_min0 = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR+2,u_char); cdrom_msf.cdmsf_sec0 = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR+1,u_char); cdrom_msf.cdmsf_frame0 = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR+0,u_char); Sector = cdrom_msf.cdmsf_min0*60*75+cdrom_msf.cdmsf_sec0*75 +cdrom_msf.cdmsf_frame0-150; } else { Sector = *CALC_PTR(req_buf,MSCD_READ_STARTSECTOR,u_long); } C_printf("CDROM: reading sector %#x (fmt %d)\n", Sector, *CALC_PTR(req_buf,MSCD_READ_ADRESSING,u_char)); if ((off_t) -1 == lseek (cdrom_fd, Sector*CD_FRAMESIZE, SEEK_SET)) { HI(ax) = (errno == EINVAL ? 0x08 : 0x0F); C_printf("CDROM: lseek failed: %s\n", strerror(errno)); LO(ax) = 1; } else { n = *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE; if (transfer_buf == NULL) { n = dos_read (cdrom_fd, dos_transfer_buf, n); } else { n = unix_read (cdrom_fd, transfer_buf, n); } if ( n < 0 ) { /* cd must be in drive, reset drive and try again */ cdrom_reset(); if ((off_t) -1 == lseek (cdrom_fd, Sector*CD_FRAMESIZE, SEEK_SET)) { HI(ax) = (errno == EINVAL ? 0x08 : 0x0F); C_printf("CDROM: lseek failed: %s\n", strerror(errno)); LO(ax) = 1; } else { n = *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE; if (transfer_buf == NULL) n = dos_read (cdrom_fd, dos_transfer_buf, n); else n = unix_read (cdrom_fd, transfer_buf, n); if ( n < 0) { HI(ax) = (errno == EFAULT ? 0x0A : 0x0F); C_printf("CDROM: sector read (to %p, len %#x) failed: %s\n", transfer_buf, *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE, strerror(errno)); LO(ax) = 1; } else LO(ax) = 0; } } if (n != *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE) { C_printf("CDROM: sector read len %#x got %#x\n", *CALC_PTR(req_buf,MSCD_READ_NUMSECTORS,u_short)*CD_FRAMESIZE, n); LO(ax) = 1; HI(ax) = 0x0F; } else { #ifdef CDROM_DEBUG dump_cd_sect(transfer_buf); #endif LO(ax) = 0; } } break; case 0x03: /* seek */ req_buf = SEG_ADR((unsigned char *), es, di); if ((off_t)-1 == lseek (cdrom_fd, *CALC_PTR(req_buf,MSCD_SEEK_STARTSECTOR,u_long)*CD_FRAMESIZE, SEEK_SET)) { C_printf("CDROM: lseek failed: %s\n", strerror(errno)); LO(ax) = 1; } break; case 0x04: /* play */ req_buf = SEG_ADR((unsigned char *), es, di); if (*CALC_PTR(req_buf,MSCD_PLAY_ADRESSING,u_char) == 1) { cdrom_msf.cdmsf_min0 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR+2,u_char); cdrom_msf.cdmsf_sec0 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR+1,u_char); cdrom_msf.cdmsf_frame0 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR+0,u_char); Sector_plus_150 = cdrom_msf.cdmsf_min0*60*75+cdrom_msf.cdmsf_sec0*75 +cdrom_msf.cdmsf_frame0; audio_status.last_StartSector = Sector_plus_150; } else { Sector_plus_150 = *CALC_PTR(req_buf,MSCD_PLAY_STARTSECTOR,u_long) + 150; cdrom_msf.cdmsf_min0 = (Sector_plus_150 / (60*75)); cdrom_msf.cdmsf_sec0 = (Sector_plus_150 % (60*75)) / 75; cdrom_msf.cdmsf_frame0 = (Sector_plus_150 % (60*75)) % 75; audio_status.last_StartSector = Sector_plus_150; } Sector_plus_150 += *CALC_PTR(req_buf,MSCD_PLAY_NUMSECTORS,u_long); cdrom_msf.cdmsf_min1 = (Sector_plus_150 / (60*75)); cdrom_msf.cdmsf_sec1 = (Sector_plus_150 % (60*75)) / 75; cdrom_msf.cdmsf_frame1 = (Sector_plus_150 % (60*75)) % 75; audio_status.last_EndSector = Sector_plus_150; audio_status.paused_bit = 0; if (ioctl (cdrom_fd, CDROMPLAYMSF, &cdrom_msf)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMPLAYMSF, &cdrom_msf)) { /* no disk in drive */ LO(ax) = 1; break; } } LO(ax) = 0; break; case 0x05: /* pause (stop) audio */ LO(ax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl) == 0) { if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) { audio_status.last_StartSector = cdrom_subchnl.cdsc_absaddr.msf.minute*60*75 +cdrom_subchnl.cdsc_absaddr.msf.second*75 +cdrom_subchnl.cdsc_absaddr.msf.frame; ioctl (cdrom_fd, CDROMPAUSE, NULL); audio_status.paused_bit = 1; } else { audio_status.last_StartSector = 0; audio_status.last_EndSector = 0; audio_status.paused_bit = 0; } } else { audio_status.last_StartSector = 0; audio_status.last_EndSector = 0; audio_status.paused_bit = 0; audio_status.media_changed = 1; } break; case 0x06: /* resume audio */ LO(ax) = 0; if (audio_status.paused_bit) { if (ioctl (cdrom_fd, CDROMRESUME, NULL) == 0) { audio_status.paused_bit = 0; HI(ax) = 1; } } else LO(ax) = 1; break; case 0x07: /* location of head */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); if (*CALC_PTR(req_buf,MSCD_LOCH_ADRESSING,u_char) == 0) { *CALC_PTR(req_buf,MSCD_LOCH_LOCATION,u_long) = cdrom_subchnl.cdsc_absaddr.msf.minute*60*75 +cdrom_subchnl.cdsc_absaddr.msf.second*75 +cdrom_subchnl.cdsc_absaddr.msf.frame-150; } else {/* red book adressing */ *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+3,u_char) = 0; *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+2,u_char) = cdrom_subchnl.cdsc_absaddr.msf.minute; *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+1,u_char) = cdrom_subchnl.cdsc_absaddr.msf.second; *CALC_PTR(req_buf,MSCD_LOCH_LOCATION+0,u_char) = cdrom_subchnl.cdsc_absaddr.msf.frame; } break; case 0x08: /* return sectorsize */ LO(ax) = 0; LWORD(ebx) = CD_FRAMESIZE; break; case 0x09: /* media changed */ /* this function will be called from MSCDEX before each new disk access ! */ HI(ax) = 0; LO(ax) = 0; LO(bx) = 0; C_printf("CDROM: media changed? %#x\n", audio_status.media_changed); errno = 0; if (eject_allowed) { if ((audio_status.media_changed) || ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { if (errno == EIO) cdrom_reset(); audio_status.media_changed = 0; LO(bx) = 1; /* media has been changed */ C_printf("CDROM: media changed? yes\n"); ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl); if (! ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) cdrom_reset(); /* disc in drive */ } else /* media has not changed, check audio status */ if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; /* audio playing in progress */ } break; case 0x0A: /* device status */ HI(ax) = 0; LO(ax) = 0; if (eject_allowed) { if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LWORD(ebx) = audio_status.status | 0x800; C_printf("CDROM: subch failed: %s\n", strerror(errno)); break; } else cdrom_reset(); } } /* disk in drive */ LWORD(ebx) = audio_status.status; if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; break; case 0x0B: /* drive reset */ LO(ax) = 0; break; case 0x0C: /* lock/unlock door */ cdrom_reset(); if (LO(bx) == 1) audio_status.status &= 0xFFFFFFFD; else audio_status.status |= 0x2; LO(ax) = 0; break; case 0x0D: /* eject */ LO(ax) = 0; if ((eject_allowed) && (audio_status.status & 0x02)) /* drive unlocked ? */ { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMEJECT)) { LO(ax) = errno; } } break; case 0x0E: /* close tray */ LO(ax) = 0; if ((eject_allowed) && (audio_status.status & 0x02)) /* drive unlocked ? */ { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMCLOSETRAY)) { LO(ax) = errno; } } break; case 0x0F: /* audio channel control */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); cdrom_volctrl.channel0 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME0, u_char); cdrom_volctrl.channel1 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME1, u_char); cdrom_volctrl.channel2 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME2, u_char); cdrom_volctrl.channel3 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME3, u_char); audio_status.volume0 = cdrom_volctrl.channel0; audio_status.volume1 = cdrom_volctrl.channel1; audio_status.volume2 = cdrom_volctrl.channel2; audio_status.volume3 = cdrom_volctrl.channel3; audio_status.outchan0 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME0-1, u_char); audio_status.outchan1 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME1-1, u_char); audio_status.outchan2 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME2-1, u_char); audio_status.outchan3 = *CALC_PTR(req_buf, MSCD_CTRL_VOLUME3-1, u_char); ioctl (cdrom_fd, CDROMVOLCTRL, &cdrom_volctrl); break; case 0x10: /* audio disk info */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMREADTOCHDR, &cdrom_tochdr)) { /* no disk in drive */ LO(ax) = 1; break; } } req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_DISKINFO_LTN,u_char) = cdrom_tochdr.cdth_trk0; *CALC_PTR(req_buf,MSCD_DISKINFO_HTN,u_char) = cdrom_tochdr.cdth_trk1; cdrom_tocentry.cdte_track = CDROM_LEADOUT; cdrom_tocentry.cdte_format = CDROM_MSF; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { C_printf ("Fatal cdrom error(audio disk info); read toc header succeeded but following read entry didn't\n"); LO(ax) = 1; break; } #ifdef __linux__ *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+3,u_char) = 0; *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+2,u_char) = cdrom_tocentry.cdte_addr.msf.minute; *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+1,u_char) = cdrom_tocentry.cdte_addr.msf.second; *CALC_PTR(req_buf,MSCD_DISKINFO_LEADOUT+0,u_char) = cdrom_tocentry.cdte_addr.msf.frame; #endif break; case 0x11: /* track info */ req_buf = SEG_ADR((unsigned char *), ds, si); cdrom_tocentry.cdte_track = *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKNUM,u_char); cdrom_tocentry.cdte_format = CDROM_MSF; C_printf("CDROM: track info, track %d\n", cdrom_tocentry.cdte_track); if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { /* XXX MSCDEX reads beyond the end of existing tracks. Sigh. */ if (errno != EINVAL) audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { if (errno == EIO) { audio_status.media_changed = 1; /* no disk in drive */ } LO(ax) = 1; break; } } #ifdef __linux__ *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+3,u_char) = 0; *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+2,u_char) = cdrom_tocentry.cdte_addr.msf.minute; *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+1,u_char) = cdrom_tocentry.cdte_addr.msf.second; *CALC_PTR(req_buf,MSCD_TRACKINFO_TRACKPOS+0,u_char) = cdrom_tocentry.cdte_addr.msf.frame; #endif *CALC_PTR(req_buf,MSCD_TRACKINFO_CTRL,u_char) = cdrom_tocentry.cdte_ctrl << 4 | 0x20; LO(ax) = 0; break; case 0x12: /* volume size */ cdrom_tocentry.cdte_track = CDROM_LEADOUT; cdrom_tocentry.cdte_format = CDROM_MSF; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMREADTOCENTRY, &cdrom_tocentry)) { /* no disk in drive */ LO(ax) = 1; break; } } req_buf = SEG_ADR((unsigned char *), ds, si); #ifdef __linux__ *CALC_PTR(req_buf,MSCD_GETVOLUMESIZE_SIZE,int) = cdrom_tocentry.cdte_addr.msf.minute*60*75 +cdrom_tocentry.cdte_addr.msf.second*60 +cdrom_tocentry.cdte_addr.msf.frame; #endif LO(ax) = 0; break; case 0x13: /* q channel */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_QCHAN_CTRL,u_char) = (cdrom_subchnl.cdsc_adr << 4) + (cdrom_subchnl.cdsc_ctrl); *CALC_PTR(req_buf,MSCD_QCHAN_TNO,u_char) = cdrom_subchnl.cdsc_trk; *CALC_PTR(req_buf,MSCD_QCHAN_IND,u_char) = cdrom_subchnl.cdsc_ind; #ifdef __linux__ *CALC_PTR(req_buf,MSCD_QCHAN_MIN,u_char) = cdrom_subchnl.cdsc_reladdr.msf.minute; *CALC_PTR(req_buf,MSCD_QCHAN_SEC,u_char) = cdrom_subchnl.cdsc_reladdr.msf.second; *CALC_PTR(req_buf,MSCD_QCHAN_FRM,u_char) = cdrom_subchnl.cdsc_reladdr.msf.frame; #endif *CALC_PTR(req_buf,MSCD_QCHAN_ZERO,u_char) = 0; *CALC_PTR(req_buf,MSCD_QCHAN_AMIN,u_char) = cdrom_subchnl.cdsc_absaddr.msf.minute; *CALC_PTR(req_buf,MSCD_QCHAN_ASEC,u_char) = cdrom_subchnl.cdsc_absaddr.msf.second; *CALC_PTR(req_buf,MSCD_QCHAN_AFRM,u_char) = cdrom_subchnl.cdsc_absaddr.msf.frame; break; case 0x14: /* audio status */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_AUDSTAT_PAUSED,u_short)= audio_status.paused_bit; *CALC_PTR(req_buf,MSCD_AUDSTAT_START ,u_long) = audio_status.last_StartSector; *CALC_PTR(req_buf,MSCD_AUDSTAT_END ,u_long) = audio_status.last_EndSector; break; case 0x15: /* get audio channel information */ LWORD(eax) = 0; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { audio_status.media_changed = 1; if (ioctl (cdrom_fd, CDROMSUBCHNL, &cdrom_subchnl)) { /* no disk in drive */ LO(ax) = 1; break; } } if (cdrom_subchnl.cdsc_audiostatus == CDROM_AUDIO_PLAY) HI(ax) = 1; req_buf = SEG_ADR((unsigned char *), ds, si); *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME0,u_char) = audio_status.volume0; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME1,u_char) = audio_status.volume1; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME2,u_char) = audio_status.volume2; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME3,u_char) = audio_status.volume3; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME0-1,u_char) = audio_status.outchan0; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME1-1,u_char) = audio_status.outchan1; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME2-1,u_char) = audio_status.outchan2; *CALC_PTR(req_buf,MSCD_AUDCHAN_VOLUME3-1,u_char) = audio_status.outchan3; break; default: C_printf ("CDROM: unknown request %#x!\n",HI(ax)); }
static void *stdin_read_thread(void *x) { int fd, fdi; unsigned char buf[1024]; #ifdef SH_HISTORY unsigned char realbuf[1024], *buf_ptr; SHLIST history; SHLIST *item = &history; int cmdlen = 0, ins_flag = 0; #endif int r, n; int state = 0; int *fds = (int*) x; fd = fds[0]; fdi = fds[1]; free(fds); #ifdef SH_HISTORY shListInitList( &history ); #endif for(;;) { /* fdi is really the client's stdin, so use read, not adb_read here */ r = unix_read(fdi, buf, 1024); if(r == 0) break; if(r < 0) { if(errno == EINTR) continue; break; } #ifdef SH_HISTORY if( (r == 3) && /* Arrow processing */ (memcmp( (void *)buf, SH_ARROW_ANY, 2 ) == 0) ) { switch( buf[2] ) { case SH_ARROW_UP: item = shListGetNextItem( &history, item ); break; case SH_ARROW_DOWN: item = shListGetPrevItem( &history, item ); break; default: item = NULL; break; } memset( buf, SH_DEL_CHAR, cmdlen ); if( item != NULL ) { n = snprintf( (char *)(&buf[cmdlen]), sizeof buf - cmdlen, "%s", (char *)(item->data) ); memcpy( realbuf, item->data, n ); } else { /* Clean buffer */ item = &history; n = 0; } r = n + cmdlen; cmdlen = n; ins_flag = 0; if( r == 0 ) continue; } else { #endif for(n = 0; n < r; n++){ switch(buf[n]) { case '\n': #ifdef SH_HISTORY if( ins_flag && (SH_BLANK_CHAR <= realbuf[0]) ) { buf_ptr = malloc(cmdlen + 1); if( buf_ptr != NULL ) { memcpy( buf_ptr, realbuf, cmdlen ); buf_ptr[cmdlen] = '\0'; if( (item = shListFindItem( &history, (void *)buf_ptr, shItemCmp )) == NULL ) { shListInsFirstItem( &history, (void *)buf_ptr ); item = &history; } } } cmdlen = 0; ins_flag = 0; #endif state = 1; break; case '\r': state = 1; break; case '~': if(state == 1) state++; break; case '.': if(state == 2) { fprintf(stderr,"\n* disconnect *\n"); #ifdef HAVE_TERMIO_H stdin_raw_restore(fdi); #endif exit(0); } default: #ifdef SH_HISTORY if( buf[n] == SH_DEL_CHAR ) { if( cmdlen > 0 ) cmdlen--; } else { realbuf[cmdlen] = buf[n]; cmdlen++; } ins_flag = 1; #endif state = 0; } } #ifdef SH_HISTORY } #endif r = adb_write(fd, buf, r); if(r <= 0) { break; } } #ifdef SH_HISTORY shListDelAllItems( &history, (shListFree)free ); #endif return 0; }
int capfs_read(int fd, char *buf, size_t count) { int i; int64_t size = 0; fdesc_p pfd_p = pfds[fd]; /* variables added for correct handling of EOF */ char *contacted; int64_t exp_next_off, act_last_off, known_file_sz, calc_file_sz, start_off; if (fd < 0 || fd >= CAPFS_NR_OPEN || (pfds[fd] && pfds[fd]->fs == FS_RESV)) { errno = EBADF; return(-1); } if (capfs_mode == 1) { LOG(stderr, CRITICAL_MSG, SUBSYS_LIB, "capfs_read is not yet implemented for capfs! Please use" "the VFS interface for accessing such files\n"); errno = ENOSYS; return -1; } if (!pfd_p || pfd_p->fs == FS_UNIX) return(unix_read(fd, buf, count)); if (pfd_p->fs == FS_PDIR) return(unix_read(fd, buf, count)); #ifdef STRICT_FDESC_CHECK if (do_fdesc_check(fd) < 0) { LOG(stderr, CRITICAL_MSG, SUBSYS_LIB, "check failed at start of capfs_read()\n"); } #endif start_off = pfd_p->fd.off; exp_next_off = pfd_p->fd.off + count; known_file_sz = 0; contacted = malloc(PCOUNT * sizeof(char)); for (i = 0; i < PCOUNT; i++) { contacted[i] = 0; pfd_p->fd.iod[i].ack.status = 0; pfd_p->fd.iod[i].ack.dsize = 0; } /* build jobs, including requests and acks */ if (build_rw_jobs(pfd_p, buf, count, J_READ) < 0) { LOG(stderr, WARNING_MSG, SUBSYS_LIB, "build_rw_jobs failed in capfs_read\n"); return(-1); } /* determine what iods we will contact */ for (i = 0; i < PCOUNT; i++) { /* this isn't so efficient, but i don't want to muck with jlist imp. */ if (j_search(active_p, pfd_p->fd.iod[i].sock) != NULL) { contacted[i] = 1; } } /* send requests; receive data and acks */ while (!jlist_empty(active_p)) { if (do_jobs(active_p, &socks, -1) < 0) { PERROR(SUBSYS_LIB,"do_jobs"); free(contacted); return(-1); } } /* pass through responses, checking for errors, sizes */ for (i = 0; i < PCOUNT; i++) { if (contacted[i]) { if (pfd_p->fd.iod[i].ack.status) { errno = pfd_p->fd.iod[i].ack.eno; free(contacted); return -1; } /* update known file size */ calc_file_sz = fsize_to_file_size(pfd_p->fd.iod[i].ack.ack.rw.fsize, i, pfd_p); size += pfd_p->fd.iod[i].ack.dsize; if (calc_file_sz > known_file_sz) { known_file_sz = calc_file_sz; } } } /* check for short read */ if (exp_next_off <= known_file_sz) { /* we definitely did not hit EOF */ if (size < count) { LOG(stderr, WARNING_MSG, SUBSYS_LIB, " capfs_read: hit hole, read %Ld of %d (everything should be ok)\n", size, count); } pfd_p->fd.off = exp_next_off; size = count; /* ensure correct return value (size might have hole) */ errno = 0; } else { mack ack; mreq req; struct sockaddr saddr; struct capfs_options opt; opt.tcp = MGR_USE_TCP; opt.use_hcache = 0; /* we know we got a short read. it MIGHT be EOF, or it might just * be that we hit a hole that happened to extend to the end of our * region to read. we need to figure out which one happened. */ act_last_off = known_file_sz; /* the quick and dirty way to figure out what happened is to * stat() the file. a better solution would be to collect the * remaining sizes from the iods we didn't already talk to. */ req.uid = getuid(); req.gid = getgid(); req.type = MGR_FSTAT; req.dsize = 0; req.req.fstat.meta = pfd_p->fd.meta; saddr = pfd_p->fd.meta.mgr; if (send_mreq_saddr(&opt, &saddr, &req, NULL, &ack, NULL) < 0 || ack.status != 0) { PERROR(SUBSYS_LIB,"capfs_read: send_mreq_saddr - "); /* error talking to mgr, but not really critical. * assume we hit EOF, return what we know. */ pfd_p->fd.off = act_last_off; size = act_last_off - start_off; } else { /* got a response; determine if we hit EOF */ if (ack.ack.fstat.meta.u_stat.st_size > known_file_sz) { /* the file is in fact bigger than we were told by the * other iods */ known_file_sz = ack.ack.fstat.meta.u_stat.st_size; } if (exp_next_off <= known_file_sz) { /* didn't really hit EOF */ if (size < count) { LOG(stderr, WARNING_MSG, SUBSYS_LIB, " capfs_read: hit hole, read %Ld of %d (everything should be ok)\n", size, count); } pfd_p->fd.off = exp_next_off; size = count; /* ensure correct return value */ errno = 0; } else { /* we really did hit EOF; return short read */ if(known_file_sz > start_off) { pfd_p->fd.off = known_file_sz; size = known_file_sz - start_off; errno = 0; } else { /* apparently tried to read after seeking beyond EOF; * keep current offset but do not return any data */ pfd_p->fd.off = start_off; size = 0; errno = 0; } } } } pfd_p->fd.meta.u_stat.atime = time(NULL); LOG(stderr, DEBUG_MSG, SUBSYS_LIB, "capfs_read: completed %Ld bytes; new offset = %Ld\n", size, pfd_p->fd.off); #ifdef STRICT_FDESC_CHECK if (do_fdesc_check(fd) < 0) { LOG(stderr, CRITICAL_MSG, SUBSYS_LIB, "check failed at end of capfs_read()\n"); } #endif free(contacted); return(size); }