pdisk, ofctl and yaboot

Garrett Cooper yanefbsd at gmail.com
Sun Jun 29 19:46:00 UTC 2008


On Sun, Jun 29, 2008 at 11:59 AM, Niels S. Eliasen
<nse at delfi-konsult.com> wrote:
> Hi Garrett
> perhaps I'm, daft... don't answer! ;-)
> but that snippet code of yours.... How do I incorporate this into the code
> for grub ??
> (you have probably guessed by now... that I am not very well versed in C...)
>
> Den 27/06/2008 kl. 18.21 skrev Garrett Cooper:
>
>> On Fri, Jun 27, 2008 at 9:14 AM, Peter Grehan <grehan at freebsd.org> wrote:
>>>>
>>>> 3. Anyone that knows how to integrate the Open Firmware parameters for
>>>> FreeBSD with yaboot ?
>>>
>>>  At one point the loader's load address conflicted with yaboot. This may
>>> not
>>> be the case anymore - it's been a very long time since I looked at it.
>>> But
>>> in theory the loader could be booted from yaboot.
>>>
>>>> If only FreeBSD, NetBSD and OpenBSD (all macppc) could agree upon how to
>>>> integrate with yaboot... alternatively find one unified boot-sequence...
>>>> life would be so much easier ....
>>
>> IIRC yaboot was being deprecated for Grub 2.x. There are some
>> outstanding bugs (I found) with how yaboot parses secondary cd drives
>> and the like that I was going to debug and fix a while back, but I got
>> caught up with other things...
>> I'd definitely compile the last stable and work from that though
>> because there are a few new helpful features for booting from
>> non-standard locations for yaboot.conf files.
>> Cheers,
>> -Garrett
>
> kind regards
>
> nse

That'll either have to be patched in or included as separate source
(with CFLAGS += -D_GNU_COMPAT).

I'll checkout grub2 once I get my Macbook back (Tuesday-ish) and see
if I can make sure that getline functions properly under FreeBSD and
Linux.

I modified the source to now include getdelims(3) (simple modification).

Cheers,
-Garrett

/*
 * Licensed under New BSD [3-clause] License available in FreeBSD.
 *
 * Author:	Garrett Cooper
 * Email:	gcooper [at {SpamFree}] freebsd [dot] org
 * Date:	June 28, 2008
 *
 */

#include <limits.h>     /* For INT_MAX */
#include <stdio.h>      /* For everything stdio (fgetc, etc). */
#include <string.h>     /* malloc, free, and the usual memory suspects. */
#include <sys/types.h>  /* For ssize_t */

/*
 * Analog to _GNU_SOURCE -- do this to avoid confusing autoconf /
 * automake (I'm sure they have
 * some sort of getline() detection scheme), until it can be verified
 * that this is fully compatible and
 * doesn't accidentally break existing functionality.
 */
#if _GNU_COMPAT

#define DEFAULT_LINES   	256
#define DEFAULT_LINES_INC	16
#define MAX_LINE_SIZE   	INT_MAX

ssize_t getline(char **, size_t*, FILE*);
ssize_t getdelims(char **, size_t*, int, FILE*);

/*
 * XXX: WRITE PROPER COMMENTS HERE.
 */
ssize_t
getline(char **linep, size_t *n, FILE *fp)
{
	return getdelims(linep, n, (int) '\0', fp);
}

/*
 * @name	 getdelims
 *
 * @desc	 Gets a line up to a char delimited by delim or a '\0' terminator.
 *
 * @param	**linep	- array of char** to use as placeholder for read line. NULL
 *			  terminated. If NULL, will allocate DEFAULT_LINES+1 via
 *			  calloc().
 * @param	*n	- Number of chars requested to be read, then is replaced with.
 * @param	delim	- Delimiter to break lines with.
 * @param	*fp	- file descriptor to read.
 *
 * @pre	  *fp != NULL
 *
 * @ret	  ssize_t == length of str on success.
 * @ret	  ssize_t == -1 for error
 *
 * @todo	 Fix Doxygen comments =).
 * @todo	 Check compatibility with GNU getline().
 *
 */
ssize_t
getdelims(char **linep, size_t *n, int delim, FILE *fp)
{
	char *line_tmp;
	/* Index in line_tmp */
	int idx;
	/* Assume FAIL until proven otherwise. */
	int ret_code = -1;

	if (n == NULL)
		 goto done;

	/* XXX: *n = 0 => GNU getline compat? */
	*n = 0;

	/* fp cannot be NULL (segfault prone). */
	if (fp == NULL)
		 goto done;

	line_tmp = (char*) malloc(MAX_LINE_SIZE+1);

	idx = 0;

	/*
	 * Grab each char until a newline's encountered or '/0'.
	 *
	 * XXX: Tune the while conditional so that realloc's are done as necessary?
	 */
	do {
		 ch = fgetc(fp);
		 if (ch == '\0' || ch != (char) delim)
			  break;

		 *(line_tmp+idx) = ch;

		 idx++;

	} while (idx < MAX_LINE_SIZE);

	/* Include newline */
	if (ch == '\n') {
		 *(line_tmp+idx) = '\n'
		 idx++;
	}

	*(line_tmp+idx) = '\0';

	/*
	 * malloc a new char** area for linep because it's NULL. Make sure
	 * that there are +1 lines so a NULL can be stored there.
	 */
	if (linep == NULL) {
		 linep = (char**) calloc(DEFAULT_LINES+1,*sizeof(char**));
		 if (linep == NULL)
			  goto done;
	}
	/*
	 * Increment size of linep, because we've potentially run out of play space.
	 *
	 * XXX: Tune to not increment in specific cases, lest we _will_ run
	 * out of memory?
	 */
	else {
		 linep = (char**) realloc(linep,
			(DEFAULT_LINES_INC+1)*sizeof(char**)+sizeof(linep));
		 /* NULL terminate linep */
		 *(linep+sizeof(linep)) = NULL;
	}

	size_t n_new = sizeof(line_tmp);

	/* Don't do jack if line_tmp has 0-length. */
	if (1 < n_new) {

		 /* Allocate a new char* for *linep because it's NULL. */
		 if (*linep == NULL) {
			  *linep = (char*) malloc(n_new);
		 }
		 /* Resize *linep to meet line_tmp's size. */
		 else if (*n != sizeof(line_tmp)) {
			  *linep = (char*) realloc(*linep, n_new);
		 }

		 /* Avoid NULL deref (segfault). */
		 if (*linep == NULL)
			  goto done;

		 /* Copy string */
		 strcpy(*linep, line_tmp);
		 *n = n_new;

		 /* Done! */
		 ret_code = strlen(*linep);

	}

done:
	/* cleanup temporary vars */
	if (line_tmp != NULL)
		 free(line_tmp);
	/* end cleanup */

	return ret_code;

}
#endif


More information about the freebsd-ppc mailing list