Menu

#5 atftp fails to write to /proc/self/fd/1

v1.0_(example)
closed
nobody
None
5
2021-01-31
2020-03-16
No

I've been using atftp for many years, and I often fetch small blocks of
text data and write them to stdout by doing something like this:

 atftp -g -l /proc/self/fd/1 -r cmd@version 10.0.0.99 

This has worked flawlessy for something like 8-10 years. Within the past few days, it started
failing with the following error:

$ atftp -g -l /proc/self/fd/1 -r cmd@version 10.0.0.99
tftp: error writing to file /proc/self/fd/1
tftp: aborting

Strace indicates the failure seems to be caused by atftp trying to do a seek() on a non-seekable file:

openat(AT_FDCWD, "/proc/self/fd/1", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
sendto(3, "\0\1cmd@version\0octet\0", 20, 0, {sa_family=AF_INET, sin_port=htons(69), sin_addr=inet_addr("10.0.0.99")}, 128) = 20
select(1024, [3], NULL, NULL, {tv_sec=5, tv_usec=0}) = 1 (in [3], left {tv_sec=4, tv_usec=985378})
recvmsg(3, {msg_name={sa_family=AF_INET, sin_port=htons(69), sin_addr=inet_addr("10.0.0.99")}, msg_namelen=128->16, msg_iov=[{iov_base="\0\3\0\1\nU-Boot 2010.06-svn11541 Ver"..., iov_len=516}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 67
connect(3, {sa_family=AF_INET, sin_port=htons(69), sin_addr=inet_addr("10.0.0.99")}, 128) = 0
fstat(4, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0
lseek(4, 0, SEEK_SET)                   = -1 ESPIPE (Illegal seek)
write(2, "tftp: error writing to file /pro"..., 44) = 44

This seek() call doesn't seem to be something recent, so I'm baffled why it worked up until a few days ago.

I also don't really understand the need for the seek() call. Doesn't the TFTP protocol require that blocks be sent in the proper order?

Discussion

  • Anonymous

    Anonymous - 2020-03-16

    This code seems to work well:

    int tftp_file_write(FILE *fp, char *data_buffer, int data_buffer_size, long block_number, int data_size,
                        int convert, long *prev_block_number, int *temp)
    {
         static long filepos;
         int bytes_written;
         int c;
         char prevchar = *temp;
    
         if (!convert)
         {
              /* Simple case, just seek and write */
              long position = (block_number - 1)*data_buffer_size;
              if (position != filepos)
                   if (fseek(fp, position, SEEK_SET) != 0)
                        return 0;
                   else
                        filepos = position;
              bytes_written = fwrite(data_buffer, 1, data_size, fp);
              filepos += bytes_written;
         }
         else if (block_number != *prev_block_number)
         {
              /* 
     [...]
    
     
  • Anonymous

    Anonymous - 2020-09-25

    Is this project alive?

     
    • Martin Dummer

      Martin Dummer - 2021-01-31

      Hello Grant,
      yes, i try to maintain the atftp a little bit, there will probably be no further developments.
      I will merge your patch and say "thank you"!

       
  • Martin Dummer

    Martin Dummer - 2021-01-31
    • status: open --> closed
     

Log in to post a comment.

MongoDB Logo MongoDB