ssize_t read(int socket, void *buf, size_t count) { int fd; init_preload(); return (fd_fork_get(socket, &fd) == fd_rsocket) ? rread(fd, buf, count) : real.read(fd, buf, count); }
static void rnfs3(void *v) { SunMsg *m; m = v; switch(m->call->type){ default: abort(); case Nfs3CallTNull: rnull0(m); break; case Nfs3CallTGetattr: rgetattr(m); break; case Nfs3CallTLookup: rlookup(m); break; case Nfs3CallTAccess: raccess(m); break; case Nfs3CallTReadlink: rreadlink(m); break; case Nfs3CallTRead: rread(m); break; case Nfs3CallTReadDir: rreaddir(m); break; case Nfs3CallTReadDirPlus: rreaddirplus(m); break; case Nfs3CallTFsStat: rfsstat(m); break; case Nfs3CallTFsInfo: rfsinfo(m); break; case Nfs3CallTPathconf: rpathconf(m); break; case Nfs3CallTSetattr: case Nfs3CallTWrite: case Nfs3CallTCreate: case Nfs3CallTMkdir: case Nfs3CallTSymlink: case Nfs3CallTMknod: case Nfs3CallTRemove: case Nfs3CallTRmdir: case Nfs3CallTLink: case Nfs3CallTCommit: rrofs(m); break; } }
static int compress_fd (int from, int to) { ssize_t us, cs, len; u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; u8 *header; nr_read = nr_written = 0; while ((us = rread (from, &buf1[MAX_HDR_SIZE], blocksize)) > 0) { cs = lzf_compress (&buf1[MAX_HDR_SIZE], us, &buf2[MAX_HDR_SIZE], us > 4 ? us - 4 : us); if (cs) { header = &buf2[MAX_HDR_SIZE - TYPE1_HDR_SIZE]; header[0] = 'Z'; header[1] = 'V'; header[2] = 1; header[3] = cs >> 8; header[4] = cs & 0xff; header[5] = us >> 8; header[6] = us & 0xff; len = cs + TYPE1_HDR_SIZE; } else { // write uncompressed header = &buf1[MAX_HDR_SIZE - TYPE0_HDR_SIZE]; header[0] = 'Z'; header[1] = 'V'; header[2] = 0; header[3] = us >> 8; header[4] = us & 0xff; len = us + TYPE0_HDR_SIZE; } if (raw) { header = &buf2[MAX_HDR_SIZE]; len = cs; } if (wwrite (to, header, len) == -1) return -1; }
/* void testbitmask(void) { setmaskbit(31); setmaskbit(95); setmaskbit(159);setmaskbit(223); setmaskbit(287); setmaskbit(351); setmaskbit(415);setmaskbit(479); setmaskbit(90); setmaskbit(154);setmaskbit(218); setmaskbit(282); setmaskbit(346); setmaskbit(347); setmaskbit(348); setmaskbit(349); setmaskbit(350); setmaskbit(100); setmaskbit(164);setmaskbit(228); setmaskbit(292); setmaskbit(356); setmaskbit(355); setmaskbit(354); setmaskbit(353); setmaskbit(352); printfreemask(); clearmaskbit(31); clearmaskbit(95); clearmaskbit(159);clearmaskbit(223); clearmaskbit(287); clearmaskbit(351); clearmaskbit(415);clearmaskbit(479); clearmaskbit(90); clearmaskbit(154);clearmaskbit(218); clearmaskbit(282); clearmaskbit(346); clearmaskbit(347); clearmaskbit(348); clearmaskbit(349); clearmaskbit(350); clearmaskbit(100); clearmaskbit(164);clearmaskbit(228); clearmaskbit(292); clearmaskbit(356); clearmaskbit(355); clearmaskbit(354); clearmaskbit(353); clearmaskbit(352); printfreemask(); } */ void test_fs(void){ int fd1, fd2; //File descriptors fd1 = fcreat("Test File", 0); //Creating a new file printf("Helo %d\n", fd1); //fd2 = fcreat("Sample", 0); //Creating a new file fd1 = fopen("Test File", 1);//Opening a file in write-only mode printf("file opened in write only mode..%d\n",fd1); wwrite(fd1); fclose(fd1); //fwrite(fd1, ) fd1 = fopen("Test File", 0); //Opening the same file in Read only mode rread(fd1); //fclose(fd1); //fd2 = fopen("Sample", 1); //Opening a file in write only mode //fwrite(fd2, ) //fseek(fd2, 2); //fd2 = fopen("Sample", 0); //Opening a file in read only mode //rread(fd2); //fclose(fd2); }
static void service(int cfd, int sfd, int dfd) { Fcall f; int r; Fid* fp; fidpool = allocfidpool(nop); for(;;){ fp = nil; r = getfcall(cfd, &f); if (r <= 0){ fprint(dfd, "trfs: getfcall %r\n"); break; } if(verbose) fprint(dfd , "c→s %F\n", &f); switch(f.type){ case Tclunk: case Tremove: // BUG in lib9p? removefid leaks fid. // is that what it should do? fp = lookupfid(fidpool, f.fid); if (fp != nil){ removefid(fidpool, f.fid); closefid(fp); closefid(fp); fp = nil; } break; case Tcreate: tcreate(&f); // and also... case Topen: fp = allocfid(fidpool, f.fid); fp->aux = 0; break; case Tread: tread(&f); break; case Twalk: twalk(&f); break; case Twstat: twstat(&f); break; } if(verbose && debug) fprint(dfd , "c→s %F\n", &f); if (putfcall(sfd, &f) < 0) fprint(dfd , "can't putfcall: %r\n"); r = getfcall(sfd, &f); if (r <= 0){ fprint(dfd, "trfs: 2nd getfcall %r\n"); break; } if (verbose) fprint(dfd, "c←s %F\n", &f); switch(f.type){ case Ropen: case Rcreate: fp->qid = f.qid; break; case Rread: rread(&f); break; case Rstat: rstat(&f); break; } if(verbose && debug) fprint(dfd , "c←s %F\n", &f); if (putfcall(cfd, &f) < 0) fprint(dfd , "can't 2n dputfcall: %r\n"); if (fp != nil) closefid(fp); } }
void rfServ_(int acceptSock) { static char fname[] = "rfServ_()"; struct LSFHeader msgHdr; struct LSFHeader buf; struct sockaddr_in from; socklen_t fromLen = sizeof(from); int sock; XDR xdrs; sock = accept(acceptSock, (struct sockaddr *)&from, &fromLen); if (sock < 0) { ls_errlog(stderr, I18N_FUNC_FAIL_MM, fname, "readDecodeHdr_"); closesocket(acceptSock); return; } xdrmem_create(&xdrs, (char *) &buf, sizeof(buf), XDR_DECODE); for (;;) { XDR_SETPOS(&xdrs, 0); if (readDecodeHdr_(sock, (char *)&buf, SOCK_READ_FIX, &xdrs, &msgHdr) < 0) { ls_errlog(stderr, I18N_FUNC_FAIL_MM, fname, "readDecodeHdr_"); closesocket(sock); xdr_destroy(&xdrs); return; } switch (msgHdr.opCode) { case RF_OPEN: ropen(sock, &msgHdr); break; case RF_CLOSE: rclose(sock, &msgHdr); break; case RF_WRITE: rwrite(sock, &msgHdr); break; case RF_READ: rread(sock, &msgHdr); break; case RF_STAT: rstat(sock, &msgHdr); break; case RF_GETMNTHOST: rgetmnthost(sock, &msgHdr); break; case RF_FSTAT: rfstat(sock, &msgHdr); break; case RF_LSEEK: rlseek(sock, &msgHdr); break; case RF_UNLINK: runlink(sock, &msgHdr); break; case RF_TERMINATE: closesocket(sock); return; default: ls_errlog(stderr, _i18n_msg_get(ls_catd, NL_SETN, 602, "%s: Unknown opcode %d"), fname, msgHdr.opCode); xdr_destroy(&xdrs); break; } } }
void respond(Req *r, char *error) { int i, m, n; char errbuf[ERRMAX]; Srv *srv; srv = r->srv; assert(srv != nil); if(r->responded){ assert(r->pool); goto free; } assert(r->responded == 0); r->error = error; switch(r->ifcall.type){ default: assert(0); /* * Flush is special. If the handler says so, we return * without further processing. Respond will be called * again once it is safe. */ case Tflush: if(rflush(r, error)<0) return; break; case Tversion: rversion(r, error); break; case Tauth: rauth(r, error); break; case Tattach: rattach(r, error); break; case Twalk: rwalk(r, error); break; case Topen: ropen(r, error); break; case Tcreate: rcreate(r, error); break; case Tread: rread(r, error); break; case Twrite: rwrite(r, error); break; case Tclunk: rclunk(r, error); break; case Tremove: rremove(r, error, errbuf); break; case Tstat: rstat(r, error); break; case Twstat: rwstat(r, error); break; } r->ofcall.tag = r->ifcall.tag; r->ofcall.type = r->ifcall.type+1; if(r->error) setfcallerror(&r->ofcall, r->error); if(chatty9p) fprint(2, "-%d-> %F\n", srv->outfd, &r->ofcall); qlock(&srv->wlock); n = convS2M(&r->ofcall, srv->wbuf, srv->msize); if(n <= 0){ fprint(2, "n = %d %F\n", n, &r->ofcall); abort(); } assert(n > 2); /* * There is a race here - we must remove the entry before * the write, so that if the client is very fast and reuses the * tag, the read loop won't think it is still in use. * * By removing the entry before the write, we open up a * race with incoming Tflush messages. Specifically, an * incoming Tflush might not see r even though it has not * yet been responded to. It would then send an Rflush * immediately, potentially before we do the write. This can't * happen because we already old srv->wlock, so nothing * is going out on the wire before this write. */ if(r->pool) /* not a fake */ closereq(removereq(r->pool, r->ifcall.tag)); qlock(&r->lk); r->responded = 1; if(r->pool) if(r->ref.ref == 1+r->nflush) if(r->fid){ /* * There are no references other than in our r->flush array, * so no one else should be accessing r concurrently. * Close the fid now, before responding to the message. * * If the client is behaving (there are no outstanding T-messages * that reference r->fid) and the message is a Tclunk or Tremove, * then this closefid will call destroyfid. * * This means destroyfid can't piddle around * indefinitely (we're holding srv->wlock!), but it provides * for tighter semantics as to when destroyfid is called. * * LANL has observed cases where waiting until after the write * can delay a closefid on a Twrite for many 9P transactions, * so that a handful of transactions can happen including a Tclunk * and a Topen, and the original fid will still not be destroyed. */ closefid(r->fid); r->fid = nil; } qunlock(&r->lk); m = write(srv->outfd, srv->wbuf, n); if(m != n) sysfatal("lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd); qunlock(&srv->wlock); free: qlock(&r->lk); /* no one will add flushes now */ for(i=0; i<r->nflush; i++){ r->flush[i]->oldreq = nil; /* so it doesn't try to lock us! */ respond(r->flush[i], nil); } free(r->flush); r->flush = nil; r->nflush = 0; qunlock(&r->lk); if(r->pool) closereq(r); else free(r); }
void respond(Req *r, char *error) { int i, m, n; char errbuf[ERRMAX]; Srv *srv; srv = r->srv; assert(srv != nil); assert(r->responded == 0); r->error = error; switch(r->ifcall.type){ default: assert(0); /* * Flush is special. If the handler says so, we return * without further processing. Respond will be called * again once it is safe. */ case Tflush: if(rflush(r, error)<0) return; break; case Tversion: rversion(r, error); break; case Tauth: rauth(r, error); break; case Tattach: rattach(r, error); break; case Twalk: rwalk(r, error); break; case Topen: ropen(r, error); break; case Tcreate: rcreate(r, error); break; case Tread: rread(r, error); break; case Twrite: rwrite(r, error); break; case Tclunk: rclunk(r, error); break; case Tremove: rremove(r, error, errbuf); break; case Tstat: rstat(r, error); break; case Twstat: rwstat(r, error); break; } r->ofcall.tag = r->ifcall.tag; r->ofcall.type = r->ifcall.type+1; if(r->error) setfcallerror(&r->ofcall, r->error); if(chatty9p) fprint(2, "-%d-> %F\n", srv->outfd, &r->ofcall); qlock(&srv->wlock); n = convS2M(&r->ofcall, srv->wbuf, srv->msize); if(n <= 0){ fprint(2, "n = %d %F\n", n, &r->ofcall); abort(); } assert(n > 2); if(r->pool) /* not a fake */ closereq(removereq(r->pool, r->ifcall.tag)); m = write(srv->outfd, srv->wbuf, n); if(m != n) sysfatal("lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd); qunlock(&srv->wlock); qlock(&r->lk); /* no one will add flushes now */ r->responded = 1; qunlock(&r->lk); for(i=0; i<r->nflush; i++) respond(r->flush[i], nil); free(r->flush); r->flush = nil; r->nflush = 0; if(r->pool) closereq(r); else free(r); }
static void *job_thread(void *arg) { struct mfile *mf; struct job *job = arg; spinlock_lock(&dblock); mf = newfid(job->request.fid); if (debug) fprintf(stderr, "CS:%F", &job->request); switch (job->request.type) { default: fprintf(stderr, "CS:unknown request type %d", job->request.type); break; case Tversion: rversion(job); break; case Tauth: rauth(job); break; case Tflush: rflush(job); break; case Tattach: rattach(job, mf); break; case Twalk: rwalk(job, mf); break; case Topen: ropen(job, mf); break; case Tcreate: rcreate(job, mf); break; case Tread: rread(job, mf); break; case Twrite: rwrite(job, mf); break; case Tclunk: rclunk(job, mf); break; case Tremove: rremove(job, mf); break; case Tstat: rstat(job, mf); break; case Twstat: rwstat(job, mf); break; } spinlock_unlock(&dblock); freejob(job); if (debug) fprintf(stderr, "CS:Job done\n"); return 0; }
void io(void) { volatile long n; volatile uchar mdata[IOHDRSZ + Maxfdata]; Job *volatile job; Mfile *volatile mf; volatile Request req; memset(&req, 0, sizeof req); /* * a slave process is sometimes forked to wait for replies from other * servers. The master process returns immediately via a longjmp * through 'mret'. */ if(setjmp(req.mret)) putactivity(0); req.isslave = 0; stop = 0; while(!stop){ procsetname("%d %s/dns Twrites of %d 9p rpcs read; %d alarms", stats.qrecvd9p, mntpt, stats.qrecvd9prpc, stats.alarms); n = read9pmsg(mfd[0], mdata, sizeof mdata); if(n<=0){ dnslog("error reading 9P from %s: %r", mntpt); sleep(2000); /* don't thrash after read error */ return; } stats.qrecvd9prpc++; job = newjob(); if(convM2S(mdata, n, &job->request) != n){ freejob(job); continue; } mf = newfid(job->request.fid, 0); if(debug) dnslog("%F", &job->request); getactivity(&req, 0); req.aborttime = timems() + Maxreqtm; req.from = "9p"; switch(job->request.type){ default: warning("unknown request type %d", job->request.type); break; case Tversion: rversion(job); break; case Tauth: rauth(job); break; case Tflush: rflush(job); break; case Tattach: rattach(job, mf); break; case Twalk: rwalk(job, mf); break; case Topen: ropen(job, mf); break; case Tcreate: rcreate(job, mf); break; case Tread: rread(job, mf); break; case Twrite: /* &req is handed to dnresolve() */ rwrite(job, mf, &req); break; case Tclunk: rclunk(job, mf); break; case Tremove: rremove(job, mf); break; case Tstat: rstat(job, mf); break; case Twstat: rwstat(job, mf); break; } freejob(job); /* * slave processes die after replying */ if(req.isslave){ putactivity(0); _exits(0); } putactivity(0); } /* kill any udp server, notifier, etc. processes */ postnote(PNGROUP, getpid(), "die"); sleep(1000); }
//! List a range of SAVED records. //! Checks that the time specified is not later than device time // void listRecordsSince(const char* since) { struct weatherRecord record; char datestr[17]; // convert date/time given to time_t time_t since_t = cvtStr2Time_t(since); // get current date and time - getDateTime() found in header.h char* devtimestr = (char*) getDateTime(); //printf("DEBUG: device date = %s\n", devtimestr); time_t devtime = cvtStr2Time_t(devtimestr); // check for since date in the future if (since_t > devtime) { printf("Date %s is in the future, date now is %s\n", since, getDateTime()); exit(1); } // maximum number of records, getRecordsStored() in header.h int guard = getRecordsStored(); //printf("DEBUG: (main.c) there are %d records stored\n", guard); int headings = (options.verbose == 1) ? 1 : 0; // Record 0 is the current reading, it is continually overwritten until the // polling period is reached, at which time a new current record is started // with a 0 second delay. int recordidx = 0; // skip the 0 record as it is the current value and should be read using // -r 0 // (rread() found in wrecord.h) weatherRecordPtr p = rread(&record, recordidx++); // calculate time of the first saved record time_t tmptime = devtime - (record.interval * 60); // starting with the first saved record (recordidx == 1) // while the record time is greater than the time since (and there are records!) // output the result while((tmptime > since_t) && (recordidx < guard)) { // read the record p = rread(&record, recordidx++); // calculate its date/time tmptime -= (record.interval * 60); // if it is later than since then print it if (tmptime > since_t) { cvtTime2Str(datestr, 17, &tmptime); // tell getDateTime() to use our date/time (usedate is external, see header.h) usedate = datestr; if (options.verbose == 0) { rprints(&record, recordPrintSpecification, fieldseparator); } else { rprintv(&record, recordPrintSpecification, fieldseparator, headings); } // reset getDateTime() to use device time usedate = NULL; // no more headings for this list headings = 0; } } }
//! List a range of records. //! Checks that the end is not greater than the number of records stored // void listRecords(int start, int end) { struct weatherRecord record; //printf("DEBUG: -r %d:%d\n", start, end); if (end < start) { end = start; } int numrecs = getRecordsStored(); //printf("DEBUG: (main.c) there are %d records stored\n", numrecs); if (end >= numrecs) { printf("invalid end record number %d\n", end); return; } // set up for storing the time of readings // convert date/time given to time_t // get current date and time using getDateTime() (see header.h) char* devtimestr = (char*) getDateTime(); //printf("DEBUG: device date = %s\n", devtimestr); time_t devtime = cvtStr2Time_t(devtimestr); // prepare, get a record pointer and a record counter and temp time weatherRecordPtr p = NULL; int recordidx = 0; time_t tmptime = devtime; if (daterequired()) { // read up to the starting record, adjusting time while(recordidx < start) { // calculate time of the first stored record using rread() (see wrecord.h) p = rread(&record, recordidx++); tmptime -= (record.interval * 60); } } else { recordidx = start; } // now recordidx is pointing at the first record to be listed // and tmptime is holding the time of that record // get date string storage char datestr[17]; // see if headings are to be printed, for options see cmdline.h int headings = (options.verbose == 1) ? 1 : 0; // loop through the records to be listed while(recordidx <= end) { // read the record (see wrecord.h) p = rread(&record, recordidx++); // convert the date to a string cvtTime2Str(datestr, 17, &tmptime); // tell getDateTime() to use our date/time (usedate is external, see header.h) usedate = datestr; // print the record using functions specified in wrecord.h if (options.verbose == 0) { rprints(&record, recordPrintSpecification, fieldseparator); } else { rprintv(&record, recordPrintSpecification, fieldseparator, headings); } // calculate date/time of next saved record tmptime -= (record.interval * 60); // reset getDateTime() to use device time usedate = NULL; // no more headings for this list headings = 0; } /* int headings = (options.verbose == 1) ? 1 : 0; for(int i = end; i >= 0 && i >= start; i--) { rread(&record, i); if (options.verbose == 0) { rprints(&record, recordPrintSpecification, fieldseparator); } else { rprintv(&record, recordPrintSpecification, fieldseparator, headings); } headings = 0; } */ }
void ioproc0(void *v) { long n; Mfile *mf; uchar mdata[IOHDRSZ + Maxfdata]; Request req; Job *job; USED(v); for(;;){ n = read9pmsg(mfd[0], mdata, sizeof mdata); if(n <= 0){ syslog(0, logfile, "error reading mntpt: %r"); break; } job = newjob(); if(convM2S(mdata, n, &job->request) != n){ freejob(job); continue; } if(debug) syslog(0, logfile, "%F", &job->request); getactivity(&req); req.aborttime = now + 60; /* don't spend more than 60 seconds */ mf = nil; switch(job->request.type){ case Tversion: case Tauth: case Tflush: break; case Tattach: mf = newfid(job->request.fid, 1); if(mf == nil){ sendmsg(job, "fid in use"); goto skip; } break; default: mf = newfid(job->request.fid, 0); if(mf == nil){ sendmsg(job, "unknown fid"); goto skip; } break; } switch(job->request.type){ default: syslog(1, logfile, "unknown request type %d", job->request.type); break; case Tversion: rversion(job); break; case Tauth: rauth(job); break; case Tflush: rflush(job); break; case Tattach: rattach(job, mf); break; case Twalk: rwalk(job, mf); break; case Topen: ropen(job, mf); break; case Tcreate: rcreate(job, mf); break; case Tread: rread(job, mf); break; case Twrite: rwrite(job, mf, &req); break; case Tclunk: rclunk(job, mf); break; case Tremove: rremove(job, mf); break; case Tstat: rstat(job, mf); break; case Twstat: rwstat(job, mf); break; } skip: freejob(job); putactivity(); } }