I2C_RESULT i2c_RxByte(unsigned char* pData, unsigned char bAck) { #if !defined(I2C_CFGEN_CALLTRACE) unsigned char bit; unsigned char data; /* Read the byte into pData, MSB first */ data = 0; for (bit=0; bit<8; bit++) { unsigned char b; data <<= 1; _READ(b); data += b; } *pData = data; if (bAck) { /* Write the ack bit */ _WRITE0(); } #else printf("i2c_RxByte(%d,%d)\n", (int) *pData, (int)bAck); #endif return I2C_RESULT_OK; }
I2C_RESULT i2c_TxByte(unsigned char data) { #if !defined(I2C_CFGEN_CALLTRACE) unsigned char bit; /* Send the byte in data, MSB first */ for (bit=0; bit<8; bit++) { if (data & 0x80) { _WRITE1(); } else { _WRITE0(); } data <<= 1; } /* Read and interpret 9th ACK bit */ _READ(bit); if (!bit) { /* Valid ACK */ return I2C_RESULT_OK; } else { /* bus floats, so no ACK */ return I2C_RESULT_E_NACK; } #else printf("i2c_TxByte(%d)\n", (int) data); return I2C_RESULT_OK; #endif }
long _dirreadall(int fd, Dir **d) { uchar *buf, *nbuf; long n, ts; buf = nil; ts = 0; for(;;){ nbuf = realloc(buf, ts+DIRMAX); if(nbuf == nil){ free(buf); return -1; } buf = nbuf; n = _READ(fd, buf+ts, DIRMAX); if(n <= 0) break; ts += n; } if(ts >= 0) ts = dirpackage(buf, ts, d); free(buf); return ts; }
long _dirread(int fd, Dir **d) { uchar *buf; long ts; buf = malloc(DIRMAX); if(buf == nil) return -1; ts = _READ(fd, buf, DIRMAX); if(ts >= 0) ts = dirpackage(buf, ts, d); free(buf); return ts; }
int tcgetattr(int fd, struct termios *t) { int n; char buf[60]; if(!isptty(fd)) { if(isatty(fd)) { /* If there is no emulation return sensible defaults */ t->c_iflag = ISTRIP|ICRNL|IXON|IXOFF; t->c_oflag = OPOST|TAB3|ONLCR; t->c_cflag = B9600; t->c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK; t->c_cc[VINTR] = CINTR; t->c_cc[VQUIT] = CQUIT; t->c_cc[VERASE] = CERASE; t->c_cc[VKILL] = CKILL; t->c_cc[VEOF] = CEOF; t->c_cc[VEOL] = CEOL; t->c_cc[VSTART] = CSTART; t->c_cc[VSTOP] = CSTOP; return 0; } else { errno = ENOTTY; return -1; } } if(_SEEK(fd, -2, 0) != -2) { _syserrno(); return -1; } n = _READ(fd, buf, 57); if(n < 0) { _syserrno(); return -1; } t->c_iflag = strtoul(buf+4, 0, 16); t->c_oflag = strtoul(buf+9, 0, 16); t->c_cflag = strtoul(buf+14, 0, 16); t->c_lflag = strtoul(buf+19, 0, 16); for(n = 0; n < NCCS; n++) t->c_cc[n] = strtoul(buf+24+(n*3), 0, 16); return 0; }
long _READN(int f, void *av, long n) { char *a; long m, t; a = av; t = 0; while(t < n){ m = _READ(f, a+t, n-t); if(m <= 0){ if(t == 0) return m; break; } t += m; } return t; }
int _IOUNIT(int fd) { int i, cfd; char buf[128], *args[10]; snprint(buf, sizeof buf, "#d/%dctl", fd); cfd = _OPEN(buf, OREAD); if(cfd < 0) return 0; i = _READ(cfd, buf, sizeof buf-1); _CLOSE(cfd); if(i <= 0) return 0; buf[i] = '\0'; if(getfields(buf, args, 10, 1) != 10) return 0; return atoi(args[7]); }
ssize_t read(int d, void *buf, size_t nbytes) { int n, noblock, isbuf; Fdinfo *f; if(d<0 || d>=OPEN_MAX || !(_fdinfo[d].flags&FD_ISOPEN)){ errno = EBADF; return -1; } if(nbytes <= 0) return 0; if(buf == 0){ errno = EFAULT; return -1; } f = &_fdinfo[d]; noblock = f->oflags&O_NONBLOCK; isbuf = f->flags&(FD_BUFFERED|FD_BUFFEREDX); if(noblock || isbuf){ if(f->flags&FD_BUFFEREDX) { errno = EIO; return -1; } if(!isbuf) { if(_startbuf(d) != 0) { errno = EIO; return -1; } } n = _readbuf(d, buf, nbytes, noblock); }else{ n = _READ(d, buf, nbytes); if(n < 0) _syserrno(); } return n; }
pid_t tcgetpgrp(int fd) { int n; pid_t pgrp; char buf[100]; if(!isptty(fd)) { errno = ENOTTY; return -1; } if(_SEEK(fd, -2, 0) != -2) { _syserrno(); return -1; } n = _READ(fd, buf, sizeof(buf)); if(n < 0) { _syserrno(); return -1; } pgrp = atoi(buf+24+(NCCS*3)); return pgrp; }
int rename(const char *from, const char *to) { int n; char *f, *t; Dir *d, nd; if(access(to, 0) >= 0){ if(_REMOVE(to) < 0){ _syserrno(); return -1; } } if((d = _dirstat(to)) != nil){ free(d); errno = EEXIST; return -1; } if((d = _dirstat(from)) == nil){ _syserrno(); return -1; } f = strrchr(from, '/'); t = strrchr(to, '/'); f = f? f+1 : (char *)from; t = t? t+1 : (char *)to; n = 0; if(f-from==t-to && strncmp(from, to, f-from)==0){ /* from and to are in same directory (we miss some cases) */ _nulldir(&nd); nd.name = t; if(_dirwstat(from, &nd) < 0){ _syserrno(); n = -1; } }else{ /* different directories: have to copy */ int ffd, tfd; char buf[8192]; tfd = -1; if((ffd = _OPEN(from, 0)) < 0 || (tfd = _CREATE(to, 1, d->mode)) < 0){ _CLOSE(ffd); _syserrno(); n = -1; } while(n>=0 && (n = _READ(ffd, buf, 8192)) > 0) if(_WRITE(tfd, buf, n) != n){ _syserrno(); n = -1; } _CLOSE(ffd); _CLOSE(tfd); if(n>0) n = 0; if(n == 0) { if(_REMOVE(from) < 0){ _syserrno(); return -1; } } } free(d); return n; }
void _envsetup(void) { int dfd, fdinited, n, nd, m, i, j, f, nohandle, psize, cnt; char *ps, *p; char **pp; char name[NAME_MAX+5]; Dir *d9, *d9a; static char **emptyenvp = 0; environ = emptyenvp; /* pessimism */ nohandle = 0; fdinited = 0; cnt = 0; strcpy(name, "#e"); dfd = _OPEN(name, 0); if(dfd < 0) return; name[2] = '/'; ps = p = malloc(Envhunk); if(p == 0) return; psize = Envhunk; nd = _dirreadall(dfd, &d9a); _CLOSE(dfd); for(j=0; j<nd; j++) { d9 = &d9a[j]; n = strlen(d9->name); if(n >= sizeof name - 4) continue; /* shouldn't be possible */ m = d9->length; i = p - ps; if(i+n+1+m+1 > psize) { psize += (n+m+2 < Envhunk)? Envhunk : n+m+2; ps = realloc(ps, psize); if (ps == 0) { free(d9a); return; } p = ps + i; } memcpy(p, d9->name, n); p[n] = '='; strcpy(name+3, d9->name); f = _OPEN(name, O_RDONLY); if(f < 0 || _READ(f, p+n+1, m) != m) m = 0; _CLOSE(f); if(p[n+m] == 0) m--; for(i=0; i<m; i++) if(p[n+1+i] == 0) p[n+1+i] = 1; p[n+1+m] = 0; if(strcmp(d9->name, "_fdinfo") == 0) { _fdinit(p+n+1, p+n+1+m); fdinited = 1; } else if(strcmp(d9->name, "_sighdlr") == 0) sigsetup(p+n+1, p+n+1+m); else if(strcmp(d9->name, "nohandle") == 0) nohandle = 1; p += n+m+2; cnt++; } free(d9a); if(!fdinited) _fdinit(0, 0); pp = malloc((1+cnt)*sizeof(char *)); if (pp == 0) return; environ = pp; p = ps; for(i = 0; i < cnt; i++) { *pp++ = p; p = memchr(p, 0, ps+psize-p); if (!p) break; p++; } *pp = 0; if(!nohandle) _NOTIFY(_notehandler); }