int ptyfs_close(void *v) { struct vop_close_args /* { struct vnode *a_vp; int a_fflag; kauth_cred_t a_cred; } */ *ap = v; struct vnode *vp = ap->a_vp; struct ptyfsnode *ptyfs = VTOPTYFS(vp); mutex_enter(&vp->v_interlock); if (vp->v_usecount > 1) PTYFS_ITIMES(ptyfs, NULL, NULL, NULL); mutex_exit(&vp->v_interlock); switch (ptyfs->ptyfs_type) { case PTYFSpts: case PTYFSptc: return spec_close(v); case PTYFSroot: return 0; default: return EINVAL; } }
int tmpfs_spec_close(void *v) { struct vop_close_args /* { struct vnode *a_vp; int a_fflag; kauth_cred_t a_cred; } */ *ap = v; struct vnode *vp = ap->a_vp; tmpfs_update(VP_TO_TMPFS_NODE(vp), NULL); return (spec_close(ap)); }
/* * Close wrapper for special devices. * * Update the times on the inode then do device close. */ int ufsspec_close(void *v) { struct vop_close_args *ap = v; struct vnode *vp = ap->a_vp; struct inode *ip = VTOI(vp); if (ap->a_vp->v_usecount > 1) { struct timeval tv; getmicrotime(&tv); ITIMES(ip, &tv, &tv); } return (spec_close(ap)); }
/* based on minimal daemon code from the daemon-HOWTO */ int main(void) { /* Our process ID and Session ID */ pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { //syslog(LOG_ERR,"setsid() error. EXIT."); exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir("/")) < 0) { /* Log the failure */ //syslog(LOG_ERR,"chdir() error. EXIT."); exit(EXIT_FAILURE); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* Daemon-specific initialization goes here */ /* use syslog */ setlogmask (LOG_UPTO (LOG_NOTICE)); openlog ("spec_ptp2ntpd", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); syslog (LOG_NOTICE, "Program started by User %d", getuid()); // Attach to SPEC shared memory int bar = BASE_BAR0; int bus = -1, dev_fn = -1; void *card; void *map_base; card = spec_open(bus, dev_fn); if(!card) { syslog(LOG_ERR, "Can't detect a SPEC card under the given " "adress. Make sure a SPEC card is present in your PC, " "the driver is loaded and you run the program as root. EXIT.\n"); exit(1); } syslog(LOG_NOTICE,"Found SPEC at %x \n",(uint)card); map_base = spec_get_base(card, bar); if(!map_base || map_base == (void *) -1) { syslog(LOG_ERR,"mmap(/dev/mem): %s. EXIT.\n", strerror(errno)); syslog(LOG_ERR, "map_base = %x \n",(uint)map_base); exit(1); } syslog(LOG_NOTICE,"map_base = %u \n",(uint)map_base); syslog (LOG_NOTICE, "Attached to SPEC SHM at %x", (uint)map_base); // attach to NTP shared memory T = getShmTime(0); if (T==0) { /* error */ syslog(LOG_ERR,"getShmTime() error"); syslog(LOG_ERR,"EXITING."); exit(EXIT_FAILURE); } else { syslog (LOG_NOTICE, "Attached to NTP SHM at %x", (uint)T); } // initialize T->mode=1; // does it matter? set here or by NTP? T->leap=0; // ? T->precision=-10; //? T->nsamples=10; // ? shmdt(T); //detach struct timeval tv; uint32_t nsec_cycles, s_lsb, usecs; double cycle = 1/125e6; uint32_t nsecs; /* The Big Loop */ while (1) { T = getShmTime(0); // attach to shared memory gettimeofday(&tv,NULL); // system time-stamp // WR time nsec_cycles = read_mem(map_base, 4 ); // read nanoseconds, in number of 62.5MHz ref cycles nsecs = (uint32_t) (cycle*nsec_cycles*1e9); usecs = (uint32_t) (cycle*nsec_cycles*1e6); s_lsb = read_mem(map_base, 8 ); // read utc lsb //s_msb = read_mem(map_base, 12 ); // read utc msb // clock time T->clockTimeStampSec = s_lsb; T->clockTimeStampUSec = usecs; // offset 4 msec, just for fun T->clockTimeStampNSec = nsecs; // time stamp T->receiveTimeStampSec = tv.tv_sec; T->receiveTimeStampUSec = tv.tv_usec; T->receiveTimeStampNSec = tv.tv_usec*1000; T->valid = 1; T->count += 1; shmdt(T); // detach, required here? syslog (LOG_NOTICE, "WR time is %d.%09d ", (int)s_lsb,(int)nsecs); syslog (LOG_NOTICE, "system time is %d.%06d ", (int)tv.tv_sec,(int)tv.tv_usec); sleep(8); // minpoll is 4, so NTP reads every 16s } spec_close(card); closelog(); exit(EXIT_SUCCESS); }