func main() { var ( rset, wset, eset syscall.FdSet still_running, curl_timeout int = 0, 0 err error ) ch1 := curl.EasyInit() ch2 := curl.EasyInit() ch1.Setopt(curl.OPT_URL, "http://www.163.com") ch1.Setopt(curl.OPT_HEADER, 0) ch1.Setopt(curl.OPT_VERBOSE, true) ch2.Setopt(curl.OPT_URL, "http://www.baidu.com") ch2.Setopt(curl.OPT_HEADER, 0) ch2.Setopt(curl.OPT_VERBOSE, true) mh := curl.MultiInit() mh.AddHandle(ch1) mh.AddHandle(ch2) for { FD_ZERO(&rset) FD_ZERO(&wset) FD_ZERO(&eset) timeout := syscall.Timeval{Sec: 1, Usec: 0} curl_timeout, err = mh.Timeout() if err != nil { fmt.Printf("Error multi_timeout: %s\n", err) } if curl_timeout >= 0 { timeout.Sec = int64(curl_timeout / 1000) if timeout.Sec > 1 { timeout.Sec = 1 } else { timeout.Usec = int64((curl_timeout % 1000)) * 1000 } } max_fd, err := mh.Fdset(&rset, &wset, &eset) if err != nil { fmt.Printf("Error FDSET: %s\n", err) } _, err = syscall.Select(int(max_fd+1), &rset, &wset, &eset, &timeout) if err != nil { fmt.Printf("Error select: %s\n", err) } else { still_running, err = mh.Perform() if still_running > 0 { fmt.Printf("Still running: %d\n", still_running) } else { break } } } }
func (w *Worker) createRawSocket() (fd int) { socket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_TCP) if err != nil { fmt.Fprintf(os.Stderr, "fail to Socket :%s\n", err.Error()) os.Exit(1) } err = syscall.SetsockoptString(socket, syscall.IPPROTO_IP, syscall.IP_HDRINCL, "1") if err != nil { fmt.Fprintf(os.Stderr, "SetsockoptString error :%s\ns", err.Error()) os.Exit(1) } timeVal := new(syscall.Timeval) timeVal.Sec = 6 err = syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, timeVal) if err != nil { fmt.Fprintf(os.Stderr, "SetsockoptTimeval error :%s", err.Error()) os.Exit(1) } return socket }
func (self *Uptime) Get() error { tv := syscall.Timeval{} if err := sysctlbyname("kern.boottime", &tv); err != nil { return err } self.Length = time.Since(time.Unix(tv.Unix())).Seconds() return nil }
func getRusage(usage usageType) float64 { rusage := &syscall.Rusage{} syscall.Getrusage(0, rusage) var time *syscall.Timeval if usage == USER_TIME { time = &rusage.Utime } else { time = &rusage.Stime } nsec := time.Nano() return float64(nsec) / 1000000000 }
func (p *Pinger) listenIpv4() { if p.conn == nil { panic("conn doesnt exist") } log.Printf("starting rawSocket listener\n") rb := make([]byte, 1500) pkt := EchoResponse{} var readErr error var data []byte ipconn, ok := p.conn.(*net.IPConn) if !ok { panic("connection is not IPConn") } file, err := ipconn.File() if err != nil { panic(err.Error()) } defer file.Close() fd := file.Fd() var pktTime time.Time recvTime := syscall.Timeval{} for { if p.conn == nil { break } n, peer, err := p.conn.ReadFrom(rb) if err != nil { readErr = err break } _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.SIOCGSTAMP), uintptr(unsafe.Pointer(&recvTime))) err = nil if errno != 0 { err = errno } if err == nil { pktTime = time.Unix(0, recvTime.Nano()) } else { pktTime = time.Now() } rm, err := icmp.ParseMessage(ProtocolICMP, rb[:n]) if err != nil { fmt.Println(err.Error()) continue } if rm.Type == ipv4.ICMPTypeEchoReply { data = rm.Body.(*icmp.Echo).Data if len(data) < 9 { log.Printf("go-pinger: invalid data payload from %s. Expected at least 9bytes got %d", peer.String(), len(data)) continue } pkt = EchoResponse{ Peer: peer.String(), Seq: rm.Body.(*icmp.Echo).Seq, Id: rm.Body.(*icmp.Echo).ID, Received: pktTime, } if p.Debug { log.Printf("go-pinger: recieved pkt. %s\n", pkt.String()) } select { case p.packetChan <- pkt: default: log.Printf("go-pinger: droped echo response due to blocked packetChan. %s\n", pkt.String()) } } } if p.Debug { log.Printf("listen loop ended.") } p.m.Lock() if p.running { log.Println(readErr.Error()) p.Stop() p.start() } p.m.Unlock() }
// timeToTimeval - Convert time.Time to syscall.Timeval // // Note: This does not use syscall.NsecToTimespec because // that does not work properly for times before 1970, // see https://github.com/golang/go/issues/12777 func timeToTimeval(t *time.Time) syscall.Timeval { var tv syscall.Timeval tv.Usec = int32(t.Nanosecond() / 1000) tv.Sec = t.Unix() return tv }
func timevalToDuration(tv syscall.Timeval) time.Duration { return time.Duration(tv.Nano()) * time.Nanosecond }
// Returns errors (if any) triggered by the inotify subsystem or when reading // the file. Errors when writing to the writer are ignored. func streamFile(writer io.Writer, path string, maxIdleTime uint32) error { handle, err := os.Open(path) if err != nil { return err } _, err = handle.Seek(0, os.SEEK_END) if err != nil { handle.Close() return err } reader := bufio.NewReader(handle) readBuffer := make([]byte, 4096) inotifyFd, err := syscall.InotifyInit() if err != nil { handle.Close() return err } watchDesc, err := syscall.InotifyAddWatch(inotifyFd, path, syscall.IN_MODIFY) if err != nil { syscall.Close(inotifyFd) handle.Close() return err } eventsBuffer := make([]byte, syscall.SizeofInotifyEvent*4096) selectMaxIdleTime := syscall.Timeval{} selectMaxIdleTime.Sec = int64(maxIdleTime) inotifyFdSet := syscall.FdSet{} lastWriteTime := time.Now() canScan := true for canScan && !timeout(lastWriteTime, maxIdleTime) { clearAll(&inotifyFdSet) set(&inotifyFdSet, inotifyFd) _, err := syscall.Select(inotifyFd+1, &inotifyFdSet, nil, nil, &selectMaxIdleTime) if err != nil { break } if !isSet(&inotifyFdSet, inotifyFd) { continue } numEventsBytes, err := syscall.Read(inotifyFd, eventsBuffer[0:]) if numEventsBytes < syscall.SizeofInotifyEvent { if numEventsBytes < 0 { err = errors.New("inotify: read failed.") } else { err = errors.New("inotify: short read.") } break } var offset uint32 = 0 for offset <= uint32(numEventsBytes-syscall.SizeofInotifyEvent) { event := (*syscall.InotifyEvent)(unsafe. Pointer(&eventsBuffer[offset])) n, err := reader.Read(readBuffer) if err != nil { // Ignore the EOF error and continue polling // the file until timeout. if err == io.EOF { err = nil } break } buffer := make([]byte, n) for index := 0; index < n; index++ { buffer[index] = readBuffer[index] } _, err = writer.Write(buffer) if err != nil { // Stop scanning for updates to the file. canScan = false // Ignore the write error. err = nil break } lastWriteTime = time.Now() // Move to the next event. offset += syscall.SizeofInotifyEvent + event.Len } } // The inotify watch gets automatically removed by the inotify system // when the file is removed. If the above loop times out, but the file // is removed only just before the if block below is executed, then the // removal of the watch below will throw an error as the watch // descriptor is obsolete. We ignore this error because it is harmless. syscall.InotifyRmWatch(inotifyFd, uint32(watchDesc)) // Though we return the first error that occured, we still need to // attempt to close all the file descriptors. inotifyCloseErr := syscall.Close(inotifyFd) handleCloseErr := handle.Close() if err != nil { return err } else if inotifyCloseErr != nil { return inotifyCloseErr } return handleCloseErr }
func (s *SyncReceiver) HandleConnection(conn net.Conn) { var err error defer func() { log.Println("Receiver: client disconnect with:", err) if err != nil { conn.Write([]byte{VerifyResultError}) } conn.Close() }() log.Println("New Connection Com") br := bufio.NewReader(conn) headerLen := syncHeaderLen() headerBuf := make([]byte, headerLen) _, err = br.Read(headerBuf) if err != nil { return } syncHeader := NewSyncHeaderFromBytes(headerBuf) log.Println("Read Header Succ", syncHeader.FileLength) buf_filename, err := br.ReadBytes('\n') //log.Println(len(buf_filename), buf_filename) if len(buf_filename) <= 1 { return } filename := string(buf_filename[0 : len(buf_filename)-1]) log.Println("filename:", filename) filename = path.Join(s.cfg.SyncRootFolder, filename) var fi os.FileInfo fi, err = os.Stat(filename) if os.IsNotExist(err) || fi.IsDir() { log.Printf("no such file: %s\n", filename) conn.Write([]byte{VerifyResultTransferToMe}) //NOW Read&Write Entire File rbuf := make([]byte, 512) //readbuf //create temp file tempfilename := filename + ".syncing" tempFile, err := os.Create(tempfilename) if err != nil { log.Println("Create temp file error", err) return } endTransfer := false readedBytes := int64(0) for !endTransfer { n, err := br.Read(rbuf) if err != nil { log.Println("Transfering File Err:", err) return } if n > 0 { if nw, err := tempFile.Write(rbuf[0:n]); err != nil || nw != n { log.Println("Write tempfile error") return } } readedBytes += int64(n) if readedBytes > syncHeader.FileLength { log.Println("Transfer more than syncheader:", readedBytes, syncHeader.FileLength) return } else if readedBytes == syncHeader.FileLength { endTransfer = true } log.Println("recv:", n) } if err := tempFile.Close(); err != nil { log.Println("Sync&Close temp file failed!") return } // log.Println("file recv over") //rename file & give a new mod time os.Rename(tempfilename, filename) fi, _ = os.Stat(filename) accessTimeval := new(syscall.Timeval) accessTimeval.Sec = fi.ModTime().Unix() modTimeval := new(syscall.Timeval) modTimeval.Sec = syncHeader.FileModTime.Unix() err = syscall.Utimes(filename, []syscall.Timeval{*accessTimeval, *modTimeval}) if err != nil { log.Println("utime error:", err) return } err = nil conn.Write([]byte{VerifyResultDoNext}) log.Println("sync over!!!") } else { if syncHeader.FileLength == fi.Size() && syncHeader.FileModTime.Equal(fi.ModTime()) { log.Println("Timestamp & Size Equal. This file is synced") conn.Write([]byte{VerifyResultDoNext}) //TBD continue the loop } else { log.Println("Modtime not equal. So need file compare") //Send need compare flag conn.Write([]byte{VerifyResultNeedCompare}) //Compute & Send chunkchecksum // syncHeader.FileLength f, err := os.Open(filename) if err != nil { log.Println("open file err:", err) return } checkSum := NewRollingCheckSum(f, syncHeader.ChunkSize) hashes, err := checkSum.SumEveryChunk() if err != nil { log.Println("error when generate checksum", err) return } checksumBytes := CheckSumPackArrayToBytes(hashes) conn.Write(checksumBytes) //adler+md5 //Recv TransferData Packages } } /* version := br.ReadByte() packageType := br.ReadByte() if !(version == 0x01 && packageType == PackageTypeSyncRequest) { return } return temp2 := make([]byte, 2) br.Read(temp) //little endian packageLen := uint16(temp2[0])|(uint16(temp2[1])<<8) io.WriteString(conn, "Hi") */ }