anchor.diff:  %% logrotate)
   ensure(Fd,DevName) when is_atom(DevName) ->
       Fd;
  -ensure({Fd,INode},FileName) ->
  +ensure({Fd,INode},FileInfo) ->
  +    FileName = element(2, FileInfo),
       case file:read_file_info(FileName) of
           {ok,#file_info{inode=INode}} ->
               {Fd,INode};
           _ ->
               _ = file:close(Fd),
               _ = file:close(Fd), % delayed_write cause close not to close
  -            case do_open_log_file({file,FileName}) of
  +            case do_open_log_file(FileInfo) of
                   {ok,File} ->
                       File;
                   Error ->
  
positive.code: 
  file_ctrl_init(HandlerName, FileInfo, Starter) when is_tuple(FileInfo) ->
      process_flag(message_queue_data, off_heap),
      FileName = element(2, FileInfo),
      case do_open_log_file(FileInfo) of
          {ok,File} ->
              Starter ! {self(),ok},
              file_ctrl_loop(File, FileName, false, ok, ok, HandlerName);
          {error,Reason} ->
              Starter ! {self(),{error,{open_failed,FileName,Reason}}}
      end;
  file_ctrl_init(HandlerName, StdDev, Starter) ->
      Starter ! {self(),ok},
      file_ctrl_loop(StdDev, StdDev, false, ok, ok, HandlerName).
  
  file_ctrl_loop(File, DevName, Synced,
                 PrevWriteResult, PrevSyncResult, HandlerName) ->
      receive
          %% asynchronous event
          {log,Bin} ->
              File1 = ensure(File, DevName),
              Result = write_to_dev(File1, Bin, DevName,
                                    PrevWriteResult, HandlerName),
              file_ctrl_loop(File1, DevName, false,
                             Result, PrevSyncResult, HandlerName);
  
          %% synchronous event
          {{log,Bin},{From,MRef}} ->
              File1 = ensure(File, DevName),
              Result = write_to_dev(File1, Bin, DevName,
                                    PrevWriteResult, HandlerName),
              From ! {MRef,ok},
              file_ctrl_loop(File1, DevName, false,
                             Result, PrevSyncResult, HandlerName);
  
          filesync ->
              File1 = ensure(File, DevName),
              Result = sync_dev(File1, DevName, Synced,
                                PrevSyncResult, HandlerName),
              file_ctrl_loop(File1, DevName, true,
                             PrevWriteResult, Result, HandlerName);
  
          {filesync,{From,MRef}} ->
              File1 = ensure(File, DevName),
              Result = sync_dev(File1, DevName, Synced,
                                PrevSyncResult, HandlerName),
              From ! {MRef,ok},
              file_ctrl_loop(File1, DevName, true,
                             PrevWriteResult, Result, HandlerName);
  
          stop ->
  
negative.code: write_to_dev(DevName, Bin, _DevName, _PrevWriteResult, _HandlerName)
    when is_atom(DevName) ->
      io:put_chars(DevName, Bin);
  write_to_dev({Fd,_}, Bin, FileInfo, PrevWriteResult, HandlerName) ->
      Result = ?file_write(Fd, Bin),
      maybe_notify_error(write,Result,PrevWriteResult,FileInfo,HandlerName).
  
  sync_dev(_, _FileInfo, true, PrevSyncResult, _HandlerName) ->
      PrevSyncResult;
  sync_dev({Fd,_}, FileInfo, false, PrevSyncResult, HandlerName) ->
      Result = ?file_datasync(Fd),
      maybe_notify_error(filesync,Result,PrevSyncResult,FileInfo,HandlerName).
  
  maybe_notify_error(_Op, ok, _PrevResult, _FileInfo, _HandlerName) ->
      ok;
  maybe_notify_error(_Op, PrevResult, PrevResult, _FileInfo, _HandlerName) ->
      %% don't report same error twice
      PrevResult;
  maybe_notify_error(Op, Error, _PrevResult, FileInfo, HandlerName) ->
      FileName = element(2, FileInfo),
      logger_h_common:error_notify({HandlerName,Op,FileName,Error}),
      Error.
  