-1

I am trying to print the position of the file pointer(via the printpos() function) showing its position in the child and parent. Upon compiling my code I am left with these errors:

xxxxxx@ubuntu:~/USP_ASG2$ gcc -o q1 q1.c 
/tmp/cc4zpABN.o: In function `main':
q1.c:(.text+0xdd): undefined reference to `printpos'
q1.c:(.text+0x171): undefined reference to `printpos'
q1.c:(.text+0x1fd): undefined reference to `printpos'
q1.c:(.text+0x2a4): undefined reference to `printpos'
collect2: error: ld returned 1 exit status

code(for reference):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  char x[3];
  x[0]='y';
  int ch;

  while(x[0]=='y'||x[0]=='Y')
  {
  int status;
  pid_t pid;

  int a = 123456;
  float b = 123.456;
  char c = 'Z';
  char buff[5];
  int fd = open("/proc/meminfo", O_RDONLY);

  //Retriving address's
  void *ap=&a, *bp=&b, *cp=&c;

    printf("\n---------------Initial Values---------------\n");
    printf("Parent Values:\n");
    printf("Integer a: \tvalue = %d, \taddress = %p\n", a, ap);
    printf("Float b: \tvalue = %f, \taddress = %p\n", b, bp);
    printf("Char c: \tvalue = %c, \t\taddress = %p\n", c, cp); 
    printpos("Pointer Position: ", fd);

    pid = fork();

  if(pid > 0)
  {
    pid = wait(&status);
    printf("\nParent Changed Values:\n");
    printf("Integer a: \tvalue = %d, \taddress = %p\n", a, ap);
    printf("Float b: \tvalue = %f, \taddress = %p\n", b, bp);
    printf("Char c: \tvalue = %c, \t\taddress = %p\n", c, cp);
    printpos("Pointer Position: ", fd);

    sleep(1);
  }
  else if(pid == 0)
  {

    printf("\nChild Initial Values:\n");
    printf("Integer a: \tvalue = %d, \taddress = %p\n", a, ap);
    printf("Float b: \tvalue = %f, \taddress = %p\n", b, bp);
    printf("Char c: \tvalue = %c, \t\taddress = %p\n", c, cp);
    printpos("Pointer Position: ", fd);

    a = 654321;
    b = 654.321;
    c = 'A';
    read(fd, buff, 5);

    printf("\n---------------Changed Values---------------\n");
    printf("\nChild Changed Values:\n");
    printf("Integer a: \tvalue = %d, \taddress = %p\n", a, ap);
    printf("Float b: \tvalue = %f, \taddress = %p\n", b, bp);
    printf("Char c: \tvalue = %c, \t\taddress = %p\n", c, cp);
    printpos("Pointer Position: ", fd);

    return 0;
  }
  else
    printf("fork() did not work"); 

  if(pid >0)
  {
      printf("Run Again?(y/n):");
      fgets(x, 2, stdin);
      while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
  }
  }

 return 0; 
}
Andrew Ricci
  • 475
  • 5
  • 21
  • 1
    `printpos` is not a standard C function (AFAIK). So the obvious question - where is `printpos` defined? – kaylum Oct 13 '15 at 00:15
  • 1
    The linker, much like everybody looking at your code, is unable to find `printpos()` anywhere. Of course the compiler could have told you something was fishy, if you'd asked its opinion (`-Wall -Wextra -Wpedantic`), rather than running roughshod over its feelings and ignoring the problems until you no longer could. – EOF Oct 13 '15 at 00:15
  • Makes sense. I must be looking at really old examples then. – Andrew Ricci Oct 13 '15 at 00:18
  • There's never been a standard function like this, so age wouldn't do it. Maybe you're looking at examples for a specific system that adds it. – Barmar Oct 13 '15 at 00:30
  • Its a UNIX textbook. This book is all code. Unless its pseudo code, but I doubt it. Book is "UNIX System Programming 2nd Edition" By Dina Grey, Ben Salama, and Keith Haviland. – Andrew Ricci Oct 13 '15 at 01:45
  • @AndrewRicci Page 102 of the book provides the implementation of `printpos`. Which unsurprisingly is essentially `lseek` as shown in the accepted answer. – kaylum Oct 13 '15 at 02:54

2 Answers2

0

You can use lseek and printf.

printf("Pointer Position: %lld\n", lseek(fd, 0, SEEK_CUR));
Jason
  • 3,777
  • 14
  • 27
  • `lseek()` returns a result of type `off_t`, which may or may not be the same type as `long long`. You need a cast: `printf("Pointer Position: %lld\n", (long long)lseek(fd, 0, SEEK_CUR));` – Keith Thompson Oct 13 '15 at 00:30
  • @KeithThompson is correct. Platform differences are a bit of a rabbit hole, but casting to `(long long)` will generally be safe. – Jason Oct 13 '15 at 00:53
0

The problem here is that there is no function called printpos. Here is some code that should do what was intended.

void printpos( char* text, int fd )
{
    off_t position;
    position = lseek( fd, 0, SEEK_CUR );
    if( position >= 0 )
    {
        printf( "%s%lld\n", text, (long long)position );
    }
    else
    {
        printf( "Error getting position in file\n" );
    }
}

[Edit: Updated code to add (long long) cast of off_t as it may be a different type on some platforms]

waterjuice
  • 829
  • 5
  • 14