// Chtimes changes the access and modification times of the named
// file, similar to the Unix utime() or utimes() functions.
//
// The argument times are in nanoseconds, although the underlying
// filesystem may truncate or round the values to a more
// coarse time unit.
func Chtimes(name string, atime_ns int64, mtime_ns int64) Error {
	var utimes [2]syscall.Timeval
	utimes[0] = syscall.NsecToTimeval(atime_ns)
	utimes[1] = syscall.NsecToTimeval(mtime_ns)
	if e := syscall.Utimes(name, utimes[0:]); e != 0 {
		return &PathError{"chtimes", name, Errno(e)}
	}
	return nil
}
Example #2
0
// Chtimes changes the access and modification times of the named
// file, similar to the Unix utime() or utimes() functions.
//
// The underlying filesystem may truncate or round the values to a
// less precise time unit.
func Chtimes(name string, atime time.Time, mtime time.Time) error {
	var utimes [2]syscall.Timeval
	atime_ns := atime.Unix()*1e9 + int64(atime.Nanosecond())
	mtime_ns := mtime.Unix()*1e9 + int64(mtime.Nanosecond())
	utimes[0] = syscall.NsecToTimeval(atime_ns)
	utimes[1] = syscall.NsecToTimeval(mtime_ns)
	if e := syscall.Utimes(name, utimes[0:]); e != nil {
		return &PathError{"chtimes", name, e}
	}
	return nil
}
Example #3
0
func setClock(t time.Time) error {
	tv := syscall.NsecToTimeval(t.UnixNano())
	if err := syscall.Settimeofday(&tv); err != nil {
		return errors.New("settimeofday: " + err.Error())
	}
	return nil
}
Example #4
0
File: api3.go Project: ziutek/dvb
// WaitEvent can return dvb.ErrOverflow. If deadline is non zero time WaitEvent
// returns true if it doesn't receive any event up to deatline.
func (f API3) WaitEvent(ev *Event, deadline time.Time) (bool, error) {
	fd := f.Fd()
	if !deadline.IsZero() {
		timeout := deadline.Sub(time.Now())
		if timeout <= 0 {
			return true, nil
		}
		var r syscall.FdSet
		r.Bits[fd/64] = 1 << (fd % 64)
		tv := syscall.NsecToTimeval(int64(timeout))
		n, err := syscall.Select(int(fd+1), &r, nil, nil, &tv)
		if err != nil {
			return false, Error{"get", "event (select)", err}
		}
		if n == 0 {
			return true, nil
		}
	}
	_, _, e := syscall.Syscall(
		syscall.SYS_IOCTL,
		fd,
		_FE_GET_EVENT,
		uintptr(unsafe.Pointer(ev)),
	)
	if e != 0 {
		if e == syscall.EOVERFLOW {
			return false, dvb.ErrOverflow
		}
		return false, Error{"get", "event", e}
	}
	return false, nil
}
func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.Error) {
	if p.nReady == 0 {
		var timeout *syscall.Timeval
		var tv syscall.Timeval
		timeout = nil
		if nsec > 0 {
			tv = syscall.NsecToTimeval(nsec)
			timeout = &tv
		}

		var n, e int
		var tmpReadFds, tmpWriteFds syscall.FdSet_t
		for {
			// Temporary syscall.FdSet_ts into which the values are copied
			// because select mutates the values.
			tmpReadFds = *p.readFds
			tmpWriteFds = *p.writeFds

			n, e = syscall.Select(p.maxFd+1, &tmpReadFds, &tmpWriteFds, nil, timeout)
			if e != syscall.EINTR {
				break
			}
		}
		if e != 0 {
			return -1, 0, os.NewSyscallError("select", e)
		}
		if n == 0 {
			return -1, 0, nil
		}

		p.nReady = n
		*p.readyReadFds = tmpReadFds
		*p.readyWriteFds = tmpWriteFds
		p.lastFd = 0
	}

	flag := false
	for i := p.lastFd; i < p.maxFd+1; i++ {
		if syscall.FDIsSet(i, p.readyReadFds) {
			flag = true
			mode = 'r'
			syscall.FDClr(i, p.readyReadFds)
		} else if syscall.FDIsSet(i, p.readyWriteFds) {
			flag = true
			mode = 'w'
			syscall.FDClr(i, p.readyWriteFds)
		}
		if flag {
			if !syscall.FDIsSet(i, p.repeatFds) {
				p.DelFD(i, mode)
			}
			p.nReady--
			p.lastFd = i
			return i, mode, nil
		}
	}

	// Will not reach here.  Just to shut up the compiler.
	return -1, 0, nil
}
Example #6
0
func traceOne(addr *syscall.SockaddrInet4, ttl int) *ReturnArgs {
	cli, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		exitWithError(err)
	}
	srv, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
	if err != nil {
		exitWithError(err)
	}

	defer syscall.Close(cli)
	defer syscall.Close(srv)

	// set ttl, stolen from somewhere else...
	// https://github.com/aeden/traceroute/blob/master/traceroute.go#L195
	if err := syscall.SetsockoptInt(cli, syscall.SOL_IP, syscall.IP_TTL, ttl); err != nil {
		exitWithError(err)
	}

	// set timeout, stolen from somewhere else...
	// https://github.com/aeden/traceroute/blob/master/traceroute.go#L197
	tv := syscall.NsecToTimeval(1e6 * TIMEOUT)
	if err := syscall.SetsockoptTimeval(srv, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv); err != nil {
		exitWithError(err)
	}
	if err := syscall.Bind(srv, toAddr(HOST, RECV_PORT)); err != nil {
		exitWithError(err)
	}

	rr := &ReturnArgs{}
	start := time.Now()
	if err := syscall.Sendto(cli, makeICMP(), 0, addr); err != nil {
		return rr
	}

	buf := make([]byte, 512)
	_, from, err := syscall.Recvfrom(srv, buf, 0)
	if err != nil {
		return rr
	}

	rr.elapsed = float64(time.Since(start).Nanoseconds()) / 1e6
	t, c := parseICMP(buf)
	if t == 3 && c == 3 { // Destination port unreachable, type==3 && code==3
		rr.done = true
	} else if t != 11 { // Time Exceeded, type==11 && code in (0,1)
		return rr
	}
	rr.ok = true
	rr.ip = toStr(from)
	addrs, err := net.LookupAddr(rr.ip)
	if err != nil {
		rr.addr = rr.ip
	} else {
		rr.addr = addrs[0]
	}
	return rr
}
Example #7
0
File: select.go Project: yubo/gotty
// Select wraps syscall.Select with Go types
func Select(n int, r, w, e *FDSet, timeout time.Duration) error {
	var timeval *syscall.Timeval
	if timeout >= 0 {
		t := syscall.NsecToTimeval(timeout.Nanoseconds())
		timeval = &t
	}

	return sysSelect(n, r, w, e, timeval)
}
Example #8
0
File: trace.go Project: mag-/gtr
// Traceroute executes traceroute to given destination, using options from TracerouteOptions
// and sending updates to chan c
//
// Outbound packets are UDP packets and inbound packets are ICMP.
//
// Returns an error or nil if no error occurred
func Traceroute(dest *net.IPAddr, options *TracerouteOptions, c chan TraceUpdate) (err error) {
	var destAddr [4]byte
	copy(destAddr[:], dest.IP.To4())
	socketAddr, err := getSocketAddr()
	if err != nil {
		return
	}

	timeoutMs := (int64)(options.TimeoutMs)
	tv := syscall.NsecToTimeval(1000 * 1000 * timeoutMs)

	ttl := 1
	for {
		// Set up receiving socket
		recvSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
		if err != nil {
			log.Fatal("Cannot setup receive socket, please run as root or with CAP_NET_RAW permissions")
			return err
		}
		// Set up sending socket
		sendSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
		if err != nil {
			log.Fatal("Cannot setup sending socket")
			return err
		}

		start := time.Now()
		syscall.SetsockoptInt(sendSocket, 0x0, syscall.IP_TTL, ttl)
		syscall.SetsockoptTimeval(recvSocket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
		syscall.Bind(recvSocket, &syscall.SockaddrInet4{Port: options.Port, Addr: socketAddr})
		syscall.Sendto(sendSocket, []byte{0x0}, 0, &syscall.SockaddrInet4{Port: options.Port, Addr: destAddr})

		var p = make([]byte, options.PacketSize)
		n, from, err := syscall.Recvfrom(recvSocket, p, 0)
		elapsed := time.Since(start)
		if err == nil {
			currAddr := from.(*syscall.SockaddrInet4).Addr
			hop := TraceUpdate{Success: true, Address: currAddr, N: n, ElapsedTime: elapsed, TTL: ttl}
			currHost, err := net.LookupAddr(hop.addressString())
			if err == nil {
				hop.Host = currHost[0]
			}
			// Send update
			c <- hop
			ttl += 1
			// We reached the destination
			if ttl > options.MaxTTL || currAddr == destAddr {
				ttl = 1
			}
		} else {
			c <- TraceUpdate{Success: false, TTL: ttl}
			ttl += 1
		}
		syscall.Close(recvSocket)
		syscall.Close(sendSocket)
	}
}
Example #9
0
// setSocketTimeout sets the receive and send timeouts on the given socket.
func setSocketTimeout(fd int, timeout time.Duration) error {
	tv := syscall.NsecToTimeval(timeout.Nanoseconds())
	for _, opt := range []int{syscall.SO_RCVTIMEO, syscall.SO_SNDTIMEO} {
		if err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, opt, &tv); err != nil {
			return os.NewSyscallError("setsockopt", err)
		}
	}
	return nil
}
Example #10
0
func (f *AzukiFile) Utimens(a *time.Time, m *time.Time) fuse.Status {
	tv := make([]syscall.Timeval, 2)
	if a == nil {
		tv[0].Usec = _UTIME_OMIT
	} else {
		n := a.UnixNano()
		tv[0] = syscall.NsecToTimeval(n)
	}

	if m == nil {
		tv[1].Usec = _UTIME_OMIT
	} else {
		n := a.UnixNano()
		tv[1] = syscall.NsecToTimeval(n)
	}

	err := syscall.Futimes(int(f.File.Fd()), tv)
	return fuse.ToStatus(err)
}
Example #11
0
func Hop(port, ttl int, IP_addr net.IP) (*Hop_ret, error) {

	ret_addr := net.IPv4(0, 0, 0, 0)
	success := false
	// make sockets
	send_udp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		return nil, err
	}
	recv_icmp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
	if err != nil {
		return nil, err
	}

	//editing TTL value for outgoing IPv4 packets
	if err := syscall.SetsockoptInt(send_udp_s, syscall.SOL_IP, syscall.IP_TTL, ttl); err != nil {
		return nil, err
	}
	tv := syscall.NsecToTimeval(1000 * 1000 * TIME_OUT_MS)
	syscall.SetsockoptTimeval(recv_icmp_s, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)

	defer syscall.Close(send_udp_s)
	defer syscall.Close(recv_icmp_s)

	//connect sockets
	if err := syscall.Bind(recv_icmp_s, &syscall.SockaddrInet4{Port: port, Addr: [4]byte{137, 224, 226, 47}}); err != nil {
		return nil, err
	}

	//send udp-packet
	var IP [4]byte
	copy(IP[:], IP_addr.To4())
	if err := syscall.Sendto(send_udp_s, []byte{0x42, 0x42}, 0, &syscall.SockaddrInet4{Port: 1337, Addr: IP}); err != nil {
		return nil, err
	}

	//receive ICMP
	recv_buffer := make([]byte, 4096)
	_, _, err = syscall.Recvfrom(recv_icmp_s, recv_buffer, 0)
	if err == nil {
		header, err := ipv4.ParseHeader(recv_buffer)
		if err != nil {
			log.Errorf("%q", err)
		}
		success = true
		ret_addr = header.Src
	} else {
		//time out
		success = false
		ret_addr = net.IPv4(0, 0, 0, 0)
		//log.Errorf("%q", err)
	}
	//resolve (timeout) errors, retry or return false...
	return &Hop_ret{Addr: ret_addr, TTL: ttl, success: success}, nil
}
Example #12
0
// This implementation should work for all systems that implement the utimes syscall
func (e *entry) SetMtime(mtime time.Time) error {
	tvMtime := syscall.NsecToTimeval(mtime.UnixNano())
	tvAtime := syscall.NsecToTimeval(time.Now().UnixNano())

	resolvedPath := resolveSymlink(e.realPath())

	err := syscall.Utimes(resolvedPath, []syscall.Timeval{tvAtime, tvMtime})

	if err != nil {
		return err
	}

	e.fileInfo, err = os.Stat(resolvedPath)

	if err != nil {
		return err
	}

	return nil
}
Example #13
0
// Take a shared lock on an object.
func (ioctx *IOContext) LockShared(oid, name, cookie, tag, desc string, duration time.Duration, flags *byte) (int, error) {
	c_oid := C.CString(oid)
	c_name := C.CString(name)
	c_cookie := C.CString(cookie)
	c_tag := C.CString(tag)
	c_desc := C.CString(desc)

	var c_duration C.struct_timeval
	if duration != 0 {
		tv := syscall.NsecToTimeval(time.Now().Add(duration).UnixNano())
		c_duration = C.struct_timeval{tv_sec: C.__time_t(tv.Sec), tv_usec: C.__suseconds_t(tv.Usec)}
	}

	var c_flags C.uint8_t
	if flags != nil {
		c_flags = C.uint8_t(*flags)
	}

	defer C.free(unsafe.Pointer(c_oid))
	defer C.free(unsafe.Pointer(c_name))
	defer C.free(unsafe.Pointer(c_cookie))
	defer C.free(unsafe.Pointer(c_tag))
	defer C.free(unsafe.Pointer(c_desc))

	ret := C.rados_lock_shared(
		ioctx.ioctx,
		c_oid,
		c_name,
		c_cookie,
		c_tag,
		c_desc,
		&c_duration,
		c_flags)

	// 0 on success, negative error code on failure
	// -EBUSY if the lock is already held by another (client, cookie) pair
	// -EEXIST if the lock is already held by the same (client, cookie) pair

	switch ret {
	case 0:
		return int(ret), nil
	case -16: // EBUSY
		return int(ret), nil
	case -17: // EEXIST
		return int(ret), nil
	default:
		return int(ret), RadosError(int(ret))
	}
}
Example #14
0
// SetSocketTimeout sets the send and receive timeout for each socket in the
// netlink handle. Although the socket timeout has granularity of one
// microsecond, the effective granularity is floored by the kernel timer tick,
// which default value is four milliseconds.
func (h *Handle) SetSocketTimeout(to time.Duration) error {
	if to < time.Microsecond {
		return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
	}
	tv := syscall.NsecToTimeval(to.Nanoseconds())
	for _, sh := range h.sockets {
		fd := sh.Socket.GetFd()
		err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
		if err != nil {
			return err
		}
		err = syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &tv)
		if err != nil {
			return err
		}
	}
	return nil
}
Example #15
0
func main() {
	lsFiles := exec.Command("git", "ls-files", "-z")

	out, err := lsFiles.Output()
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		os.Exit(1)
	}

	files := strings.Split(strings.TrimRight(string(out), "\x00"), "\x00")
	for _, file := range files {
		gitLog := exec.Command(
			"/bin/sh", "-c",
			fmt.Sprintf(`git log -n 1 --date=rfc2822 "%s" | head -n 3 | tail -n 1`, file),
		)

		out, err := gitLog.Output()

		if err != nil {
			fmt.Fprint(os.Stderr, err)
			os.Exit(1)
		}

		mStr := strings.TrimSpace(strings.TrimLeft(string(out), "Date:"))
		mTime, err := time.Parse(rfc2822, mStr)

		if err != nil {
			fmt.Fprintf(os.Stderr, "%s on %s", err, file)
			os.Exit(1)
		}

		mTimeval := syscall.NsecToTimeval(mTime.UnixNano())
		times := []syscall.Timeval{
			mTimeval,
			mTimeval,
		}
		syscall.Utimes(file, times)

		fmt.Printf("%s: %s\n", file, mTime)
	}
}
Example #16
0
func waitWithTimeout(socket int, timeout time.Duration) (state SocketState, err error) {
	wfdset := &syscall.FdSet{}

	FD_ZERO(wfdset)
	FD_SET(wfdset, socket)

	timeval := syscall.NsecToTimeval(int64(timeout))

	syscall.Select(socket+1, nil, wfdset, nil, &timeval)

	errcode, err := syscall.GetsockoptInt(socket, syscall.SOL_SOCKET, syscall.SO_ERROR)
	if err != nil {
		state = SocketError
		return
	}

	if errcode == int(syscall.EHOSTUNREACH) {
		state = SocketNotReached
		return
	}

	if errcode == int(syscall.ECONNREFUSED) {
		state = SocketPortClosed
		return
	}

	if errcode != 0 {
		state = SocketError
		err = fmt.Errorf("Connect Error: %v", errcode)
		return
	}

	if FD_ISSET(wfdset, socket) {
		state = SocketConnected
	} else {
		state = SocketTimedOut
	}
	return
}
Example #17
0
func main() {
	switch len(flag.Args()) {
	case 0:
		fmt.Printf("%v\n", date(z))
	case 1:
		argv0 := flag.Args()[0]
		if argv0[0] == '+' {
			fmt.Printf("%v\n", dateMap(argv0[1:]))
		} else {
			t, err := getTime(argv0)
			if err != nil {
				log.Fatalf("%v: %v", argv0, err)
			}
			tv := syscall.NsecToTimeval(t.UnixNano())
			if err := syscall.Settimeofday(&tv); err != nil {
				log.Fatalf("%v: %v", argv0, err)
			}
		}
	default:
		usage()
	}
}
Example #18
0
// Read reads from serial port. Port must be opened before calling this method.
// It is blocked until all data received or timeout after p.timeout.
func (p *port) Read(b []byte) (n int, err error) {
	var rfds syscall.FdSet

	fd := int(p.file.Fd())
	fdSet(fd, &rfds)

	var tv *syscall.Timeval
	if p.timeout > 0 {
		timeout := syscall.NsecToTimeval(p.timeout.Nanoseconds())
		tv = &timeout
	}
	if err = syscall.Select(fd+1, &rfds, nil, nil, tv); err != nil {
		err = fmt.Errorf("serial: could not select: %v", err)
		return
	}
	if !fdIsSet(fd, &rfds) {
		// Timeout
		err = ErrTimeout
		return
	}
	n, err = p.file.Read(b)
	return
}
Example #19
0
// Traceroute uses the given dest (hostname) and options to execute a traceroute
// from your machine to the remote host.
//
// Outbound packets are UDP packets and inbound packets are ICMP.
//
// Returns a TracerouteResult which contains an array of hops. Each hop includes
// the elapsed time and its IP address.
func Traceroute(dest string, options *TracerouteOptions, c ...chan TracerouteHop) (result TracerouteResult, err error) {
	result.Hops = []TracerouteHop{}
	destAddr, err := destAddr(dest)
	result.DestinationAddress = destAddr
	socketAddr, err := socketAddr()
	if err != nil {
		return
	}

	timeoutMs := (int64)(options.TimeoutMs())
	tv := syscall.NsecToTimeval(1000 * 1000 * timeoutMs)

	ttl := 1
	retry := 0
	for {
		//log.Println("TTL: ", ttl)
		start := time.Now()

		// Set up the socket to receive inbound packets
		recvSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
		if err != nil {
			return result, err
		}

		// Set up the socket to send packets out.
		sendSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
		if err != nil {
			return result, err
		}
		// This sets the current hop TTL
		syscall.SetsockoptInt(sendSocket, 0x0, syscall.IP_TTL, ttl)
		// This sets the timeout to wait for a response from the remote host
		syscall.SetsockoptTimeval(recvSocket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)

		defer syscall.Close(recvSocket)
		defer syscall.Close(sendSocket)

		// Bind to the local socket to listen for ICMP packets
		syscall.Bind(recvSocket, &syscall.SockaddrInet4{Port: options.Port(), Addr: socketAddr})

		// Send a single null byte UDP packet
		syscall.Sendto(sendSocket, []byte{0x0}, 0, &syscall.SockaddrInet4{Port: options.Port(), Addr: destAddr})

		var p = make([]byte, options.PacketSize())
		n, from, err := syscall.Recvfrom(recvSocket, p, 0)
		elapsed := time.Since(start)
		if err == nil {
			currAddr := from.(*syscall.SockaddrInet4).Addr

			hop := TracerouteHop{Success: true, Address: currAddr, N: n, ElapsedTime: elapsed, TTL: ttl}

			// TODO: this reverse lookup appears to have some standard timeout that is relatively
			// high. Consider switching to something where there is greater control.
			currHost, err := net.LookupAddr(hop.AddressString())
			if err == nil {
				hop.Host = currHost[0]
			}

			notify(hop, c)

			result.Hops = append(result.Hops, hop)

			ttl += 1
			retry = 0

			if ttl > options.MaxHops() || currAddr == destAddr {
				closeNotify(c)
				return result, nil
			}
		} else {
			retry += 1
			if retry > options.Retries() {
				notify(TracerouteHop{Success: false, TTL: ttl}, c)
				ttl += 1
				retry = 0
			}
		}

	}
}
Example #20
0
func (self *Syncer) copyRegularFile(srcName string, stat *os.FileInfo, dstName string, out chan SyncStats) {
	stats := new(SyncStats)
	defer func() { out <- *stats }()

	outfd, err := os.Open(dstName, os.O_CREATE|os.O_EXCL|os.O_WRONLY,
		stat.Permission())
	if err != nil {
		fmt.Fprintf(self.ErrorWriter,
			"Error opening copy output file %s: %s\n",
			dstName, err)
		stats.ErrorCount++
		return
	}
	defer outfd.Close()

	infd, err := os.Open(srcName, os.O_RDONLY, 0)
	if err != nil {
		fmt.Fprintf(self.ErrorWriter,
			"Error opening copy source file %s: %s\n",
			srcName, err)
		stats.ErrorCount++
		return
	}
	defer infd.Close()

	const BUF_SIZE = 1024 * 256
	buf := make([]byte, BUF_SIZE)
	bytesRemain := stat.Size
	for bytesRemain > 0 {
		n, err := infd.Read(buf)
		switch {
		case n == 0:
			break
		case n < 0:
			stats.ErrorCount++
			fmt.Fprintf(self.ErrorWriter, "Error copying file %s in read: %s",
				srcName, err)
			return
		default:
			outN, err := outfd.Write(buf[0:n])
			if err != nil || outN != n {
				fmt.Fprintf(self.ErrorWriter, "Error copying file %s in write: %s",
					srcName, err)
				return
			}
			bytesRemain -= int64(outN)
		}
	}

	// Close it explicitly before we syscall.Utime() it, even
	// though the precautionary defer'd Close() above will close
	// it again later.  That's harmless.
	err = outfd.Close()
	if err != nil {
		stats.ErrorCount++
		return
	}

	// When the Chtimes patch is merged upstream...
	// err = os.Chtimes(dstName, stat.Atime_ns, stat.Mtime_ns)
	var tv []syscall.Timeval = make([]syscall.Timeval, 2)
	tv[0] = syscall.NsecToTimeval(stat.Atime_ns)
	tv[1] = syscall.NsecToTimeval(stat.Mtime_ns)
	errno := syscall.Utimes(dstName, tv)
	if errno != 0 {
		fmt.Fprintf(self.ErrorWriter, "Error modifying utimes on %s: %v",
			dstName, errno)
		stats.ErrorCount++
		return
	}

	stats.FilesCreated++
	if self.Verbose {
		fmt.Fprintln(self.VerboseWriter, dstName)
	}
}
Example #21
0
func setsockoptNsec(fd, level, opt int, nsec int64) os.Error {
	var tv = syscall.NsecToTimeval(nsec)
	return os.NewSyscallError("setsockopt", syscall.SetsockoptTimeval(fd, level, opt, &tv))
}
Example #22
0
func (sock fd) connectTimeout(addr ax25Addr, timeout time.Duration) (err error) {
	if timeout == 0 {
		return sock.connect(addr)
	}
	if err = syscall.SetNonblock(int(sock), true); err != nil {
		return err
	}

	err = sock.connect(addr)
	if err == nil {
		return nil // Connected
	} else if err != syscall.EINPROGRESS {
		return fmt.Errorf("Unable to connect: %s", err)
	}

	// Shamelessly stolen from src/pkg/exp/inotify/inotify_linux.go:
	//
	// Create fdSet, taking into consideration that
	// 64-bit OS uses Bits: [16]int64, while 32-bit OS uses Bits: [32]int32.
	// This only support File Descriptors up to 1024
	//
	if sock > 1024 {
		panic(fmt.Errorf("connectTimeout: File Descriptor >= 1024: %v", sock))
	}
	fdset := new(syscall.FdSet)
	fElemSize := 32 * 32 / len(fdset.Bits)
	fdset.Bits[int(sock)/fElemSize] |= 1 << uint(int(sock)%fElemSize)
	//
	// Thanks!
	//

	// Wait or timeout
	var n int
	var tv syscall.Timeval
	for {
		tv = syscall.NsecToTimeval(int64(timeout))
		n, err = syscall.Select(int(sock)+1, nil, fdset, nil, &tv)
		if n < 0 && err != syscall.EINTR {
			return fmt.Errorf("Unable to connect: %s", err)
		} else if n > 0 {
			/* TODO: verify that connection is OK
			 * lon = sizeof(int);
			 * if (getsockopt(soc, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
			 *   fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
			 *   exit(0);
			 * }
			 * // Check the value returned...
			 * if (valopt) {
			 *   fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));
			 *   exit(0);
			 * }
			 */
			break
		} else {
			return fmt.Errorf("Unable to connect: timeout")
		}
	}

	syscall.SetNonblock(int(sock), false)
	return
}
Example #23
0
func toTimeval(d time.Duration) syscall.Timeval { return syscall.NsecToTimeval(int64(d)) }
Example #24
0
func Traceroute(dest string, options *TracerouteOptions, c ...chan TracerouteHop) (result TracerouteResult, err error) {
	result.Hops = []TracerouteHop{}
	destAddr, err := destAddr(dest)
	result.DestinationAddress = destAddr
	sockAddr, err := socketAddr()
	if err != nil {
		return
	}

	timeoutMs := (int64)(options.TimeoutMs())
	tv := syscall.NsecToTimeval(1000 * 1000 * timeoutMs)

	ttl := 1
	retry := 0
	for {
		start := time.Now()
		recvSock, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
		if err != nil {
			return result, err
		}
		sendSock, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
		if err != nil {
			return result, err
		}
		syscall.SetsockoptInt(sendSock, 0x0, syscall.IP_TTL, ttl)

		syscall.SetsockoptTimeval(recvSock, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
		defer syscall.Close(sendSock)
		defer syscall.Close(recvSock)

		syscall.Bind(recvSock, &syscall.SockaddrInet4{Port: options.Port(), Addr: sockAddr})

		syscall.Sendto(sendSock, []byte{0x0}, 0, &syscall.SockaddrInet4{Port: options.Port(), Addr: destAddr})

		var p = make([]byte, options.PacketSize())
		n, form, err := syscall.Recvfrom(recvSock, p, 0)
		elapsed := time.Since(start)
		if err == nil {
			currAddr := form.(*syscall.SockaddrInet4).Addr
			hop := TracerouteHop{Success: true, Address: currAddr, N: n, ElapsedTime: elapsed, TTL: ttl}
			currHost, err := net.LookupAddr(hop.AddressString())
			if err == nil {
				hop.Host = currHost[0]
			}
			notify(hop, c)

			result.Hops = append(result.Hops, hop)
			ttl += 1
			retry = 0

			if ttl > options.MaxHops() || currAddr == destAddr {
				closeNotify(c)
				return result, nil
			}

		} else {
			retry += 1
			if retry > options.Retries() {
				notify(TracerouteHop{Success: false, TTL: ttl}, c)
				ttl += 1
				retry = 0
			}
		}

	}
	return
}
Example #25
0
// readEvents reads from the inotify file descriptor, converts the
// received events into Event objects and sends them via the Event channel
func (w *Watcher) readEvents() {
	var buf [syscall.SizeofInotifyEvent * 4096]byte

	// Timeout after 500 milliseconds when waiting for events
	// so we can reliably close the Watcher
	timeout := int64(500e6)
	readFds := newFdSet(w.fd)
	for {
		var n int
		var err error
		select {
		// See if there is a message on the "done" channel
		case <-w.done:
		// Otherwise select fd with timeout
		default:
			tmpSet := *readFds
			timeval := syscall.NsecToTimeval(timeout)
			n, err = syscall.Select(w.fd+1, &tmpSet, nil, nil, &timeval)
			if n == 1 {
				n, err = syscall.Read(w.fd, buf[0:])
			} else if err != nil {
				w.Error <- err
			} else {
				continue
			}
		}

		// If EOF or a "done" message is received
		if n == 0 {
			goto done
		}
		if n < 0 {
			w.Error <- os.NewSyscallError("read", err)
			continue
		}
		if n < syscall.SizeofInotifyEvent {
			w.Error <- errors.New("inotify: short read in readEvents()")
			continue
		}

		var offset uint32 = 0
		// We don't know how many events we just read into the buffer
		// While the offset points to at least one whole event...
		for offset <= uint32(n-syscall.SizeofInotifyEvent) {
			// Point "raw" to the event in the buffer
			raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
			event := new(Event)
			event.Mask = uint32(raw.Mask)
			event.Cookie = uint32(raw.Cookie)
			nameLen := uint32(raw.Len)
			// If the event happened to the watched directory or the watched file, the kernel
			// doesn't append the filename to the event, but we would like to always fill the
			// the "Name" field with a valid filename. We retrieve the path of the watch from
			// the "paths" map.
			w.mu.Lock()
			event.Name = w.paths[int(raw.Wd)]
			// Check if the the watch was removed
			if event.Mask&IN_IGNORED != 0 {
				// remove stale watch
				delete(w.watches, event.Name)
				delete(w.paths, int(raw.Wd))
			}
			w.mu.Unlock()
			if nameLen > 0 {
				// Point "bytes" at the first byte of the filename
				bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
				// The filename is padded with NUL bytes. TrimRight() gets rid of those.
				event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
			}
			// Send the event on the events channel
			w.Event <- event

			// Move to the next event in the buffer
			offset += syscall.SizeofInotifyEvent + nameLen
		}
	}
done:
	w.isClosed = true // keep API behaviour consistent when EOF was read
	err := syscall.Close(w.fd)
	if err != nil {
		w.Error <- os.NewSyscallError("close", err)
	}
	close(w.Event)
	close(w.Error)
	for path, watch := range w.watches {
		delete(w.watches, path)
		delete(w.paths, int(watch.wd))
	}
}
Example #26
0
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
	if p.nReady == 0 {
		var timeout *syscall.Timeval
		var tv syscall.Timeval
		timeout = nil
		if nsec > 0 {
			tv = syscall.NsecToTimeval(nsec)
			timeout = &tv
		}

		var n int
		var e error
		var tmpReadFds, tmpWriteFds syscall.FdSet
		for {
			if p.closed {
				return -1, 0, errors.New("pollster closed")
			}

			// Temporary syscall.FdSet's into which the values are copied
			// because select mutates the values.
			tmpReadFds = *p.readFds
			tmpWriteFds = *p.writeFds

			s.Unlock()
			n, e = syscall.Select(p.maxFd+1, &tmpReadFds, &tmpWriteFds, nil, timeout)
			s.Lock()

			if e != syscall.EINTR {
				break
			}
		}
		if e == syscall.EBADF {
			// Some file descriptor has been closed.
			tmpReadFds = syscall.FdSet{}
			tmpWriteFds = syscall.FdSet{}
			n = 0
			for i := 0; i < p.maxFd+1; i++ {
				if syscall.FDIsSet(i, p.readFds) {
					var s syscall.Stat_t
					if syscall.Fstat(i, &s) == syscall.EBADF {
						syscall.FDSet(i, &tmpReadFds)
						n++
					}
				} else if syscall.FDIsSet(i, p.writeFds) {
					var s syscall.Stat_t
					if syscall.Fstat(i, &s) == syscall.EBADF {
						syscall.FDSet(i, &tmpWriteFds)
						n++
					}
				}
			}
		} else if e != nil {
			return -1, 0, os.NewSyscallError("select", e)
		}
		if n == 0 {
			return -1, 0, nil
		}

		p.nReady = n
		*p.readyReadFds = tmpReadFds
		*p.readyWriteFds = tmpWriteFds
		p.lastFd = 0
	}

	flag := false
	for i := p.lastFd; i < p.maxFd+1; i++ {
		if syscall.FDIsSet(i, p.readyReadFds) {
			flag = true
			mode = 'r'
			syscall.FDClr(i, p.readyReadFds)
		} else if syscall.FDIsSet(i, p.readyWriteFds) {
			flag = true
			mode = 'w'
			syscall.FDClr(i, p.readyWriteFds)
		}
		if flag {
			if !syscall.FDIsSet(i, p.repeatFds) {
				p.DelFD(i, mode)
			}
			p.nReady--
			p.lastFd = i
			return i, mode, nil
		}
	}

	// Will not reach here.  Just to shut up the compiler.
	return -1, 0, nil
}
Example #27
0
func MakeTimeval(t time.Duration) syscall.Timeval {
	return syscall.NsecToTimeval(int64(t))
}
Example #28
0
// readEvents reads from the inotify file descriptor, converts the
// received events into Event objects and sends them via the Event channel
func (w *Watcher) readEvents() {
	var (
		buf   [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
		n     int                                     // Number of bytes read with read()
		errno error                                   // Syscall errno
	)

	rfds := &syscall.FdSet{}
	timeout := &syscall.Timeval{}

	for {
		// Select to see if data available
		*timeout = syscall.NsecToTimeval(selectWaitTime)
		FD_ZERO(rfds)
		FD_SET(rfds, w.fd)
		if _, errno = syscall.Select(w.fd+1, rfds, nil, nil, timeout); errno != nil {
			w.Error <- os.NewSyscallError("select", errno)
		}

		// See if there is a message on the "done" channel
		select {
		case <-w.done:
			syscall.Close(w.fd)
			close(w.internalEvent)
			close(w.Error)
			return
		default:
		}

		// Check select result to see if Read will block, only read if no blocking.
		if FD_ISSET(rfds, w.fd) {
			n, errno = syscall.Read(w.fd, buf[0:])
		} else {
			continue
		}

		// If EOF is received
		if n == 0 {
			syscall.Close(w.fd)
			close(w.internalEvent)
			close(w.Error)
			return
		}

		if n < 0 {
			w.Error <- os.NewSyscallError("read", errno)
			continue
		}
		if n < syscall.SizeofInotifyEvent {
			w.Error <- errors.New("inotify: short read in readEvents()")
			continue
		}

		var offset uint32 = 0
		// We don't know how many events we just read into the buffer
		// While the offset points to at least one whole event...
		for offset <= uint32(n-syscall.SizeofInotifyEvent) {
			// Point "raw" to the event in the buffer
			raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
			event := new(FileEvent)
			event.mask = uint32(raw.Mask)
			event.cookie = uint32(raw.Cookie)
			nameLen := uint32(raw.Len)
			// If the event happened to the watched directory or the watched file, the kernel
			// doesn't append the filename to the event, but we would like to always fill the
			// the "Name" field with a valid filename. We retrieve the path of the watch from
			// the "paths" map.
			w.mu.Lock()
			event.Name = w.paths[int(raw.Wd)]
			w.mu.Unlock()
			watchedName := event.Name
			if nameLen > 0 {
				// Point "bytes" at the first byte of the filename
				bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
				// The filename is padded with NUL bytes. TrimRight() gets rid of those.
				event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
			}

			// Send the events that are not ignored on the events channel
			if !event.ignoreLinux() {
				// Setup FSNotify flags (inherit from directory watch)
				w.fsnmut.Lock()
				if _, fsnFound := w.fsnFlags[event.Name]; !fsnFound {
					if fsnFlags, watchFound := w.fsnFlags[watchedName]; watchFound {
						w.fsnFlags[event.Name] = fsnFlags
					} else {
						w.fsnFlags[event.Name] = FSN_ALL
					}
				}
				w.fsnmut.Unlock()

				w.internalEvent <- event
			}

			// Move to the next event in the buffer
			offset += syscall.SizeofInotifyEvent + nameLen
		}
	}
}