LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-25-2007, 10:39 AM   #1
vadiml
Member
 
Registered: Oct 2003
Posts: 44

Rep: Reputation: 19
Splice syscall does not work


Hello,
I'm trying to do a splice syscall from
tcp socket to a write side of a pipe
and getting BAD FILE DESCRIPTOR error...

Is it expected behaviour?
 
Old 10-25-2007, 12:45 PM   #2
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
Can you show what code is causing this error? Please post code in [code] tags to preserve formatting ans aid readability.

Last edited by matthewg42; 12-15-2007 at 06:19 PM.
 
Old 10-26-2007, 05:21 AM   #3
vadiml
Member
 
Registered: Oct 2003
Posts: 44

Original Poster
Rep: Reputation: 19
Ok, here is the code it is run with:
./tsplice 127.0.0.1:9000
Btw, where one can find the full doc for splice syscall?

Thanks

Code:
// tsplice.c - test splice syscall 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>



int 
sa_pton(int af, const char *cp, struct sockaddr *sa)
{
  sa->sa_family = af;
  return inet_pton(af, cp, &((struct sockaddr_in *) sa)->sin_addr);

}

void 
sa_set_port(struct sockaddr *sa, int port)
{
  ((struct sockaddr_in *) sa)->sin_port = htons(port);
}


int 
sa_ptonp(int af, const char *cp, struct sockaddr *sa)
{
  char *ports;
  int r;
  char *cp2 = alloca(strlen(cp) + 1);

  strcpy(cp2, cp);
  ports = strrchr(cp2, ':');
  if (ports)
    *ports = 0;

  sa->sa_family = af;
  r =  inet_pton(af, cp2, &((struct sockaddr_in *) sa)->sin_addr);
  if (r > 0)
    sa_set_port(sa, atoi(ports+1));

  return r;

}


void error(const char *m)
{
  perror(m);
  exit(1);
}

char data[] = "012345678";

#define DATASIZE (sizeof(data))

char  rbuf[256];

main(int argc, char *argv[])
{
  struct sockaddr sa;
  struct sockaddr lsa;
  int s1, s2, s3;
  int pipes[2];
  int r1, r2, r3;
  loff_t o1 = 0, o2 = 0;
  int alen = sizeof(lsa);

  sa_ptonp(AF_INET, argv[1], &sa);

  s1 = socket(AF_INET, SOCK_STREAM, 0);
  if (s1 < 0)
    error("socket");

  r1 = bind(s1, &sa, sizeof(sa));
  if (r1 < 0)
    error("bind");

  r1 = listen(s1, 1);
  if (r1 < 0)
    error("listen");


  s2 = socket(AF_INET, SOCK_STREAM, 0);
  if (s2 < 0)
    error("second socket");

  r1 = connect(s2, &sa, sizeof(sa));
  if (r1 < 0)
    error("connect");

  s3 = accept(s1, &lsa, &alen);
  if (s3 < 0)
    error("connect");

  pipe(pipes);
  
  r1 = write(s2, data, DATASIZE);
  r2 = splice(s3, &o1, pipes[1], &o2, DATASIZE, 0);
  if (r2 < 0)
    {
      error("splice syscall");
    }

  printf("r1=%d, r2=%d\n", r1, r2);


  r3 = read(pipes[0], rbuf, DATASIZE);


  printf("r1=%d, r2=%d, r3=%d, data=%s\n", r1, r2, r3, rbuf);
  

}
 
Old 10-13-2015, 12:23 AM   #4
ikrabbe
LQ Newbie
 
Registered: Oct 2015
Location: Borussia Dortmund
Distribution: gentoo, plan9, 9front
Posts: 2

Rep: Reputation: Disabled
Quote:
Originally Posted by vadiml View Post
Ok, here is the code it is run with:
./tsplice 127.0.0.1:9000
Btw, where one can find the full doc for splice syscall?
Just check splice(2).

If you get <0 from a ssize_t syscall, it should be informative to check errno... hmm you do:
When you get a bad file descriptor: Output the fd number. Check the pipe call.

The
Code:
connect
without a listening
Code:
accept
should block your program.

Last edited by ikrabbe; 10-13-2015 at 12:30 AM. Reason: code review
 
Old 10-15-2015, 04:37 AM   #5
vadiml
Member
 
Registered: Oct 2003
Posts: 44

Original Poster
Rep: Reputation: 19
Problem with splice

now i'm getting:

splice syscall: Illegal seek


Any ideas about the reason?
 
Old 10-15-2015, 05:24 AM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 2,835

Rep: Reputation: 791Reputation: 791Reputation: 791Reputation: 791Reputation: 791Reputation: 791Reputation: 791
This syscall might not work on pipe/socket? Anyways, it is a linux-only feature, so you shouldn't use it at all. Use sendfile.

Edit: whenever you change something, always quote the modified code, for those who aren't clairvoyants.

Last edited by NevemTeve; 10-15-2015 at 05:27 AM.
 
Old 10-15-2015, 05:58 AM   #7
ikrabbe
LQ Newbie
 
Registered: Oct 2015
Location: Borussia Dortmund
Distribution: gentoo, plan9, 9front
Posts: 2

Rep: Reputation: Disabled
don't seek in pipes!

@vadiml as NevemTeve told you, seek does not work anywhere.
splice is meant to be used for pipes and you cannot seek in pipes.

Assume this example:

echo "Hello, world\!" | some-seeking-program

now you can try to seek the 8th byte of stdin, which should fail with illegal seek too as you cannot seek in pipes.
 
Old 10-15-2015, 07:43 AM   #8
vadiml
Member
 
Registered: Oct 2003
Posts: 44

Original Poster
Rep: Reputation: 19
I've found the problem:

Code:
r2 = splice(s3, &o1, pipes[1], &o2, DATASIZE, 0);
should be modified as follows;

Code:
r2 = splice(s3, 0, pipes[1], 0, DATASIZE, 0);
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
syscall hook robertos Linux - Kernel 15 03-09-2007 07:33 PM
need help with splice() and disk read graphicsMan Programming 0 02-19-2007 11:13 AM
DISCUSSION: Splice Traffic with Perlbal jeremy LinuxAnswers Discussion 0 02-05-2007 05:38 PM
Deleting elements from array in perl with splice signalno9 Programming 2 08-16-2005 10:57 PM
how do i splice an x-box controller cable? ubuntu-addict General 4 11-12-2004 07:22 AM


All times are GMT -5. The time now is 01:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration